Repository navigation
Description
Summary
When the agent is actively running (executing tool calls), incoming text messages from the user are silently queued with no interruption and no feedback. The user has no way to stop the agent except by using /stop. Natural language stop requests ("stop", "para", "frena") are treated as regular messages and enqueued.
Impact
High — the user loses control of the agent during long tool-call sequences. The only escape hatch is knowing about /stop, which is not discoverable in the moment.
Reproduction
- Send a message that triggers a multi-tool-call response (e.g. a complex coding task)
- While the agent is running, send a plain text message like "stop" or "wait"
- Observe: no feedback, no interruption. The message is queued silently.
- The agent continues until it finishes or
/stopis used.
Root Cause
gateway/platforms/base.py lines ~3317-3339:
When session_key in self._active_sessions and the message is not a recognized slash command (checked via should_bypass_active_session), the message enters the queue path:
if self._is_queue_text_debounce_candidate(event):
await self._queue_text_debounce(session_key, event)
else:
merge_pending_message_event(self._pending_messages, session_key, event, ...)
return # Don't process now - will be handled after current task finishesNo feedback is sent to the user. No interrupt is triggered.
Evidence from logs
19:08:21 INFO [Telegram] Flushing text batch ...session... (6 chars)
19:09:56 INFO [Telegram] Flushing text batch ...session... (24 chars)
19:10:49 INFO [Telegram] Flushing text batch ...session... (13 chars)
19:11:04 INFO [Telegram] Flushing text batch ...session... (4 chars)
19:11:48 INFO Invalidated run generation [...] (stop_command) <- /stop finally worked
Four messages received and flushed but never delivered as interrupts. Only /stop broke through.
Proposed Solutions (not mutually exclusive)
- Feedback on queue: When a message is enqueued during an active session, send a brief acknowledgment: "⏳ Agent busy — message queued. Use /stop to interrupt."
- Natural stop-word detection: Recognize bare stop-intent messages (configurable list: "stop", "para", "halt", "cancel", etc.) and treat them as
/stopequivalents. - Configurable busy_text_mode: interrupt: Add an option where ANY incoming text interrupts the running agent (current behavior is queue-only unless
busy_input_mode: steer).
Solution 1 is the minimum viable fix — the user at least knows their message did not interrupt anything.
Environment
- Hermes Agent (latest main as of 2026-05-24)
- Platform: Telegram DM
- Model: claude-opus-4.6 via gateway
Activity
kiyo-e commentedon May 26, 2026
I’m seeing this on Telegram as well.
When I send another normal text message while a Telegram turn is active, it does not interrupt the current run. The current run continues with no visible feedback that the new message was queued. After the current run finishes, that queued message is then read and handled as the next turn.
This happens even when the active turn is not especially long-running. I started noticing it after updating to a build where #21444 appeared to be addressed, though I’m not saying that fix necessarily caused it.
perqin commentedon May 28, 2026
I ran into the same issue and found that it is introduced by #31341 . You could explicitly add
display.busy_text_mode: interruptin config.yaml to go back to the previous behavior. Sadly I think this is a breaking change and the default value should beinterruptinstead ofqueue🙁UnderLotus commentedon May 29, 2026
Confirming this on v0.15.1 (2026.5.29), Telegram gateway.
Text messages while agent is busy are silently queued — no interrupt, no ack. Only
/stopbreaks through.Log evidence (same pattern as OP):
Three minutes of text messages completely ignored in between.
fix(gateway): plain text while busy interrupts by default again (#40590)
teknium1 commentedon Jun 6, 2026
Fixed in PR #40590 (merged to main as 54e7b74). Root cause: a second undocumented knob, busy_text_mode (default queue), short-circuited plain TEXT messages before busy_input_mode was consulted — so the advertised interrupt default was silently overridden. busy_input_mode is now the single source of truth and defaults to interrupt; busy_text_mode survives only as a legacy explicit override. #40590
fix(gateway): plain text while busy interrupts by default again (#40590)
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): send feedback when text messages are queued during acti…
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): plain text while busy interrupts by default again (Nous…
fix(gateway): plain text while busy interrupts by default again (Nous…