diff --git a/docs/zh-CN/concepts/models.md b/docs/zh-CN/concepts/models.md index 49a381824..bda1cdcff 100644 --- a/docs/zh-CN/concepts/models.md +++ b/docs/zh-CN/concepts/models.md @@ -1,57 +1,57 @@ --- read_when: - - 添加或修改模型 CLI(models list/set/scan/aliases/fallbacks)时 - - 更改模型回退行为或选择 UX 时 - - 更新模型扫描探测项(工具/图像)时 -summary: 模型 CLI:列表、设置、别名、回退、扫描、状态 -title: 模型 CLI + - 添加或修改 models CLI(models list/set/scan/aliases/fallbacks) + - 更改模型回退行为或选择 UX + - 更新模型扫描探测(工具/图像) +summary: Models CLI:列出、设置、别名、回退、扫描、状态 +title: Models CLI x-i18n: - generated_at: "2026-04-05T17:47:05Z" + generated_at: "2026-04-05T21:58:57Z" model: gpt-5.4 provider: openai - source_hash: b6a24f7621b0dd573571164b6690731eb318f7f78972dd310b9b6a9a3888489e + source_hash: 09507720942af72bf7027c733879935d53c79c72b607d737a131eaa02b9b2576 source_path: concepts/models.md workflow: 15 --- -# 模型 CLI +# Models CLI -有关凭证配置轮换、冷却时间及其与回退的交互方式,请参阅 [/concepts/model-failover](/zh-CN/concepts/model-failover)。 -提供商快速概览与示例:[/concepts/model-providers](/zh-CN/concepts/model-providers)。 +有关凭证配置轮换、冷却时间以及它们如何与回退交互,请参阅 [/concepts/model-failover](/zh-CN/concepts/model-failover)。 +提供商快速概览和示例:[/concepts/model-providers](/zh-CN/concepts/model-providers)。 -## 模型选择的工作方式 +## 模型选择如何工作 OpenClaw 按以下顺序选择模型: 1. **主模型**(`agents.defaults.model.primary` 或 `agents.defaults.model`)。 -2. `agents.defaults.model.fallbacks` 中的 **回退模型**(按顺序)。 -3. **提供商凭证故障转移**会先在单个提供商内部发生,然后才会移动到下一个模型。 +2. `agents.defaults.model.fallbacks` 中的**回退模型**(按顺序)。 +3. **提供商凭证故障转移**会先在提供商内部发生,然后才会切换到下一个模型。 相关项: -- `agents.defaults.models` 是 OpenClaw 可使用的模型允许列表/目录(以及别名)。 +- `agents.defaults.models` 是 OpenClaw 可使用模型的允许列表/目录(以及别名)。 - `agents.defaults.imageModel` **仅在**主模型无法接受图像时使用。 -- `agents.defaults.pdfModel` 由 `pdf` 工具使用。如果省略,该工具会依次回退到 `agents.defaults.imageModel`,然后是解析后的会话/默认模型。 -- `agents.defaults.imageGenerationModel` 由共享图像生成能力使用。如果省略,`image_generate` 仍可推断出一个由凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的图像生成提供商。如果你设置了特定的提供商/模型,也请配置该提供商的凭证/API 密钥。 -- `agents.defaults.videoGenerationModel` 由共享视频生成能力使用。如果省略,`video_generate` 仍可推断出一个由凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按提供商 ID 顺序尝试其余已注册的视频生成提供商。如果你设置了特定的提供商/模型,也请配置该提供商的凭证/API 密钥。 -- 每个智能体的默认值可通过 `agents.list[].model` 加上绑定覆盖 `agents.defaults.model`(参见 [/concepts/multi-agent](/zh-CN/concepts/multi-agent))。 +- `agents.defaults.pdfModel` 由 `pdf` 工具使用。如果省略,该工具会依次回退到 `agents.defaults.imageModel`,然后是已解析的当前会话/默认模型。 +- `agents.defaults.imageGenerationModel` 用于共享的图像生成功能。如果省略,`image_generate` 仍可推断出由凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按 provider-id 顺序尝试其余已注册的图像生成提供商。如果你设置了特定的提供商/模型,也请配置该提供商的凭证/API key。 +- `agents.defaults.videoGenerationModel` 用于共享的视频生成功能。如果省略,`video_generate` 仍可推断出由凭证支持的提供商默认值。它会先尝试当前默认提供商,然后按 provider-id 顺序尝试其余已注册的视频生成提供商。如果你设置了特定的提供商/模型,也请配置该提供商的凭证/API key。 +- 每个智能体的默认值可以通过 `agents.list[].model` 加上绑定覆盖 `agents.defaults.model`(参见 [/concepts/multi-agent](/zh-CN/concepts/multi-agent))。 ## 快速模型策略 -- 将你的主模型设置为你可用的、能力最强的最新一代模型。 -- 对成本/延迟敏感的任务和重要性较低的聊天,使用回退模型。 -- 对启用了工具的智能体或不受信任的输入,避免使用较旧/较弱的模型层级。 +- 将你的主模型设置为你可用的最强新一代模型。 +- 对于成本/延迟敏感的任务和风险较低的聊天,使用回退模型。 +- 对于启用了工具的智能体或不受信任的输入,避免使用较旧/较弱的模型层级。 ## 新手引导(推荐) -如果你不想手动编辑配置,可以运行新手引导: +如果你不想手动编辑配置,请运行新手引导: ```bash openclaw onboard ``` -它可以为常见提供商设置模型 + 凭证,包括 **OpenAI Code (Codex) 订阅** -(OAuth)和 **Anthropic**(API 密钥或 Claude CLI)。 +它可以为常见提供商设置模型和凭证,包括 **OpenAI Code (Codex)** +订阅(OAuth)和 **Anthropic**(API key 或 Claude CLI)。 ## 配置键名(概览) @@ -63,24 +63,25 @@ openclaw onboard - `agents.defaults.models`(允许列表 + 别名 + 提供商参数) - `models.providers`(写入 `models.json` 的自定义提供商) -模型引用会被规范化为小写。像 `z.ai/*` 这样的提供商别名会规范化为 +模型引用会规范化为小写。像 `z.ai/*` 这样的提供商别名会规范化为 `zai/*`。 提供商配置示例(包括 OpenCode)位于 [/providers/opencode](/zh-CN/providers/opencode)。 -## “模型不被允许” (以及为什么回复会停止) +## “模型不被允许”(以及为什么回复会停止) -如果设置了 `agents.defaults.models`,它就会成为 `/model` 和会话覆盖的**允许列表**。当用户选择了不在该允许列表中的模型时,OpenClaw 会返回: +如果设置了 `agents.defaults.models`,它就会成为 `/model` 和会话覆盖的**允许列表**。当用户选择了不在该允许列表中的模型时, +OpenClaw 会返回: ``` Model "provider/model" is not allowed. Use /model to list available models. ``` -这会在生成正常回复**之前**发生,因此消息看起来可能像是“没有回应”。修复方法是以下任一项: +这会在生成正常回复**之前**发生,因此消息看起来像是“没有响应”。解决方法是: - 将该模型添加到 `agents.defaults.models`,或 -- 清除允许列表(移除 `agents.defaults.models`),或 +- 清空允许列表(移除 `agents.defaults.models`),或 - 从 `/model list` 中选择一个模型。 允许列表示例配置: @@ -99,7 +100,7 @@ Model "provider/model" is not allowed. Use /model to list available models. ## 在聊天中切换模型(`/model`) -你可以在不重启的情况下,为当前会话切换模型: +你可以在不重启的情况下为当前会话切换模型: ``` /model @@ -111,23 +112,23 @@ Model "provider/model" is not allowed. Use /model to list available models. 说明: -- `/model`(以及 `/model list`)是一个紧凑的编号选择器(模型家族 + 可用提供商)。 -- 在 Discord 上,`/model` 和 `/models` 会打开一个交互式选择器,其中包含提供商和模型下拉菜单,以及一个提交步骤。 -- `/model <#>` 会从该选择器中选择。 +- `/model`(以及 `/model list`)是一个紧凑的编号选择器(模型系列 + 可用提供商)。 +- 在 Discord 上,`/model` 和 `/models` 会打开一个交互式选择器,其中包含提供商和模型下拉菜单,以及一个 Submit 步骤。 +- `/model <#>` 会从该选择器中进行选择。 - `/model` 会立即持久化新的会话选择。 -- 如果智能体处于空闲状态,下一次运行会立刻使用新模型。 -- 如果某次运行已经处于活跃状态,OpenClaw 会将实时切换标记为待处理,并且只会在一个干净的重试点重启到新模型。 -- 如果工具活动或回复输出已经开始,待处理切换可能会继续排队,直到稍后的重试机会或下一次用户轮次。 +- 如果智能体处于空闲状态,下一次运行会立即使用新模型。 +- 如果某次运行已处于活动状态,OpenClaw 会将实时切换标记为待处理,并且只会在一次干净的重试点重启并切换到新模型。 +- 如果工具活动或回复输出已经开始,待处理的切换可能会保持排队状态,直到稍后的重试机会或下一次用户轮次。 - `/model status` 是详细视图(凭证候选项,以及在已配置时显示提供商端点 `baseUrl` + `api` 模式)。 -- 模型引用通过按**第一个** `/` 拆分来解析。输入 `/model ` 时,请使用 `provider/model`。 +- 模型引用通过按**第一个** `/` 进行拆分来解析。输入 `/model ` 时,请使用 `provider/model`。 - 如果模型 ID 本身包含 `/`(OpenRouter 风格),你必须包含提供商前缀(例如:`/model openrouter/moonshotai/kimi-k2`)。 - 如果你省略了提供商,OpenClaw 会按以下顺序解析输入: 1. 别名匹配 2. 该精确无前缀模型 ID 的唯一已配置提供商匹配 - 3. 已弃用的回退:回退到已配置的默认提供商 - 如果该提供商不再暴露已配置的默认模型,OpenClaw 会改为回退到第一个已配置的提供商/模型,以避免暴露过时的、已移除提供商默认值。 + 3. 已弃用的回退行为:回退到已配置的默认提供商 + 如果该提供商不再提供已配置的默认模型,OpenClaw 会改为回退到第一个已配置的提供商/模型,以避免暴露陈旧的、已移除提供商默认值。 -完整命令行为/配置: [Slash commands](/zh-CN/tools/slash-commands)。 +完整的命令行为/配置: [Slash commands](/zh-CN/tools/slash-commands)。 ## CLI 命令 @@ -166,16 +167,18 @@ openclaw models image-fallbacks clear ### `models status` -显示解析后的主模型、回退模型、图像模型,以及已配置提供商的凭证概览。它还会显示凭证存储中找到的配置档案的 OAuth 过期状态(默认会在 24 小时内发出警告)。`--plain` 仅打印解析后的主模型。 -OAuth 状态始终会显示(并包含在 `--json` 输出中)。如果某个已配置提供商没有凭证,`models status` 会打印一个 **缺少凭证** 部分。 -JSON 包含 `auth.oauth`(警告窗口 + 配置档案)和 `auth.providers` -(每个提供商的有效凭证)。 -自动化场景请使用 `--check`(缺少/已过期时退出码为 `1`,即将过期时为 `2`)。 -实时凭证检查请使用 `--probe`;探测行可能来自凭证配置档案、环境变量凭证或 `models.json`。 -如果显式的 `auth.order.` 省略了某个已存储配置档案,探测会报告 -`excluded_by_auth_order`,而不是尝试它。如果存在凭证,但无法为该提供商解析出可探测模型,探测会报告 `status: no_model`。 +显示已解析的主模型、回退模型、图像模型,以及已配置提供商的凭证概览。它还会显示凭证存储中找到的配置文件的 OAuth 过期状态(默认在 24 小时内给出警告)。`--plain` 仅打印已解析的主模型。 +OAuth 状态始终会显示(并包含在 `--json` 输出中)。如果某个已配置提供商没有凭证,`models status` 会打印一个**缺少凭证**部分。 +JSON 包含 `auth.oauth`(警告窗口 + 配置文件)和 `auth.providers` +(每个提供商的生效凭证,包括由环境变量支持的凭证)。`auth.oauth` +仅表示凭证存储配置文件的健康状态;仅使用环境变量的提供商不会出现在其中。 +自动化场景请使用 `--check`(缺少/过期时退出码为 `1`,即将过期时为 `2`)。 +使用 `--probe` 执行实时凭证检查;探测行可能来自凭证配置文件、环境变量凭证或 `models.json`。 +如果显式 `auth.order.` 省略了某个已存储配置文件,探测会报告 +`excluded_by_auth_order`,而不是尝试它。如果存在凭证,但该提供商无法解析出可探测模型,探测会报告 `status: no_model`。 -凭证选择取决于提供商/账户。对于始终在线的 Gateway 网关主机,API 密钥通常最可预测;也支持复用 Claude CLI 以及现有的 Anthropic OAuth/token 配置档案。 +凭证选择取决于提供商/账户。对于始终在线的 Gateway 网关主机,API +key 通常最可预测;也支持复用 Claude CLI,以及现有的 Anthropic OAuth/token 配置文件。 示例(Claude CLI): @@ -186,7 +189,7 @@ openclaw models status ## 扫描(OpenRouter 免费模型) -`openclaw models scan` 会检查 OpenRouter 的**免费模型目录**,并且可以选择性地探测模型的工具和图像支持。 +`openclaw models scan` 会检查 OpenRouter 的**免费模型目录**,并且可以选择性地探测模型是否支持工具和图像。 关键标志: @@ -195,11 +198,11 @@ openclaw models status - `--max-age-days `:跳过较旧模型 - `--provider `:提供商前缀筛选 - `--max-candidates `:回退列表大小 -- `--set-default`:将 `agents.defaults.model.primary` 设置为第一个选中项 -- `--set-image`:将 `agents.defaults.imageModel.primary` 设置为第一个图像选中项 +- `--set-default`:将 `agents.defaults.model.primary` 设置为首个选择项 +- `--set-image`:将 `agents.defaults.imageModel.primary` 设置为首个图像选择项 -探测需要 OpenRouter API 密钥(来自凭证配置档案或 -`OPENROUTER_API_KEY`)。如果没有密钥,请使用 `--no-probe` 仅列出候选项。 +探测需要 OpenRouter API key(来自凭证配置文件或 +`OPENROUTER_API_KEY`)。如果没有 key,请使用 `--no-probe` 仅列出候选项。 扫描结果按以下顺序排序: @@ -211,33 +214,33 @@ openclaw models status 输入 - OpenRouter `/models` 列表(筛选 `:free`) -- 需要来自凭证配置档案或 `OPENROUTER_API_KEY` 的 OpenRouter API 密钥(参见 [/environment](/zh-CN/help/environment)) -- 可选筛选项:`--max-age-days`、`--min-params`、`--provider`、`--max-candidates` +- 需要来自凭证配置文件或 `OPENROUTER_API_KEY` 的 OpenRouter API key(参见 [/environment](/zh-CN/help/environment)) +- 可选筛选条件:`--max-age-days`、`--min-params`、`--provider`、`--max-candidates` - 探测控制:`--timeout`、`--concurrency` 在 TTY 中运行时,你可以交互式选择回退模型。在非交互模式下,传入 `--yes` 以接受默认值。 ## 模型注册表(`models.json`) -`models.providers` 中的自定义提供商会被写入智能体目录下的 `models.json` -(默认是 `~/.openclaw/agents//agent/models.json`)。默认情况下会合并此文件,除非将 `models.mode` 设置为 `replace`。 +`models.providers` 中的自定义提供商会写入智能体目录下的 `models.json` +(默认路径为 `~/.openclaw/agents//agent/models.json`)。默认会合并此文件,除非将 `models.mode` 设置为 `replace`。 -匹配提供商 ID 时,合并模式的优先级如下: +对于匹配的提供商 ID,合并模式的优先级如下: -- 智能体 `models.json` 中已存在的非空 `baseUrl` 优先生效。 -- 智能体 `models.json` 中的非空 `apiKey` 仅在该提供商在当前配置/凭证配置档案上下文中**不是**由 SecretRef 管理时才优先生效。 -- 由 SecretRef 管理的提供商 `apiKey` 值会从源标记刷新(环境变量引用使用 `ENV_VAR_NAME`,文件/exec 引用使用 `secretref-managed`),而不是持久化解析后的密钥。 -- 由 SecretRef 管理的提供商请求头值会从源标记刷新(环境变量引用使用 `secretref-env:ENV_VAR_NAME`,文件/exec 引用使用 `secretref-managed`)。 -- 智能体中为空或缺失的 `apiKey`/`baseUrl` 会回退到配置中的 `models.providers`。 +- 如果智能体 `models.json` 中已存在非空 `baseUrl`,则其优先。 +- 智能体 `models.json` 中的非空 `apiKey` 仅在该提供商在当前配置/凭证配置文件上下文中不是由 SecretRef 管理时才优先。 +- 由 SecretRef 管理的提供商 `apiKey` 值会从源标记刷新(环境变量引用使用 `ENV_VAR_NAME`,file/exec 引用使用 `secretref-managed`),而不是持久化已解析的密钥。 +- 由 SecretRef 管理的提供商 header 值会从源标记刷新(环境变量引用使用 `secretref-env:ENV_VAR_NAME`,file/exec 引用使用 `secretref-managed`)。 +- 智能体中的 `apiKey`/`baseUrl` 为空或缺失时,会回退到配置中的 `models.providers`。 - 其他提供商字段会从配置和规范化后的目录数据中刷新。 -标记持久化以源为准:OpenClaw 会根据当前源配置快照(预解析),而不是根据解析后的运行时密钥值来写入标记。 -这适用于 OpenClaw 重新生成 `models.json` 的所有情况,包括由命令驱动的路径,例如 `openclaw agent`。 +标记持久化遵循源配置权威:OpenClaw 会根据活动源配置快照(预解析)写入标记,而不是根据运行时已解析的密钥值写入。 +这适用于 OpenClaw 重新生成 `models.json` 的所有情况,包括像 `openclaw agent` 这样的命令驱动路径。 ## 相关内容 -- [模型提供商](/zh-CN/concepts/model-providers) — 提供商路由与凭证 -- [模型故障转移](/zh-CN/concepts/model-failover) — 回退链 -- [图像生成](/zh-CN/tools/image-generation) — 图像模型配置 -- [视频生成](/tools/video-generation) — 视频模型配置 -- [配置参考](/zh-CN/gateway/configuration-reference#agent-defaults) — 模型配置键名 +- [Model Providers](/zh-CN/concepts/model-providers) — 提供商路由和凭证 +- [Model Failover](/zh-CN/concepts/model-failover) — 回退链 +- [Image Generation](/zh-CN/tools/image-generation) — 图像模型配置 +- [Video Generation](/zh-CN/tools/video-generation) — 视频模型配置 +- [Configuration Reference](/zh-CN/gateway/configuration-reference#agent-defaults) — 模型配置键名 diff --git a/docs/zh-CN/gateway/protocol.md b/docs/zh-CN/gateway/protocol.md index 4d218129e..754704893 100644 --- a/docs/zh-CN/gateway/protocol.md +++ b/docs/zh-CN/gateway/protocol.md @@ -1,27 +1,27 @@ --- read_when: - - 实现或更新 gateway WS 客户端 - - 调试协议不匹配或连接失败 - - 重新生成协议 schema/models + - 实现或更新 Gateway 网关 WS 客户端时 + - 调试协议不匹配或连接失败时 + - 重新生成协议 schema / 模型时 summary: Gateway 网关 WebSocket 协议:握手、帧、版本控制 -title: Gateway Protocol +title: Gateway 网关协议 x-i18n: - generated_at: "2026-04-05T08:25:22Z" + generated_at: "2026-04-05T21:59:30Z" model: gpt-5.4 provider: openai - source_hash: c37f5b686562dda3ba3516ac6982ad87b2f01d8148233284e9917099c6e96d87 + source_hash: dcf6b4a88bb213e0704a767bf466329c8b33656919e933668f5f6ef06864ea55 source_path: gateway/protocol.md workflow: 15 --- -# Gateway protocol(WebSocket) +# Gateway 网关协议(WebSocket) -Gateway 网关 WS 协议是 OpenClaw 的**单一控制平面 + 节点传输层**。所有客户端(CLI、web UI、macOS 应用、iOS/Android 节点、headless 节点)都通过 WebSocket 连接,并在握手时声明自己的**角色** + **scope**。 +Gateway 网关 WS 协议是 OpenClaw 的**单一控制平面 + 节点传输协议**。所有客户端(CLI、Web UI、macOS 应用、iOS / Android 节点、无头节点)都通过 WebSocket 连接,并在握手时声明其**角色**和**作用域**。 ## 传输 -- WebSocket,使用带 JSON 负载的文本帧。 -- 第一帧**必须**是一个 `connect` 请求。 +- WebSocket,使用带有 JSON 负载的文本帧。 +- 第一帧**必须**是 `connect` 请求。 ## 握手(connect) @@ -81,7 +81,7 @@ Gateway 网关 → 客户端: } ``` -当签发了设备 token 时,`hello-ok` 还会包含: +发放设备令牌时,`hello-ok` 还会包含: ```json { @@ -93,7 +93,7 @@ Gateway 网关 → 客户端: } ``` -在受信任的 bootstrap 交接过程中,`hello-ok.auth` 还可能在 `deviceTokens` 中包含额外的有界角色条目: +在受信任的引导交接期间,`hello-ok.auth` 还可能在 `deviceTokens` 中包含额外的受限角色条目: ```json { @@ -112,12 +112,7 @@ Gateway 网关 → 客户端: } ``` -对于内置的 node/operator bootstrap 流程,主 node token 仍保持为 -`scopes: []`,而任何交接的 operator token 都会被限制在 bootstrap -operator 允许列表内(`operator.approvals`、`operator.read`、 -`operator.talk.secrets`、`operator.write`)。Bootstrap scope 检查仍保持 -按角色前缀进行:operator 条目只满足 operator 请求,非 operator -角色仍然需要自身角色前缀下的 scopes。 +对于内置的 node / operator 引导流程,主 node 令牌保持为 `scopes: []`,而任何交接的 operator 令牌都保持受限于引导 operator 允许列表(`operator.approvals`、`operator.read`、`operator.talk.secrets`、`operator.write`)。引导作用域检查始终保持按角色前缀进行:operator 条目只能满足 operator 请求,而非 operator 角色仍然需要其自身角色前缀下的作用域。 ### 节点示例 @@ -160,18 +155,18 @@ operator 允许列表内(`operator.approvals`、`operator.read`、 - **响应**:`{type:"res", id, ok, payload|error}` - **事件**:`{type:"event", event, payload, seq?, stateVersion?}` -有副作用的方法需要 **idempotency keys**(见 schema)。 +有副作用的方法需要**幂等键**(参见 schema)。 -## 角色 + scopes +## 角色 + 作用域 ### 角色 -- `operator` = 控制平面客户端(CLI/UI/自动化)。 -- `node` = 能力宿主(camera/screen/canvas/system.run)。 +- `operator` = 控制平面客户端(CLI / UI / 自动化)。 +- `node` = 能力宿主(camera / screen / canvas / system.run)。 -### Scopes(operator) +### 作用域(operator) -常见 scopes: +常见作用域: - `operator.read` - `operator.write` @@ -180,30 +175,25 @@ operator 允许列表内(`operator.approvals`、`operator.read`、 - `operator.pairing` - `operator.talk.secrets` -带 `includeSecrets: true` 的 `talk.config` 需要 `operator.talk.secrets` -(或 `operator.admin`)。 +带有 `includeSecrets: true` 的 `talk.config` 需要 `operator.talk.secrets`(或 `operator.admin`)。 -由插件注册的 gateway RPC 方法可以请求自己的 operator scope,但 -保留的核心管理员前缀(`config.*`、`exec.approvals.*`、`wizard.*`、 -`update.*`)始终解析为 `operator.admin`。 +插件注册的 Gateway 网关 RPC 方法可以请求其自己的 operator 作用域,但保留的核心管理前缀(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终解析为 `operator.admin`。 -方法 scope 只是第一道门槛。某些通过 -`chat.send` 到达的斜杠命令还会在其上叠加更严格的命令级检查。例如,持久化的 -`/config set` 和 `/config unset` 写入需要 `operator.admin`。 +方法作用域只是第一道门槛。通过 `chat.send` 到达的一些斜杠命令还会在此之上应用更严格的命令级检查。例如,持久化的 `/config set` 和 `/config unset` 写入需要 `operator.admin`。 -`node.pair.approve` 在基础方法 scope 之上还有额外的审批时 scope 检查: +`node.pair.approve` 也在基础方法作用域之上增加了额外的审批时作用域检查: - 无命令请求:`operator.pairing` -- 带非 exec node 命令的请求:`operator.pairing` + `operator.write` +- 带有非 exec 节点命令的请求:`operator.pairing` + `operator.write` - 包含 `system.run`、`system.run.prepare` 或 `system.which` 的请求: `operator.pairing` + `operator.admin` -### Caps/commands/permissions(node) +### caps / commands / permissions(node) 节点在连接时声明能力声明: - `caps`:高层能力类别。 -- `commands`:供 invoke 使用的命令允许列表。 +- `commands`:用于 invoke 的命令允许列表。 - `permissions`:细粒度开关(例如 `screen.record`、`camera.capture`)。 Gateway 网关将这些视为**声明**,并在服务端强制执行允许列表。 @@ -211,319 +201,251 @@ Gateway 网关将这些视为**声明**,并在服务端强制执行允许列 ## 在线状态 - `system-presence` 返回按设备身份键控的条目。 -- 在线状态条目包含 `deviceId`、`roles` 和 `scopes`,这样 UI 就可以在设备同时以 **operator** 和 **node** 身份连接时,仍显示为单行。 +- 在线状态条目包含 `deviceId`、`roles` 和 `scopes`,这样 UI 即使在同一设备同时以 **operator** 和 **node** 连接时,也能显示为单行。 ## 常见 RPC 方法族 -本页不是自动生成的完整清单,但公开 WS 接口比上面的握手/认证示例更广。下面是 Gateway 网关当前暴露的主要方法族。 +本页不是生成的完整导出,但公开的 WS 接口比上面的握手 / 认证示例更广。这些是 Gateway 网关当前公开的主要方法族。 -`hello-ok.features.methods` 是一个保守的发现列表,由 -`src/gateway/server-methods-list.ts` 加上已加载的插件/渠道方法导出构建而成。 -应将其视为功能发现,而不是 -`src/gateway/server-methods/*.ts` 中每个可调用辅助方法的自动生成清单。 +`hello-ok.features.methods` 是一个保守的发现列表,由 `src/gateway/server-methods-list.ts` 加上已加载的插件 / 渠道方法导出构建而成。应将其视为功能发现,而不是 `src/gateway/server-methods/*.ts` 中实现的每个可调用辅助函数的生成导出。 -### 系统与身份 +### 系统和身份 -- `health` 返回缓存的或新近探测的 gateway 健康快照。 -- `status` 返回类似 `/status` 的 gateway 摘要;敏感字段 - 仅对具有 admin scope 的 operator 客户端可见。 -- `gateway.identity.get` 返回 relay 和 - pairing 流程所使用的 gateway 设备身份。 -- `system-presence` 返回当前已连接 - operator/node 设备的在线状态快照。 -- `system-event` 追加系统事件,并可更新/广播在线状态 - 上下文。 -- `last-heartbeat` 返回最近一次持久化的 heartbeat 事件。 -- `set-heartbeats` 切换 gateway 上的 heartbeat 处理。 +- `health` 返回缓存的或新探测的 Gateway 网关健康状态快照。 +- `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅对具有 admin 作用域的 operator 客户端包含。 +- `gateway.identity.get` 返回中继和配对流程使用的 Gateway 网关设备身份。 +- `system-presence` 返回当前已连接 operator / node 设备的在线状态快照。 +- `system-event` 追加系统事件,并可更新 / 广播在线状态上下文。 +- `last-heartbeat` 返回最新持久化的心跳事件。 +- `set-heartbeats` 切换 Gateway 网关上的心跳处理。 -### 模型与使用情况 +### 模型和用量 - `models.list` 返回运行时允许的模型目录。 -- `usage.status` 返回 provider 使用窗口/剩余额度摘要。 -- `usage.cost` 返回某个日期范围的聚合成本使用摘要。 -- `doctor.memory.status` 返回活动默认智能体工作区的 - 向量 memory / embedding 就绪状态。 -- `sessions.usage` 返回按会话统计的使用摘要。 -- `sessions.usage.timeseries` 返回某个会话的时间序列使用情况。 -- `sessions.usage.logs` 返回某个会话的使用日志条目。 +- `usage.status` 返回提供商用量窗口 / 剩余额度摘要。 +- `usage.cost` 返回某日期范围内的聚合成本用量摘要。 +- `doctor.memory.status` 返回活动默认 agent 工作区的向量记忆 / embedding 就绪状态。 +- `sessions.usage` 返回按会话统计的用量摘要。 +- `sessions.usage.timeseries` 返回单个会话的时间序列用量。 +- `sessions.usage.logs` 返回单个会话的用量日志条目。 -### 渠道与登录辅助 +### 渠道和登录辅助 -- `channels.status` 返回内置 + 内置插件/渠道状态摘要。 -- `channels.logout` 让特定渠道/账户登出,前提是该渠道 - 支持登出。 -- `web.login.start` 为当前支持 QR 的 web - 渠道 provider 启动 QR/web 登录流程。 -- `web.login.wait` 等待该 QR/web 登录流程完成,并在成功后启动 - 渠道。 -- `push.test` 向已注册的 iOS node 发送一个测试 APNs push。 +- `channels.status` 返回内置 + 内置打包的渠道 / 插件状态摘要。 +- `channels.logout` 在渠道支持登出的情况下登出特定渠道 / 账户。 +- `web.login.start` 为当前支持 QR 的 Web 渠道提供商启动 QR / Web 登录流程。 +- `web.login.wait` 等待该 QR / Web 登录流程完成,并在成功时启动渠道。 +- `push.test` 向已注册的 iOS 节点发送测试 APNs 推送。 - `voicewake.get` 返回已存储的唤醒词触发器。 - `voicewake.set` 更新唤醒词触发器并广播变更。 -### 消息与日志 +### 消息和日志 -- `send` 是直接的出站投递 RPC,用于在聊天运行器之外按渠道/账户/线程目标发送消息。 -- `logs.tail` 返回已配置的 gateway 文件日志尾部,支持 cursor/limit 和 - max-byte 控制。 +- `send` 是直接的出站投递 RPC,用于在聊天运行器之外按渠道 / 账户 / 线程目标发送消息。 +- `logs.tail` 返回配置的 Gateway 网关文件日志尾部,支持 cursor / limit 和最大字节控制。 ### Talk 和 TTS -- `talk.config` 返回生效的 Talk 配置负载;`includeSecrets` - 需要 `operator.talk.secrets`(或 `operator.admin`)。 -- `talk.mode` 为 WebChat/Control UI - 客户端设置/广播当前 Talk 模式状态。 -- `talk.speak` 通过当前激活的 Talk 语音 provider 合成语音。 -- `tts.status` 返回 TTS 启用状态、当前 provider、回退 providers - 以及 provider 配置状态。 -- `tts.providers` 返回可见的 TTS provider 清单。 +- `talk.config` 返回生效的 Talk 配置负载;`includeSecrets` 需要 `operator.talk.secrets`(或 `operator.admin`)。 +- `talk.mode` 为 WebChat / Control UI 客户端设置 / 广播当前 Talk 模式状态。 +- `talk.speak` 通过当前活动的 Talk 语音提供商合成语音。 +- `tts.status` 返回 TTS 启用状态、活动提供商、回退提供商和提供商配置状态。 +- `tts.providers` 返回可见的 TTS 提供商清单。 - `tts.enable` 和 `tts.disable` 切换 TTS 偏好状态。 -- `tts.setProvider` 更新首选 TTS provider。 -- `tts.convert` 运行一次性 text-to-speech 转换。 +- `tts.setProvider` 更新首选 TTS 提供商。 +- `tts.convert` 执行一次性文本转语音转换。 ### Secrets、配置、更新和向导 -- `secrets.reload` 重新解析活动 SecretRef,并且仅在完全成功时切换运行时 secret 状态。 -- `secrets.resolve` 为特定 - command/target 集合解析命令目标 secret 分配。 -- `config.get` 返回当前配置快照和 hash。 +- `secrets.reload` 重新解析活动 SecretRef,并且仅在完全成功时替换运行时 secret 状态。 +- `secrets.resolve` 为特定命令 / 目标集解析命令目标 secret 分配。 +- `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 节点会保留用户可见文档和常见校验字段: +- `config.schema` 返回 Control UI 和 CLI 工具使用的实时配置 schema 负载:schema、`uiHints`、版本和生成元数据;当运行时能够加载时,还包括插件 + 渠道 schema 元数据。该 schema 包含从 UI 使用的相同标签和帮助文本派生的字段 `title` / `description` 元数据,包括在存在匹配字段文档时的嵌套对象、通配符、数组项以及 `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 更新流程,并且仅在 - 更新本身成功时安排重启。 -- `wizard.start`、`wizard.next`、`wizard.status` 和 `wizard.cancel` 通过 - WS RPC 暴露新手引导向导。 + - 子项摘要暴露 `key`、规范化 `path`、`type`、`required`、 + `hasChildren`,以及匹配的 `hint` / `hintPath`。 +- `update.run` 运行 Gateway 网关更新流程,并且仅在更新本身成功时安排重启。 +- `wizard.start`、`wizard.next`、`wizard.status` 和 `wizard.cancel` 通过 WS RPC 暴露新手引导向导。 ### 现有主要方法族 -#### 智能体与工作区辅助 +#### agent 和工作区辅助 -- `agents.list` 返回已配置的智能体条目。 -- `agents.create`、`agents.update` 和 `agents.delete` 管理智能体记录和 - 工作区连线。 -- `agents.files.list`、`agents.files.get` 和 `agents.files.set` 管理为智能体暴露的 - bootstrap 工作区文件。 -- `agent.identity.get` 返回某个智能体或 - 会话的生效 assistant 身份。 -- `agent.wait` 等待一次运行结束,并在 - 可用时返回终态快照。 +- `agents.list` 返回已配置的 agent 条目。 +- `agents.create`、`agents.update` 和 `agents.delete` 管理 agent 记录和工作区接线。 +- `agents.files.list`、`agents.files.get` 和 `agents.files.set` 管理为 agent 暴露的引导工作区文件。 +- `agent.identity.get` 返回某个 agent 或会话的生效助手身份。 +- `agent.wait` 等待一次运行结束,并在可用时返回终态快照。 #### 会话控制 - `sessions.list` 返回当前会话索引。 -- `sessions.subscribe` 和 `sessions.unsubscribe` 切换当前 WS 客户端的 - 会话变更事件订阅。 -- `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 切换某个会话的 - transcript/message 事件订阅。 -- `sessions.preview` 返回特定 session - key 的有界 transcript 预览。 -- `sessions.resolve` 解析或规范化某个会话目标。 -- `sessions.create` 创建新的会话条目。 +- `sessions.subscribe` 和 `sessions.unsubscribe` 为当前 WS 客户端切换会话变更事件订阅。 +- `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 为单个会话切换转录 / 消息事件订阅。 +- `sessions.preview` 返回特定会话键的受限转录预览。 +- `sessions.resolve` 解析或规范化会话目标。 +- `sessions.create` 创建新会话条目。 - `sessions.send` 向现有会话发送消息。 - `sessions.steer` 是活动会话的中断并引导变体。 - `sessions.abort` 中止某个会话的活动工作。 -- `sessions.patch` 更新会话元数据/覆盖项。 +- `sessions.patch` 更新会话元数据 / 覆盖项。 - `sessions.reset`、`sessions.delete` 和 `sessions.compact` 执行会话维护。 - `sessions.get` 返回完整存储的会话行。 -- 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 - `chat.inject`。 -- `chat.history` 针对 UI 客户端做了显示标准化:可见文本中的内联指令标签会被移除, - 纯文本工具调用 XML 负载(包括 - `...`、`...`、 - `...`、`...` 以及 - 被截断的工具调用块)和泄露的 ASCII/全角模型控制 token - 会被移除,纯静默 token 的 assistant 行(例如精确的 `NO_REPLY` / - `no_reply`)会被省略,过大的行则可能被占位符替换。 +- 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。 +- `chat.history` 已为 UI 客户端进行显示规范化:内联指令标签会从可见文本中移除,纯文本工具调用 XML 负载(包括 `...`、`...`、`...`、`...` 以及被截断的工具调用块)和泄露的 ASCII / 全角模型控制标记会被移除,纯静默标记的助手行(例如完全等于 `NO_REPLY` / `no_reply`)会被省略,过大的行可能会被占位符替换。 -#### 设备配对与设备 token +#### 设备配对和设备令牌 - `device.pair.list` 返回待处理和已批准的配对设备。 -- `device.pair.approve`、`device.pair.reject` 和 `device.pair.remove` 管理 - 设备配对记录。 -- `device.token.rotate` 在已批准的角色 - 和 scope 边界内轮换某个配对设备 token。 -- `device.token.revoke` 撤销某个配对设备 token。 +- `device.pair.approve`、`device.pair.reject` 和 `device.pair.remove` 管理设备配对记录。 +- `device.token.rotate` 在已批准的角色和作用域边界内轮换已配对设备令牌。 +- `device.token.revoke` 撤销已配对设备令牌。 -#### Node 配对、invoke 和待处理工作 +#### 节点配对、调用和待处理工作 - `node.pair.request`、`node.pair.list`、`node.pair.approve`、 - `node.pair.reject` 和 `node.pair.verify` 涵盖 node 配对和 bootstrap - 校验。 -- `node.list` 和 `node.describe` 返回已知/已连接 node 状态。 -- `node.rename` 更新某个已配对 node 标签。 -- `node.invoke` 将命令转发给已连接 node。 -- `node.invoke.result` 返回某个 invoke 请求的结果。 -- `node.event` 将 node 发起的事件带回 gateway。 -- `node.canvas.capability.refresh` 刷新带 scope 的 canvas 能力 token。 -- `node.pending.pull` 和 `node.pending.ack` 是已连接 node 的队列 API。 -- `node.pending.enqueue` 和 `node.pending.drain` 管理离线/断开连接 node 的持久待处理工作。 + `node.pair.reject` 和 `node.pair.verify` 涵盖节点配对和引导验证。 +- `node.list` 和 `node.describe` 返回已知 / 已连接节点状态。 +- `node.rename` 更新已配对节点标签。 +- `node.invoke` 将命令转发到已连接节点。 +- `node.invoke.result` 返回 invoke 请求的结果。 +- `node.event` 将源自节点的事件带回 Gateway 网关。 +- `node.canvas.capability.refresh` 刷新有作用域限制的 canvas 能力令牌。 +- `node.pending.pull` 和 `node.pending.ack` 是已连接节点队列 API。 +- `node.pending.enqueue` 和 `node.pending.drain` 为离线 / 断开连接节点管理持久化待处理工作。 #### 审批方法族 -- `exec.approval.request` 和 `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` 通过 node 中继命令管理 node 本地 exec - 审批策略。 +- `exec.approval.request` 和 `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.waitDecision` 和 - `plugin.approval.resolve` 处理插件定义的审批流程。 + `plugin.approval.resolve` 涵盖插件定义的审批流程。 #### 其他主要方法族 -- 自动化: - - `wake` 调度立即或下一次 heartbeat 的唤醒文本注入 +- automation: + - `wake` 安排立即或下一次心跳时注入唤醒文本 - `cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、 `cron.run`、`cron.runs` -- Skills/工具:`skills.*`、`tools.catalog`、`tools.effective` +- Skills / 工具:`skills.*`、`tools.catalog`、`tools.effective` ### 常见事件族 -- `chat`:UI 聊天更新,例如 `chat.inject` 和其他仅 transcript 的聊天 - 事件。 -- `session.message` 和 `session.tool`:订阅会话的 transcript/事件流更新。 -- `sessions.changed`:会话索引或元数据已变更。 +- `chat`:UI 聊天更新,例如 `chat.inject` 和其他仅转录的聊天事件。 +- `session.message` 和 `session.tool`:已订阅会话的转录 / 事件流更新。 +- `sessions.changed`:会话索引或元数据已更改。 - `presence`:系统在线状态快照更新。 -- `tick`:周期性 keepalive / 存活事件。 -- `health`:gateway 健康快照更新。 -- `heartbeat`:heartbeat 事件流更新。 -- `cron`:cron 运行/任务变更事件。 -- `shutdown`:gateway 关闭通知。 -- `node.pair.requested` / `node.pair.resolved`:node 配对生命周期。 -- `node.invoke.request`:node invoke 请求广播。 -- `device.pair.requested` / `device.pair.resolved`:配对设备生命周期。 -- `voicewake.changed`:唤醒词触发器配置已变更。 -- `exec.approval.requested` / `exec.approval.resolved`:exec 审批 - 生命周期。 -- `plugin.approval.requested` / `plugin.approval.resolved`:插件审批 - 生命周期。 +- `tick`:周期性保活 / 存活事件。 +- `health`:Gateway 网关健康状态快照更新。 +- `heartbeat`:心跳事件流更新。 +- `cron`:cron 运行 / 任务变更事件。 +- `shutdown`:Gateway 网关关闭通知。 +- `node.pair.requested` / `node.pair.resolved`:节点配对生命周期。 +- `node.invoke.request`:节点 invoke 请求广播。 +- `device.pair.requested` / `device.pair.resolved`:已配对设备生命周期。 +- `voicewake.changed`:唤醒词触发器配置已更改。 +- `exec.approval.requested` / `exec.approval.resolved`:exec 审批生命周期。 +- `plugin.approval.requested` / `plugin.approval.resolved`:插件审批生命周期。 -### Node 辅助方法 +### 节点辅助方法 -- 节点可以调用 `skills.bins`,以获取当前 skill 可执行文件列表, - 用于自动允许检查。 +- 节点可以调用 `skills.bins` 来获取当前 Skills 可执行文件列表,以供自动允许检查使用。 -### Operator 辅助方法 +### operator 辅助方法 -- Operators 可以调用 `tools.catalog`(`operator.read`)来获取某个 - 智能体的运行时工具目录。响应包含分组后的工具和来源元数据: +- operator 可以调用 `tools.catalog`(`operator.read`)来获取某个 agent 的运行时工具目录。响应包含分组后的工具和来源元数据: - `source`:`core` 或 `plugin` - `pluginId`:当 `source="plugin"` 时的插件所有者 - - `optional`:某个插件工具是否为可选 -- Operators 可以调用 `tools.effective`(`operator.read`)来获取某个 - 会话的运行时生效工具清单。 - - `sessionKey` 为必填。 - - gateway 会从会话在服务端派生可信运行时上下文,而不是接受 - 调用方提供的认证或投递上下文。 - - 响应以会话为作用域,并反映当前活动对话此刻可使用的内容, - 包括 core、plugin 和渠道工具。 -- Operators 可以调用 `skills.status`(`operator.read`)来获取某个 - 智能体可见的 skill 清单。 - - `agentId` 为可选;省略时读取默认智能体工作区。 - - 响应包含资格状态、缺失要求、配置检查,以及 - 已清理的安装选项,而不会暴露原始 secret 值。 -- Operators 可以调用 `skills.search` 和 `skills.detail`(`operator.read`)来获取 - ClawHub 发现元数据。 -- Operators 可以调用 `skills.install`(`operator.admin`),支持两种模式: - - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 将某个 - skill 文件夹安装到默认智能体工作区的 `skills/` 目录中。 - - Gateway 安装器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` - 在 gateway 主机上运行一个已声明的 `metadata.openclaw.install` 操作。 -- Operators 可以调用 `skills.update`(`operator.admin`),支持两种模式: - - ClawHub 模式更新某个已跟踪 slug 或默认智能体工作区中的所有已跟踪 ClawHub 安装项。 - - 配置模式修补 `skills.entries.` 的值,例如 `enabled`、 + - `optional`:插件工具是否为可选 +- operator 可以调用 `tools.effective`(`operator.read`)来获取某个会话的运行时生效工具清单。 + - `sessionKey` 是必填项。 + - Gateway 网关从服务端的会话中派生受信任的运行时上下文,而不是接受调用方提供的认证或投递上下文。 + - 响应按会话限定,并反映当前活动对话此刻可用的内容,包括 core、插件和渠道工具。 +- operator 可以调用 `skills.status`(`operator.read`)来获取某个 agent 的可见 Skills 清单。 + - `agentId` 是可选的;省略它可读取默认 agent 工作区。 + - 响应包含资格、缺失要求、配置检查和已清理的安装选项,而不会暴露原始 secret 值。 +- operator 可以调用 `skills.search` 和 `skills.detail`(`operator.read`)来获取 ClawHub 发现元数据。 +- operator 可以通过两种模式调用 `skills.install`(`operator.admin`): + - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 将 skill 文件夹安装到默认 agent 工作区的 `skills/` 目录中。 + - Gateway 网关安装器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` + 在 Gateway 网关宿主机上运行已声明的 `metadata.openclaw.install` 操作。 +- operator 可以通过两种模式调用 `skills.update`(`operator.admin`): + - ClawHub 模式会更新一个被跟踪的 slug,或更新默认 agent 工作区中的所有被跟踪 ClawHub 安装项。 + - 配置模式会修补 `skills.entries.` 值,例如 `enabled`、 `apiKey` 和 `env`。 ## Exec 审批 -- 当某个 exec 请求需要审批时,gateway 会广播 `exec.approval.requested`。 -- Operator 客户端通过调用 `exec.approval.resolve` 来处理(需要 `operator.approvals` scope)。 -- 对于 `host=node`,`exec.approval.request` 必须包含 `systemRunPlan`(规范化的 `argv`/`cwd`/`rawCommand`/会话元数据)。缺少 `systemRunPlan` 的请求会被拒绝。 -- 审批后,被转发的 `node.invoke system.run` 调用会复用该规范化 - `systemRunPlan` 作为权威命令/cwd/会话上下文。 -- 如果调用方在 prepare 与最终获批的 `system.run` 转发之间篡改了 +- 当某个 exec 请求需要审批时,Gateway 网关会广播 `exec.approval.requested`。 +- operator 客户端通过调用 `exec.approval.resolve` 来处理(需要 `operator.approvals` 作用域)。 +- 对于 `host=node`,`exec.approval.request` 必须包含 `systemRunPlan`(规范化的 `argv` / `cwd` / `rawCommand` / 会话元数据)。缺少 `systemRunPlan` 的请求会被拒绝。 +- 审批后,转发的 `node.invoke system.run` 调用会复用该规范化 + `systemRunPlan` 作为权威的命令 / cwd / 会话上下文。 +- 如果调用方在 prepare 与最终获批的 `system.run` 转发之间修改了 `command`、`rawCommand`、`cwd`、`agentId` 或 - `sessionKey`,gateway 会拒绝该运行,而不会信任被篡改的负载。 + `sessionKey`,Gateway 网关将拒绝该运行,而不是信任被修改的负载。 -## 智能体投递回退 +## agent 投递回退 - `agent` 请求可以包含 `deliver=true` 以请求出站投递。 -- `bestEffortDeliver=false` 保持严格行为:未解析或仅内部可用的投递目标会返回 `INVALID_REQUEST`。 -- `bestEffortDeliver=true` 允许在无法解析外部可投递路由时回退为仅会话执行(例如内部/webchat 会话或存在歧义的多渠道配置)。 +- `bestEffortDeliver=false` 保持严格行为:无法解析或仅内部可用的投递目标会返回 `INVALID_REQUEST`。 +- `bestEffortDeliver=true` 允许在无法解析任何外部可投递路由时回退到仅会话执行(例如内部 / webchat 会话或含糊的多渠道配置)。 ## 版本控制 - `PROTOCOL_VERSION` 位于 `src/gateway/protocol/schema.ts`。 - 客户端发送 `minProtocol` + `maxProtocol`;服务器会拒绝不匹配。 -- Schemas + models 从 TypeBox 定义生成: +- Schemas + 模型由 TypeBox 定义生成: - `pnpm protocol:gen` - `pnpm protocol:gen:swift` - `pnpm protocol:check` ## 认证 -- 共享密钥 gateway 认证使用 `connect.params.auth.token` 或 - `connect.params.auth.password`,具体取决于已配置的认证模式。 -- 像 Tailscale Serve - (`gateway.auth.allowTailscale: true`)或非 loopback - `gateway.auth.mode: "trusted-proxy"` 这样的带身份模式,会从 - 请求头而不是 `connect.params.auth.*` 中满足 connect 认证检查。 -- 私有入口的 `gateway.auth.mode: "none"` 会完全跳过共享密钥 connect 认证; - 不要在公开/不可信入口上暴露该模式。 -- 完成配对后,Gateway 网关会签发一个按连接 - 角色 + scopes 限定的**设备 token**。它会在 `hello-ok.auth.deviceToken` 中返回,客户端应将其持久保存,以用于后续连接。 -- 客户端在任何成功连接后都应持久保存主 `hello-ok.auth.deviceToken`。 -- 使用该**已存储**设备 token 重连时,也应复用该 token 已存储的 - 已批准 scope 集。这可以保留之前已授予的读/探测/status 访问权限,并避免在重连时静默收窄为更窄的隐式 admin-only scope。 -- 正常 connect 认证优先级是:显式共享 token/password 优先,其次是显式 `deviceToken`,再其次是按设备存储的 token,最后是 bootstrap token。 -- 额外的 `hello-ok.auth.deviceTokens` 条目是 bootstrap 交接 token。 - 仅当连接使用了 bootstrap 认证且运行在如 `wss://` 或 loopback/本地配对这类可信传输上时,才持久保存它们。 -- 如果客户端提供了**显式** `deviceToken` 或显式 `scopes`,则该 - 调用方请求的 scope 集仍然是权威的;只有当客户端复用已存储的按设备 token 时,才会复用缓存的 scopes。 -- 设备 token 可通过 `device.token.rotate` 和 - `device.token.revoke` 轮换/撤销(需要 `operator.pairing` scope)。 -- Token 签发/轮换始终受限于 - 该设备配对条目中记录的已批准角色集;轮换 token 不能把设备扩展到配对审批从未授予过的角色。 -- 对于配对设备 token 会话,除非调用方还拥有 `operator.admin`,否则设备管理是自作用域的:非管理员调用方只能移除/撤销/轮换**自己的**设备条目。 -- `device.token.rotate` 还会根据调用方当前会话 scopes 检查所请求的 operator scope 集。非管理员调用方不能将 token 轮换为比自己当前持有的更宽的 operator scope 集。 +- 基于共享密钥的 Gateway 网关认证使用 `connect.params.auth.token` 或 + `connect.params.auth.password`,具体取决于配置的认证模式。 +- 携带身份的模式,例如 Tailscale Serve + (`gateway.auth.allowTailscale: true`)或非 loopback 的 + `gateway.auth.mode: "trusted-proxy"`,会通过请求头而不是 `connect.params.auth.*` 满足 connect 认证检查。 +- 私有入口的 `gateway.auth.mode: "none"` 会完全跳过基于共享密钥的 connect 认证;不要在公共 / 不受信任入口上暴露该模式。 +- 配对后,Gateway 网关会发放一个**设备令牌**,其作用域受连接角色 + 作用域限制。它会在 `hello-ok.auth.deviceToken` 中返回,客户端应将其持久化以供未来连接使用。 +- 客户端在任意成功连接后都应持久化主 `hello-ok.auth.deviceToken`。 +- 使用该**已存储**设备令牌重新连接时,也应复用为该令牌存储的已批准作用域集。这可以保留先前已授予的读取 / 探测 / 状态访问权限,并避免重新连接时悄然收缩为更窄的隐式仅管理员作用域。 +- 正常 connect 认证优先级为:显式共享 token / password 优先,然后是显式 `deviceToken`,再然后是按设备存储的令牌,最后是引导令牌。 +- 额外的 `hello-ok.auth.deviceTokens` 条目是引导交接令牌。仅在连接使用了受信任传输(如 `wss://` 或 loopback / 本地配对)并采用引导认证时才持久化它们。 +- 如果客户端提供了**显式** `deviceToken` 或显式 `scopes`,则该调用方请求的作用域集保持权威;只有在客户端复用按设备存储的令牌时,才会复用缓存作用域。 +- 设备令牌可通过 `device.token.rotate` 和 + `device.token.revoke` 轮换 / 撤销(需要 `operator.pairing` 作用域)。 +- 令牌发放 / 轮换始终受该设备配对条目中记录的已批准角色集约束;轮换令牌不能将设备扩展到配对审批从未授予的角色。 +- 对于已配对设备令牌会话,除非调用方还拥有 `operator.admin`,否则设备管理是自限定的:非管理员调用方只能移除 / 撤销 / 轮换其**自己的**设备条目。 +- `device.token.rotate` 还会根据调用方当前会话作用域检查所请求的 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` 的客户端行为: - - 受信任客户端可以使用缓存的按设备 token 尝试一次有界重试。 - - 如果该重试失败,客户端应停止自动重连循环,并向操作员显示后续操作指引。 +- `AUTH_TOKEN_MISMATCH` 的客户端行为: + - 受信任客户端可以尝试使用缓存的按设备令牌进行一次有限重试。 + - 如果该重试失败,客户端应停止自动重连循环,并向 operator 显示需要人工操作的指导。 ## 设备身份 + 配对 -- 节点应包含稳定的设备身份(`device.id`),它来源于 - keypair 指纹。 -- Gateways 按设备 + 角色签发 token。 +- 节点应包含稳定的设备身份(`device.id`),该身份应派生自密钥对指纹。 +- Gateway 网关按设备 + 角色发放令牌。 - 除非启用了本地自动批准,否则新的设备 ID 需要配对审批。 -- 配对自动批准以直接本地 loopback 连接为中心。 -- OpenClaw 还为 - 可信共享密钥辅助流提供了一条狭义的后端/容器本地自连接路径。 -- 同主机 tailnet 或 LAN 连接仍被视为远程配对, - 需要审批。 -- 所有 WS 客户端都必须在 `connect` 时包含 `device` - 身份(operator + node)。 - Control UI 只能在以下模式下省略它: +- 配对自动批准以直接本地 local loopback 连接为中心。 +- OpenClaw 还提供一条狭窄的后端 / 容器本地自连接路径,用于受信任的共享密钥辅助流程。 +- 对 operator 设备的本地自动批准会播种一个受限的按设备令牌基线,而不是持久化任意请求的 operator 作用域。共享密钥会话仍可能比静默发放的设备令牌更宽。 +- 同主机 tailnet 或 LAN 连接在配对上仍视为远程连接,并需要批准。 +- 所有 WS 客户端在 `connect` 期间都必须包含 `device` 身份(operator + node)。 + Control UI 仅可在以下模式中省略它: - `gateway.controlUi.allowInsecureAuth=true`,用于仅 localhost 的不安全 HTTP 兼容。 - 成功的 `gateway.auth.mode: "trusted-proxy"` operator Control UI 认证。 - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(破窗开关,严重降低安全性)。 @@ -531,36 +453,34 @@ Gateway 网关将这些视为**声明**,并在服务端强制执行允许列 ### 设备认证迁移诊断 -对于仍在使用挑战前签名行为的旧版客户端,`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` 与 public key 指纹不匹配。 | -| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | Public key 格式/规范化失败。 | +| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | 签名时间戳超出允许的时钟偏差。 | +| `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` 与公钥指纹不匹配。 | +| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | 公钥格式 / 规范化失败。 | 迁移目标: - 始终等待 `connect.challenge`。 - 对包含服务器 nonce 的 v2 负载进行签名。 - 在 `connect.params.device.nonce` 中发送相同的 nonce。 -- 首选签名负载是 `v3`,它除了 device/client/role/scopes/token/nonce 字段外,还绑定 `platform` 和 `deviceFamily`。 -- 出于兼容性,旧版 `v2` 签名仍然被接受,但配对设备的元数据钉住机制仍会在重连时控制命令策略。 +- 首选签名负载为 `v3`,它除 device / client / role / scopes / token / nonce 字段之外,还绑定 `platform` 和 `deviceFamily`。 +- 出于兼容性,旧版 `v2` 签名仍然被接受,但已配对设备元数据固定仍会在重连时控制命令策略。 -## TLS + pinning +## TLS + 固定 - WS 连接支持 TLS。 -- 客户端可选择钉住 gateway 证书指纹(参见 `gateway.tls` - 配置,以及 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。 +- 客户端可以选择固定 Gateway 网关证书指纹(参见 `gateway.tls` + 配置以及 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。 ## 范围 -该协议暴露了**完整 gateway API**(status、channels、models、chat、 -agent、sessions、nodes、approvals 等)。确切接口由 -`src/gateway/protocol/schema.ts` 中的 TypeBox schemas 定义。 +此协议暴露**完整的 Gateway 网关 API**(status、channels、models、chat、 +agent、sessions、nodes、approvals 等)。其精确接口由 `src/gateway/protocol/schema.ts` 中的 TypeBox schema 定义。