-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
Expose stopReason in message_sending plugin hook metadata #66235
Copy link
Copy link
Closed as not planned
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.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.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.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.staleMarked as stale due to inactivityMarked as stale due to inactivity
Description
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.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.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.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.staleMarked as stale due to inactivityMarked as stale due to inactivity
Type
Fields
Priority
None yet
Problem
When a model generates text before a tool call (e.g., "Let me check that..."), that text block gets delivered to the messaging channel as a separate message. In non-streaming mode, these reasoning preamble messages arrive after the actual response, creating visible inner monologue leaks in channels like Discord.
Current behavior
The
message_sendingplugin hook receives:There is no way to distinguish between:
stopReason: "toolUse") — always inner monologuestopReason: "stop" / "end_turn") — the actual replyProposed change
Pass
stopReason(and optionallyhasToolCalls: boolean) through to themessage_sendinghook metadata:The relevant code is in
applyMessageSendingHook()in the delivery pipeline, which constructs the metadata object. ThestopReasonis available in the agent command layer but is not currently forwarded to delivery.Why this matters
This would allow plugins to structurally suppress reasoning preambles:
This is more reliable than content-based pattern matching (regex for "Let me..." / "Now I need to...") which can false-positive on legitimate responses.
Context
Running an OpenClaw Discord bot that monitors guild channels. In non-streaming mode, text blocks from
stopReason: "toolUse"responses consistently leak as separate messages. The existingoutput-sanitizerplugin catches most cases viaMETA_PLANNING_PATTERNSregex, but a structural filter would be definitive.Workaround
Re-enable the
output-sanitizerplugin with content-based filtering.