它是什么
- 面向 Gateway 网关的原生聊天 UI。
- 使用与其他渠道相同的会话和路由规则。
- 确定性路由:回复始终返回 WebChat。
- 历史记录始终从 Gateway 网关获取(不监视本地文件)。如果无法访问 Gateway 网关,WebChat 为只读。
快速开始
- 启动 Gateway 网关。
- 打开 WebChat UI(macOS/iOS 应用)或 Control UI 聊天标签页。
- 确保已配置有效的 Gateway 网关认证路径(默认使用 shared-secret,即使在 loopback 上也是如此)。
工作原理
- UI 连接到 Gateway 网关 WebSocket,并使用
chat.history、chat.send、chat.inject和chat.message.getRPC 方法。 chat.history为稳定性设有边界:Gateway 网关可能会截断长文本字段、省略较重的元数据,并将过大的条目替换为[chat.history omitted: message too large]。API 客户端可以发送每请求的maxChars,为一次调用覆盖默认限制。- 当可见的助手消息在
chat.history中被截断时,Control UI 可以打开侧边阅读器,并按需通过chat.message.get获取完整的显示规范化条目,而不增加默认历史记录载荷。chat.message.get使用与chat.history相同的 transcript 分支和显示规则,但通过messageId定位单个条目,并在完整内容无法再返回时给出真实的不可用原因。 chat.history会跟随仅追加会话文件的活动 transcript 分支,因此废弃的重写分支和被取代的提示词副本不会在 WebChat 中渲染。- 压缩条目会渲染为“已压缩的历史记录”分隔线,说明压缩后的 transcript 会作为检查点保留,并提供打开会话检查点的操作(在权限允许时可分支或恢复)。
- Control UI 会记住
chat.history返回的后端 Gateway 网关sessionId,并在后续chat.send调用中带上它,因此重新连接和页面刷新会继续同一个已存储对话,除非用户启动或重置会话。 chat.send接收一个幂等键(Control UI 使用 run id);Gateway 网关会对复用同一键的重复请求去重,因此同一会话/消息/附件的重试或重复进行中的提交不会创建第二个 run。- 工作区启动文件和待处理的
BOOTSTRAP.md指令通过智能体 system prompt 的# Project Context部分提供,而不是复制到 WebChat 用户消息中。如果 bootstrap 内容被截断,system prompt 会改为获得一条简短的“Bootstrap 上下文通知”;详细计数和配置旋钮保留在诊断界面上。 chat.history上的显示规范化会剥离:仅运行时使用的 OpenClaw 上下文、入站信封包装器、内联投递指令标签(如[[reply_to_current]]、[[reply_to:<id>]]和[[audio_as_voice]])、纯文本工具调用 XML 载荷(<tool_call>、<function_call>、<tool_calls>、<function_calls>,包括被截断的块),以及泄漏的 ASCII/全角模型控制 token。整个可见文本仅为静默 tokenNO_REPLY(不区分大小写)的助手条目会被省略。- 带 reasoning 标记的回复载荷(
isReasoning: true)会从 WebChat 助手内容、transcript 回放文本和音频内容块中排除,因此仅思考用途的载荷不会作为可见助手消息或可播放音频出现。 chat.inject会将一条助手注记直接追加到 transcript,并广播到 UI(没有 agent run)。- 已中止的 run 可以让部分助手输出在 UI 中保持可见。Gateway 网关会在存在已缓冲输出时,将该部分文本持久化到 transcript 历史记录中,并用中止元数据标记该条目。
Transcript 和投递模型
WebChat 有两条独立的数据路径:- 会话 JSONL 文件是持久的模型/运行时 transcript。对于普通 agent run,嵌入式 OpenClaw 运行时会通过其会话管理器持久化模型可见的
user、assistant和toolResult消息。WebChat 不会将任意投递、状态或辅助文本写入该 transcript。 - Gateway 网关
ReplyPayload事件是实时投递投影:面向 WebChat/渠道显示、分块流式传输、指令标签、媒体嵌入、TTS/音频标志和 UI fallback 行为进行规范化。它们本身不是规范会话日志。 - 需要通过
tools.message发送可见回复的 harness,仍然使用 WebChat 作为当前 run 的内部源回复接收端。来自该活动 WebChat run 的无目标message.send会投影到同一聊天并镜像到会话 transcript;WebChat 不会变成可复用的出站渠道,也永远不会继承lastChannel。 - 只有当 Gateway 网关在普通嵌入式智能体轮次之外拥有一条已显示消息时,WebChat 才会注入助手 transcript 条目:
chat.inject、非智能体命令回复、已中止的部分输出,以及 WebChat 管理的媒体 transcript 补充。 - 如果实时助手文本在 run 期间出现,但在重新加载历史记录后消失,请按顺序检查:原始 JSONL 是否包含助手文本,
chat.history显示投影是否剥离了它,然后 Control UI 乐观尾部合并是否用持久化快照替换了本地投递状态。
message_end。任何将已投递最终载荷镜像到 transcript 的 fallback,都必须先避免重复写入嵌入式运行时已写入的助手轮次。
Control UI 智能体工具面板
- Control UI
/agents工具面板有一个由tools.effective(sessionKey=...)支持的“当前可用”视图:这是服务器派生的只读投影,表示当前会话的工具清单,包括 core、插件、渠道拥有以及已发现的 MCP 服务器工具。 - 一个单独的配置编辑视图(由
tools.catalog支持)涵盖配置档、按智能体覆盖项和目录语义。 - 运行时可用性按会话限定。在同一智能体上切换会话可能会改变“当前可用”列表。如果已配置的 MCP 服务器自上次发现以来尚未连接或未发生变化,面板会显示提示,而不是从读取路径静默启动 MCP 传输。
- 配置编辑器不表示运行时可用;有效访问仍遵循策略优先级(
allow/deny,按智能体和提供商/渠道覆盖)。
远程使用
- 远程模式会通过 SSH/Tailscale 隧道传输 Gateway 网关 WebSocket。
- 你不需要运行单独的 WebChat 服务器。
配置参考(WebChat)
完整配置:配置 WebChat 没有持久化配置部分。Gateway 网关使用内置的chat.history 显示限制;API 客户端可以发送每请求的 maxChars,为单次调用覆盖该限制。旧版 channels.webchat 和 gateway.webchat 配置已退役;运行 openclaw doctor --fix 将其移除。
相关全局选项:
gateway.port、gateway.bind:WebSocket 主机/端口。gateway.auth.mode、gateway.auth.token、gateway.auth.password: shared-secret WebSocket 认证。gateway.auth.allowTailscale:启用后,浏览器 Control UI 聊天标签页可以使用 Tailscale Serve 身份标头。gateway.auth.mode: "trusted-proxy":用于位于感知身份的非 loopback代理源之后的浏览器客户端的反向代理认证(请参阅 Trusted Proxy Auth)。gateway.remote.url、gateway.remote.token、gateway.remote.password:远程 Gateway 网关目标。session.*:会话存储和主键默认值。