From cbefdb24a61c022183569be8486078a66c73b4ae Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Sat, 2 May 2026 13:35:38 +0000 Subject: [PATCH] chore(i18n): refresh zh-CN translations --- docs/zh-CN/cli/mcp.md | 210 ++++++++-------- docs/zh-CN/gateway/protocol.md | 437 ++++++++++++++++----------------- 2 files changed, 314 insertions(+), 333 deletions(-) diff --git a/docs/zh-CN/cli/mcp.md b/docs/zh-CN/cli/mcp.md index 60c42dd02..14651b496 100644 --- a/docs/zh-CN/cli/mcp.md +++ b/docs/zh-CN/cli/mcp.md @@ -1,31 +1,31 @@ --- read_when: - - 将 Codex、Claude Code 或其他 MCP 客户端连接到由 OpenClaw 支持的渠道 + - 将 Codex、Claude Code 或其他 MCP 客户端连接到 OpenClaw 支持的渠道 - 正在运行 `openclaw mcp serve` - 管理 OpenClaw 保存的 MCP 服务器定义 sidebarTitle: MCP summary: 通过 MCP 暴露 OpenClaw 渠道对话,并管理已保存的 MCP 服务器定义 title: MCP x-i18n: - generated_at: "2026-04-28T11:48:28Z" + generated_at: "2026-05-02T13:33:59Z" model: gpt-5.5 provider: openai - source_hash: d66ec20b81ab3894c7202ee1c1c6666bd9cdeffc8d48a280b1f298bb358887ef + source_hash: d1d3b5d7c3a9075c020a35bc9617d6e6902c96b40cc03e76119d01d0d94fd014 source_path: cli/mcp.md workflow: 16 --- `openclaw mcp` 有两个职责: -- 通过 `openclaw mcp serve` 将 OpenClaw 作为 MCP 服务器运行 -- 使用 `list`、`show`、`set` 和 `unset` 管理 OpenClaw 拥有的出站 MCP 服务器定义 +- 使用 `openclaw mcp serve` 将 OpenClaw 作为 MCP 服务器运行 +- 使用 `list`、`show`、`set` 和 `unset` 管理由 OpenClaw 拥有的出站 MCP 服务器定义 换句话说: -- `serve` 是 OpenClaw 作为 MCP 服务器运行 -- `list` / `show` / `set` / `unset` 是 OpenClaw 作为 MCP 客户端侧注册表运行,用于其运行时之后可能使用的其他 MCP 服务器 +- `serve` 是 OpenClaw 充当 MCP 服务器 +- `list` / `show` / `set` / `unset` 是 OpenClaw 充当 MCP 客户端侧注册表,供其他 MCP 服务器被其运行时稍后使用 -当 OpenClaw 应该自行托管一个编码 harness 会话并通过 ACP 路由该运行时时,请使用 [`openclaw acp`](/zh-CN/cli/acp)。 +当 OpenClaw 应自行托管编码 harness 会话并通过 ACP 路由该运行时时,请使用 [`openclaw acp`](/zh-CN/cli/acp)。 ## OpenClaw 作为 MCP 服务器 @@ -33,17 +33,17 @@ x-i18n: ### 何时使用 `serve` -在以下情况下使用 `openclaw mcp serve`: +在以下情况使用 `openclaw mcp serve`: - Codex、Claude Code 或其他 MCP 客户端应直接与 OpenClaw 支持的渠道对话通信 -- 你已有一个带路由会话的本地或远程 OpenClaw Gateway 网关 -- 你想要一个可跨 OpenClaw 渠道后端工作的 MCP 服务器,而不是运行单独的按渠道桥接器 +- 你已经有一个带有已路由会话的本地或远程 OpenClaw Gateway 网关 +- 你想要一个可跨 OpenClaw 渠道后端工作的 MCP 服务器,而不是运行单独的逐渠道桥接器 -当 OpenClaw 应该自行托管编码运行时并将智能体会话保留在 OpenClaw 内部时,请改用 [`openclaw acp`](/zh-CN/cli/acp)。 +当 OpenClaw 应自行托管编码运行时并将智能体会话保留在 OpenClaw 内部时,请改用 [`openclaw acp`](/zh-CN/cli/acp)。 -### 工作原理 +### 工作方式 -`openclaw mcp serve` 会启动一个 stdio MCP 服务器。MCP 客户端拥有该进程。只要客户端保持 stdio 会话打开,桥接器就会通过 WebSocket 连接到本地或远程 OpenClaw Gateway 网关,并通过 MCP 暴露已路由的渠道对话。 +`openclaw mcp serve` 会启动一个 stdio MCP 服务器。MCP 客户端拥有该进程。当客户端保持 stdio 会话打开时,桥接器会通过 WebSocket 连接到本地或远程 OpenClaw Gateway 网关,并通过 MCP 暴露已路由的渠道对话。 @@ -53,10 +53,10 @@ x-i18n: 桥接器通过 WebSocket 连接到 OpenClaw Gateway 网关。 - 已路由的会话变为 MCP 对话以及转录/历史工具。 + 已路由会话会变为 MCP 对话以及转录记录/历史工具。 - 当桥接器已连接时,实时事件会排入内存队列。 + 桥接器连接期间,实时事件会排入内存队列。 如果启用了 Claude 渠道模式,同一会话也可以接收 Claude 专用推送通知。 @@ -65,13 +65,13 @@ x-i18n: - - 实时队列状态从桥接器连接时开始 - - 较旧的转录历史通过 `messages_read` 读取 - - Claude 推送通知仅在 MCP 会话存活时存在 + - 实时队列状态在桥接器连接时开始 + - 较早的转录记录历史通过 `messages_read` 读取 + - Claude 推送通知只在 MCP 会话存活期间存在 - 当客户端断开连接时,桥接器会退出,实时队列也会消失 - - 一次性智能体入口点,例如 `openclaw agent` 和 `openclaw infer model run`,会在回复完成时停用它们打开的任何内置 MCP 运行时,因此重复的脚本化运行不会累积 stdio MCP 子进程 - - 由 OpenClaw 启动的 stdio MCP 服务器(内置或用户配置)会在关闭时作为进程树被拆除,因此服务器启动的子进程不会在父 stdio 客户端退出后继续存活 - - 删除或重置会话会通过共享运行时清理路径释放该会话的 MCP 客户端,因此不会有与已移除会话绑定的残留 stdio 连接 + - `openclaw agent` 和 `openclaw infer model run` 等一次性智能体入口点会在回复完成时回收它们打开的任何内置 MCP 运行时,因此重复的脚本化运行不会累积 stdio MCP 子进程 + - OpenClaw 启动的 stdio MCP 服务器(内置或用户配置)会在关闭时作为进程树被拆除,因此服务器启动的子进程不会在父 stdio 客户端退出后继续存在 + - 删除或重置会话会通过共享运行时清理路径处置该会话的 MCP 客户端,因此不会留下与已移除会话绑定的 stdio 连接 @@ -95,17 +95,17 @@ x-i18n: ### `serve` 暴露的内容 -桥接器使用现有的 Gateway 网关会话路由元数据来暴露由渠道支持的对话。当 OpenClaw 已有带已知路由的会话状态时,对话会出现,例如: +桥接器使用现有 Gateway 网关会话路由元数据来暴露渠道支持的对话。当 OpenClaw 已有带已知路由的会话状态时,就会出现一个对话,例如: - `channel` - 接收方或目标元数据 - 可选 `accountId` - 可选 `threadId` -这让 MCP 客户端可以在一个位置: +这为 MCP 客户端提供一个位置来: - 列出最近的已路由对话 -- 读取最近的转录历史 +- 读取最近的转录记录历史 - 等待新的入站事件 - 通过同一路由发回回复 - 查看桥接器连接期间到达的审批请求 @@ -128,7 +128,7 @@ x-i18n: openclaw mcp serve --url wss://gateway-host:18789 --password-file ~/.openclaw/gateway.password ``` - + ```bash openclaw mcp serve --verbose openclaw mcp serve --claude-channel-mode off @@ -142,9 +142,9 @@ x-i18n: - 列出最近的、已有 Gateway 网关会话状态中的路由元数据的、由会话支持的对话。 + 列出最近的、由会话支持且 Gateway 网关会话状态中已具有路由元数据的对话。 - 有用的过滤器: + 有用的筛选器: - `limit` - `search` @@ -154,21 +154,21 @@ x-i18n: - 按 `session_key` 返回一个对话。 + 使用直接 Gateway 网关会话查找,通过 `session_key` 返回一个对话。 - 读取一个由会话支持的对话的最近转录消息。 + 读取一个由会话支持的对话的最近转录记录消息。 - 从一个转录消息中提取非文本消息内容块。这是对转录内容的元数据视图,不是独立的持久附件 blob 存储。 + 从一条转录记录消息中提取非文本消息内容块。这是转录记录内容之上的元数据视图,不是独立持久的附件 blob 存储。 读取自数字游标以来排队的实时事件。 - 长轮询,直到下一个匹配的排队事件到达或超时到期。 + 长轮询,直到下一个匹配的排队事件到达,或超时到期。 - 当通用 MCP 客户端需要接近实时的投递且不使用 Claude 专用推送协议时,请使用此工具。 + 当通用 MCP 客户端需要近实时投递且不使用 Claude 专用推送协议时,请使用它。 @@ -182,10 +182,10 @@ x-i18n: - 列出桥接器连接到 Gateway 网关后观察到的待处理 exec/plugin 审批请求。 + 列出桥接器连接到 Gateway 网关以来观察到的待处理 exec/插件审批请求。 - 使用以下选项解析一个待处理 exec/plugin 审批请求: + 使用以下值解决一个待处理的 exec/插件审批请求: - `allow-once` - `allow-always` @@ -196,7 +196,7 @@ x-i18n: ### 事件模型 -桥接器在连接期间保留一个内存中的事件队列。 +桥接器在连接期间维护一个内存事件队列。 当前事件类型: @@ -208,21 +208,21 @@ x-i18n: - `claude_permission_request` -- 队列仅限实时;它从 MCP 桥接器启动时开始 -- `events_poll` 和 `events_wait` 本身不会重放较旧的 Gateway 网关历史 -- 持久积压应通过 `messages_read` 读取 +- 队列仅限实时;它在 MCP 桥接器启动时开始 +- `events_poll` 和 `events_wait` 本身不会重放较早的 Gateway 网关历史 +- 持久积压记录应使用 `messages_read` 读取 ### Claude 渠道通知 -桥接器也可以暴露 Claude 专用渠道通知。这是 Claude Code 渠道适配器在 OpenClaw 中的等价物:标准 MCP 工具仍然可用,但实时入站消息也可以作为 Claude 专用 MCP 通知到达。 +桥接器也可以暴露 Claude 专用渠道通知。这是 OpenClaw 中等价于 Claude Code 渠道适配器的功能:标准 MCP 工具仍可用,但实时入站消息也可以作为 Claude 专用 MCP 通知到达。 - + `--claude-channel-mode off`:仅标准 MCP 工具。 - + `--claude-channel-mode on`:启用 Claude 渠道通知。 @@ -230,19 +230,19 @@ x-i18n: -启用 Claude 渠道模式后,服务器会声明 Claude 实验性能力,并且可以发出: +启用 Claude 渠道模式后,服务器会声明 Claude 实验能力,并可以发出: - `notifications/claude/channel` - `notifications/claude/channel/permission` 当前桥接器行为: -- 入站 `user` 转录消息会作为 `notifications/claude/channel` 转发 -- 通过 MCP 收到的 Claude 权限请求会在内存中跟踪 +- 入站 `user` 转录记录消息会作为 `notifications/claude/channel` 转发 +- 通过 MCP 接收的 Claude 权限请求会在内存中跟踪 - 如果关联的对话稍后发送 `yes abcde` 或 `no abcde`,桥接器会将其转换为 `notifications/claude/channel/permission` - 这些通知仅限实时会话;如果 MCP 客户端断开连接,就没有推送目标 -这是有意设计为客户端专用的。通用 MCP 客户端应依赖标准轮询工具。 +这是有意设计的客户端专用行为。通用 MCP 客户端应依赖标准轮询工具。 ### MCP 客户端配置 @@ -266,7 +266,7 @@ stdio 客户端配置示例: } ``` -对于大多数通用 MCP 客户端,请从标准工具表面开始,并忽略 Claude 模式。仅为真正理解 Claude 专用通知方法的客户端开启 Claude 模式。 +对于大多数通用 MCP 客户端,请从标准工具界面开始,并忽略 Claude 模式。仅在客户端实际理解 Claude 专用通知方法时开启 Claude 模式。 ### 选项 @@ -291,29 +291,29 @@ stdio 客户端配置示例: Claude 通知模式。 - 在 stderr 上输出详细日志。 + 在 stderr 输出详细日志。 尽可能优先使用 `--token-file` 或 `--password-file`,而不是内联密钥。 -### 安全和信任边界 +### 安全与信任边界 -桥接器不会自行发明路由。它只暴露 Gateway 网关已经知道如何路由的对话。 +桥接器不会凭空创建路由。它只暴露 Gateway 网关已经知道如何路由的对话。 这意味着: -- 发送方 allowlist、配对以及渠道级信任仍属于底层 OpenClaw 渠道配置 -- `messages_send` 只能通过现有存储路由回复 +- 发送方允许列表、配对和渠道级信任仍属于底层 OpenClaw 渠道配置 +- `messages_send` 只能通过现有已存储路由回复 - 审批状态仅对当前桥接器会话实时/内存可用 -- 桥接器身份验证应使用你会信任任何其他远程 Gateway 网关客户端使用的同一 Gateway 网关令牌或密码控制 +- 桥接器认证应使用你愿意信任给任何其他远程 Gateway 网关客户端的相同 Gateway 网关令牌或密码控制 -如果某个对话未出现在 `conversations_list` 中,通常原因不是 MCP 配置,而是底层 Gateway 网关会话中的路由元数据缺失或不完整。 +如果某个对话未出现在 `conversations_list` 中,通常原因不是 MCP 配置,而是底层 Gateway 网关会话中缺失或不完整的路由元数据。 ### 测试 -OpenClaw 为此桥接器提供了确定性的 Docker 冒烟测试: +OpenClaw 为此桥接器提供一个确定性的 Docker 冒烟测试: ```bash pnpm test:docker:mcp-channels @@ -322,34 +322,34 @@ pnpm test:docker:mcp-channels 该冒烟测试会: - 启动一个带种子数据的 Gateway 网关容器 -- 启动第二个容器并生成 `openclaw mcp serve` -- 验证对话发现、转录读取、附件元数据读取、实时事件队列行为和出站发送路由 +- 启动第二个容器,并生成 `openclaw mcp serve` +- 验证对话发现、转录记录读取、附件元数据读取、实时事件队列行为和出站发送路由 - 通过真实的 stdio MCP 桥接器验证 Claude 风格的渠道和权限通知 这是在不把真实 Telegram、Discord 或 iMessage 账号接入测试运行的情况下证明桥接器工作的最快方式。 -如需更广泛的测试背景,请参阅 [测试](/zh-CN/help/testing)。 +有关更广泛的测试上下文,请参阅 [测试](/zh-CN/help/testing)。 ### 故障排除 - - 通常表示 Gateway 网关会话尚不可路由。确认底层会话已存储渠道/提供商、接收方,以及可选账号/线程路由元数据。 + + 通常意味着 Gateway 网关会话尚不可路由。确认底层会话已存储渠道/提供商、接收方以及可选账号/线程路由元数据。 - - 这是预期行为。实时队列从桥接器连接时开始。使用 `messages_read` 读取较旧的转录历史。 + + 符合预期。实时队列在桥接器连接时开始。使用 `messages_read` 读取较早的转录记录历史。 检查以下所有项: - 客户端保持 stdio MCP 会话打开 - `--claude-channel-mode` 为 `on` 或 `auto` - - 客户端确实理解 Claude 专用通知方法 + - 客户端实际理解 Claude 专用通知方法 - 入站消息发生在桥接器连接之后 - - `permissions_list_open` 仅显示桥接器连接期间观察到的审批请求。它不是持久审批历史 API。 + + `permissions_list_open` 只显示桥接器连接期间观察到的审批请求。它不是持久的审批历史 API。 @@ -359,25 +359,25 @@ pnpm test:docker:mcp-channels 这些命令不会通过 MCP 暴露 OpenClaw。它们管理 OpenClaw 配置中 `mcp.servers` 下由 OpenClaw 拥有的 MCP 服务器定义。 -这些已保存的定义供 OpenClaw 后续启动或配置的运行时使用,例如嵌入式 Pi 和其他运行时适配器。OpenClaw 会集中存储这些定义,因此这些运行时不需要维护自己的重复 MCP 服务器列表。 +这些已保存的定义用于 OpenClaw 稍后启动或配置的运行时,例如嵌入式 Pi 和其他运行时适配器。OpenClaw 会集中存储这些定义,因此这些运行时不需要维护自己的重复 MCP 服务器列表。 - + - 这些命令只读取或写入 OpenClaw 配置 - 它们不会连接到目标 MCP 服务器 - - 它们不会验证命令、URL 或远程传输协议当前是否可达 + - 它们不会验证命令、URL 或远程传输协议当前是否可访问 - 运行时适配器会在执行时决定它们实际支持哪些传输形态 - - 嵌入式 Pi 会在普通 `coding` 和 `messaging` 工具配置文件中暴露已配置的 MCP 工具;`minimal` 仍会隐藏它们,而 `tools.deny: ["bundle-mcp"]` 会显式禁用它们 - - 会话范围的内置 MCP 运行时会在空闲 `mcp.sessionIdleTtlMs` 毫秒后被回收(默认 10 分钟;设为 `0` 可禁用),一次性嵌入式运行会在运行结束时清理它们 + - 嵌入式 Pi 会在普通 `coding` 和 `messaging` 工具配置文件中暴露已配置的 MCP 工具;`minimal` 仍会隐藏它们,并且 `tools.deny: ["bundle-mcp"]` 会显式禁用它们 + - 会话作用域的内置 MCP 运行时会在空闲 `mcp.sessionIdleTtlMs` 毫秒后被回收(默认 10 分钟;设置为 `0` 可禁用),一次性嵌入式运行会在运行结束时清理它们 -运行时适配器可以将这个共享注册表规范化为其下游客户端期望的形状。例如,嵌入式 Pi 会直接使用 OpenClaw 的 `transport` 值,而 Claude Code 和 Gemini 会接收 CLI 原生的 `type` 值,例如 `http`、`sse` 或 `stdio`。 +运行时适配器可能会将这个共享注册表规范化为其下游客户端期望的形态。例如,嵌入式 Pi 会直接使用 OpenClaw 的 `transport` 值,而 Claude Code 和 Gemini 会收到 CLI 原生的 `type` 值,例如 `http`、`sse` 或 `stdio`。 ### 已保存的 MCP 服务器定义 -OpenClaw 还会在配置中存储一个轻量级 MCP 服务器注册表,供需要 OpenClaw 托管 MCP 定义的界面使用。 +OpenClaw 还会在配置中存储一个轻量级 MCP 服务器注册表,供需要 OpenClaw 管理的 MCP 定义的界面使用。 命令: @@ -388,10 +388,10 @@ OpenClaw 还会在配置中存储一个轻量级 MCP 服务器注册表,供需 说明: -- `list` 会按服务器名称排序。 +- `list` 会对服务器名称排序。 - 不带名称的 `show` 会打印完整的已配置 MCP 服务器对象。 -- `set` 期望命令行上有一个 JSON 对象值。 -- 对于 Streamable HTTP MCP 服务器,请使用 `transport: "streamable-http"`。为兼容起见,`openclaw mcp set` 也会将 CLI 原生的 `type: "http"` 规范化为同一个规范配置形状。 +- `set` 需要在命令行中提供一个 JSON 对象值。 +- 对 Streamable HTTP MCP 服务器使用 `transport: "streamable-http"`。为保持兼容,`openclaw mcp set` 也会将 CLI 原生的 `type: "http"` 规范化为相同的规范配置形态。 - 如果指定名称的服务器不存在,`unset` 会失败。 示例: @@ -404,7 +404,7 @@ openclaw mcp set docs '{"url":"https://mcp.example.com","transport":"streamable- openclaw mcp unset context7 ``` -示例配置形状: +示例配置形态: ```json { @@ -427,30 +427,30 @@ openclaw mcp unset context7 启动本地子进程,并通过 stdin/stdout 通信。 -| 字段 | 描述 | -| -------------------------- | ---------------------------- | -| `command` | 要启动的可执行文件(必填) | -| `args` | 命令行参数数组 | -| `env` | 额外环境变量 | -| `cwd` / `workingDirectory` | 进程的工作目录 | +| 字段 | 描述 | +| -------------------------- | ------------------------ | +| `command` | 要生成的可执行文件(必需) | +| `args` | 命令行参数数组 | +| `env` | 额外环境变量 | +| `cwd` / `workingDirectory` | 进程的工作目录 | **Stdio 环境变量安全过滤器** -OpenClaw 会拒绝可能在第一次 RPC 之前改变 stdio MCP 服务器启动方式的解释器启动环境变量键名,即使它们出现在服务器的 `env` 块中。被阻止的键名包括 `NODE_OPTIONS`、`PYTHONSTARTUP`、`PYTHONPATH`、`PERL5OPT`、`RUBYOPT`、`SHELLOPTS`、`PS4` 以及类似的运行时控制变量。启动会以配置错误拒绝这些键名,避免它们注入隐式前置脚本、替换解释器,或对 stdio 进程启用调试器。普通凭据、代理和服务器专用环境变量(`GITHUB_TOKEN`、`HTTP_PROXY`、自定义 `*_API_KEY` 等)不受影响。 +OpenClaw 会拒绝解释器启动环境变量键名,这些键名可能在第一个 RPC 之前改变 stdio MCP 服务器的启动方式,即使它们出现在服务器的 `env` 块中也是如此。被阻止的键名包括 `NODE_OPTIONS`、`PYTHONSTARTUP`、`PYTHONPATH`、`PERL5OPT`、`RUBYOPT`、`SHELLOPTS`、`PS4` 以及类似的运行时控制变量。启动时会以配置错误拒绝这些变量,因此它们不能注入隐式前导代码、替换解释器,或针对 stdio 进程启用调试器。普通凭证、代理和服务器特定的环境变量(`GITHUB_TOKEN`、`HTTP_PROXY`、自定义 `*_API_KEY` 等)不受影响。 -如果你的 MCP 服务器确实需要其中一个被阻止的变量,请在 Gateway 网关主机进程上设置它,而不是放在 stdio 服务器的 `env` 下。 +如果你的 MCP 服务器确实需要其中某个被阻止的变量,请在 Gateway 网关宿主进程上设置它,而不是设置在 stdio 服务器的 `env` 下。 ### SSE / HTTP 传输协议 -通过 HTTP Server-Sent Events 连接到远程 MCP 服务器。 +通过 HTTP 服务器发送事件连接到远程 MCP 服务器。 -| 字段 | 描述 | -| --------------------- | ------------------------------------------------------ | -| `url` | 远程服务器的 HTTP 或 HTTPS URL(必填) | -| `headers` | 可选的 HTTP 标头键值映射(例如身份验证令牌) | -| `connectionTimeoutMs` | 每个服务器的连接超时时间,单位为毫秒(可选) | +| 字段 | 描述 | +| --------------------- | ----------------------------------------- | +| `url` | 远程服务器的 HTTP 或 HTTPS URL(必需) | +| `headers` | 可选的 HTTP 标头键值映射(例如身份验证令牌) | +| `connectionTimeoutMs` | 每个服务器的连接超时时间,单位为 ms(可选) | 示例: @@ -469,20 +469,20 @@ OpenClaw 会拒绝可能在第一次 RPC 之前改变 stdio MCP 服务器启动 } ``` -`url`(userinfo)和 `headers` 中的敏感值会在日志和 Status 输出中被脱敏。 +`url`(userinfo)和 `headers` 中的敏感值会在日志和 Status 输出中被遮盖。 ### Streamable HTTP 传输协议 -`streamable-http` 是与 `sse` 和 `stdio` 并列的额外传输协议选项。它使用 HTTP 流式传输与远程 MCP 服务器进行双向通信。 +`streamable-http` 是 `sse` 和 `stdio` 之外的另一种传输协议选项。它使用 HTTP 流式传输与远程 MCP 服务器进行双向通信。 -| 字段 | 描述 | -| --------------------- | ------------------------------------------------------------------------------------ | -| `url` | 远程服务器的 HTTP 或 HTTPS URL(必填) | -| `transport` | 设为 `"streamable-http"` 以选择此传输协议;省略时,OpenClaw 使用 `sse` | +| 字段 | 描述 | +| --------------------- | ------------------------------------------------------------------------------------- | +| `url` | 远程服务器的 HTTP 或 HTTPS URL(必需) | +| `transport` | 设置为 `"streamable-http"` 以选择此传输协议;省略时,OpenClaw 使用 `sse` | | `headers` | 可选的 HTTP 标头键值映射(例如身份验证令牌) | -| `connectionTimeoutMs` | 每个服务器的连接超时时间,单位为毫秒(可选) | +| `connectionTimeoutMs` | 每个服务器的连接超时时间,单位为 ms(可选) | -OpenClaw 配置使用 `transport: "streamable-http"` 作为规范写法。通过 `openclaw mcp set` 保存时会接受 CLI 原生 MCP `type: "http"` 值,并且现有配置中可由 `openclaw doctor --fix` 修复,但嵌入式 Pi 会直接使用 `transport`。 +OpenClaw 配置使用 `transport: "streamable-http"` 作为规范写法。通过 `openclaw mcp set` 保存时会接受 CLI 原生的 MCP `type: "http"` 值,并且现有配置中的该值会由 `openclaw doctor --fix` 修复,但嵌入式 Pi 直接使用的是 `transport`。 示例: @@ -504,22 +504,22 @@ OpenClaw 配置使用 `transport: "streamable-http"` 作为规范写法。通过 ``` -这些命令只管理已保存的配置。它们不会启动渠道桥接、打开实时 MCP 客户端会话,或证明目标服务器可达。 +这些命令只管理已保存的配置。它们不会启动渠道桥接、打开实时 MCP 客户端会话,也不会证明目标服务器可访问。 ## 当前限制 -此页面记录的是当前已发布的桥接。 +本页记录的是当前已发布的桥接能力。 当前限制: -- 对话发现依赖现有 Gateway 网关会话路由元数据 -- 除 Claude 专用适配器之外,没有通用推送协议 +- 对话发现依赖现有的 Gateway 网关会话路由元数据 +- 除 Claude 专用适配器外,还没有通用推送协议 - 还没有消息编辑或回应工具 -- HTTP/SSE/streamable-http 传输协议会连接到单个远程服务器;尚不支持多路复用上游 -- `permissions_list_open` 仅包含桥接连接期间观察到的批准 +- HTTP/SSE/streamable-http 传输协议会连接到单个远程服务器;目前还没有多路复用上游 +- `permissions_list_open` 只包含桥接连接期间观察到的批准 -## 相关 +## 相关内容 - [CLI 参考](/zh-CN/cli) - [插件](/zh-CN/cli/plugins) diff --git a/docs/zh-CN/gateway/protocol.md b/docs/zh-CN/gateway/protocol.md index 0db219cd4..e27c0caff 100644 --- a/docs/zh-CN/gateway/protocol.md +++ b/docs/zh-CN/gateway/protocol.md @@ -2,26 +2,25 @@ read_when: - 实现或更新 Gateway 网关 WS 客户端 - 调试协议不匹配或连接失败 - - 正在重新生成协议架构/模型 + - 重新生成协议架构/模型 summary: Gateway 网关 WebSocket 协议:握手、帧、版本控制 title: Gateway 网关协议 x-i18n: - generated_at: "2026-05-01T08:59:06Z" + generated_at: "2026-05-02T13:34:01Z" model: gpt-5.5 provider: openai - source_hash: 8295e4e416250e7381393c0aa6a0016719f96552485cf9d56bb3896c9704c4a9 + source_hash: bc8bd6bae485f13bbd0e8762d30abdfab7e2aee635f8ebac1a38798493239798 source_path: gateway/protocol.md workflow: 16 --- -Gateway 网关 WS 协议是 OpenClaw 的**单一控制平面 + 节点传输协议**。 -所有客户端(CLI、Web UI、macOS 应用、iOS/Android 节点、无头节点)都通过 WebSocket 连接,并在握手时声明它们的**角色** + **作用域**。 +Gateway 网关 WS 协议是 OpenClaw 的**单一控制平面 + 节点传输协议**。所有客户端(CLI、Web UI、macOS 应用、iOS/Android 节点、无头节点)都通过 WebSocket 连接,并在握手时声明其**角色** + **作用域**。 -## 传输协议 +## 传输 -- WebSocket,带 JSON 载荷的文本帧。 +- WebSocket,使用带 JSON 载荷的文本帧。 - 第一帧**必须**是 `connect` 请求。 -- 连接前帧上限为 64 KiB。握手成功后,客户端应遵循 `hello-ok.policy.maxPayload` 和 `hello-ok.policy.maxBufferedBytes` 限制。启用诊断后,超大的入站帧和缓慢的出站缓冲区会在 Gateway 网关关闭或丢弃受影响帧之前发出 `payload.large` 事件。这些事件会保留大小、限制、表面和安全原因代码。它们不会保留消息正文、附件内容、原始帧正文、令牌、Cookie 或密钥值。 +- 连接前帧上限为 64 KiB。握手成功后,客户端应遵循 `hello-ok.policy.maxPayload` 和 `hello-ok.policy.maxBufferedBytes` 限制。启用诊断后,过大的入站帧和缓慢的出站缓冲区会在 Gateway 网关关闭或丢弃受影响帧之前发出 `payload.large` 事件。这些事件会保留大小、限制、表面和安全原因代码。它们不会保留消息正文、附件内容、原始帧正文、令牌、Cookie 或机密值。 ## 握手(connect) @@ -96,11 +95,11 @@ Gateway 网关 → 客户端: } ``` -当 Gateway 网关仍在完成启动 sidecar 时,`connect` 请求可能返回可重试的 `UNAVAILABLE` 错误,其中 `details.reason` 设置为 `"startup-sidecars"`,并包含 `retryAfterMs`。客户端应在整体连接预算内重试该响应,而不是将其暴露为终止性的握手失败。 +当 Gateway 网关仍在完成启动 sidecar 时,`connect` 请求可能返回可重试的 `UNAVAILABLE` 错误,并将 `details.reason` 设为 `"startup-sidecars"`,同时带有 `retryAfterMs`。客户端应在其整体连接预算内重试该响应,而不是将其呈现为终止性握手失败。 `server`、`features`、`snapshot` 和 `policy` 都是 schema(`src/gateway/protocol/schema/frames.ts`)要求的字段。`auth` 也是必需的,并报告协商后的角色/作用域。`canvasHostUrl` 是可选的。 -当没有签发设备令牌时,`hello-ok.auth` 会报告协商后的权限,不包含令牌字段: +未签发设备令牌时,`hello-ok.auth` 会报告协商后的权限,不包含令牌字段: ```json { @@ -111,9 +110,9 @@ Gateway 网关 → 客户端: } ``` -受信任的同进程后端客户端(`client.id: "gateway-client"`、`client.mode: "backend"`)在使用共享 Gateway 网关令牌/密码进行认证时,可以在直接 loopback 连接上省略 `device`。此路径保留给内部控制平面 RPC,并避免陈旧的 CLI/设备配对基线阻塞本地后端工作,例如子智能体会话更新。远程客户端、浏览器来源客户端、节点客户端以及显式设备令牌/设备身份客户端仍使用正常的配对和作用域升级检查。 +受信任的同进程后端客户端(`client.id: "gateway-client"`、`client.mode: "backend"`)在使用共享 Gateway 网关令牌/密码认证时,可以在直接 local loopback 连接上省略 `device`。此路径保留给内部控制平面 RPC,并避免过期的 CLI/设备配对基线阻塞本地后端工作,例如子智能体会话更新。远程客户端、浏览器来源客户端、节点客户端,以及显式设备令牌/设备身份客户端,仍使用正常的配对和作用域升级检查。 -当签发设备令牌时,`hello-ok` 还会包含: +签发设备令牌时,`hello-ok` 还会包含: ```json { @@ -125,7 +124,7 @@ Gateway 网关 → 客户端: } ``` -在受信任的启动引导交接期间,`hello-ok.auth` 也可能在 `deviceTokens` 中包含额外的有界角色条目: +在受信任的引导交接期间,`hello-ok.auth` 也可能在 `deviceTokens` 中包含额外的有界角色条目: ```json { @@ -144,7 +143,7 @@ Gateway 网关 → 客户端: } ``` -对于内置节点/操作员启动引导流程,主节点令牌保持 `scopes: []`,任何交接出的操作员令牌都保持限制在启动引导操作员允许列表(`operator.approvals`、`operator.read`、`operator.talk.secrets`、`operator.write`)内。启动引导作用域检查保持角色前缀规则:操作员条目只满足操作员请求,非操作员角色仍需要其自身角色前缀下的作用域。 +对于内置的节点/operator 引导流程,主节点令牌保持 `scopes: []`,任何交接的 operator 令牌都会限制在引导 operator 允许列表(`operator.approvals`、`operator.read`、`operator.talk.secrets`、`operator.write`)内。引导作用域检查保持角色前缀化:operator 条目只满足 operator 请求,非 operator 角色仍需要其自身角色前缀下的作用域。 ### 节点示例 @@ -181,7 +180,7 @@ Gateway 网关 → 客户端: } ``` -## 成帧 +## 帧格式 - **请求**:`{type:"req", id, method, params}` - **响应**:`{type:"res", id, ok, payload|error}` @@ -196,7 +195,7 @@ Gateway 网关 → 客户端: - `operator` = 控制平面客户端(CLI/UI/自动化)。 - `node` = 能力宿主(camera/screen/canvas/system.run)。 -### 作用域(操作员) +### 作用域(operator) 常见作用域: @@ -209,16 +208,15 @@ Gateway 网关 → 客户端: 带有 `includeSecrets: true` 的 `talk.config` 需要 `operator.talk.secrets`(或 `operator.admin`)。 -插件注册的 Gateway 网关 RPC 方法可以请求自己的操作员作用域,但保留的核心管理员前缀(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终解析为 `operator.admin`。 +插件注册的 Gateway 网关 RPC 方法可以请求它们自己的 operator 作用域,但保留的核心 admin 前缀(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终解析为 `operator.admin`。 -方法作用域只是第一道门禁。通过 `chat.send` 到达的某些斜杠命令会在其上应用更严格的命令级检查。例如,持久化的 `/config set` 和 `/config unset` 写入需要 `operator.admin`。 +方法作用域只是第一道门。一些通过 `chat.send` 到达的斜杠命令会在其上应用更严格的命令级检查。例如,持久化的 `/config set` 和 `/config unset` 写入需要 `operator.admin`。 -`node.pair.approve` 在基础方法作用域之上还有额外的批准时作用域检查: +`node.pair.approve` 在基础方法作用域之上,还有额外的批准时作用域检查: - 无命令请求:`operator.pairing` - 带非 exec 节点命令的请求:`operator.pairing` + `operator.write` -- 包含 `system.run`、`system.run.prepare` 或 `system.which` 的请求: - `operator.pairing` + `operator.admin` +- 包含 `system.run`、`system.run.prepare` 或 `system.which` 的请求:`operator.pairing` + `operator.admin` ### 能力/命令/权限(节点) @@ -228,17 +226,17 @@ Gateway 网关 → 客户端: - `commands`:用于调用的命令允许列表。 - `permissions`:细粒度开关(例如 `screen.record`、`camera.capture`)。 -Gateway 网关 将这些视为**声明**,并执行服务端允许列表。 +Gateway 网关会将这些视为**声明**,并强制执行服务器端允许列表。 ## 在线状态 -- `system-presence` 返回按设备身份作为键的条目。 -- 在线状态条目包含 `deviceId`、`roles` 和 `scopes`,因此即使设备同时以**操作员**和**节点**身份连接,UI 也可以为每个设备显示单行。 -- `node.list` 包含可选的 `lastSeenAtMs` 和 `lastSeenReason` 字段。已连接节点会将其当前连接时间报告为 `lastSeenAtMs`,原因是 `connect`;当受信任的节点事件更新其配对元数据时,已配对节点也可以报告持久的后台在线状态。 +- `system-presence` 返回以设备身份为键的条目。 +- 在线状态条目包含 `deviceId`、`roles` 和 `scopes`,因此 UI 可以为每个设备显示单行,即使它同时以 **operator** 和**节点**身份连接。 +- `node.list` 包含可选的 `lastSeenAtMs` 和 `lastSeenReason` 字段。已连接节点会报告其当前连接时间作为 `lastSeenAtMs`,原因是 `connect`;当受信任节点事件更新其配对元数据时,已配对节点也可以报告持久的后台在线状态。 ### 节点后台存活事件 -节点可以使用 `event: "node.presence.alive"` 调用 `node.event`,记录已配对节点在后台唤醒期间存活,而不将其标记为已连接。 +节点可以调用 `node.event`,并传入 `event: "node.presence.alive"`,以记录已配对节点在后台唤醒期间处于存活状态,而不将其标记为已连接。 ```json { @@ -247,9 +245,9 @@ Gateway 网关 将这些视为**声明**,并执行服务端允许列表。 } ``` -`trigger` 是封闭枚举:`background`、`silent_push`、`bg_app_refresh`、`significant_location`、`manual` 或 `connect`。未知的触发器字符串会在持久化前由 Gateway 网关规范化为 `background`。该事件仅对已认证的节点设备会话是持久的;无设备或未配对会话返回 `handled: false`。 +`trigger` 是封闭枚举:`background`、`silent_push`、`bg_app_refresh`、`significant_location`、`manual` 或 `connect`。未知触发字符串会在持久化前由 Gateway 网关规范化为 `background`。该事件仅对已认证的节点设备会话持久;无设备或未配对会话返回 `handled: false`。 -成功的 Gateway 网关会返回结构化结果: +成功的 Gateway 网关返回结构化结果: ```json { @@ -260,174 +258,177 @@ Gateway 网关 将这些视为**声明**,并执行服务端允许列表。 } ``` -旧版 Gateway 网关可能仍会为 `node.event` 返回 `{ "ok": true }`;客户端应将其视为已确认的 RPC,而不是持久在线状态持久化。 +较旧的 Gateway 网关仍可能对 `node.event` 返回 `{ "ok": true }`;客户端应将其视为已确认的 RPC,而不是持久在线状态的持久化。 ## 广播事件作用域限定 -服务端推送的 WebSocket 广播事件受作用域门禁保护,因此限定为配对作用域或仅节点的会话不会被动接收会话内容。 +服务器推送的 WebSocket 广播事件受作用域门控,因此配对作用域或仅节点会话不会被动接收会话内容。 - **聊天、智能体和工具结果帧**(包括流式 `agent` 事件和工具调用结果)至少需要 `operator.read`。没有 `operator.read` 的会话会完全跳过这些帧。 -- **插件定义的 `plugin.*` 广播**会根据插件注册方式,以 `operator.write` 或 `operator.admin` 为门禁。 -- **Status 和传输事件**(`heartbeat`、`presence`、`tick`、连接/断开连接生命周期等)保持不受限制,以便每个已认证会话都可以观察传输健康状态。 -- **未知广播事件族**默认受作用域门禁保护(失败关闭),除非已注册处理器显式放宽限制。 +- **插件定义的 `plugin.*` 广播**会根据插件注册方式,被门控为 `operator.write` 或 `operator.admin`。 +- **Status 和传输事件**(`heartbeat`、`presence`、`tick`、连接/断开连接生命周期等)保持不受限制,以便每个已认证会话都能观察传输健康状态。 +- **未知广播事件族**默认受作用域门控(失败关闭),除非注册的处理程序显式放宽它们。 -每个客户端连接都会保留自己的单客户端序列号,因此即使不同客户端看到事件流中不同的作用域过滤子集,广播也能在该 socket 上保持单调顺序。 +每个客户端连接都会保留自己的按客户端序列号,因此即使不同客户端看到事件流中不同的作用域过滤子集,广播也会在该套接字上保持单调顺序。 ## 常见 RPC 方法族 -公共 WS 表面比上面的握手/认证示例更广。这不是生成的转储,`hello-ok.features.methods` 是一个保守的设备发现列表,由 `src/gateway/server-methods-list.ts` 加上已加载的插件/渠道方法导出构建。应将其视为功能设备发现,而不是 `src/gateway/server-methods/*.ts` 的完整枚举。 +公共 WS 表面比上面的握手/认证示例更广。这不是生成的转储,`hello-ok.features.methods` 是一个保守的设备发现列表,由 `src/gateway/server-methods-list.ts` 加上已加载的插件/渠道方法导出构建。请将其视为功能设备发现,而不是 `src/gateway/server-methods/*.ts` 的完整枚举。 - + - `health` 返回缓存的或新探测的 Gateway 网关健康快照。 - - `diagnostics.stability` 返回最近的有界诊断稳定性记录器。它保留事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID 等运行元数据。它不会保留聊天文本、Webhook 正文、工具输出、原始请求或响应正文、令牌、Cookie 或密钥值。需要操作员读取作用域。 - - `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅包含在管理员作用域的操作员客户端中。 + - `diagnostics.stability` 返回最近的有界诊断稳定性记录器。它保留事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID 等操作元数据。它不会保留聊天文本、Webhook 正文、工具输出、原始请求或响应正文、令牌、Cookie 或机密值。需要 operator 读取作用域。 + - `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅对 admin 作用域的 operator 客户端包含。 - `gateway.identity.get` 返回中继和配对流程使用的 Gateway 网关设备身份。 - - `system-presence` 返回已连接操作员/节点设备的当前在线状态快照。 - - `system-event` 追加系统事件,并可更新/广播在线状态上下文。 - - `last-heartbeat` 返回最新持久化的 heartbeat 事件。 - - `set-heartbeats` 切换 Gateway 网关上的 heartbeat 处理。 + - `system-presence` 返回已连接 operator/节点设备的当前在线状态快照。 + - `system-event` 追加系统事件,并可以更新/广播在线状态上下文。 + - `last-heartbeat` 返回最新持久化的 Heartbeat 事件。 + - `set-heartbeats` 切换 Gateway 网关上的 Heartbeat 处理。 - - - `models.list` 返回运行时允许的模型目录。传入 `{ "view": "configured" }` 可获取适合选择器大小的已配置模型(先是 `agents.defaults.models`,然后是 `models.providers.*.models`),或传入 `{ "view": "all" }` 获取完整目录。 + + - `models.list` 返回运行时允许的模型目录。传入 `{ "view": "configured" }` 可获取适合选择器展示的已配置模型(先是 `agents.defaults.models`,然后是 `models.providers.*.models`),或传入 `{ "view": "all" }` 获取完整目录。 - `usage.status` 返回提供商用量窗口/剩余额度摘要。 - - `usage.cost` 返回某个日期范围内的聚合费用用量摘要。 - - `doctor.memory.status` 返回当前默认 agent 工作区的向量记忆 / 缓存 embedding 就绪状态。只有在调用方明确需要实时 ping embedding 提供商时,才传入 `{ "probe": true }` 或 `{ "deep": true }`。 - - `doctor.memory.remHarness` 为远程控制平面客户端返回有界、只读的 REM harness 预览。它可能包含工作区路径、记忆片段、渲染后的有依据 Markdown,以及深度提升候选项,因此调用方需要 `operator.read`。 + - `usage.cost` 返回某个日期范围内聚合的费用用量摘要。 + - `doctor.memory.status` 返回当前默认智能体工作区的向量记忆 / 缓存嵌入就绪状态。仅当调用方明确想要实时 ping 嵌入提供商时,才传入 `{ "probe": true }` 或 `{ "deep": true }`。 + - `doctor.memory.remHarness` 为远程控制平面客户端返回有界、只读的 REM harness 预览。它可以包含工作区路径、记忆片段、渲染后的有依据 markdown,以及深度提升候选项,因此调用方需要 `operator.read`。 - `sessions.usage` 返回每个会话的用量摘要。 - - `sessions.usage.timeseries` 返回某个会话的时间序列用量。 - - `sessions.usage.logs` 返回某个会话的用量日志条目。 + - `sessions.usage.timeseries` 返回一个会话的时间序列用量。 + - `sessions.usage.logs` 返回一个会话的用量日志条目。 - - `channels.status` 返回内置 + bundled 渠道/插件 Status 摘要。 - - `channels.logout` 在渠道支持退出登录时,为指定渠道/账号退出登录。 + - `channels.status` 返回内置 + 捆绑渠道/插件的 Status 摘要。 + - `channels.logout` 在渠道支持退出登录时,退出某个特定渠道/账号。 - `web.login.start` 为当前支持二维码的 Web 渠道提供商启动二维码/Web 登录流程。 - - `web.login.wait` 等待该二维码/Web 登录流程完成,并在成功后启动渠道。 + - `web.login.wait` 等待该二维码/Web 登录流程完成,并在成功后启动该渠道。 - `push.test` 向已注册的 iOS 节点发送测试 APNs 推送。 - - `voicewake.get` 返回存储的唤醒词触发器。 - - `voicewake.set` 更新唤醒词触发器并广播变更。 + - `voicewake.get` 返回已存储的唤醒词触发器。 + - `voicewake.set` 更新唤醒词触发器并广播更改。 - - - `send` 是直接出站投递 RPC,用于在聊天运行器之外按渠道/账号/线程定向发送。 - - `logs.tail` 返回已配置的 Gateway 网关文件日志尾部内容,带有 cursor/limit 和最大字节数控制。 + + - `send` 是在聊天运行器之外面向渠道/账号/线程目标发送消息的直接出站投递 RPC。 + - `logs.tail` 使用游标/限制和最大字节控制,返回已配置的 Gateway 网关文件日志尾部内容。 - `talk.config` 返回生效的 Talk 配置载荷;`includeSecrets` 需要 `operator.talk.secrets`(或 `operator.admin`)。 - `talk.mode` 为 WebChat/Control UI 客户端设置/广播当前 Talk 模式状态。 - - `talk.speak` 通过当前 Talk 语音提供商合成语音。 - - `tts.status` 返回 TTS 启用状态、当前提供商、回退提供商以及提供商配置状态。 + - `talk.speak` 通过当前活动的 Talk 语音提供商合成语音。 + - `tts.status` 返回 TTS 启用状态、当前活动提供商、后备提供商以及提供商配置状态。 - `tts.providers` 返回可见的 TTS 提供商清单。 - - `tts.enable` 和 `tts.disable` 切换 TTS 偏好设置状态。 + - `tts.enable` 和 `tts.disable` 切换 TTS 偏好状态。 - `tts.setProvider` 更新首选 TTS 提供商。 - - `tts.convert` 运行一次性文本转语音转换。 + - `tts.convert` 执行一次性文本转语音转换。 - - `secrets.reload` 重新解析当前 SecretRefs,并且仅在完全成功时替换运行时密钥状态。 + - `secrets.reload` 重新解析活动 SecretRefs,并且仅在完全成功时替换运行时密钥状态。 - `secrets.resolve` 为特定命令/目标集合解析命令目标密钥分配。 - `config.get` 返回当前配置快照和哈希。 - `config.set` 写入经过验证的配置载荷。 - `config.patch` 合并部分配置更新。 - `config.apply` 验证并替换完整配置载荷。 - - `config.schema` 返回 Control UI 和 CLI 工具使用的实时配置 schema 载荷:schema、`uiHints`、版本和生成元数据;在运行时可以加载时,还包括插件 + 渠道 schema 元数据。schema 包含字段 `title` / `description` 元数据,这些元数据派生自 UI 使用的相同标签和帮助文本;当存在匹配字段文档时,还包括嵌套对象、通配符、数组项以及 `anyOf` / `oneOf` / `allOf` 组合分支。 - - `config.schema.lookup` 为一个配置路径返回路径作用域的查找载荷:规范化路径、浅层 schema 节点、匹配的 hint + `hintPath`,以及供 UI/CLI 下钻使用的直接子项摘要。查找 schema 节点会保留面向用户的文档和常见验证字段(`title`、`description`、`type`、`enum`、`const`、`format`、`pattern`、数字/字符串/数组/对象边界,以及 `additionalProperties`、`deprecated`、`readOnly`、`writeOnly` 等标志)。子项摘要暴露 `key`、规范化后的 `path`、`type`、`required`、`hasChildren`,以及匹配的 `hint` / `hintPath`。 - - `update.run` 运行 Gateway 网关更新流程,并且仅在更新本身成功时安排重启。包管理器更新会在包替换后强制进行非延迟、无冷却的更新重启,这样旧 Gateway 网关进程就不会继续从已替换的 `dist` 树中惰性加载。 - - `update.status` 返回最新缓存的更新重启哨兵,包括可用时重启后的运行版本。 + - `config.schema` 返回 Control UI 和 CLI 工具使用的实时配置 schema 载荷:schema、`uiHints`、版本和生成元数据;当运行时可以加载时,还包括插件 + 渠道 schema 元数据。该 schema 包含字段 `title` / `description` 元数据,这些元数据来自 UI 使用的相同标签和帮助文本;当存在匹配的字段文档时,还包括嵌套对象、通配符、数组项,以及 `anyOf` / `oneOf` / `allOf` 组合分支。 + - `config.schema.lookup` 为一个配置路径返回按路径限定的查找载荷:规范化路径、浅层 schema 节点、匹配的提示 + `hintPath`,以及用于 UI/CLI 下钻的直接子项摘要。查找 schema 节点会保留面向用户的文档和常见验证字段(`title`、`description`、`type`、`enum`、`const`、`format`、`pattern`、数字/字符串/数组/对象边界,以及 `additionalProperties`、`deprecated`、`readOnly`、`writeOnly` 等标志)。子项摘要会暴露 `key`、规范化后的 `path`、`type`、`required`、`hasChildren`,以及匹配的 `hint` / `hintPath`。 + - `update.run` 运行 Gateway 网关更新流程,并且仅在更新本身成功时安排重启。包管理器更新会在包替换后强制执行非延迟、无冷却的更新重启,以便旧 Gateway 网关进程不会继续从已替换的 `dist` 树中延迟加载。 + - `update.status` 返回最新缓存的更新重启哨兵;如果可用,还包括重启后的运行版本。 - `wizard.start`、`wizard.next`、`wizard.status` 和 `wizard.cancel` 通过 WS RPC 暴露新手引导向导。 - - - `agents.list` 返回已配置的 agent 条目,包括生效模型和运行时元数据。 - - `agents.create`、`agents.update` 和 `agents.delete` 管理 agent 记录和工作区连线。 - - `agents.files.list`、`agents.files.get` 和 `agents.files.set` 管理为 agent 暴露的引导工作区文件。 - - `artifacts.list`、`artifacts.get` 和 `artifacts.download` 为明确的 `sessionKey`、`runId` 或 `taskId` 作用域暴露从 transcript 派生的 artifact 摘要和下载。运行和任务查询会在服务器端解析所属会话,并且只返回来源匹配的 transcript 媒体;不安全或本地 URL 来源会返回不支持的下载,而不会在服务器端抓取。 - - `agent.identity.get` 返回某个 agent 或会话的生效助手身份。 - - `agent.wait` 等待一次运行完成,并在可用时返回终态快照。 + + - `agents.list` 返回已配置的智能体条目,包括生效模型和运行时元数据。 + - `agents.create`、`agents.update` 和 `agents.delete` 管理智能体记录和工作区接线。 + - `agents.files.list`、`agents.files.get` 和 `agents.files.set` 管理为智能体暴露的引导工作区文件。 + - `artifacts.list`、`artifacts.get` 和 `artifacts.download` 为显式的 `sessionKey`、`runId` 或 `taskId` 范围暴露由转录生成的产物摘要和下载。运行和任务查询会在服务端解析所属会话,并且只返回来源匹配的转录媒体;不安全或本地 URL 来源会返回不支持的下载,而不是在服务端获取。 + - `agent.identity.get` 返回某个智能体或会话的生效助手身份。 + - `agent.wait` 等待一次运行完成,并在可用时返回终止快照。 - - `sessions.list` 返回当前会话索引;当配置了 agent 运行时后端时,会包含每行的 `agentRuntime` 元数据。 + - `sessions.list` 返回当前会话索引;当配置了智能体运行时后端时,包括每行的 `agentRuntime` 元数据。 - `sessions.subscribe` 和 `sessions.unsubscribe` 为当前 WS 客户端切换会话变更事件订阅。 - - `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 为一个会话切换 transcript/消息事件订阅。 - - `sessions.preview` 返回特定会话键的有界 transcript 预览。 + - `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 为一个会话切换转录/消息事件订阅。 + - `sessions.preview` 返回特定会话键的有界转录预览。 + - `sessions.describe` 为精确会话键返回一行 Gateway 网关会话。 - `sessions.resolve` 解析或规范化会话目标。 - `sessions.create` 创建新的会话条目。 - `sessions.send` 向现有会话发送消息。 - - `sessions.steer` 是活动会话的中断并 Steering queue 变体。 - - `sessions.abort` 中止某个会话的活动工作。调用方可以传入 `key` 加可选的 `runId`,也可以仅传入 `runId`,用于 Gateway 网关可解析到会话的活动运行。 + - `sessions.steer` 是用于活动会话的中断并引导变体。 + - `sessions.abort` 中止某个会话的活动工作。调用方可以传入 `key` 加可选的 `runId`,也可以只为 Gateway 网关可解析到会话的活动运行传入 `runId`。 - `sessions.patch` 更新会话元数据/覆盖项,并报告解析后的规范模型以及生效的 `agentRuntime`。 - `sessions.reset`、`sessions.delete` 和 `sessions.compact` 执行会话维护。 - `sessions.get` 返回完整存储的会话行。 - - 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。`chat.history` 会为 UI 客户端进行显示规范化:从可见文本中剥离内联指令标签,剥离纯文本工具调用 XML 载荷(包括 `...`、`...`、`...`、`...` 以及截断的工具调用块)和泄漏的 ASCII/全角模型控制 token,省略精确为 `NO_REPLY` / `no_reply` 等纯静默 token 的助手行,并且过大的行可替换为占位符。 + - 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。`chat.history` 会针对 UI 客户端进行显示规范化:可见文本中的内联指令标签会被剥离,纯文本工具调用 XML 载荷(包括 `...`、`...`、`...`、`...`,以及被截断的工具调用块)和泄漏的 ASCII/全角模型控制 token 会被剥离,精确的 `NO_REPLY` / `no_reply` 等纯静默 token 助手行会被省略,过大的行可以被替换为占位符。 - - `device.pair.list` 返回待处理和已批准的已配对设备。 + - `device.pair.list` 返回待处理和已批准的配对设备。 - `device.pair.approve`、`device.pair.reject` 和 `device.pair.remove` 管理设备配对记录。 - - `device.token.rotate` 在已批准角色和调用方作用域边界内轮换已配对设备 token。 - - `device.token.revoke` 在已批准角色和调用方作用域边界内撤销已配对设备 token。 + - `device.token.rotate` 在已批准角色和调用方范围边界内轮换配对设备 token。 + - `device.token.revoke` 在已批准角色和调用方范围边界内撤销配对设备 token。 - - `node.pair.request`、`node.pair.list`、`node.pair.approve`、`node.pair.reject`、`node.pair.remove` 和 `node.pair.verify` 涵盖节点配对和引导验证。 + - `node.pair.request`、`node.pair.list`、`node.pair.approve`、`node.pair.reject`、`node.pair.remove` 和 `node.pair.verify` 覆盖节点配对和引导验证。 - `node.list` 和 `node.describe` 返回已知/已连接节点状态。 - - `node.rename` 更新已配对节点标签。 + - `node.rename` 更新配对节点标签。 - `node.invoke` 将命令转发到已连接节点。 - `node.invoke.result` 返回调用请求的结果。 - - `node.event` 将节点源事件带回 Gateway 网关。 - - `node.canvas.capability.refresh` 刷新作用域 canvas-capability token。 + - `node.event` 将源自节点的事件带回 Gateway 网关。 + - `node.canvas.capability.refresh` 刷新按范围限定的 canvas 能力 token。 - `node.pending.pull` 和 `node.pending.ack` 是已连接节点队列 API。 - `node.pending.enqueue` 和 `node.pending.drain` 管理离线/断开连接节点的持久待处理工作。 - - - `exec.approval.request`、`exec.approval.get`、`exec.approval.list` 和 `exec.approval.resolve` 涵盖一次性 exec 审批请求以及待处理审批查找/重放。 - - `exec.approval.waitDecision` 等待一个待处理 exec 审批,并返回最终决定(超时时返回 `null`)。 + + - `exec.approval.request`、`exec.approval.get`、`exec.approval.list` 和 `exec.approval.resolve` 覆盖一次性 exec 审批请求以及待处理审批查找/重放。 + - `exec.approval.waitDecision` 等待一个待处理 exec 审批并返回最终决定(超时时返回 `null`)。 - `exec.approvals.get` 和 `exec.approvals.set` 管理 Gateway 网关 exec 审批策略快照。 - `exec.approvals.node.get` 和 `exec.approvals.node.set` 通过节点中继命令管理节点本地 exec 审批策略。 - - `plugin.approval.request`、`plugin.approval.list`、`plugin.approval.waitDecision` 和 `plugin.approval.resolve` 涵盖插件定义的审批流程。 + - `plugin.approval.request`、`plugin.approval.list`、`plugin.approval.waitDecision` 和 `plugin.approval.resolve` 覆盖插件定义的审批流程。 - - 自动化:`wake` 安排立即或下一次 Heartbeat 唤醒文本注入;`cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、`cron.run`、`cron.runs` 管理定时工作。 + - 自动化:`wake` 安排立即或下一个 Heartbeat 的唤醒文本注入;`cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、`cron.run`、`cron.runs` 管理定时工作。 - Skills 和工具:`commands.list`、`skills.*`、`tools.catalog`、`tools.effective`、`tools.invoke`。 -### 常见事件系列 +### 常见事件族 -- `chat`:UI 聊天更新,例如 `chat.inject` 和其他仅 transcript 的聊天 +- `chat`:UI 聊天更新,例如 `chat.inject` 和其他仅转录的聊天 事件。 -- `session.message` 和 `session.tool`:已订阅会话的 transcript/事件流更新。 -- `sessions.changed`:会话索引或元数据已变更。 -- `presence`:系统 presence 快照更新。 -- `tick`:周期性 keepalive / liveness 事件。 +- `session.message` 和 `session.tool`:已订阅会话的转录/事件流更新。 +- `sessions.changed`:会话索引或元数据已更改。 +- `presence`:系统在线状态快照更新。 +- `tick`:周期性 keepalive / 存活事件。 - `health`:Gateway 网关健康快照更新。 -- `heartbeat`:Heartbeat 事件流更新。 +- `heartbeat`:heartbeat 事件流更新。 - `cron`:cron 运行/作业变更事件。 - `shutdown`:Gateway 网关关闭通知。 - `node.pair.requested` / `node.pair.resolved`:节点配对生命周期。 - `node.invoke.request`:节点调用请求广播。 -- `device.pair.requested` / `device.pair.resolved`:已配对设备生命周期。 -- `voicewake.changed`:唤醒词触发器配置已变更。 -- `exec.approval.requested` / `exec.approval.resolved`:exec 审批生命周期。 -- `plugin.approval.requested` / `plugin.approval.resolved`:插件审批生命周期。 +- `device.pair.requested` / `device.pair.resolved`:配对设备生命周期。 +- `voicewake.changed`:唤醒词触发器配置已更改。 +- `exec.approval.requested` / `exec.approval.resolved`:exec 审批 + 生命周期。 +- `plugin.approval.requested` / `plugin.approval.resolved`:插件审批 + 生命周期。 ### 节点辅助方法 @@ -436,77 +437,59 @@ Gateway 网关 将这些视为**声明**,并执行服务端允许列表。 ### 操作员辅助方法 -- 操作员可以调用 `commands.list`(`operator.read`)来获取某个智能体的运行时 - 命令清单。 - - `agentId` 是可选的;省略它可读取默认智能体工作区。 - - `scope` 控制主 `name` 目标指向的表面: +- 操作者可以调用 `commands.list`(`operator.read`)来获取智能体的运行时命令清单。 + - `agentId` 是可选的;省略它可读取默认 Agent 工作区。 + - `scope` 控制主要 `name` 面向的界面: - `text` 返回不带前导 `/` 的主文本命令令牌 - - `native` 和默认的 `both` 路径会在可用时返回感知提供商的原生命名 + - `native` 和默认的 `both` 路径会在可用时返回感知提供商的原生命令名称 - `textAliases` 携带精确的斜杠别名,例如 `/model` 和 `/m`。 - `nativeName` 在存在时携带感知提供商的原生命令名称。 - - `provider` 是可选的,并且只影响原生命名以及原生插件命令可用性。 - - `includeArgs=false` 会从响应中省略序列化后的参数元数据。 -- 操作员可以调用 `tools.catalog`(`operator.read`)来获取某个智能体的运行时工具目录。响应包含分组工具和来源元数据: + - `provider` 是可选的,只影响原生命名以及原生插件命令的可用性。 + - `includeArgs=false` 会从响应中省略序列化的参数元数据。 +- 操作者可以调用 `tools.catalog`(`operator.read`)来获取智能体的运行时工具目录。响应包含分组工具和来源元数据: - `source`:`core` 或 `plugin` - - `pluginId`:当 `source="plugin"` 时的插件所有者 - - `optional`:某个插件工具是否为可选项 -- 操作员可以调用 `tools.effective`(`operator.read`)来获取某个会话的运行时有效工具 - 清单。 + - `pluginId`:当 `source="plugin"` 时为插件所有者 + - `optional`:插件工具是否为可选 +- 操作者可以调用 `tools.effective`(`operator.read`)来获取会话的运行时生效工具清单。 - `sessionKey` 是必需的。 - - Gateway 网关会从服务端的会话推导可信运行时上下文,而不是接受 - 调用方提供的认证或交付上下文。 - - 响应限定在会话范围内,并反映当前活跃对话现在可以使用的内容, - 包括核心、插件和渠道工具。 -- 操作员可以调用 `tools.invoke`(`operator.write`),通过与 `/tools/invoke` - 相同的 Gateway 网关策略路径调用一个可用工具。 - - `name` 是必需的。`args`、`sessionKey`、`agentId`、`confirm` 和 - `idempotencyKey` 是可选的。 - - 如果同时存在 `sessionKey` 和 `agentId`,解析出的会话智能体必须匹配 - `agentId`。 - - 响应是面向 SDK 的信封,包含 `ok`、`toolName`、可选的 `output`,以及带类型的 - `error` 字段。审批或策略拒绝会在载荷中返回 `ok:false`,而不是 - 绕过 Gateway 网关工具策略管线。 -- 操作员可以调用 `skills.status`(`operator.read`)来获取某个智能体的可见 - skill 清单。 - - `agentId` 是可选的;省略它可读取默认智能体工作区。 - - 响应包含资格、缺失需求、配置检查,以及经过清理的安装选项, - 不会暴露原始密钥值。 -- 操作员可以调用 `skills.search` 和 `skills.detail`(`operator.read`)获取 - ClawHub 发现元数据。 -- 操作员可以调用 `skills.install`(`operator.admin`),有两种模式: - - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 会将一个 - skill 文件夹安装到默认智能体工作区的 `skills/` 目录中。 - - Gateway 网关安装器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` - 会在 Gateway 网关主机上运行一个声明的 `metadata.openclaw.install` 操作。 -- 操作员可以调用 `skills.update`(`operator.admin`),有两种模式: - - ClawHub 模式会更新一个被跟踪的 slug,或默认智能体工作区中所有被跟踪的 - ClawHub 安装。 - - 配置模式会修补 `skills.entries.` 值,例如 `enabled`、 - `apiKey` 和 `env`。 + - Gateway 网关会从服务端的会话中派生可信运行时上下文,而不是接受调用方提供的认证或投递上下文。 + - 响应限定在会话范围内,并反映当前活动对话现在可以使用的内容,包括核心、插件和渠道工具。 +- 操作者可以调用 `tools.invoke`(`operator.write`),通过与 `/tools/invoke` 相同的 Gateway 网关策略路径调用一个可用工具。 + - `name` 是必需的。`args`、`sessionKey`、`agentId`、`confirm` 和 `idempotencyKey` 是可选的。 + - 如果同时存在 `sessionKey` 和 `agentId`,解析出的会话智能体必须与 `agentId` 匹配。 + - 响应是面向 SDK 的信封,包含 `ok`、`toolName`、可选的 `output`,以及带类型的 `error` 字段。审批或策略拒绝会在载荷中返回 `ok:false`,而不是绕过 Gateway 网关工具策略流水线。 +- 操作者可以调用 `skills.status`(`operator.read`)来获取智能体的可见 skill 清单。 + - `agentId` 是可选的;省略它可读取默认 Agent 工作区。 + - 响应包含资格状态、缺失要求、配置检查,以及经过净化的安装选项,且不会暴露原始密钥值。 +- 操作者可以调用 `skills.search` 和 `skills.detail`(`operator.read`)获取 ClawHub 设备发现元数据。 +- 操作者可以用两种模式调用 `skills.install`(`operator.admin`): + - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 会将一个 skill 文件夹安装到默认 Agent 工作区的 `skills/` 目录。 + - Gateway 网关安装器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` 会在 Gateway 网关主机上运行已声明的 `metadata.openclaw.install` 操作。 +- 操作者可以用两种模式调用 `skills.update`(`operator.admin`): + - ClawHub 模式会更新一个已跟踪的 slug,或更新默认 Agent 工作区中所有已跟踪的 ClawHub 安装项。 + - 配置模式会修补 `skills.entries.` 的值,例如 `enabled`、`apiKey` 和 `env`。 ### `models.list` 视图 -`models.list` 接受一个可选的 `view` 参数: +`models.list` 接受可选的 `view` 参数: -- 省略或 `"default"`:当前运行时行为。如果配置了 `agents.defaults.models`,响应就是允许的目录;否则响应是完整的 Gateway 网关目录。 -- `"configured"`:适合选择器大小的行为。如果配置了 `agents.defaults.models`,它仍然优先。否则响应会使用显式的 `models.providers.*.models` 条目,只有在不存在已配置模型行时才回退到完整目录。 -- `"all"`:完整的 Gateway 网关目录,绕过 `agents.defaults.models`。将它用于诊断和发现 UI,而不是常规模型选择器。 +- 省略或 `"default"`:当前运行时行为。如果已配置 `agents.defaults.models`,响应为允许的目录;否则响应为完整 Gateway 网关目录。 +- `"configured"`:适合选择器规模的行为。如果已配置 `agents.defaults.models`,它仍然优先。否则响应会使用显式的 `models.providers.*.models` 条目,只有在不存在已配置的模型行时才回退到完整目录。 +- `"all"`:完整 Gateway 网关目录,绕过 `agents.defaults.models`。用于诊断和发现 UI,而不是普通模型选择器。 ## Exec 审批 - 当 exec 请求需要审批时,Gateway 网关会广播 `exec.approval.requested`。 -- 操作员客户端通过调用 `exec.approval.resolve` 来处理(需要 `operator.approvals` 作用域)。 +- 操作者客户端通过调用 `exec.approval.resolve` 进行处理(需要 `operator.approvals` scope)。 - 对于 `host=node`,`exec.approval.request` 必须包含 `systemRunPlan`(规范的 `argv`/`cwd`/`rawCommand`/会话元数据)。缺少 `systemRunPlan` 的请求会被拒绝。 -- 审批后,转发的 `node.invoke system.run` 调用会复用该规范 - `systemRunPlan`,作为权威的命令/cwd/会话上下文。 -- 如果调用方在准备和最终已批准的 `system.run` 转发之间修改了 `command`、`rawCommand`、`cwd`、`agentId` 或 - `sessionKey`,Gateway 网关会拒绝运行,而不是信任被修改的载荷。 +- 审批后,转发的 `node.invoke system.run` 调用会复用该规范的 `systemRunPlan`,将其作为权威的命令/cwd/会话上下文。 +- 如果调用方在 prepare 和最终获批的 `system.run` 转发之间修改 `command`、`rawCommand`、`cwd`、`agentId` 或 `sessionKey`,Gateway 网关会拒绝本次运行,而不是信任被修改的载荷。 -## 智能体交付回退 +## 智能体投递回退 -- `agent` 请求可以包含 `deliver=true` 来请求出站交付。 -- `bestEffortDeliver=false` 保持严格行为:无法解析或仅限内部的交付目标会返回 `INVALID_REQUEST`。 -- `bestEffortDeliver=true` 允许在无法解析外部可交付路由时回退到仅会话执行(例如内部/webchat 会话或有歧义的多渠道配置)。 +- `agent` 请求可以包含 `deliver=true` 来请求出站投递。 +- `bestEffortDeliver=false` 保持严格行为:无法解析或仅限内部的投递目标会返回 `INVALID_REQUEST`。 +- `bestEffortDeliver=true` 允许在无法解析外部可投递路由时回退到仅会话执行(例如内部/webchat 会话或多渠道配置不明确)。 ## 版本控制 @@ -519,104 +502,101 @@ Gateway 网关 将这些视为**声明**,并执行服务端允许列表。 ### 客户端常量 -`src/gateway/client.ts` 中的参考客户端使用这些默认值。这些值在 -协议 v3 中保持稳定,并且是第三方客户端的预期基线。 +`src/gateway/client.ts` 中的参考客户端使用这些默认值。这些值在协议 v3 中保持稳定,并且是第三方客户端的预期基线。 | 常量 | 默认值 | 来源 | | ----------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | | `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | -| 请求超时(每次 RPC) | `30_000` ms | `src/gateway/client.ts`(`requestTimeoutMs`) | +| 请求超时(每个 RPC) | `30_000` ms | `src/gateway/client.ts`(`requestTimeoutMs`) | | 预认证 / 连接挑战超时 | `15_000` ms | `src/gateway/handshake-timeouts.ts`(配置/环境变量可以提高成对的服务端/客户端预算) | | 初始重连退避 | `1_000` ms | `src/gateway/client.ts`(`backoffMs`) | | 最大重连退避 | `30_000` ms | `src/gateway/client.ts`(`scheduleReconnect`) | -| 设备令牌关闭后的快速重试钳制 | `250` ms | `src/gateway/client.ts` | -| `terminate()` 前的强制停止宽限 | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` | +| 设备令牌关闭后的快速重试限制 | `250` ms | `src/gateway/client.ts` | +| `terminate()` 前的强制停止宽限期 | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` | | `stopAndWait()` 默认超时 | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` | -| 默认 tick 间隔(`hello-ok` 前) | `30_000` ms | `src/gateway/client.ts` | -| tick 超时关闭 | 静默超过 `tickIntervalMs * 2` 时使用代码 `4000` | `src/gateway/client.ts` | +| 默认 tick 间隔(`hello-ok` 前) | `30_000` ms | `src/gateway/client.ts` | +| tick 超时关闭 | 静默超过 `tickIntervalMs * 2` 时使用 code `4000` | `src/gateway/client.ts` | | `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024`(25 MB) | `src/gateway/server-constants.ts` | -服务器会在 `hello-ok` 中公布有效的 `policy.tickIntervalMs`、`policy.maxPayload` -和 `policy.maxBufferedBytes`;客户端应遵循这些值,而不是握手前的默认值。 +服务器会在 `hello-ok` 中公布生效的 `policy.tickIntervalMs`、`policy.maxPayload` 和 `policy.maxBufferedBytes`;客户端应遵循这些值,而不是握手前的默认值。 ## 认证 -- shared-secret Gateway 网关认证使用 `connect.params.auth.token` 或 +- 共享密钥 Gateway 网关认证使用 `connect.params.auth.token` 或 `connect.params.auth.password`,具体取决于配置的认证模式。 -- 带身份信息的模式,例如 Tailscale Serve +- 带身份的模式,例如 Tailscale Serve (`gateway.auth.allowTailscale: true`) 或非 loopback - `gateway.auth.mode: "trusted-proxy"`,会从请求头满足 connect 认证检查, - 而不是使用 `connect.params.auth.*`。 -- 私有入口 `gateway.auth.mode: "none"` 会完全跳过 shared-secret connect 认证; + `gateway.auth.mode: "trusted-proxy"`,会通过请求标头满足连接认证检查, + 而不是通过 `connect.params.auth.*`。 +- 私有入口 `gateway.auth.mode: "none"` 会完全跳过共享密钥连接认证; 不要在公开/不受信任的入口上暴露该模式。 -- 配对后,Gateway 网关会颁发一个限定到连接角色 + 作用域的**设备令牌**。 - 它会在 `hello-ok.auth.deviceToken` 中返回,客户端应将其持久化以供以后连接使用。 -- 客户端应在任何成功 connect 后持久化主 `hello-ok.auth.deviceToken`。 -- 使用该**已存储**设备令牌重新连接时,也应复用该令牌已存储的已批准作用域集。 - 这会保留已授予的读取/探测/status 访问权限,并避免将重连静默收窄为隐式仅管理员作用域。 -- 客户端侧 connect 认证组装(`src/gateway/client.ts` 中的 `selectConnectAuth`): - - `auth.password` 是正交的,并且在设置后总是会转发。 - - `auth.token` 按优先级填充:先是显式 shared token, - 然后是显式 `deviceToken`,再是已存储的按设备令牌(以 - `deviceId` + `role` 为键)。 - - 仅当上述内容都未解析出 `auth.token` 时,才会发送 `auth.bootstrapToken`。 - shared token 或任何解析出的设备令牌都会抑制它。 - - 在一次性 `AUTH_TOKEN_MISMATCH` 重试中,自动提升已存储设备令牌仅限于**可信端点** — - loopback,或带有固定 `tlsFingerprint` 的 `wss://`。未固定的公共 `wss://` - 不符合条件。 -- 额外的 `hello-ok.auth.deviceTokens` 条目是 bootstrap 交接令牌。 - 仅当 connect 在可信传输上使用 bootstrap 认证时才持久化它们, - 例如 `wss://` 或 loopback/local 配对。 -- 如果客户端提供**显式** `deviceToken` 或显式 `scopes`, - 调用方请求的作用域集仍然具有权威性;只有当客户端复用已存储的按设备令牌时, - 才会复用缓存作用域。 -- 设备令牌可以通过 `device.token.rotate` 和 +- 配对后,Gateway 网关会签发一个限定为连接角色 + 作用域的**设备令牌**。 + 它会在 `hello-ok.auth.deviceToken` 中返回,客户端应将其持久化以供未来连接使用。 +- 客户端应在任何成功连接后持久化主 `hello-ok.auth.deviceToken`。 +- 使用该**已存储**设备令牌重新连接时,也应复用为该令牌存储的已批准作用域集。 + 这会保留已授予的读取/探测/status 访问权限,并避免将重新连接静默收窄为 + 仅管理员的隐式作用域。 +- 客户端连接认证组装(`src/gateway/client.ts` 中的 `selectConnectAuth`): + - `auth.password` 是正交的,设置后始终会被转发。 + - `auth.token` 按优先级填充:显式共享令牌优先, + 然后是显式 `deviceToken`,再然后是已存储的每设备令牌(按 + `deviceId` + `role` 作为键)。 + - 仅当上述任一项都未解析出 `auth.token` 时,才会发送 + `auth.bootstrapToken`。共享令牌或任何已解析的设备令牌都会抑制它。 + - 在一次性 `AUTH_TOKEN_MISMATCH` 重试中,自动提升已存储设备令牌仅限于**受信任端点** — + loopback,或带有固定 `tlsFingerprint` 的 `wss://`。未固定的公开 + `wss://` 不符合条件。 +- 额外的 `hello-ok.auth.deviceTokens` 条目是引导交接令牌。 + 仅当连接在受信任传输上使用引导认证时才持久化它们,例如 `wss://` 或 + loopback/本地配对。 +- 如果客户端提供**显式** `deviceToken` 或显式 `scopes`,则该调用方请求的作用域集仍为权威来源; + 缓存作用域仅在客户端复用已存储的每设备令牌时才会被复用。 +- 设备令牌可通过 `device.token.rotate` 和 `device.token.revoke` 轮换/撤销(需要 `operator.pairing` 作用域)。 -- `device.token.rotate` 返回轮换元数据。只有在同一设备调用且已使用该设备令牌认证时, - 它才会回显替换用 bearer token,因此仅令牌客户端可以在重新连接前持久化替换令牌。 - shared/admin 轮换不会回显 bearer token。 -- 令牌颁发、轮换和撤销都限定在该设备配对条目中记录的已批准角色集内; - 令牌变更不能扩展或目标指向配对批准从未授予的设备角色。 -- 对于已配对设备令牌会话,设备管理默认限定于自身,除非调用方还拥有 - `operator.admin`:非管理员调用方只能移除/撤销/轮换其**自己的**设备条目。 -- `device.token.rotate` 和 `device.token.revoke` 也会根据调用方当前会话作用域 - 检查目标 operator 令牌作用域集。非管理员调用方不能轮换或撤销比自己已持有范围更宽的 +- `device.token.rotate` 返回轮换元数据。只有在同设备调用且已使用 + 该设备令牌完成认证时,它才会回显替换用 bearer 令牌,这样仅令牌客户端可在 + 重新连接前持久化替换令牌。共享/管理员轮换不会回显 bearer 令牌。 +- 令牌签发、轮换和撤销都会受限于该设备配对条目中记录的已批准角色集; + 令牌变更不能扩展或指向配对批准从未授予的设备角色。 +- 对于已配对设备令牌会话,除非调用方还拥有 `operator.admin`,否则设备管理是自限定作用域的: + 非管理员调用方只能移除/撤销/轮换其**自己的**设备条目。 +- `device.token.rotate` 和 `device.token.revoke` 还会将目标 operator + 令牌作用域集与调用方当前会话作用域进行检查。非管理员调用方不能轮换或撤销比自己已持有作用域更宽的 operator 令牌。 - 认证失败包含 `error.details.code` 以及恢复提示: - `error.details.canRetryWithDeviceToken`(布尔值) - - `error.details.recommendedNextStep` (`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`) -- `AUTH_TOKEN_MISMATCH` 的客户端行为: - - 可信客户端可以尝试一次有界重试,并使用缓存的按设备令牌。 - - 如果该重试失败,客户端应停止自动重连循环,并展示 operator 操作指引。 + - `error.details.recommendedNextStep`(`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`) +- 客户端针对 `AUTH_TOKEN_MISMATCH` 的行为: + - 受信任客户端可以尝试一次有界重试,使用缓存的每设备令牌。 + - 如果该重试失败,客户端应停止自动重新连接循环,并显示 operator 操作指导。 ## 设备身份 + 配对 -- 节点应包含一个从密钥对指纹派生的稳定设备身份(`device.id`)。 -- Gateway 网关会按设备 + 角色颁发令牌。 +- 节点应包含从密钥对指纹派生的稳定设备身份(`device.id`)。 +- Gateway 网关会按设备 + 角色签发令牌。 - 除非启用了本地自动批准,否则新的设备 ID 需要配对批准。 - 配对自动批准以直接 local loopback 连接为中心。 -- OpenClaw 还有一个狭窄的后端/容器本地自连接路径,用于可信 shared-secret 辅助流程。 -- 同主机 tailnet 或 LAN 连接仍会按远程配对处理,并且需要批准。 +- OpenClaw 还提供一个狭窄的后端/容器本地自连接路径,用于受信任的共享密钥辅助流程。 +- 同主机 tailnet 或 LAN 连接仍会被视为远程配对,并需要批准。 - WS 客户端通常会在 `connect` 期间包含 `device` 身份(operator + - 节点)。仅以下显式信任路径允许无设备的 operator 例外: - - `gateway.controlUi.allowInsecureAuth=true` 用于仅 localhost 的不安全 HTTP 兼容性。 + 节点)。仅以下显式信任路径属于无设备 operator 例外: + - `gateway.controlUi.allowInsecureAuth=true`,用于仅限 localhost 的不安全 HTTP 兼容。 - 成功的 `gateway.auth.mode: "trusted-proxy"` operator Control UI 认证。 - - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(应急绕过,严重安全降级)。 - - 直接 loopback 的 `gateway-client` 后端 RPC,使用 shared - gateway token/password 认证。 + - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(应急破窗,严重降低安全性)。 + - 使用共享 Gateway 网关令牌/密码认证的 direct-loopback `gateway-client` 后端 RPC。 - 所有连接都必须签署服务器提供的 `connect.challenge` nonce。 ### 设备认证迁移诊断 -对于仍使用挑战前签名行为的旧版客户端,`connect` 现在会在 -`error.details.code` 下返回 `DEVICE_AUTH_*` 详细代码,并带有稳定的 `error.details.reason`。 +对于仍使用挑战前签名行为的旧版客户端,`connect` 现在会在 `error.details.code` 下返回 +`DEVICE_AUTH_*` 详情代码,并带有稳定的 `error.details.reason`。 常见迁移失败: | 消息 | details.code | details.reason | 含义 | | --------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- | -| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | 客户端省略了 `device.nonce`(或发送为空)。 | -| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | 客户端使用过期/错误的 nonce 进行了签名。 | +| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | 客户端省略了 `device.nonce`(或发送了空值)。 | +| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | 客户端使用过期/错误的 nonce 签名。 | | `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | 签名载荷与 v2 载荷不匹配。 | | `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | 已签名时间戳超出允许偏差。 | | `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` 与公钥指纹不匹配。 | @@ -626,24 +606,25 @@ Gateway 网关 将这些视为**声明**,并执行服务端允许列表。 - 始终等待 `connect.challenge`。 - 签署包含服务器 nonce 的 v2 载荷。 -- 在 `connect.params.device.nonce` 中发送同一个 nonce。 -- 首选签名载荷是 `v3`,它除了绑定 device/client/role/scopes/token/nonce - 字段外,还绑定 `platform` 和 `deviceFamily`。 -- 为了兼容性,旧版 `v2` 签名仍会被接受,但已配对设备元数据固定仍会控制重连时的命令策略。 +- 在 `connect.params.device.nonce` 中发送相同的 nonce。 +- 首选签名载荷是 `v3`,它除了绑定设备/客户端/角色/作用域/令牌/nonce 字段外, + 还会绑定 `platform` 和 `deviceFamily`。 +- 为保持兼容性,旧版 `v2` 签名仍会被接受,但已配对设备的 + 元数据固定仍会控制重新连接时的命令策略。 ## TLS + 固定 - WS 连接支持 TLS。 -- 客户端可以选择固定 Gateway 网关证书指纹(参见 `gateway.tls` +- 客户端可以选择固定 Gateway 网关证书指纹(见 `gateway.tls` 配置以及 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。 ## 作用域 -此协议暴露**完整的 Gateway 网关 API**(status、渠道、模型、chat、 -智能体、会话、节点、批准等)。确切表面由 +该协议暴露**完整的 Gateway 网关 API**(status、渠道、模型、聊天、 +智能体、会话、节点、批准等)。确切接口由 `src/gateway/protocol/schema.ts` 中的 TypeBox schema 定义。 ## 相关 -- [桥接协议](/zh-CN/gateway/bridge-protocol) -- [Gateway 网关运行手册](/zh-CN/gateway) +- [Bridge protocol](/zh-CN/gateway/bridge-protocol) +- [Gateway runbook](/zh-CN/gateway)