Control UI 是一个由 Gateway 提供的、基于 Vite + Lit 的单页应用: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.
- 默认:
http://<host>:18789/ - 可选前缀:设置
gateway.controlUi.basePath(例如/openclaw)
本地快速打开
如果 Gateway 运行在同一台电脑上,请打开: 如果页面无法加载,请先启动 Gateway:openclaw gateway。
认证会在 WebSocket 握手期间通过以下方式提供:
connect.params.auth.tokenconnect.params.auth.password- 当
gateway.auth.allowTailscale: true时使用 Tailscale Serve 身份头 - 当
gateway.auth.mode: "trusted-proxy"时使用受信任代理身份头
gateway.auth.mode 为 "password" 时,密码认证也可正常工作。
设备配对(首次连接)
当你从新的浏览器或设备连接到 Control UI 时,Gateway 通常会要求进行一次一次性配对审批。这是为了防止未经授权的访问而采取的安全措施。 你会看到: “disconnected (1008): pairing required” 如果浏览器在重试配对时 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 - 非英语翻译会在浏览器中按需加载。
- 选定的区域设置会保存在浏览器存储中,并在以后访问时复用。
- 缺失的翻译键会回退到英语。
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.history、chat.send、chat.abort、chat.inject)。 - 通过浏览器实时会话通话。OpenAI 使用直接 WebRTC,Google Live 使用通过 WebSocket 的受限一次性浏览器令牌,而仅后端的实时语音插件则使用 Gateway 中继传输。中继会将提供商凭证保留在 Gateway 上,同时浏览器通过
talk.realtime.relay*RPC 流式传输麦克风 PCM,并将openclaw_agent_consult工具调用通过chat.send发送回去,以供更大、已配置的 OpenClaw 模型处理。 - 在 Chat 中流式显示工具调用和实时工具输出卡片(代理事件)。
通道、实例、会话、梦想
通道、实例、会话、梦想
- 通道:内置以及捆绑/外部插件通道状态、二维码登录和按通道配置(
channels.status、web.login.*、config.patch)。 - 实例:在线列表 + 刷新(
system-presence)。 - 会话:列表 + 每个会话的 model/thinking/fast/verbose/trace/reasoning 覆盖(
sessions.list、sessions.patch)。 - Dreams:做梦状态、启用/禁用切换,以及 Dream Diary 阅读器(
doctor.memory.status、doctor.memory.dreamDiary、config.patch)。
Cron、技能、节点、exec 审批
Cron、技能、节点、exec 审批
- Cron 作业:列出/添加/编辑/运行/启用/禁用 + 运行历史(
cron.*)。 - 技能:状态、启用/禁用、安装、API 密钥更新(
skills.*)。 - 节点:列表 + 能力(
node.list)。 - Exec 审批:编辑 gateway 或节点允许列表 +
exec host=gateway/node的询问策略(exec.approvals.*)。
配置
配置
- 查看/编辑
~/.openclaw/openclaw.json(config.get、config.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 调用(
status、health、models.list)。 - 日志:带过滤/导出的 gateway 文件日志实时尾随(
logs.tail)。 - 更新:执行包/git 更新 + 重启(
update.run)并生成重启报告,然后在重连后轮询update.status以验证正在运行的 gateway 版本。
Cron 作业面板说明
Cron 作业面板说明
- 对于独立作业,投递方式默认是 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。
聊天行为
Send and history semantics
Send and history semantics
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.listRPC,并将view: "all"。 - 当新的 Gateway 会话使用报告显示上下文压力较高时,聊天撰写区会显示上下文提示,并在推荐的压缩级别提供一个压缩按钮,以运行正常的会话压缩路径。过期的令牌快照会被隐藏,直到 Gateway 再次报告新的使用情况。
Talk 模式(浏览器实时)
Talk 模式(浏览器实时)
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(或单独的中止短语,如stop、stop action、stop run、stop openclaw、please 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.webmanifest | PWA 清单。浏览器在可访问后会提供“安装应用”。 |
ui/public/sw.js | 处理 push 事件和通知点击的 service worker。 |
push/vapid-keys.json (under the OpenClaw state dir) | 用于签署 Web Push 负载的自动生成 VAPID 密钥对。 |
push/web-push-subscriptions.json | 持久化的浏览器订阅端点。 |
OPENCLAW_VAPID_PUBLIC_KEYOPENCLAW_VAPID_PRIVATE_KEYOPENCLAW_VAPID_SUBJECT(默认值为mailto:openclaw@localhost)
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 控制:
- strict
- scripts (default)
- trusted
禁用托管嵌入中的脚本执行。
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 settinggateway.controlUi.chatMessageMaxWidth:
960px or 82%, plus constrained min(...), max(...), clamp(...), calc(...), and fit-content(...) width expressions.
Tailnet access (recommended)
- 集成的 Tailscale Serve(首选)
- 绑定到 tailnet + 令牌
保持 Gateway 只监听回环地址,并让 Tailscale Serve 通过 HTTPS 代理它:打开:
https://<magicdns>/(或你配置的gateway.controlUi.basePath)
gateway.auth.allowTailscale 为 true 时,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,而不是两个普通的不匹配请求并行竞争。不安全 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://<magicdns>/(Serve)http://127.0.0.1:18789/(在 gateway 主机上)
不安全认证开关行为
不安全认证开关行为
allowInsecureAuth 只是一个本地兼容性开关:- 它允许 localhost 的 Control UI 会话在不安全 HTTP 上下文中在没有设备身份的情况下继续。
- 它不会绕过配对检查。
- 它不会放宽远程(非 localhost)设备身份要求。
仅用于紧急开关
仅用于紧急开关
关于 trusted-proxy 的说明
关于 trusted-proxy 的说明
- 成功的 trusted-proxy 认证可以在不需要设备身份的情况下允许 operator Control UI 会话。
- 这不适用于 node-role Control UI 会话。
- 同主机回环反向代理仍然不满足 trusted-proxy 认证;参见 Trusted proxy auth。
内容安全策略
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 提供静态文件。使用以下命令构建:
ws://127.0.0.1:18789)。
调试/测试:开发服务器 + 远程网关
Control UI 是静态文件;WebSocket 目标是可配置的,可以不同于 HTTP 源。当你希望本地运行 Vite 开发服务器、但网关运行在其他位置时,这会非常方便。说明
说明
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 头来源回退模式,但这是一个危险的安全模式。
相关内容
- Dashboard — 网关仪表盘
- Health Checks — 网关健康监控
- TUI — 终端用户界面
- WebChat — 基于浏览器的聊天界面