Skip to main content

Documentation Index

Fetch the complete documentation index at: https://openclaw.zhcndoc.com/llms.txt

Use this file to discover all available pages before exploring further.

Control UI 是一个由 Gateway 提供的、基于 Vite + Lit 的单页应用:
  • 默认:http://<host>:18789/
  • 可选前缀:设置 gateway.controlUi.basePath(例如 /openclaw
它通过同一端口上直接连接到 Gateway WebSocket。

本地快速打开

如果 Gateway 运行在同一台电脑上,请打开: 如果页面无法加载,请先启动 Gateway:openclaw gateway 认证会在 WebSocket 握手期间通过以下方式提供:
  • connect.params.auth.token
  • connect.params.auth.password
  • gateway.auth.allowTailscale: true 时使用 Tailscale Serve 身份头
  • gateway.auth.mode: "trusted-proxy" 时使用受信任代理身份头
仪表盘设置面板会为当前浏览器标签页会话和所选 gateway URL 保留一个 token;密码不会持久化。首次连接时,引导流程通常会为共享密钥认证生成一个 gateway token,但当 gateway.auth.mode"password" 时,密码认证也可正常工作。

设备配对(首次连接)

当你从新的浏览器或设备连接到 Control UI 时,Gateway 通常会要求进行一次一次性配对审批。这是为了防止未经授权的访问而采取的安全措施。 你会看到: “disconnected (1008): pairing required”
1

列出待处理请求

openclaw devices list
2

按请求 ID 批准

openclaw devices approve <requestId>
如果浏览器在重试配对时 auth 细节发生变化(角色/作用域/公钥),之前的待处理请求会被新请求取代,并创建一个新的 requestId。请在批准前重新运行 openclaw devices list 如果浏览器已经配对,但你将其从只读访问改为写入/管理员访问,这会被视为一次审批升级,而不是静默重连。OpenClaw 会保持旧审批有效,阻止更宽权限的重连,并要求你明确批准新的作用域集合。 一旦批准,该设备就会被记住,除非你使用 openclaw devices revoke --device <id> --role <role> 撤销它,否则不会再次要求重新批准。有关令牌轮换和撤销,请参见 Devices CLI
  • 直接的本地回环浏览器连接(127.0.0.1 / localhost)会被自动批准。
  • gateway.auth.allowTailscale: true、Tailscale 身份验证通过,并且浏览器展示其设备身份时,Tailscale Serve 可以跳过 Control UI 操作会话的配对往返流程。
  • 直接的 Tailnet 绑定、LAN 浏览器连接,以及没有设备身份的浏览器配置文件仍然需要显式批准。
  • 每个浏览器配置文件都会生成一个唯一的设备 ID,因此切换浏览器或清除浏览器数据都需要重新配对。

个人身份(浏览器本地)

Control UI 支持按浏览器保存的个人身份(显示名称和头像),用于在共享会话中将其附加到发出的消息上以便归属。它存储在浏览器中,作用域仅限于当前浏览器配置文件,不会同步到其他设备,也不会在服务端持久化,除了你实际发送消息时的正常对话作者元数据之外。清除站点数据或切换浏览器会将其重置为空。 同样的浏览器本地模式也适用于助手头像覆盖。上传的助手头像仅在本地浏览器上覆盖 Gateway 解析出的身份,不会通过 config.patch 往返回传。对于直接写入该字段的非 UI 客户端(例如脚本化 gateway 或自定义仪表盘),共享的 ui.assistant.avatar 配置字段仍然可用。

运行时配置端点

Control UI 会从 /__openclaw/control-ui-config.json 获取其运行时设置。该端点与 HTTP 表面的其他部分使用相同的 gateway 认证进行保护:未认证的浏览器无法获取它,而成功获取则需要已有有效的 gateway token/password、Tailscale Serve 身份或受信任代理身份。

语言支持

Control UI 在首次加载时可以根据你的浏览器区域设置自动本地化。要在之后覆盖它,请打开 Overview -> Gateway Access -> Language。语言选择器位于 Gateway Access 卡片中,而不是 Appearance 下。
  • 支持的区域设置:en, zh-CN, zh-TW, pt-BR, de, es, ja-JP, ko, fr, ar, it, tr, uk, id, pl, th, vi, nl, fa
  • 非英语翻译会在浏览器中按需加载。
  • 选定的区域设置会保存在浏览器存储中,并在以后访问时复用。
  • 缺失的翻译键会回退到英语。
Docs 翻译会为相同的非英语区域设置生成,但 docs 站点内置的 Mintlify 语言选择器仅限于 Mintlify 接受的区域设置代码。泰语(th)和波斯语(fa)文档仍会在发布仓库中生成;在 Mintlify 支持这些代码之前,它们可能不会出现在该选择器中。

Appearance 主题

Appearance 面板保留了内置的 Claw、Knot 和 Dash 主题,以及一个浏览器本地的 tweakcn 导入槽位。要导入主题,请打开 tweakcn themes,选择或创建一个主题,点击 Share,并将复制的主题链接粘贴到 Appearance 中。导入器还接受 https://tweakcn.com/r/themes/<id> 注册表 URL、类似 https://tweakcn.com/editor/theme?theme=amethyst-haze 的编辑器 URL、相对的 /themes/<id> 路径、原始主题 ID,以及默认主题名称,例如 amethyst-haze 导入的主题仅存储在当前浏览器配置文件中。它们不会写入 gateway 配置,也不会在设备之间同步。替换导入的主题会更新那个本地槽位;如果已选中导入主题,清空它会将当前活动主题切回 Claw。

它目前能做什么

  • 通过 Gateway WS 与模型聊天(chat.historychat.sendchat.abortchat.inject)。
  • 通过浏览器实时会话通话。OpenAI 使用直接 WebRTC,Google Live 使用通过 WebSocket 的受限一次性浏览器令牌,而仅后端的实时语音插件则使用 Gateway 中继传输。中继会将提供商凭证保留在 Gateway 上,同时浏览器通过 talk.realtime.relay* RPC 流式传输麦克风 PCM,并将 openclaw_agent_consult 工具调用通过 chat.send 发送回去,以供更大、已配置的 OpenClaw 模型处理。
  • 在 Chat 中流式显示工具调用和实时工具输出卡片(代理事件)。
  • 通道:内置以及捆绑/外部插件通道状态、二维码登录和按通道配置(channels.statusweb.login.*config.patch)。
  • 实例:在线列表 + 刷新(system-presence)。
  • 会话:列表 + 每个会话的 model/thinking/fast/verbose/trace/reasoning 覆盖(sessions.listsessions.patch)。
  • Dreams:做梦状态、启用/禁用切换,以及 Dream Diary 阅读器(doctor.memory.statusdoctor.memory.dreamDiaryconfig.patch)。
  • Cron 作业:列出/添加/编辑/运行/启用/禁用 + 运行历史(cron.*)。
  • 技能:状态、启用/禁用、安装、API 密钥更新(skills.*)。
  • 节点:列表 + 能力(node.list)。
  • Exec 审批:编辑 gateway 或节点允许列表 + exec host=gateway/node 的询问策略(exec.approvals.*)。
  • 查看/编辑 ~/.openclaw/openclaw.jsonconfig.getconfig.set)。
  • 带验证地应用并重启(config.apply),并唤醒最后一个活动会话。
  • 写入包含 base-hash 守卫,以防止覆盖并发编辑。
  • 写入(config.set/config.apply/config.patch)会对提交的配置载荷中的引用进行 active SecretRef 解析预检;未解析的 active 提交引用会在写入前被拒绝。
  • Schema 和表单渲染(config.schema / config.schema.lookup,包括字段 title / description、匹配到的 UI 提示、直接子摘要、嵌套对象/通配符/数组/组合节点上的文档元数据,以及在可用时的插件和通道 schema);只有当快照具有安全的原始往返能力时,Raw JSON 编辑器才可用。
  • 如果某个快照无法安全地原始往返,Control UI 会强制该快照使用 Form 模式并禁用 Raw 模式。
  • Raw JSON 编辑器中的“Reset to saved”会保留原始作者形态(格式、注释、$include 布局),而不是重新渲染为扁平化快照,因此当快照可安全往返时,外部编辑在重置后仍然会保留。
  • 结构化的 SecretRef 对象值会在表单文本输入中以只读方式渲染,以防止意外的对象到字符串损坏。
  • 调试:状态/健康/模型快照 + 事件日志 + 手动 RPC 调用(statushealthmodels.list)。
  • 日志:带过滤/导出的 gateway 文件日志实时尾随(logs.tail)。
  • 更新:执行包/git 更新 + 重启(update.run)并生成重启报告,然后在重连后轮询 update.status 以验证正在运行的 gateway 版本。
  • 对于独立作业,投递方式默认是 announce summary。如果你只想内部运行,可以切换为 none。
  • 当选择 announce 时,会显示 channel/target 字段。
  • Webhook 模式使用 delivery.mode = "webhook",并将 delivery.to 设置为有效的 HTTP(S) webhook URL。
  • 对于主会话作业,可使用 webhook 和 none 投递模式。
  • 高级编辑控件包括运行后删除、清除 agent 覆盖、cron 精确/错峰选项、agent model/thinking 覆盖,以及尽力而为投递切换。
  • 表单验证是行内进行的,并带有字段级错误;无效值会禁用保存按钮,直到修正为止。
  • 设置 cron.webhookToken 以发送专用 bearer token;如果省略,则 webhook 发送时不带 auth header。
  • 已弃用的回退方式:带有 notify: true 的已存储旧作业在迁移前仍可使用 cron.webhook

聊天行为

  • chat.send非阻塞的:它会立即以 { runId, status: "started" } 确认,并通过 chat 事件流式返回响应。
  • 聊天上传支持图片和非视频文件。图片保留原生图片路径;其他文件会作为受管媒体存储,并在历史记录中显示为附件链接。
  • 使用相同的 idempotencyKey 重新发送时,运行中会返回 { status: "in_flight" },完成后返回 { status: "ok" }
  • chat.history 响应的大小会受限以确保 UI 安全。当转录条目过大时,Gateway 可能会截断较长的文本字段、省略较重的元数据块,并用占位符替换过大的消息([chat.history omitted: message too large])。
  • 助手/生成的图像会作为受管媒体引用持久化,并通过已认证的 Gateway 媒体 URL 返回,因此重新加载不依赖于原始 base64 图像载荷仍保留在聊天历史响应中。
  • chat.history 还会从可见的助手文本中移除仅用于显示的内联指令标签(例如 [[reply_to_*]][[audio_as_voice]])、纯文本工具调用 XML 载荷(包括 <tool_call>...</tool_call><function_call>...</function_call><tool_calls>...</tool_calls><function_calls>...</function_calls> 以及被截断的工具调用块)、泄露的 ASCII/全角模型控制令牌,并省略其全部可见文本仅为精确静默令牌 NO_REPLY / no_reply 的助手条目。
  • 在活动发送和最终历史刷新期间,如果 chat.history 短暂返回较旧快照,聊天视图会保留本地乐观的用户/助手消息可见;一旦 Gateway 历史追上,规范转录将替换这些本地消息。
  • chat.inject 会向会话转录附加一条助手备注,并广播一个 chat 事件用于仅 UI 更新(不进行 agent 运行,也不进行通道投递)。
  • 聊天页眉中的模型和 thinking 选择器会通过 sessions.patch 立即修补当前活动会话;它们是持久的会话覆盖,而不是仅限一次发送的选项。
  • 在 Control UI 中输入 /new 会创建并切换到与 New Chat 相同的新仪表盘会话。输入 /reset 会保留 Gateway 对当前会话的显式原地重置。
  • 聊天模型选择器请求 Gateway 的配置模型视图。如果存在 agents.defaults.models,则该允许列表驱动选择器。否则,选择器会显示显式的 models.providers.*.models 条目以及具有可用 auth 的提供商。完整目录仍可通过调试 models.list RPC,并将 view: "all"
  • 当新的 Gateway 会话使用报告显示上下文压力较高时,聊天撰写区会显示上下文提示,并在推荐的压缩级别提供一个压缩按钮,以运行正常的会话压缩路径。过期的令牌快照会被隐藏,直到 Gateway 再次报告新的使用情况。
Talk 模式使用已注册的实时语音提供商。要配置 OpenAI,请设置 talk.provider: "openai" 并加上 talk.providers.openai.apiKey;或者配置 Google,设置 talk.provider: "google" 并加上 talk.providers.google.apiKey;Voice Call 实时提供商配置仍可作为后备复用。浏览器不会接收标准的提供商 API 密钥。OpenAI 会接收一个用于 WebRTC 的临时 Realtime 客户端密钥。Google Live 会接收一个一次性、受限制的 Live API 认证令牌,用于浏览器 WebSocket 会话,其中说明和工具声明会被 Gateway 锁定进令牌中。仅提供后端实时桥接的提供商会通过 Gateway 中继传输运行,因此凭据和供应商套接字都保留在服务器端,而浏览器音频则通过已认证的 Gateway RPC 传输。Realtime 会话提示词由 Gateway 组装;talk.realtime.session 不接受调用方提供的指令覆盖。在 Chat 撰写器中,Talk 控件是麦克风听写按钮旁边的波形按钮。Talk 启动时,撰写器状态行会显示 Connecting Talk...,然后在音频连接时显示 Talk live,或者在通过 chat.send 调用已配置的大模型咨询实时工具调用时显示 Asking OpenClaw...维护者实时冒烟测试:OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts 会验证 OpenAI 浏览器 WebRTC SDP 交换、Google Live 受限令牌浏览器 WebSocket 设置,以及带伪造麦克风媒体的 Gateway 中继浏览器适配器。该命令只打印提供商状态,不会记录密钥。
  • 点击 Stop(调用 chat.abort)。
  • 当运行处于活动状态时,正常的后续消息会排队。点击排队消息上的 Steer 可将该后续消息注入正在运行的轮次。
  • 输入 /stop(或单独的中止短语,如 stopstop actionstop runstop openclawplease stop)可进行带外中止。
  • chat.abort 支持 { sessionKey }(不需要 runId),用于中止该会话的所有活动运行。
  • 当一个运行被中止时,部分助手文本仍然可以在 UI 中显示。
  • 如果存在缓冲输出,Gateway 会将被中止的部分助手文本持久化到转录历史中。
  • 持久化条目包含中止元数据,因此转录消费者可以区分中止的部分输出和正常完成输出。

PWA 安装与 Web Push

Control UI 随附 manifest.webmanifest 和 service worker,因此现代浏览器可以将其安装为独立的 PWA。Web Push 允许 Gateway 在标签页或浏览器窗口未打开时也能通过通知唤醒已安装的 PWA。
Surface它的作用
ui/public/manifest.webmanifestPWA 清单。浏览器在可访问后会提供“安装应用”。
ui/public/sw.js处理 push 事件和通知点击的 service worker。
push/vapid-keys.json (under the OpenClaw state dir)用于签署 Web Push 负载的自动生成 VAPID 密钥对。
push/web-push-subscriptions.json持久化的浏览器订阅端点。
当你想固定密钥时,通过 Gateway 进程上的环境变量覆盖 VAPID 密钥对(适用于多主机部署、密钥轮换或测试):
  • OPENCLAW_VAPID_PUBLIC_KEY
  • OPENCLAW_VAPID_PRIVATE_KEY
  • OPENCLAW_VAPID_SUBJECT(默认值为 mailto:openclaw@localhost
Control UI 使用这些作用域受限的 Gateway 方法来注册和测试浏览器订阅:
  • push.web.vapidPublicKey — 获取当前活跃的 VAPID 公钥。
  • push.web.subscribe — 注册一个 endpoint 以及 keys.p256dh/keys.auth
  • push.web.unsubscribe — 移除已注册的端点。
  • push.web.test — 向调用方的订阅发送测试通知。
Web Push 独立于 iOS APNS 中继路径(有关中继支持的推送,请参见 Configuration)以及现有的 push.test 方法,后者面向原生移动配对。

托管嵌入

助手消息可以通过 [embed ...] 短代码以内联方式渲染托管的网页内容。iframe 沙箱策略由 gateway.controlUi.embedSandbox 控制:
禁用托管嵌入中的脚本执行。
示例:
{
  gateway: {
    controlUi: {
      embedSandbox: "scripts",
    },
  },
}
仅当嵌入文档确实需要同源行为时才使用 trusted。对于大多数 agent 生成的游戏和交互式画布,scripts 是更安全的选择。
默认情况下,绝对的外部 http(s) 嵌入 URL 会被阻止。如果你有意让 [embed url="https://..."] 加载第三方页面,请设置 gateway.controlUi.allowExternalEmbedUrls: true

Chat message width

Grouped chat messages use a readable default max-width. Wide-monitor deployments can override it without patching bundled CSS by setting gateway.controlUi.chatMessageMaxWidth:
{
  gateway: {
    controlUi: {
      chatMessageMaxWidth: "min(1280px, 82%)",
    },
  },
}
The value is validated before it reaches the browser. Supported values include plain lengths and percentages such as 960px or 82%, plus constrained min(...), max(...), clamp(...), calc(...), and fit-content(...) width expressions.
保持 Gateway 只监听回环地址,并让 Tailscale Serve 通过 HTTPS 代理它:
openclaw gateway --tailscale serve
打开:
  • https://<magicdns>/(或你配置的 gateway.controlUi.basePath
默认情况下,当 gateway.auth.allowTailscaletrue 时,Control UI/WebSocket Serve 请求可以通过 Tailscale 身份头(tailscale-user-login)进行认证。OpenClaw 会通过 tailscale whois 解析 x-forwarded-for 地址并将其与该头匹配来验证身份,并且只在请求命中回环且带有 Tailscale 的 x-forwarded-* 头时接受这些请求。对于具有浏览器设备身份的 Control UI 操作员会话,这条经过验证的 Serve 路径还会跳过设备配对往返;无设备的浏览器和 node-role 连接仍会遵循正常的设备检查。如果你希望即使是 Serve 流量也必须使用显式共享密钥凭据,请将 gateway.auth.allowTailscale: false。然后使用 gateway.auth.mode: "token""password"对于该异步 Serve 身份路径,同一客户端 IP 和认证作用域的失败认证尝试会在速率限制写入之前被串行化。因此,同一浏览器发出的并发错误重试,第二个请求可能会显示 retry later,而不是两个普通的不匹配请求并行竞争。
无令牌的 Serve 认证假定 gateway 主机是可信的。如果不可信的本地代码可能在该主机上运行,请要求使用 token/password 认证。

不安全 HTTP

如果你通过普通 HTTP(http://<lan-ip>http://<tailscale-ip>)打开仪表盘,浏览器会以不安全上下文运行并阻止 WebCrypto。默认情况下,OpenClaw 会阻止没有设备身份的 Control UI 连接。 已记录的例外:
  • 仅限 localhost 的不安全 HTTP 兼容性,使用 gateway.controlUi.allowInsecureAuth=true
  • 通过 gateway.auth.mode: "trusted-proxy" 成功进行 operator Control UI 认证
  • 紧急开关 gateway.controlUi.dangerouslyDisableDeviceAuth=true
推荐修复: 使用 HTTPS(Tailscale Serve)或在本地打开 UI:
  • https://<magicdns>/(Serve)
  • http://127.0.0.1:18789/(在 gateway 主机上)
{
  gateway: {
    controlUi: { allowInsecureAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
allowInsecureAuth 只是一个本地兼容性开关:
  • 它允许 localhost 的 Control UI 会话在不安全 HTTP 上下文中在没有设备身份的情况下继续。
  • 它不会绕过配对检查。
  • 它不会放宽远程(非 localhost)设备身份要求。
{
  gateway: {
    controlUi: { dangerouslyDisableDeviceAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
dangerouslyDisableDeviceAuth 会禁用 Control UI 设备身份检查,是严重的安全降级。仅在紧急使用后尽快恢复。
  • 成功的 trusted-proxy 认证可以在不需要设备身份的情况下允许 operator Control UI 会话。
  • 适用于 node-role Control UI 会话。
  • 同主机回环反向代理仍然不满足 trusted-proxy 认证;参见 Trusted proxy auth
有关 HTTPS 设置指南,请参见 Tailscale

内容安全策略

Control UI 采用严格的 img-src 策略:仅允许同源资源、data: URL,以及本地生成的 blob: URL。远程 http(s) 和协议相对的图片 URL 会被浏览器拒绝,并且不会发起网络请求。 这在实际中的含义是:
  • 通过相对路径提供的头像和图片(例如 /avatars/<id>)仍然可以正常渲染,包括 UI 获取并转换为本地 blob: URL 的已认证头像路由。
  • 内联的 data:image/... URL 仍然可以渲染(适用于协议内载荷)。
  • Control UI 创建的本地 blob: URL 仍然可以渲染。
  • 通道元数据发出的远程头像 URL 会在 Control UI 的头像辅助逻辑中被移除,并替换为内置的 logo/badge,因此即使通道被入侵或恶意,也不能强迫操作者浏览器去获取任意远程图片。
你无需做任何修改即可获得这一行为——它始终开启,且不可配置。

头像路由认证

当配置了网关认证时,Control UI 的头像端点需要与 API 其余部分相同的网关令牌:
  • GET /avatar/<agentId> 仅向已认证的调用者返回头像图片。GET /avatar/<agentId>?meta=1 也在相同规则下返回头像元数据。
  • 对任一路由的未认证请求都会被拒绝(与同级的 assistant-media 路由一致)。这可以防止头像路由在其他受保护的主机上泄漏代理标识。
  • Control UI 在获取头像时会将网关令牌作为 bearer 头转发,并使用已认证的 blob URL,这样图片仍可在仪表盘中渲染。
如果你禁用网关认证(不建议在共享主机上这样做),头像路由也会变为未认证,与网关其余部分保持一致。

构建 UI

网关会从 dist/control-ui 提供静态文件。使用以下命令构建:
pnpm ui:build
可选的绝对基础路径(当你希望资产 URL 固定时):
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
用于本地开发(独立开发服务器):
pnpm ui:dev
然后将 UI 指向你的网关 WS URL(例如 ws://127.0.0.1:18789)。

调试/测试:开发服务器 + 远程网关

Control UI 是静态文件;WebSocket 目标是可配置的,可以不同于 HTTP 源。当你希望本地运行 Vite 开发服务器、但网关运行在其他位置时,这会非常方便。
1

启动 UI 开发服务器

pnpm ui:dev
2

使用 gatewayUrl 打开

http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789
可选的一次性认证(如有需要):
http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
  • gatewayUrl 会在加载后存储到 localStorage 中,并从 URL 中移除。
  • 如果你通过 gatewayUrl 传入完整的 ws://wss:// 端点,请对 gatewayUrl 的值进行 URL 编码,以便浏览器正确解析查询字符串。
  • 尽可能通过 URL 片段(#token=...)传递 token。片段不会发送到服务器,这可以避免请求日志和 Referer 泄漏。为兼容性保留的旧式 ?token= 查询参数仍会被导入一次,但仅作为后备,并会在引导完成后立即被移除。
  • password 仅保留在内存中。
  • 当设置了 gatewayUrl 时,UI 不会回退到配置或环境凭据。请显式提供 token(或 password)。缺少显式凭据会报错。
  • 当网关位于 TLS 之后时,请使用 wss://(Tailscale Serve、HTTPS 代理等)。
  • gatewayUrl 仅在顶层窗口中接受(不能嵌入),以防止点击劫持。
  • 非回环的 Control UI 部署必须显式设置 gateway.controlUi.allowedOrigins(完整来源)。这也包括远程开发环境。
  • 网关启动时会根据实际运行时绑定地址和端口,预置诸如 http://localhost:<port>http://127.0.0.1:<port> 之类的本地来源,但远程浏览器来源仍然需要显式配置。
  • 除非是在严格受控的本地测试中,否则不要使用 gateway.controlUi.allowedOrigins: ["*"]。这表示允许任何浏览器来源,而不是“匹配我正在使用的任意主机”。
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true 会启用 Host 头来源回退模式,但这是一个危险的安全模式。
示例:
{
  gateway: {
    controlUi: {
      allowedOrigins: ["http://localhost:5173"],
    },
  },
}
远程访问设置详情:远程访问

相关内容