Skip to content

fix(gateway): mirror hidden commentary-phase assistant events#92216

Merged
obviyus merged 1 commit into
openclaw:mainfrom
ragesaq:fix/channel-hidden-commentary
Jun 13, 2026
Merged

fix(gateway): mirror hidden commentary-phase assistant events#92216
obviyus merged 1 commit into
openclaw:mainfrom
ragesaq:fix/channel-hidden-commentary

Conversation

@ragesaq

@ragesaq ragesaq commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

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:

  • tool activity could reach the channel-side preamble/progress UI
  • commentary-phase assistant events did not reach the same exact hidden session subscribers
  • final delivery still worked, so the failure looked like missing preamble rather than a broken turn

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 when isControlUiVisible is false. There was no matching hidden-session mirror for assistant events whose phase resolves to commentary.

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:

  • runs only when isControlUiVisible is false
  • requires a resolved session key and exact session-message subscribers
  • mirrors only assistant frames whose resolved phase is commentary
  • accepts text or delta content only when phase is commentary
  • excludes untagged assistant frames and final_answer frames
  • preserves aborted-run suppression
  • reuses the existing hidden sendAgentPayload(..., { controlUiVisible: false, dropIfSlow: true }) path

Deliberately not in scope

This PR does not define the broader channel transaction contract. It does not make room_event + message_tool_only produce 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:

  • mirrors phase: "commentary" assistant text to exact hidden session subscribers
  • mirrors phase: "commentary" delta-only assistant frames
  • does not mirror untagged text frames
  • does not mirror untagged delta-only frames
  • does not mirror terminal text without delta
  • does not mirror phase: "final_answer"
  • does not globally broadcast hidden commentary or send it through nodeSendToSession
  • does not send to other session subscribers
  • does not mirror aborted hidden runs

Validation previously run on this branch:

node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/server-chat.agent-events.test.ts --maxWorkers=1
Test Files  1 passed (1)
Tests       87 passed (87)

pnpm tsgo:core
# clean

pnpm tsgo:test:src
# clean

git diff --check
# clean

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 session agent:chisel:clickclack:channel:channel:chn_01ktq4zg9bga4dqrycqz67jts6; real ClickClack #test and #general turns driven by ragesaq through the deployed bridge.

  • Exact steps or command run after this patch:

    1. Built the OpenClaw gateway from branch fix/channel-hidden-commentary.
    2. Restarted openclaw-gateway.service and clickclack-bridge.service.
    3. Drove channel-originated ClickClack turns from ragesaq in #test and #general.
    4. Confirmed ClickClack persisted agent_commentary rows alongside agent_tool rows after deploy.
    5. Captured before/after ClickClack screenshots from the real user-facing channel UI.
  • 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:

before: final answer without commentary preamble

After this patch, ragesaq's channel-originated ClickClack turn rendered an expanded preamble with assistant commentary interleaved with tool-call rows:

after: expanded preamble with commentary and tool calls

ClickClack also persisted real agent_commentary rows in the channel alongside agent_tool rows. Example rows from the ClickClack DB after deploy:

2026-06-11T15:55:29.371130227Z  agent_commentary  Pushed (`6055c05`). Posting the summary to the channel.
2026-06-11T15:55:21.602563769Z  agent_tool        **exec**
2026-06-11T15:55:41.92467386Z   agent_tool        **message**

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_commentary messages, 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_only progress-lane contract.

Risk checklist

  • Behavior change scope: hidden/channel session-message subscribers now receive commentary-phase assistant events they were already subscribed to but missing. Control-UI-visible behavior is untouched.
  • Final-answer duplication: guarded by requiring resolved phase commentary; final_answer and untagged frames are not mirrored.
  • Session isolation: uses the existing exact session-message subscriber registry and tests assert only the selected session receives events.
  • Abort behavior: preserved and covered by regression test.
  • Persistence/schema: no schema or storage changes.
  • Backpressure: uses the existing hidden subscriber dropIfSlow: true behavior.

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.

Copilot AI review requested due to automatic review settings June 11, 2026 16:33
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) with controlUiVisible: 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.

Comment thread src/gateway/server-chat.ts
Comment thread src/gateway/server-chat.ts
@clawsweeper

clawsweeper Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 12, 2026, 11:29 PM ET / 03:29 UTC.

Summary
Review failed before ClawSweeper could summarize the requested change.

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: 🌊 off-meta tidepool
Proof: 🌊 off-meta tidepool
Patch quality: 🌊 off-meta tidepool
Result: rating does not apply to this item.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P1] No close action taken because the review did not complete.

Maintainer options:

  1. Decide the mitigation before merge
    Retry the Codex review after fixing the execution failure.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Review did not complete, so no work-lane recommendation was made.
Review details

Best 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 changes

Label changes:

  • remove P1: Current review triage priority is none.

Label justifications:

  • rating: 🌊 off-meta tidepool: Overall readiness is 🌊 off-meta tidepool; proof is 🌊 off-meta tidepool and patch quality is 🌊 off-meta tidepool.
Evidence reviewed

PR surface:

Source +26, Tests +154. Total +180 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 26 0 +26
Tests 1 154 0 +154
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 180 0 +180

What I checked:

  • failure reason: codex execution failed.
  • codex failure detail: Codex review failed for this PR with exit 1.
  • codex stderr: buildon this branch, thennode openclaw.mjs gateway --port 19099 --allow-unconfiguredwithOPENCLAW_STATE_DIR=/tmp/hi-proof-91976/stateand a minimal config pinningmodel.primary: claude-cli/claude-sonnet-4-6.\n2. Opened the Control UI chat, sent (verbose off, the reported drop case): \"First say exactly: Let me check the date. Then run the date command with your bash tool. Then say exactly: The command finished. Then give the final answer with the date.\"\n3. Sent /verbose on, repeated the same task twice (duplication check on the commentary lane).\n4. Sent /verbose off, repeated the same task once more (regression re-check).\n5. Wrapped the claudecommand in ateeshim during all runs to capture the raw CLI stream for cross-checking what the model actually emitted.\n\n**Evidence after fix:**\n\nVerbose off: pre-tool narration \"Let me check the date.\" renders as a real assistant message before the tool card, post-tool \"The command finished.\" after it (on the unpatched merge-base the first segment is dropped, per the Before evidence above).\n\n![verbose off — narration preserved](https://raw.githubusercontent.com/ragesaq/openclaw/proof/91976-evidence/.proof/verbose-off-narration-preserved.png)\n\nSecond independent verbose-off run, same result (sessionagent:main:main`, Jun 11 2026, 06:21–06:27 UTC):\n\n![first run — narration visible](https://raw.githubusercontent.com/ragesaq/openclaw/proof/9197.
  • codex stdout: No stdout captured.

Likely related people:

  • unknown: Codex failed before it could trace repository history. (role: review did not complete; confidence: low)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added the rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. label Jun 11, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 11, 2026
@ragesaq

ragesaq commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Proof section updated with exact parser fields plus before/after real user ClickClack screenshots. Real behavior proof check is now green on current head c0df835d2f.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@ragesaq

ragesaq commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up pushed on 92bf005dd0 to address the delta-only assistant stream edge case.

Validation on the new head:

node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/server-chat.agent-events.test.ts --maxWorkers=1
Test Files  1 passed (1)
Tests       87 passed (87)

pnpm tsgo:core
# clean

pnpm tsgo:test:src
# clean

git diff --check
# clean

Real behavior proof is green on 92bf005dd0, and all five raw proof URLs return 200. Copilot review comments have been answered inline.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@ragesaq

ragesaq commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Copilot follow-up is closed out.

  • Delta-only assistant stream edge case fixed in 92bf005dd0 and covered by a regression fixture.
  • Snapshot-work comment intentionally left unchanged: this mirrors the existing hidden tool-event snapshot path, uses exact-session delivery, and keeps dropIfSlow: true.
  • Both Copilot review threads are resolved.
  • Current PR checks show no failing OpenClaw Actions jobs: Real behavior proof is green; remaining CI/security jobs are queued.

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

@clawsweeper clawsweeper Bot added status: 🔁 re-review loop A fresh ClawSweeper review was explicitly requested after the latest review. and removed status: 🔁 re-review loop A fresh ClawSweeper review was explicitly requested after the latest review. labels Jun 11, 2026
@openclaw-barnacle openclaw-barnacle Bot added the docs Improvements or additions to documentation label Jun 11, 2026
@ragesaq

ragesaq commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Docs contract follow-up pushed on f92c1bfcd2.

  • Added docs/channels/agent-event-io-contract.md to define the provider-input and channel-output contract for assistant commentary, tool/item activity, lifecycle, hidden channel-session mirroring, delta-only frames, and final-answer exclusion.
  • Linked the contract from docs/channels/index.md.
  • Updated the PR body with the contract section and docs validation.

Validation after the docs follow-up:

pnpm docs:check-mdx
# Docs MDX check passed

pnpm lint:docs
# markdownlint passed

git diff --check HEAD~1..HEAD
# clean

Proof body re-check after editing still passes evaluateRealBehaviorProof, and all five raw proof URLs return 200.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jun 11, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jun 12, 2026
@ragesaq ragesaq changed the title fix(gateway): mirror hidden channel assistant commentary fix(gateway): mirror hidden commentary-phase assistant events Jun 12, 2026
@openclaw-barnacle openclaw-barnacle Bot added triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. and removed proof: supplied External PR includes structured after-fix real behavior proof. proof: sufficient ClawSweeper judged the real behavior proof convincing. labels Jun 12, 2026
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 12, 2026
@ragesaq

ragesaq commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Please rerun against the current narrowed head ba7ce8bcd634c7066fcf12c75eaa631b15c115fa.

The prior durable ClawSweeper marker says real behavior proof is missing, but the PR body now includes a ## Real behavior proof section with real user proof:

  • Real environment: deployed OpenClaw gateway built from this patch, restarted on 2026-06-11T15:31Z.
  • Real channel path: ClickClack bridge subscribed to agent:chisel:clickclack:channel:channel:chn_01ktq4zg9bga4dqrycqz67jts6.
  • Real user turns: ragesaq drove channel-originated ClickClack turns in #test and #general.
  • Visible evidence: before/after ClickClack screenshots in the PR body show the user-facing channel UI before the mirror and after the preamble rendered commentary plus tool rows.
  • Durable evidence: the PR body includes ClickClack DB rows showing persisted agent_commentary alongside agent_tool after deploy.

Current scope is trimmed per maintainer feedback: one gateway mirror commit, two files changed, no embedded-handler change, and no docs contract file.

@clawsweeper

clawsweeper Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

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]>
@obviyus
obviyus force-pushed the fix/channel-hidden-commentary branch from ba7ce8b to b2fac9d Compare June 13, 2026 03:26
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 13, 2026
@obviyus
obviyus merged commit 1bd7830 into openclaw:main Jun 13, 2026
172 of 177 checks passed
@obviyus

obviyus commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Landed via rebase onto main.

  • Scoped tests: node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway.config.ts src/gateway/server-chat.agent-events.test.ts --maxWorkers=1
  • Real transport smoke: node ~/.codex/skills/custom/telegram-e2e-bot-to-bot/scripts/run-mock-sut-e2e.mjs --text '@{sut} Please answer with OPENCLAW_E2E_OK only.' --expect OPENCLAW_E2E_OK --timeout-ms 90000
  • Review: .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main clean, no accepted/actionable findings
  • GitHub checks: exact-head Real behavior proof green; PR check set green before merge
  • Changelog: not updated; release generation owns CHANGELOG for normal PRs
  • Land commit: b2fac9d
  • Merge commit: 1bd7830

Thanks @ragesaq!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime P1 High-priority user-facing bug, regression, or broken workflow. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants