-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
message_tool_only: agent does not terminate after delivering a source reply — cascade of self-replies within one run #96827
Copy link
Copy link
Open
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
What Problem This Solves
Since v2026.6.10, an agent configured with
sourceReplyDeliveryMode: "message_tool_only"(the default visible-reply mode for group chats androom_eventturns) does not terminate its run after a successfulmessage(action=send)delivery. Instead, the agentic loop continues: the model fetches again, produces anothermessage(send), which delivers and loops again — a cascade of self-replies within a single embedded run.On Telegram this surfaces as the bot sending a rapid sequence of messages to the group, each one a new generated reply to its own previous output, until some other limit (max iterations, token budget, or the model deciding to stop) kicks in. Observed: 7
sendMessagecalls (messageIds 8031–8037) in a single 61-second run; 7 more (8039–8046) in the next 72-second run.Why This Change Was Made
The terminal-send inhibition relies on two signals that were historically coupled:
messageToolOnlySourceReplyDelivered, set inembedded-agent-subscribe.handlers.tools.tsafter a deliveredmessage(send)is detected.afterToolCallhook (installed viainstallMessageToolOnlyTerminalHookinsrc/agents/embedded-agent-runner/run/message-tool-terminal.ts) that — on v2026.5.22 through v2026.6.6 — returned{ ...hookResult, terminate: true }on a qualifying delivery.Commit
462092936a("fix(agent): continue after source message tool replies", #92343) refactoredmessage-tool-terminal.tsfor v2026.6.10 and dropped theterminate: truefrom the return (message-tool-terminal.ts:58is nowreturn hookResult;). The hook now sets only the state flag (viaonDeliveredSourceReply), with no early-termination hint.The flag-based path does not halt the loop: each successful
sendMessage okis followed by another provider fetch, the model sees its prior delivery in context and generates anothermessage(send), which delivers and loops again. TheAfterToolCallResult.terminatefield (packages/agent-core/src/types.ts:80: "the agent should stop after the current tool batch") exists precisely to break this cycle, and was the mechanism that prevented it on v2026.6.6 and earlier.User Impact
message_tool_onlysurface) see the bot reply to itself in a cascade — a visible regression from v2026.6.6 behavior, where a delivered source reply ended the run immediately.Evidence
Pre-refactor (v2026.6.6) —
src/agents/embedded-agent-runner/run/message-tool-terminal.ts:v2026.6.10 — same file, lines 57–58:
Observed cascade (Telegram group,
message_tool_only, v2026.6.10 image, single run9b2fbadb):Each
outbound send okis preceded by its own provider fetch — distinct generated replies, not retransmits.Workaround (applied locally on
local-patches-v2026.6.10): restorereturn { ...hookResult, terminate: true };at line 58. The detection path (isDeliveredMessageToolOnlySourceReply, which checks bothcontext.resultandhookResult) is unchanged from v2026.6.6, so the fix is a one-line restoration of v2026.6.6 semantics on top of v2026.6.10's refactored detection.