fix(agent-runner): deliver assistant text as fallback when model skips message tool#84328
fix(agent-runner): deliver assistant text as fallback when model skips message tool#84328billehunt wants to merge 1 commit into
Conversation
…s message tool When sourceReplyDeliveryMode is message_tool_only (default for Telegram group chats), model responses were silently dropped if the model generated text without calling the message tool. Mark those payloads for fallback delivery so the user always sees the response.
|
Codex review: needs maintainer review before merge. Workflow note: Future ClawSweeper reviews update this same comment in place. How this review workflow works
Summary Reproducibility: yes. from source inspection and PR evidence, but I did not run a live Telegram repro. Current main suppresses unmarked final replies in PR rating Rank-up moves:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. PR egg Rarity: 🥚 common. What is this egg doing here?
Real behavior proof Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land the scoped fallback with maintainer acceptance of the live Telegram proof, ideally with a focused regression test proving the fallback marks only undelivered assistant text. Do we have a high-confidence way to reproduce the issue? Yes from source inspection and PR evidence, but I did not run a live Telegram repro. Current main suppresses unmarked final replies in Is this the best way to solve the issue? Yes, likely. The patch stays in the agent-runner delivery boundary and reuses the existing side-effect helper; focused regression coverage would make it stronger. Label justifications:
What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 3bc728eaa993. |
|
Instead of adding fallbacks, we should fix the actual root cause and understand why the model doesn't use the message tool as instructed. |
Summary
Fixes #84327
When
sourceReplyDeliveryModeis"message_tool_only"(the default for Telegram group/channel chats), model responses were silently dropped if the model generated text without calling themessagetool. This marks those payloads for fallback delivery so the user always sees the response.Problem
The dispatch layer in
dispatch-from-config.tssuppresses all reply payloads that lackdeliverDespiteSourceReplySuppressionmetadata whensuppressDeliveryis true. Payloads from themessagetool get this flag viamarkReplyPayloadForSourceSuppressionDelivery, but plain assistant text payloads frombuildEmbeddedRunPayloadsnever do.When the model intermittently skips calling the
messagetool (observed after long idle periods when the Anthropic prompt cache goes cold), the response text is generated but silently discarded at the dispatch layer.Fix
In
agent-runner.ts, after the agent run completes: ifsourceReplyDeliveryModeis"message_tool_only", the model produced text payloads, and no side-effect delivery occurred (no message tool call, no block streaming, no cron adds), mark those payloads withdeliverDespiteSourceReplySuppressionso they bypass the dispatch suppression.Uses the existing
hasSuccessfulSideEffectDeliveryhelper so the fallback only activates when no other delivery path succeeded.Real behavior proof
Tested on a live Telegram bot (OpenClaw v2026.5.12,
claude-opus-4-7via Anthropic API, group chat with queue modesteer).Before fix — three consecutive turns with trajectory evidence:
[]false[][]false[][]false[]All three responses were silently discarded. User saw nothing.
After fix — deployed the fix and restarted gateway:
[]falseSame pattern (model skipped message tool), but the fallback delivery kicked in and the user received the response.
What was not tested: Block streaming interaction (block streaming was enabled but the model didn't stream in the broken turns). The fix checks
hasSuccessfulSideEffectDeliverywhich covers block streaming, so there should be no double-delivery when block streaming succeeds.Verification
🤖 AI-assisted: diagnosis and fix authored with Claude Code (Opus 4.6). Human confirmed the fix works via live Telegram testing.