Skip to content

[fix] Add opt-in ACP CodexAgent commentary progress in parent streams #89501

@100yenadmin

Description

@100yenadmin

Summary

Add an explicit configuration option for ACP parent streams to relay assistant-authored phase: "commentary" progress text and ACP status progress allowed by acp.stream.tagVisibility from CodexAgent runs.

Today sessions_spawn({ runtime: "acp", agentId: "codex", streamTo: "parent" }) can stream final-answer text and lifecycle notices back to the requester session, but it hard-suppresses assistant deltas marked phase: "commentary". Codex can spend a long time calling tools while emitting short progress prose, but OpenClaw counts that prose only as internal activity and never surfaces it to the parent.

This is not a request to expose hidden chain-of-thought. The requested text is assistant-authored ACP/Codex progress status that is already present in the event stream and separated from final answers by the ACP phase/status contract. This relies on that ACP contract; it does not opt into hidden reasoning/chain-of-thought or change final-answer selection.

Concrete scenario

A user asks a CodexAgent-backed OpenClaw agent to do a broad investigation:

"Figure out why this integration is failing, inspect the repo, check the runtime logs, and report back."

What the user sees today in the parent conversation:

Time Runtime activity Parent conversation
00:00 User sends the request. User message is visible.
00:01-30:00+ CodexAgent emits many tool calls, reads files, runs commands, and may emit assistant phase: "commentary" progress such as "I am checking the runtime path now." No natural-language update appears.
During the run An operator can confirm activity only by opening raw tool/log views, verbose/tool streaming, or another diagnostics surface. A normal user sees silence and cannot tell whether the agent is healthy, stuck, or ignoring the request.
End Final answer may eventually arrive. The user had no interim confidence for the whole run.

This differs from the operator experience in Codex Desktop or Claude Code-style environments, where long tool-heavy work usually looks like:

  1. User asks a request.
  2. Agent runs a batch of tool calls.
  3. Agent sends short assistant-authored commentary such as "I found the owning module and am checking the retry path."
  4. Agent runs the next batch of tool calls.
  5. Agent sends the final answer.

OpenClaw should not force that commentary on every deployment, but it should not hard-suppress it for every configured gateway either. This should be a documented gateway/operator config choice, not a per-user or per-sessions_spawn override. Enabling it applies to ACP parent streams served by that config.

Behavior at a glance

sequenceDiagram
  participant U as User
  participant P as Parent OpenClaw chat
  participant A as ACP CodexAgent child
  participant T as Tools and logs

  U->>P: Ask broad request
  P->>A: sessions_spawn streamTo parent
  loop 30+ minutes of work
    A->>T: tool calls, file reads, commands
    A-->>A: commentary updates internal progress only
    A--xP: no parent-visible text
  end
  A->>P: final answer or lifecycle notice
Loading
sequenceDiagram
  participant U as User
  participant P as Parent OpenClaw chat
  participant A as ACP CodexAgent child
  participant T as Tools and logs

  U->>P: Ask broad request
  P->>A: sessions_spawn streamTo parent
  Note over P,A: acp.stream.assistantCommentary = true
  loop long tool-heavy work
    A->>T: tool calls, file reads, commands
    A->>P: bounded progress commentary
  end
  A->>P: final answer
Loading

Why this should be configurable

There are two reasonable operator preferences:

  • Quiet default: keep current behavior for deployments that do not want assistant commentary or tag-visible ACP status progress in parent-visible progress.
  • Transparent progress: allow deployments that expect Codex Desktop/Claude Code-style progress updates to opt into bounded assistant-authored progress/status text during long runs.

The missing piece is a configuration switch. The current behavior is not merely "quiet by default"; it is hard-suppressed for ACP parent streams.

Problem to solve

For long tool-heavy CodexAgent runs, the user can see that many tool calls are happening locally, but the parent OpenClaw conversation remains quiet for long periods. This creates a poor operator experience:

  • The child agent appears idle even though the runtime is active.
  • The parent gets no natural-language "I am checking X / running Y / comparing Z" updates.
  • The no-output watcher may avoid declaring a stall because commentary updates lastProgressAt, but the user still sees no progress.
  • Operators have to tail logs or inspect raw tool calls to know whether the run is healthy.

This is especially confusing because Codex Desktop-style agents normally send brief status updates between tasks. OpenClaw has the raw material, but there is no documented gateway/operator switch to let deployments turn it on for ACP parent streams.

Evidence from current upstream

Checked against openclaw/openclaw main at 6c7644268f59770361d2760a27cb49823ec76717.

Duplicate/related issue search:

Relevant source:

  1. ACP parent streams explicitly treat commentary as internal progress and return before any parent-visible emit:
// src/agents/acp-spawn-parent-stream.ts
if (assistantPhase === "commentary") {
  lastProgressAt = Date.now();
  return;
}

This means commentary prevents the relay from looking stalled, but does not set firstVisibleOutputAt, append to pendingText, emit a system event, or wake the parent with a visible update.

  1. The behavior is test-backed:
// src/agents/acp-spawn-parent-stream.test.ts
it("suppresses commentary-phase assistant relay text", () => { ... });
it("still relays final_answer assistant text after suppressed commentary", () => { ... });
  1. The feature surface already exists:

docs/tools/acp-agents.md documents sessions_spawn streamTo: "parent" as:

"parent" streams initial ACP run progress summaries back to the requester session as system events.

So a user explicitly opting into parent streaming reasonably expects safe progress summaries, but commentary remains hard-blocked.

  1. The ACP stream config namespace already exists:

docs/gateway/configuration-reference.md documents:

acp: {
  stream: {
    maxOutputChars,
    maxSessionUpdateChars,
    deliveryMode,
    ...
  }
}

There is no acp.stream.commentary, acp.stream.assistantCommentary, or equivalent switch.

Proposed solution

Add an opt-in ACP stream setting, for example:

{
  acp: {
    stream: {
      assistantCommentary: true
    }
  }
}

When enabled:

  • ACP parent stream relays assistant phase: "commentary" deltas/text and ACP status progress allowed by acp.stream.tagVisibility as parent-visible progress summaries.
  • Final-answer delivery remains unchanged.
  • Commentary remains excluded from durable final transcript/final reply selection where it is currently excluded.
  • Relayed commentary/tag-visible status progress goes through the same buffering/truncation path as other parent-stream assistant output, so it is bounded and not token-spammy.
  • The default stays false, preserving current behavior for deployments that do not want commentary or tag-visible status progress in parent-visible progress.

Suggested relay behavior:

  • Reuse the existing pendingText, STREAM_BUFFER_MAX_CHARS, STREAM_SNIPPET_MAX_CHARS, and streamFlushMs mechanics in src/agents/acp-spawn-parent-stream.ts.
  • Treat commentary/tag-visible status progress as visible output only when the new config is enabled, so firstVisibleOutputAt is set and the "ACP runtime active but no visible assistant output" notice does not fire after a visible progress update.
  • Keep the existing suppression test and add a new opt-in test.
  • Pass the resolved config from spawnAcpDirect into startAcpSpawnParentStreamRelay.

Acceptance criteria

  • acp.stream.assistantCommentary exists in config schema/help/docs and defaults to false.
  • With default config, assistant events with phase: "commentary" and ACP status progress events are not emitted to the parent session.
  • With acp.stream.assistantCommentary: true and streamTo: "parent", assistant phase: "commentary" text is emitted as bounded parent-visible progress text, and ACP status progress text is emitted only when allowed by acp.stream.tagVisibility.
  • Opted-in commentary/tag-visible status progress uses the existing parent-stream buffering/truncation path.
  • final_answer relay behavior is unchanged with the option both disabled and enabled.
  • Commentary/status-only text is never selected as the durable final answer.
  • Opted-in commentary/tag-visible status progress counts as visible parent output for no-output/stall classification.
  • No Discord progress behavior, hidden chain-of-thought, auth, network, or tool-execution behavior changes.

Impact

This improves long-running CodexAgent transparency without changing the safety-sensitive final-answer boundary. It gives operators a documented knob to choose a more Codex-Desktop-like progress experience for ACP parent streams while keeping current quiet behavior for existing users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low-priority cleanup, docs, polish, ergonomics, or speculative work.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper 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:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions