Summary
Discord streaming.mode: "progress" currently works well for compact tool/activity updates, but it does not expose the assistant commentary that Codex app-server already emits as agentMessage items with phase: "commentary".
That commentary is the part of the live experience that most closely matches Codex/TUI-style progress notes:
Checking the current forecast source first.
Comparing Monday and Tuesday driving conditions.
Writing the concise recommendation.
This issue requests an opt-in Discord progress feature that renders assistant commentary in the temporary progress draft, while keeping the final assistant answer as the only durable reply.
This is not a request to expose hidden chain-of-thought. The requested stream is assistant-authored commentary/status text that is already present in the Codex app-server event stream.
Related but distinct: #59150 discusses commentary leaking into final assistant replies. This proposal depends on the same distinction between commentary and final_answer, but requests an opt-in progress rendering path where commentary is temporary UI state rather than final reply content.
Why this matters
For longer Discord turns, tool labels such as Bash, Lcm Grep, or Context compaction: running are often less useful to users than short natural-language status notes. Without commentary, Discord can feel idle or opaque even when the agent is actively working.
The desired UX is:
- The user sends a message in Discord.
- A temporary progress draft shows short assistant commentary while the turn is running.
- Tool rows can be hidden independently.
- The final response is delivered normally.
- The temporary draft is cleared/finalized through the existing cleanup path.
Proposed configuration
Add an opt-in setting under Discord progress streaming:
{
"channels": {
"discord": {
"streaming": {
"mode": "progress",
"progress": {
"commentary": true,
"toolProgress": false,
"maxLines": 12,
"label": false
}
}
}
}
}
Expected behavior:
progress.commentary: true enables assistant commentary in the temporary Discord progress draft.
progress.toolProgress: false hides tool/item/progress rows without disabling commentary.
- Existing configs keep current behavior unless
commentary is explicitly enabled.
- Final-answer delivery is unchanged.
Proposed event plumbing
Codex app-server projector
When Codex app-server emits agentMessage deltas or completions where phase === "commentary", OpenClaw should emit a non-final assistant progress event, for example:
{
stream: "assistant",
data: {
phase: "commentary",
text,
delta,
itemId
}
}
Implementation details that worked in a local patch:
- Track assistant message
phase by itemId.
- Emit commentary deltas when the resolved phase is
commentary.
- On completion, emit the full commentary text if it was not already emitted or if it differs.
- Do not route commentary through normal partial/final reply delivery.
- Keep
final_answer behavior unchanged.
Reply callback surface
Use a dedicated callback rather than overloading reasoning:
onCommentaryStream?: (payload: {
text: string;
delta?: string;
itemId?: string;
}) => void | Promise<void>;
Forward this callback through the existing runner/dispatch/reply plumbing, similar to onReasoningStream.
Proposed Discord rendering
In the Discord draft preview controller, add commentary-specific progress handling:
pushCommentaryProgress(text, { itemId })
Suggested behavior:
- Normalize whitespace.
- Strip inline delivery directives before rendering.
- Ignore empty text and
NO_REPLY.
- Replace the previous rendered line for the same
itemId instead of appending every delta.
- Allow multiple commentary
itemIds to appear as separate progress lines.
- Respect
streaming.progress.maxLines.
- Render only in
streaming.mode: "progress".
- Reuse the existing draft cleanup/finalization path.
Tool progress should remain independent:
- If
progress.toolProgress === false, tool/item/plan/patch progress rows should not update the progress draft.
- Commentary should still render when
progress.commentary === true.
Optional formatting improvement
Natural-language commentary reads better without list bullets. It would be useful for the shared progress formatter to support disabling bullets and applying a channel-specific line formatter:
formatChannelProgressDraftText({
lines,
bullet: false,
formatLine: (line) => `*${line}*`
})
This is secondary to the event plumbing. Plain text with no bullets would also be fine.
Acceptance criteria
- With
channels.discord.streaming.mode = "progress" and progress.commentary = true, Discord shows assistant commentary in the temporary progress draft.
- Commentary is not included in the final durable reply unless the assistant includes it in its final answer.
- With
progress.toolProgress = false, tool rows such as Bash, Lcm Grep, and context-compaction progress are not rendered in the Discord progress draft.
- Repeated deltas for the same commentary item update one line rather than creating many partial fragments.
- Multiple commentary items can render as separate progress lines.
progress.maxLines is respected.
- Existing configurations keep current behavior.
Test plan
Codex app-server projector:
phase: "commentary" delta emits the commentary callback/event.
phase: "commentary" completion emits commentary when appropriate.
- Commentary does not trigger normal partial reply delivery.
phase: "final_answer" behavior is unchanged.
Discord draft preview:
pushCommentaryProgress renders a compact commentary line.
- Repeated deltas for the same
itemId replace the prior line.
- Multiple
itemIds produce multiple progress lines.
maxLines is respected.
toolProgress: false suppresses tool rows without suppressing commentary.
Integration-style test:
- Simulate commentary, tool start, and final answer.
- Assert the temporary draft shows commentary during the turn.
- Assert tool rows are absent when disabled.
- Assert final answer delivery and draft cleanup behave as before.
Local validation
A local patch confirmed the behavior by:
- Emitting assistant events for Codex
agentMessage phase="commentary".
- Adding Discord
pushCommentaryProgress.
- Gating the feature behind
channels.discord.streaming.progress.commentary.
- Suppressing tool rows independently with
progress.toolProgress: false.
- Adding
bullet: false support to the shared progress formatter for cleaner Discord output.
The local patch did not synthesize status text with an LLM; it only surfaced commentary events already emitted by Codex app-server.
Summary
Discord
streaming.mode: "progress"currently works well for compact tool/activity updates, but it does not expose the assistant commentary that Codex app-server already emits asagentMessageitems withphase: "commentary".That commentary is the part of the live experience that most closely matches Codex/TUI-style progress notes:
This issue requests an opt-in Discord progress feature that renders assistant commentary in the temporary progress draft, while keeping the final assistant answer as the only durable reply.
This is not a request to expose hidden chain-of-thought. The requested stream is assistant-authored commentary/status text that is already present in the Codex app-server event stream.
Related but distinct: #59150 discusses commentary leaking into final assistant replies. This proposal depends on the same distinction between
commentaryandfinal_answer, but requests an opt-in progress rendering path where commentary is temporary UI state rather than final reply content.Why this matters
For longer Discord turns, tool labels such as
Bash,Lcm Grep, orContext compaction: runningare often less useful to users than short natural-language status notes. Without commentary, Discord can feel idle or opaque even when the agent is actively working.The desired UX is:
Proposed configuration
Add an opt-in setting under Discord progress streaming:
{ "channels": { "discord": { "streaming": { "mode": "progress", "progress": { "commentary": true, "toolProgress": false, "maxLines": 12, "label": false } } } } }Expected behavior:
progress.commentary: trueenables assistant commentary in the temporary Discord progress draft.progress.toolProgress: falsehides tool/item/progress rows without disabling commentary.commentaryis explicitly enabled.Proposed event plumbing
Codex app-server projector
When Codex app-server emits
agentMessagedeltas or completions wherephase === "commentary", OpenClaw should emit a non-final assistant progress event, for example:Implementation details that worked in a local patch:
phasebyitemId.commentary.final_answerbehavior unchanged.Reply callback surface
Use a dedicated callback rather than overloading reasoning:
Forward this callback through the existing runner/dispatch/reply plumbing, similar to
onReasoningStream.Proposed Discord rendering
In the Discord draft preview controller, add commentary-specific progress handling:
Suggested behavior:
NO_REPLY.itemIdinstead of appending every delta.itemIds to appear as separate progress lines.streaming.progress.maxLines.streaming.mode: "progress".Tool progress should remain independent:
progress.toolProgress === false, tool/item/plan/patch progress rows should not update the progress draft.progress.commentary === true.Optional formatting improvement
Natural-language commentary reads better without list bullets. It would be useful for the shared progress formatter to support disabling bullets and applying a channel-specific line formatter:
This is secondary to the event plumbing. Plain text with no bullets would also be fine.
Acceptance criteria
channels.discord.streaming.mode = "progress"andprogress.commentary = true, Discord shows assistant commentary in the temporary progress draft.progress.toolProgress = false, tool rows such asBash,Lcm Grep, and context-compaction progress are not rendered in the Discord progress draft.progress.maxLinesis respected.Test plan
Codex app-server projector:
phase: "commentary"delta emits the commentary callback/event.phase: "commentary"completion emits commentary when appropriate.phase: "final_answer"behavior is unchanged.Discord draft preview:
pushCommentaryProgressrenders a compact commentary line.itemIdreplace the prior line.itemIds produce multiple progress lines.maxLinesis respected.toolProgress: falsesuppresses tool rows without suppressing commentary.Integration-style test:
Local validation
A local patch confirmed the behavior by:
agentMessage phase="commentary".pushCommentaryProgress.channels.discord.streaming.progress.commentary.progress.toolProgress: false.bullet: falsesupport to the shared progress formatter for cleaner Discord output.The local patch did not synthesize status text with an LLM; it only surfaced commentary events already emitted by Codex app-server.