fix(agents): suppress reasoning blocks from channel delivery#18935
fix(agents): suppress reasoning blocks from channel delivery#18935BinHPdev wants to merge 5 commits intoopenclaw:mainfrom
Conversation
Two code paths injected reasoning/thinking text into channel delivery: 1. Streaming path (handlers.messages.ts): shouldEmitReasoning gated on onBlockReply being truthy, meaning reasoning was emitted specifically when a channel callback existed. Invert the condition so reasoning is suppressed when a channel callback is present. 2. Final payload builder (payloads.ts): unconditionally pushed formatted reasoning into replyItems which feeds into channel delivery. Remove the push entirely — reasoning is agent-internal and should never be forwarded to channels. Fix openclaw#18667
Additional Comments (2)
the condition now requires this effectively disables reasoning emission entirely, which suppresses it from channels (the goal) but the logic is contradictory. consider either:
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Prompt To Fix With AIThis is a comment left during a code review.
Path: src/agents/pi-embedded-subscribe.handlers.messages.ts
Line: 295:309
Comment:
logic bug: condition inverted but emission target unchanged
the condition now requires `!onBlockReply` (line 298) but `maybeEmitReasoning()` still calls `onBlockReply?.(...)` (line 308). when `onBlockReply` is undefined, the optional chaining does nothing.
this effectively disables reasoning emission entirely, which suppresses it from channels (the goal) but the logic is contradictory. consider either:
- removing `maybeEmitReasoning()` calls entirely since it's now a no-op
- or adding a comment explaining why the function does nothing by design
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.
this test expects reasoning to be emitted via Prompt To Fix With AIThis is a comment left during a code review.
Path: src/agents/pi-embedded-subscribe.subscribe-embedded-pi-session.emits-reasoning-as-separate-message-enabled.e2e.test.ts
Line: 28:44
Comment:
test expects old behavior - will fail
this test expects reasoning to be emitted via `onBlockReply` when `reasoningMode: "on"` (lines 41-43), but the PR intentionally removes this behavior. the test needs to be updated to reflect the new behavior where reasoning is suppressed from `onBlockReply`, or removed if that behavior is no longer supported.
How can I resolve this? If you propose a fix, please make it concise. |
…in test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tion - Correct function name: subscribeEmbeddedPiSession (no "To") - Remove unused vi import from vitest - Replace shallow typeof check with a real harness-based suppression test that asserts onToolResult is NOT called for memory_search and IS called for a regular tool (read) - Add isInternalToolResult guard to emitToolSummary and emitToolOutput in pi-embedded-subscribe.ts so that memory tool results are suppressed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uppressed reasoning behavior
- Remove the dead `void onBlockReply?.({ text: formattedReasoning })` call
from maybeEmitReasoning: shouldEmitReasoning is only true when !onBlockReply,
so the optional-chained call could never fire. Add a comment explaining this.
- Update the stale e2e test that expected reasoning to be emitted via
onBlockReply (2 calls) when reasoningMode:"on". The new behavior suppresses
reasoning from channel delivery entirely — assert 1 call (answer only).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Status update — addressed greptile feedback, all 5 tests passing. Changes since initial submission:
Tests verified passing locally. |
|
Closing — the reasoning block suppression logic has since landed in main (outbound.ts now filters REASONING_PREFIX payloads directly). This fix is no longer needed. |
Summary
Root Cause
Two code paths injected reasoning text into channel delivery:
Streaming path (
handlers.messages.ts):shouldEmitReasoninggated ononBlockReplybeing truthy — meaning reasoning was emitted specifically when a channel callback existed. This is backwards: reasoning should be suppressed when a channel callback is present.Final payload builder (
payloads.ts): Unconditionally pushed formatted reasoning intoreplyItemswhenreasoningLevel === "on". ThisreplyItemsarray feeds directly into channel delivery for all channels.Changes
src/agents/pi-embedded-subscribe.handlers.messages.ts: InvertonBlockReply &&to!onBlockReply &&inshouldEmitReasoningcondition, suppressing reasoning emission to channels while preserving non-channel behavior.src/agents/pi-embedded-runner/run/payloads.ts: Remove unconditional reasoning push toreplyItemsand clean up unused imports (extractAssistantThinking,formatReasoningMessage).src/agents/pi-embedded-runner/run/payloads.reasoning.test.ts: 2 tests verifying reasoning is not included in payloads and assistant answers still work normally.Test plan
pnpm vitest run src/agents/pi-embedded-runner/— 25 tests passreasoningLevel: "on"Fix #18667
🤖 Generated with Claude Code
Greptile Summary
This PR fixes reasoning/thinking blocks leaking into channel messages (iMessage, Telegram, Discord) by suppressing them from two code paths:
payloads.ts): cleanly removed reasoning fromreplyItemsarrayhandlers.messages.ts): inverted condition but created contradictory logic wheremaybeEmitReasoning()still callsonBlockReplywhich no longer existsKey issues:
!onBlockReplybut then tries to callonBlockReply?.(), effectively disabling reasoning emission (achieves the goal but via confusing dead code)emits-reasoning-as-separate-message-enabled.e2e.test.tsexpects the old behavior and will failpi-embedded-runner/tests, missing the failing test inpi-embedded-subscribeConfidence Score: 2/5
src/agents/pi-embedded-subscribe.handlers.messages.tshas contradictory logic, andemits-reasoning-as-separate-message-enabled.e2e.test.tsneeds updateLast reviewed commit: 6c5b0c2