docs/web/webchat.md
Status: the macOS/iOS SwiftUI chat UI talks directly to the Gateway WebSocket.
chat.history, chat.send, and chat.inject.chat.history is bounded for stability: Gateway may truncate long text fields, omit heavy metadata, and replace oversized entries with [chat.history omitted: message too large].chat.history, Control UI can open a side reader and fetch the full display-normalized entry on demand through chat.message.get without increasing the default history payload.chat.history follows the active transcript branch for modern append-only session files, so abandoned rewrite branches and superseded prompt copies are not rendered in WebChat.sessionId returned by chat.history and includes it on follow-up chat.send calls, so reconnects and page refreshes continue the same stored conversation unless the user starts or resets a session.chat.send run id; the Gateway still dedupes repeated requests that reuse the same idempotency key.BOOTSTRAP.md instructions are supplied through the agent system prompt's Project Context, not copied into the WebChat user message. Bootstrap truncation only adds a concise system-prompt recovery notice; detailed counts and config knobs stay on diagnostic surfaces.chat.history is also display-normalized: runtime-only OpenClaw context,
inbound envelope wrappers, inline delivery directive tags
such as [[reply_to_*]] and [[audio_as_voice]], plain-text tool-call XML
payloads (including <tool_call>...</tool_call>,
<function_call>...</function_call>, <tool_calls>...</tool_calls>,
<function_calls>...</function_calls>, and truncated tool-call blocks), and
leaked ASCII/full-width model control tokens are stripped from visible text,
and assistant entries whose whole visible text is only the exact silent
token NO_REPLY / no_reply are omitted.isReasoning: true) are excluded from WebChat assistant content, transcript replay text, and audio content blocks, so thinking-only payloads do not surface as visible assistant messages or playable audio.chat.inject appends an assistant note directly to the transcript and broadcasts it to the UI (no agent run).WebChat has two separate data paths:
user, assistant, and toolResult messages through its session manager. WebChat does not write arbitrary delivery, status, or helper text into that transcript.ReplyPayload events are the live delivery projection. They can be normalized for WebChat/channel display, block streaming, directive tags, media embedding, TTS/audio flags, and UI fallback behavior. They are not themselves the canonical session log.tools.message still use WebChat as a current-run internal source reply sink. A targetless message.send from that active WebChat run is projected into the same chat and mirrored to the session transcript; WebChat does not become a reusable outbound channel and never inherits lastChannel.chat.inject, non-agent command replies, aborted partial output, and WebChat-managed media transcript supplements.chat.history reads the stored session transcript and applies WebChat display projection. If live assistant text appears during a run but disappears after history reload, first check whether the raw JSONL contains the assistant text, then whether chat.history projection stripped it, then whether the Control UI optimistic-tail merge replaced local delivery state with the persisted snapshot.chat.message.get uses the same transcript branch and display projection rules as chat.history, including active-agent scoping, but targets one transcript entry by messageId and returns an honest unavailable reason when the full content can no longer be returned.Normal agent-run final answers should be durable because the embedded runtime writes the assistant message_end. Any fallback that mirrors a delivered final payload into the transcript must first avoid duplicating an assistant turn that the embedded runtime already wrote.
/agents Tools panel has two separate views:
tools.effective(sessionKey=...) and shows a server-derived
read-only projection of the current session inventory, including core, plugin, channel-owned,
and already-discovered MCP server tools.tools.catalog and stays focused on profiles, overrides, and
catalog semantics.allow/deny, per-agent and provider/channel overrides).Full configuration: Configuration
WebChat has no persisted config section. Gateway uses the built-in chat.history display limit; API clients can send per-request maxChars to override it for a single chat.history call. Legacy channels.webchat and gateway.webchat config is retired; run openclaw doctor --fix to remove it.
Related global options:
gateway.port, gateway.bind: WebSocket host/port.gateway.auth.mode, gateway.auth.token, gateway.auth.password:
shared-secret WebSocket auth.gateway.auth.allowTailscale: browser Control UI chat tab can use Tailscale
Serve identity headers when enabled.gateway.auth.mode: "trusted-proxy": reverse-proxy auth for browser clients behind an identity-aware non-loopback proxy source (see Trusted Proxy Auth).gateway.remote.url, gateway.remote.token, gateway.remote.password: remote gateway target.session.*: session storage and main key defaults.