Skip to content

Codex harness default can suppress direct WebChat final replies #81109

@100yenadmin

Description

@100yenadmin

TLDR

Codex harness defaults direct source-visible replies to message_tool, which is correct for many external direct-chat routes, but it is wrong for internal WebChat sessions. WebChat is an internal/non-deliverable channel, so a direct WebChat turn can suppress the normal final reply path and steer the model toward message(action=send). The user-visible symptom is a private/tool-send style response such as Sent. instead of the actual answer in the WebChat thread.

Impact

Product impact: P2 if WebChat/direct local OpenClaw sessions are run through Codex by default. Users can lose the visible answer for a normal direct WebChat turn even though the model completed the request.

QA impact: P1 for Codex runtime confidence, because this is exactly the class of first-hour local gateway behavior the runtime parity harness should catch: the wrong delivery layer is selected even though the model/runtime may otherwise be healthy.

What is wrong

extensions/codex/harness.ts sets deliveryDefaults.sourceVisibleReplies = "message_tool" for the Codex harness. dispatch-from-config applies that harness default when direct-chat messages.visibleReplies is unset. For WebChat/internal direct sessions, that default is unsafe because WebChat is not an outbound delivery target for message(action=send).

This is not a request to expose duplicate OpenClaw dynamic workspace tools in Codex. It is a product delivery-policy bug: internal WebChat source replies should stay on the automatic final-reply path.

Evidence

Local beta.5 session logs showed a direct WebChat/Codex turn using message(action=send) and then producing a visible Sent. final reply rather than the substantive answer. Source inspection matches the behavior:

  • extensions/codex/harness.ts defines the Codex harness default as sourceVisibleReplies: "message_tool".
  • src/auto-reply/reply/dispatch-from-config.ts applies harness defaults for direct source-visible replies when config is unset.
  • src/utils/message-channel-constants.ts defines WebChat as the internal message channel.
  • src/infra/outbound/targets-resolve-shared.ts rejects WebChat as an outbound delivery target.

Reproduction

A focused regression test reproduces the policy mismatch:

  1. Register a Codex harness with deliveryDefaults.sourceVisibleReplies = "message_tool".
  2. Create a direct WebChat context with Provider, Surface, and OriginatingChannel set to webchat.
  3. Leave messages.visibleReplies unset.
  4. Dispatch a normal reply.
  5. Expected: sourceReplyDeliveryMode is automatic and the final reply is queued to WebChat.
  6. Actual before fix: the harness default can select message_tool_only, suppressing automatic final delivery.

Proposed fix

Ignore harness sourceVisibleReplies: "message_tool" defaults for internal WebChat source contexts. Keep the Codex harness default for external direct-chat routes where the message tool is the intended visible-reply path.

Validation

Focused local validation on a Lexar-backed checkout:

VITEST_MAX_WORKERS=1 pnpm test src/auto-reply/reply/dispatch-from-config.test.ts -- -t "keeps internal webchat"
VITEST_MAX_WORKERS=1 pnpm test src/auto-reply/reply/dispatch-from-config.test.ts

Both passed locally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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