fix(gateway): mirror hidden commentary-phase assistant events#92216
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds support for mirroring certain hidden (non-control-UI-visible) assistant events to session message subscribers, so selected clients can still receive assistant commentary/deltas even when the main control UI is hidden.
Changes:
- Introduces a predicate to decide which assistant events should be mirrored to hidden session message subscribers.
- Adds a new handler branch that sends mirrored assistant payloads to session-message subscribers (via
broadcastToConnIds) withcontrolUiVisible: false. - Adds tests covering mirroring behavior and ensuring aborted runs do not mirror.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/gateway/server-chat.ts | Adds mirroring decision logic and a new event-handler branch to send hidden assistant events to session message subscribers. |
| src/gateway/server-chat.agent-events.test.ts | Adds test coverage for mirroring to exact session message subscribers and for aborted-run suppression. |
|
Codex review: needs real behavior proof before merge. Reviewed June 12, 2026, 11:29 PM ET / 03:29 UTC. Summary PR surface: Source +26, Tests +154. Total +180 across 2 files. Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path. Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Review detailsBest possible solution: Retry the Codex review after fixing the execution failure. Do we have a high-confidence way to reproduce the issue? Unclear. The review failed before ClawSweeper could establish a reproduction path. Is this the best way to solve the issue? Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction. AGENTS.md: unclear because the file could not be read completely. Codex review notes: model internal, reasoning high; reviewed against 6cf06e8e7eb0. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +26, Tests +154. Total +180 across 2 files. View PR surface stats
What I checked:
Likely related people:
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. How this review workflow works
|
|
Proof section updated with exact parser fields plus before/after real user ClickClack screenshots. @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Follow-up pushed on Validation on the new head: Real behavior proof is green on @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Copilot follow-up is closed out.
The prior re-review hit transient Codex transport before producing a durable verdict, so requesting a fresh run after the Copilot thread closeout. @clawsweeper re-review |
|
Docs contract follow-up pushed on
Validation after the docs follow-up: Proof body re-check after editing still passes @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review Please rerun against the current narrowed head The prior durable ClawSweeper marker says real behavior proof is missing, but the PR body now includes a
Current scope is trimmed per maintainer feedback: one gateway mirror commit, two files changed, no embedded-handler change, and no docs contract file. |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
…sage subscribers Non-control-UI-visible runs previously dropped assistant commentary on the floor for session message subscribers. Mirror those events to exact session subscribers, gated strictly on phase === "commentary" so untagged text or delta frames and final-answer streaming never dual-lane into channel surfaces. Dialects that emit commentary as untagged deltas should tag the phase at provider normalization instead. Co-authored-by: Forge <[email protected]> Co-authored-by: Chisel <[email protected]>
ba7ce8b to
b2fac9d
Compare
|
Landed via rebase onto main.
Thanks @ragesaq! |
Problem
Hidden channel-session subscribers can receive live tool events without the Control UI being visible, but they were not receiving assistant events that had already been normalized as commentary.
That made channel surfaces asymmetric:
This PR is separate from #92092. #92092 fixed claude-cli narration being dropped before gateway fanout. This PR only fixes gateway fanout for commentary events that already exist.
Root cause
createAgentEventHandler()already had a hidden-session path for tool events whenisControlUiVisibleis false. There was no matching hidden-session mirror for assistant events whose phase resolves tocommentary.The result: hidden channel subscribers could see tools, but not commentary, even when the provider/runtime had already emitted the commentary event.
Fix
Add a narrow hidden-session mirror for commentary-phase assistant events:
isControlUiVisibleis falsecommentaryfinal_answerframessendAgentPayload(..., { controlUiVisible: false, dropIfSlow: true })pathDeliberately not in scope
This PR does not define the broader channel transaction contract. It does not make
room_event + message_tool_onlyproduce commentary, does not change model prompting, does not alter provider phase normalization, and does not change ClickClack rendering.The next channel-progress fix should be a separate PR: a first-class progress/preamble lane for channel turns where final answers remain
message(action=send)owned, while interim commentary can flow as commentary/progress.Tests
Focused gateway regression coverage in
src/gateway/server-chat.agent-events.test.ts:phase: "commentary"assistant text to exact hidden session subscribersphase: "commentary"delta-only assistant framesphase: "final_answer"nodeSendToSessionValidation previously run on this branch:
Real behavior proof
Behavior addressed: hidden/channel session subscribers received tool events but not commentary-phase assistant events, preventing ClickClack from building a commentary preamble when those commentary events existed.
Real environment tested: OpenClaw gateway built from this patch and restarted on
2026-06-11T15:31Z; ClickClack bridge subscribed to the real channel sessionagent:chisel:clickclack:channel:channel:chn_01ktq4zg9bga4dqrycqz67jts6; real ClickClack#testand#generalturns driven by ragesaq through the deployed bridge.Exact steps or command run after this patch:
fix/channel-hidden-commentary.openclaw-gateway.serviceandclickclack-bridge.service.#testand#general.agent_commentaryrows alongsideagent_toolrows after deploy.Evidence after fix:
Before this patch, ragesaq's channel-originated ClickClack turn reached the final answer, but no commentary/tool preamble rendered for the long-running turn:
After this patch, ragesaq's channel-originated ClickClack turn rendered an expanded preamble with assistant commentary interleaved with tool-call rows:
ClickClack also persisted real
agent_commentaryrows in the channel alongsideagent_toolrows. Example rows from the ClickClack DB after deploy:Additional proof artifacts:
Observed result after fix: ClickClack can receive hidden commentary-phase assistant frames for the exact channel session, persist them as durable
agent_commentarymessages, and render them in the preamble while final answer delivery remains separate.What was not tested: upstream-maintainer-hosted deployment; provider/runtime generation of commentary under every model and delivery mode; the future
room_event + message_tool_onlyprogress-lane contract.Risk checklist
commentary;final_answerand untagged frames are not mirrored.dropIfSlow: truebehavior.AI assistance
AI-assisted. Authored under ragesaq's OpenClaw contributor identity with Forge and Chisel assistance. ragesaq supplied the real before/after ClickClack screenshots and directed the proof update; Chisel prepared this narrowed PR body revision with
openai/gpt-5.5.