Fix Discord progress final and status command output#85465
Conversation
|
Codex review: needs changes before merge. Reviewed May 28, 2026, 9:47 AM ET / 13:47 UTC. Summary PR surface: Source +9, Tests +64. Total +73 across 5 files. Reproducibility: yes. Source inspection shows current main appends command-output titles unless the caller supplies Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Land one status-mode command-output contract across Discord, Slack, Matrix, MS Teams, and Telegram while preserving raw/default output outside status mode. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main appends command-output titles unless the caller supplies Is this the best way to solve the issue? No, not yet. The Discord final-delivery direction is reasonable, but the status-mode command-output fix should cover the sibling chat callbacks or be explicitly split into a tracked follow-up. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against bda924b6390e. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +9, Tests +64. Total +73 across 5 files. View PR surface stats
Security concerns:
Acceptance criteria:
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
|
|
ClawSweeper PR egg 🔥 Warming up: real-behavior proof passed; findings, security review, or rank-up moves are still in progress. Hatch commandComment Hatchability rules:
What is this egg doing here?
|
|
Updated the PR body with redacted live Discord proof for the failing-tool progress/finalization path. @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review Updated the Discord
|
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review Updated the Discord progress-final cleanup race:
Local targeted tests pass:
|
|
🦞👀 Command router queued. I will update this comment with the next step. |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
0ae6203 to
0f91ab5
Compare
This comment was marked as spam.
This comment was marked as spam.
2d7f4ba to
ad6c9a8
Compare
|
Follow-up pushed at What changed:
Local validation on the rebased branch:
@clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper autofix Please extend the existing Discord progress-final/status-output fix to the other chat providers that share the same message/progress rendering path:
Scope guidance:
|
Summary
command-outputtitles when channel progress is configured withcommandText: "status"onCommandOutputprogress through the same config-aware formatter as tool/item progressprogresspreviews temporary by clearing the live progress draft before sending the final reply normallyWhy
commandText: "status"already suppresses command text for command/tool progress, butcommand-outputlines still appendedinput.title. That can expose internal command titles in channel progress even when the channel is configured for status-only command display.The shared formatter handled this correctly, but Discord's
onCommandOutputcallback was still calling the raw formatter directly. This branch now passes Discord command-output events through the config-aware formatter, matching the existingonToolStartandonItemEventbehavior.A second Discord-specific failure remained after that formatter fix: in
progressstreaming mode the live tool-progress draft could be treated as the final reply container. If the turn hit failed tools, compaction, or fresh-thread pressure, Discord could leave the progress bubble visible as the last apparent assistant message instead of showing the final assistant reply. Progress previews should stay temporary; final replies should go through the normal message path.There is also a pending-draft race: a final reply can arrive while the progress draft send is still pending or in flight and no Discord message id exists yet. Final cleanup must call the draft cleanup path anyway, because that is what cancels pending work and waits for in-flight sends before the normal final reply is delivered.
Finally, after the assistant has already queued/delivered a visible final reply, a subsequent tool-error final can still be queued as a second final. In Discord this can make the final visible event look like the tool failure instead of the answer. Once a non-error final reply is accepted, later error finals are suppressed; error finals still deliver when they are the only final outcome.
Real behavior proof
Behavior or issue addressed: A
command-outputprogress event withcommandText: "status"should render the status/exit code without appending the command-output title. Discordprogressdrafts should be cleared before the final reply is delivered normally, including the case where no draft message id exists yet, and late tool-error finals should not appear after a visible final reply.Real environment tested: Local OpenClaw checkout on this PR branch, plus redacted live Discord gateway smoke runs using the built Discord extension from this branch. The final smoke used an isolated Discord gateway configured with
streaming.mode: "progress",progress.toolProgress: true, andprogress.commandText: "status".Exact steps or command run after this patch:
command-outputevent with default options and with{ commandText: "status" }.progress.commandText: "status"and restart only that isolated gateway.printf '<redacted_marker>\n'; exit 42, then returns a normal final assistant message.Evidence after fix:
Observed result after fix: Default/raw behavior still includes the title. Status mode renders only
exit 1, so the command-output title is suppressed. Discord progress mode now uses that config-aware formatter for realonCommandOutputcallbacks; the Discord regression asserts the progress draft containsexit 1and not the command-output title. Discord progress-mode final replies no longer edit the progress draft in place; tests assert the progress draft is cleared, pending/no-id progress drafts still callclear()before final delivery,deliverDiscordReplysends the final separately, and later tool-warning finals are suppressed after a visible final. The live Discord status-mode smoke matched the delivery behavior: a failed tool with exit code 42 was followed by the normal assistant final as the visible final message.What was not tested: A Telegram transport smoke was not run for this PR. The shared formatter behavior is covered by plugin-sdk tests; the live transport proof above is Discord-specific.
Test
pnpm exec vitest run --config test/vitest/vitest.plugin-sdk.config.ts src/plugin-sdk/channel-streaming.test.tspnpm exec vitest run --config test/vitest/vitest.extension-discord.config.ts extensions/discord/src/monitor/message-handler.process.test.ts