chore(i18n): refresh zh-CN translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-05-01 08:54:45 +00:00
parent ce50b44975
commit 56ed7e6f51
6 changed files with 754 additions and 799 deletions

View File

@ -1,75 +1,75 @@
---
read_when:
- 你需要了解为什么某个 CI 作业运行或没有运行
- 你需要了解 CI 作业为什么运行或没有运行
- 你正在调试一个失败的 GitHub Actions 检查
- 你正在协调发布验证运行或重新运行
summary: CI 作业图、范围门禁、发布总括任务和本地等效命令
- 你正在协调一次发布验证运行或重新运行
summary: CI 作业图、范围门禁、发布总括项和本地命令等价项
title: CI 流水线
x-i18n:
generated_at: "2026-05-01T08:28:40Z"
generated_at: "2026-05-01T08:52:09Z"
model: gpt-5.5
provider: openai
source_hash: fdf65df865a8efcee7b0745b33b5ff633e885823177fb19c9920db37a10c59e4
source_hash: 679913539743f9495fffa010489ec95e05ce875751afa8a93bf8bf7045d6d9de
source_path: ci.md
workflow: 16
---
OpenClaw CI 会在每次推送到 `main` 和每个拉取请求上运行。`preflight` 作业会对差异进行分类,并在只有无关区域发生变更时关闭昂贵的检查通道。手动 `workflow_dispatch` 运行会有意绕过智能范围限定并为候选发布和广泛验证展开完整图。Android 检查通道通过 `include_android` 保持选择性启用。仅发布使用的插件覆盖率位于单独的 [`Plugin Prerelease`](#plugin-prerelease) 工作流中,并且只会从 [`Full Release Validation`](#full-release-validation) 或显式手动分发运行。
OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求时运行。`preflight` 作业会对差异进行分类,并在只有无关区域发生变更时关闭昂贵的通道。手动 `workflow_dispatch` 运行会有意绕过智能作用域划分并为候选发布版本和广泛验证展开完整图。Android 通道通过 `include_android` 保持选择加入。仅发布用的插件覆盖位于单独的 [`Plugin Prerelease`](#plugin-prerelease) 工作流中,并且只会从 [`Full Release Validation`](#full-release-validation) 或显式手动 dispatch 运行。
## 流水线概览
| 作业 | 用途 | 运行时机 |
| 作业 | 用途 | 运行时机 |
| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- |
| `preflight` | 检测仅文档变更、变更范围、变更的扩展,并构建 CI 清单 | 始终在非草稿推送和拉取请求上运行 |
| `security-scm-fast` | 通过 `zizmor` 进行私钥检测和工作流审计 | 始终在非草稿推送和拉取请求上运行 |
| `security-dependency-audit` | 对照 npm 公告执行无依赖的生产 lockfile 审计 | 始终在非草稿推送和拉取请求上运行 |
| `security-fast` | 快速安全作业的必需聚合项 | 始终在非草稿推送和拉取请求上运行 |
| `check-dependencies` | 生产 Knip 仅依赖检查,以及未使用文件 allowlist 保护 | 与 Node 相关的变更 |
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查和可复用下游产物 | Node 相关变更 |
| `checks-fast-core` | 快速 Linux 正确性检查通道,例如内置/插件契约/协议检查 | 与 Node 相关的变更 |
| `checks-fast-contracts-channels` | 分片渠道契约检查,并提供稳定的聚合检查结果 | 与 Node 相关的变更 |
| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和扩展检查通道 | 与 Node 相关的变更 |
| `check` | 分片主本地门禁等价项生产类型、lint、保护项、测试类型和严格冒烟测试 | 与 Node 相关的变更 |
| `check-additional` | 架构、边界、扩展表面保护、包边界和 gateway-watch 分片 | 与 Node 相关的变更 |
| `build-smoke` | 已构建 CLI 冒烟测试和启动内存冒烟测试 | 与 Node 相关的变更 |
| `checks` | 构建产物渠道测试的验证器 | Node 相关变更 |
| `checks-node-compat-node22` | Node 22 兼容性构建和冒烟检查通道 | 用于发布的手动 CI 分发 |
| `check-docs` | 文档格式化、lint 和断链检查 | 文档变更 |
| `skills-python` | 面向 Python 支持的 Skills 的 Ruff + pytest | 与 Python Skills 相关的变更 |
| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时导入说明符回归测试 | 与 Windows 相关的变更 |
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试检查通道 | macOS 相关变更 |
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 |
| `android` | 两种 flavor 的 Android 单元测试,以及一个调试 APK 构建 | 与 Android 相关的变更 |
| `test-performance-agent` | 受信任活动后的每日 Codex 慢测试优化 | 主 CI 成功或手动分发 |
| `preflight` | 检测仅文档变更、变更作用域、变更插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
| `security-scm-fast` | 通过 `zizmor` 检测私钥并审计工作流 | 始终在非草稿推送和 PR 上运行 |
| `security-dependency-audit` | 针对 npm advisories 对生产 lockfile 进行无依赖审计 | 始终在非草稿推送和 PR 上运行 |
| `security-fast` | 快速安全作业的必需聚合项 | 始终在非草稿推送和 PR 上运行 |
| `check-dependencies` | 生产 Knip 仅依赖检查,以及未使用文件 allowlist 防护 | Node 相关变更 |
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查和可复用下游产物 | Node 相关变更 |
| `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件合约/协议检查 | Node 相关变更 |
| `checks-fast-contracts-channels` | 分片的渠道合约检查,并提供稳定的聚合检查结果 | Node 相关变更 |
| `checks-node-core-test` | Core Node 测试分片,不包括渠道、内置、合约和插件通道 | Node 相关变更 |
| `check` | 分片的主本地门禁等价项生产类型、lint、防护、测试类型和严格 smoke | Node 相关变更 |
| `check-additional` | 架构、边界、插件表面防护、包边界和 gateway-watch 分片 | Node 相关变更 |
| `build-smoke` | 已构建 CLI smoke 测试和启动内存 smoke | Node 相关变更 |
| `checks` | 构建产物渠道测试的验证器 | Node 相关变更 |
| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 通道 | 发布用的手动 CI dispatch |
| `check-docs` | 文档格式化、lint 和断链检查 | 文档变更 |
| `skills-python` | Python 支持的 Skills 的 Ruff + pytest | Python Skill 相关变更 |
| `checks-windows` | Windows 专用进程/路径测试,以及共享运行时 import specifier 回归 | Windows 相关变更 |
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 |
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 |
| `android` | 两种 flavor 的 Android 单元测试,加一次 debug APK 构建 | Android 相关变更 |
| `test-performance-agent` | 可信活动后的每日 Codex 慢测试优化 | Main CI 成功或手动 dispatch |
## 快速失败顺序
1. `preflight` 决定哪些检查通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业中的步骤,不是独立作业。
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,无需等待更重的产物和平台矩阵作业。
3. `build-artifacts` 与快速 Linux 检查通道重叠运行,因此下游消费者可以在共享构建就绪后立即开始。
4. 更重的平台和运行时检查通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`
1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业内部的步骤,而不是独立作业。
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,等待更重的产物和平台矩阵作业。
3. `build-artifacts` 与快速 Linux 通道重叠运行,因此下游消费者可以在共享构建就绪后立即开始。
4. 更重的平台和运行时通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`
同一个拉取请求或 `main` ref 上有更新的推送落地GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已经被取代后继续排队。自动 CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸任务不会无限期阻塞较新的 main 运行。手动完整套件运行使用 `CI-manual-v1-*`,并且不会取消正在运行的任务
较新的推送落到同一个 PR 或 `main` ref 上GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但在整个工作流已经被取代后不会再排队。自动 CI 并发键带版本号(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸任务无法无限期阻塞新的 main 运行。手动完整套件运行使用 `CI-manual-v1-*`,且不会取消进行中的运行
## 范围与路由
## 作用域与路由
范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动分发会跳过变更范围检测,并让 preflight 清单表现得像每个有范围的区域都发生了变更
作用域逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动 dispatch 会跳过 changed-scope 检测,并让 preflight 清单表现得像每个有作用域的区域都已变更一样
- **CI 工作流编辑** 会验证 Node CI 图和工作流 lint但不会单独强制 Windows、Android 或 macOS 原生构建;这些平台检查通道仍限定于平台源代码变更
- **仅 CI 路由编辑、选定的廉价核心测试 fixture 编辑,以及窄范围插件契约 helper/test-routing 编辑** 使用快速仅 Node 清单路径:`preflight`、security 和单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接覆盖的路由或 helper 表面时此路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外保护矩阵。
- **Windows Node 检查** 范围限定于 Windows 特定的进程/路径包装器、npm/pnpm/UI runner helper、包管理器配置以及执行该检查通道的 CI 工作流表面;无关源代码、插件、install-smoke 和仅测试变更仍走 Linux Node 检查通道
- **CI 工作流编辑** 会验证 Node CI 图和工作流 lint它们本身不会强制运行 Windows、Android 或 macOS 原生构建;这些平台通道仍仅按平台源代码变更划定作用域
- **仅 CI 路由编辑、选定的廉价 core-test fixture 编辑,以及狭窄的插件合约 helper/test-routing 编辑** 会使用快速的仅 Node 清单路径:`preflight`、security 和单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接执行的路由或 helper 表面时该路径会跳过构建产物、Node 22 兼容性、渠道合约、完整 core 分片、内置插件分片以及额外防护矩阵。
- **Windows Node 检查** 仅限于 Windows 专用进程/路径 wrapper、npm/pnpm/UI runner helper、包管理器配置以及执行该通道的 CI 工作流表面无关源代码、插件、install-smoke 和仅测试变更会留在 Linux Node 通道上
最慢的 Node 测试族会被拆分或均衡,使每个作业保持较小规模而不会过度预留 runner渠道契约作为三个加权分片运行小型核心单元检查通道会配对auto-reply 作为四个均衡 worker 运行reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片agentic Gateway 网关/插件配置分布在现有的仅源码 agentic Node 作业中而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用其专用 Vitest 配置,而不是共享的插件 catch-all。include-pattern 分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和过滤的分片。`check-additional` 将 package-boundary compile/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖率分开边界保护分片会在一个作业内并发运行其小型独立保护项。Gateway 网关 watch、渠道测试和核心支持边界分片会在 `dist/``dist-runtime/` 已构建后,在 `build-artifacts` 内并发运行。
最慢的 Node 测试族会被拆分或平衡,使每个作业保持较小规模且不过度预留 runner渠道合约以三个加权分片运行小型 core 单元通道会配对auto-reply 以四个均衡 worker 运行reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片agentic 网关/插件配置会分布到现有的仅源代码 agentic Node 作业中而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件 catch-all。Include-pattern 分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和经过过滤的分片。`check-additional` 将 package-boundary 编译/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖分开boundary guard 分片在一个作业内并发运行其小型独立防护。Gateway watch、渠道测试和 core support-boundary 分片会在 `dist/``dist-runtime/`构建完成后,在 `build-artifacts` 内并发运行。
Android CI 会运行 `testPlayDebugUnitTest``testThirdPartyDebugUnitTest`,然后构建 Play 调试 APK。third-party flavor 没有单独的源集或清单;它的单元测试检查通道仍会使用 SMS/call-log BuildConfig 标志编译该 flavor同时避免在每次 Android 相关推送上重复执行调试 APK 打包作业。
Android CI 会运行 `testPlayDebugUnitTest``testThirdPartyDebugUnitTest`,然后构建 Play debug APK。third-party flavor 没有单独的源代码集或 manifest它的单元测试通道仍会使用 SMS/call-log BuildConfig 标志编译该 flavor同时避免在每次 Android 相关推送上重复执行 debug APK 打包作业。
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(一个生产 Knip 仅依赖检查,固定到最新 Knip 版本,并为 `dlx` 安装禁用 pnpm 的最小发布年龄)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现结果`scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当拉取请求新增未审查的未使用文件,或留下过期 allowlist 条目时,未使用文件保护会失败,同时保留 Knip 无法静态解析的有意动态插件、生成文件、构建、实时测试和包桥接表面。
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(一个固定到最新 Knip 版本的生产 Knip 仅依赖检查,并在 `dlx` 安装时禁用 pnpm 的最短发布年龄限制)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现与 `scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 添加新的未经审查的未使用文件,或留下过期的 allowlist 条目时,未使用文件防护会失败,同时保留 Knip 无法静态解析的有意动态插件、生成文件、构建、实时测试和包桥接表面。
## 手动分发
## 手动 dispatch
手动 CI 分发运行与正常 CI 相同的作业图,但会强制启用每个非 Android 范围检查通道Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立手动 CI 分发仅在 `include_android=true` 时运行 Android完整发布伞形工作流通过传入 `include_android=true` 启用 Android。插件预发布静态检查、仅发布使用的 `agentic-plugins` 分片、完整扩展批量扫描,以及插件预发布 Docker 检查通道都不包含在 CI 中。Docker 预发布套件仅在 `Full Release Validation` 以启用 release-validation 门禁的方式分发单独的 `Plugin Prerelease` 工作流时运行。
手动 CI dispatch 会运行与普通 CI 相同的作业图,但会强制开启每个非 Android 作用域通道Linux Node 分片、内置插件分片、渠道合约、Node 22 兼容性、`check`、`check-additional`、build smoke、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立手动 CI dispatch 只有在 `include_android=true` 时才运行 Android完整发布伞工作流会通过传入 `include_android=true` 启用 Android。插件预发布静态检查、仅发布用的 `agentic-plugins` 分片、完整插件批量扫描以及插件预发布 Docker 通道会被排除在 CI 之外。Docker 预发布套件仅在 `Full Release Validation` 以启用 release-validation 门禁的方式 dispatch 单独的 `Plugin Prerelease` 工作流时运行。
手动运行使用唯一并发组,因此候选发布完整套件不会被同一 ref 上的另一个推送或拉取请求运行取消。可选的 `target_ref` 输入允许受信任调用方针对分支、标签或完整提交 SHA 运行该图,同时使用所选分发 ref 中的工作流文件。
手动运行使用唯一的并发组,因此候选发布版本的完整套件不会被同一 ref 上的其他推送或 PR 运行取消。可选的 `target_ref` 输入让可信调用者可以针对分支、标签或完整提交 SHA 运行该图,同时使用所选 dispatch ref 中的工作流文件。
```bash
gh workflow run ci.yml --ref release/YYYY.M.D
@ -77,17 +77,17 @@ gh workflow run ci.yml --ref main -f target_ref=<branch-or-sha> -f include_andro
gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>
```
## 运行器
## Runners
| 运行器 | 作业 |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ubuntu-24.04` | `preflight`、快速安全作业和聚合项(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片和聚合项、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-responseinstall-smoke 预检也使用 GitHub 托管的 Ubuntu以便 Blacksmith 矩阵可以更早排队 |
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、较轻量的插件分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` |
| `ubuntu-24.04` | `preflight`、快速安全作业和聚合项(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片和聚合项、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-responseinstall-smoke 预检也使用 GitHub 托管的 Ubuntu这样 Blacksmith 矩阵可以更早排队 |
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、较低负载的插件分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` |
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` |
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感8 vCPU 节省的时间抵不过成本install-smoke Docker 构建32-vCPU 的排队时间成本抵不过节省的时间) |
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,以至于 8 vCPU 的成本高于节省的时间install-smoke Docker 构建32-vCPU 的排队时间成本高于节省的时间) |
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`fork 回退到 `macos-latest` |
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`fork 回退到 `macos-latest` |
| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`分叉仓库回退到 `macos-latest` |
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`分叉仓库回退到 `macos-latest` |
## 本地等效命令
@ -117,27 +117,27 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
## 完整发布验证
`Full Release Validation` 是“发布前运行全部检查”的手动总控工作流。它接受分支、标签或完整提交 SHA并以该目标分发手动 `CI` 工作流,分发 `Plugin Prerelease` 以提供仅发布相关的插件/包/静态/Docker 证明,并分发 `OpenClaw Release Checks` 以运行安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道。当提供已发布包规格时,它还可以运行发布后的 `NPM Telegram Beta E2E` 工作流。
`Full Release Validation` 是“发布前运行所有内容”的手动总括工作流。它接受分支、标签或完整提交 SHA使用该目标派发手动 `CI` 工作流,派发 `Plugin Prerelease` 以提供仅发布所需的插件/包/静态/Docker 验证,并派发 `OpenClaw Release Checks` 以执行安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道。当提供已发布的包规格时,它也可以运行发布后的 `NPM Telegram Beta E2E` 工作流。
请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、确切工作流作业名称、配置差异、构件以及聚焦重跑入口
请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、确切的工作流作业名称、配置文件差异、工件以及聚焦重跑句柄
`release_profile` 控制传入发布检查的 live/提供商覆盖范围。手动发布工作流默认使用 `stable`;仅在你有意需要广泛的建议性提供商/媒体矩阵时使用 `full`
`release_profile` 控制传入发布检查的 live/提供商覆盖范围。手动发布工作流默认使用 `stable`;仅在你有意需要宽范围的咨询性提供商/媒体矩阵时才使用 `full`
- `minimum` 保留最快的 OpenAI/核心发布关键通道。
- `stable` 添加稳定的提供商/后端集合。
- `full` 运行广泛的建议性提供商/媒体矩阵。
- `full` 运行宽范围的咨询性提供商/媒体矩阵。
该总控工作流会记录已分发的子运行 ID最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果某个子工作流重跑后变绿,只需重跑父验证器作业,即可刷新总控结果和耗时摘要。
这个总括工作流会记录派发出的子运行 ID最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行附加最慢作业表。如果某个子工作流重跑后变绿,只需重跑父级验证器作业,以刷新总括结果和耗时摘要。
对于恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。发布候选使用 `all`,仅正常完整 CI 子项使用 `ci`,仅插件预发布子项使用 `plugin-prerelease`,所有发布子项使用 `release-checks`,或在总控工作流上使用更窄的组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这会在聚焦修复后,把失败的发布环境重跑限制在有界范围内
恢复`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。发布候选使用 `all`,仅普通完整 CI 子项使用 `ci`,仅插件预发布子项使用 `plugin-prerelease`,每个发布子项使用 `release-checks`,或者在总括工作流上使用更窄的组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样可以在聚焦修复后将失败发布框的重跑范围限定住
`OpenClaw Release Checks` 使用受信任的工作流 ref将所选 ref 一次性解析为 `release-package-under-test` tarball然后将该构件同时传递给 live/E2E 发布路径 Docker 工作流和包验收分片。这样可以让发布环境之间的包字节保持一致,并避免在多个子作业中重复打包同一个候选版本。
`OpenClaw Release Checks` 使用受信任的工作流引用将所选引用解析一次为 `release-package-under-test` tarball然后将该工件传递给 live/E2E 发布路径 Docker 工作流和包验收分片。这使发布框之间的包字节保持一致,并避免在多个子作业中重新打包同一个候选版本。
针对 `ref=main``rerun_group=all` 的重复 `Full Release Validation` 运行会取代较旧的总控运行。父监视器在父运行被取消时会取消它已经分发的任何子工作流,因此较新的 main 验证不会被陈旧的两小时发布检查运行阻塞。发布分支/标签验证和聚焦重跑组保持 `cancel-in-progress: false`
对于 `ref=main``rerun_group=all` 的重复 `Full Release Validation` 运行,会由较新的总括运行取代较旧的运行。父级监视器在父级被取消时,会取消它已经派发的任何子工作流,因此较新的 main 验证不会排在过期的两小时发布检查运行之后。发布分支/标签验证和聚焦重跑组会保持 `cancel-in-progress: false`
## Live 和 E2E 分片
发布 live/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 作为命名分片运行,而不是一个串行作业
发布 live/E2E 子项保留宽范围的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 以命名分片运行,而不是作为一个串行作业运行
- `native-live-src-agents`
- `native-live-src-gateway-core`
@ -149,35 +149,35 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
- `native-live-extensions-openai`
- `native-live-extensions-o-z-other`
- `native-live-extensions-xai`
- 拆分的媒体音频/视频分片,以及提供商过滤的音乐分片
- 拆分的媒体音频/视频分片提供商过滤的音乐分片
会保持相同的文件覆盖范围,同时让缓慢的 live 提供商失败更容易重跑和诊断。聚合 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。
在保持相同文件覆盖的同时,让缓慢的 live 提供商失败更容易重跑和诊断。聚合分片名称 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 仍可用于手动一次性重跑。
原生 live 媒体分片运行`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预装了 `ffmpeg``ffprobe`;媒体作业只会在设置前验证这些二进制文件。将 Docker 支的 live 套件保留在普通 Blacksmith 运行器上,容器作业不适合启动嵌套 Docker 测试。
原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预装了 `ffmpeg``ffprobe`;媒体作业只会在设置前验证这些二进制文件。将 Docker 支的 live 套件保留在普通 Blacksmith 运行器上,因为容器作业不适合启动嵌套 Docker 测试。
Docker 支撑的 live 模型/后端分片会为每个所选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流会先构建并推送该镜像一次,然后 Docker live 模型、提供商分片 Gateway 网关、CLI 后端、ACP 绑定和 Codex harness 分片会带着 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片在脚本级携带明确的 `timeout` 上限,低于工作流作业超时,以便卡住的容器或清理路径快速失败,而不是耗尽整个发布检查预算。如果这些分片独立重建完整源 Docker 目标,则发布运行配置有误,并会在重复镜像构建上浪费实际耗时
Docker 支持的 live 模型/后端分片为每个所选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流构建并推送该镜像一次,然后 Docker live 模型、提供商分片 Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片都会以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片带明确的脚本级 `timeout` 上限,低于工作流作业超时,因此卡住的容器或清理路径会快速失败,而不是消耗整个发布检查预算。如果这些分片独立重建完整源 Docker 目标,则说明发布运行配置错误,并会在重复镜像构建上浪费墙钟时间
## 包验收
当问题是“这个可安装的 OpenClaw 包作为产品能否正常工作?”时,使用 `Package Acceptance`。它不同于普通 CI普通 CI 验证源码树,而包验收通过用户安装或更新后使用的同一个 Docker E2E harness 验证单个 tarball。
当问题是“这个可安装的 OpenClaw 包是否作为产品正常工作?”时,使用 `Package Acceptance`。它不同于普通 CI普通 CI 验证源码树,而包验收通过用户安装或更新后实际使用的同一个 Docker E2E harness 验证单个 tarball。
### 作业
1. `resolve_package` 检出 `workflow_ref`,解析一个包候选项,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 构件上传,并在 GitHub 步骤摘要中打印来源、工作流引用、包引用、版本、SHA-256 和配置。
2. `docker_acceptance` 调用 `openclaw-live-and-e2e-checks-reusable.yml`,并传入 `ref=workflow_ref``package_artifact_name=package-under-test`。可复用工作流会下载该构件,验证 tarball 清单,在需要时准备包摘要 Docker 镜像,并针对该包运行选定的 Docker 运行道,而不是打包工作流检出内容。当某个配置选择多个定向 `docker_lanes` 时,可复用工作流会准备一次包和共享镜像,然后将这些运行道展开为并行的定向 Docker 作业,并使用唯一构件
3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果 Package Acceptance 已解析出一个包,它会安装同一个 `package-under-test` 构件;独立 Telegram 调度仍可安装已发布的 npm 规格。
4. 如果包解析、Docker 验收或可选 Telegram 运行道失败,`summary` 会让工作流失败。
1. `resolve_package` 检出 `workflow_ref`,解析一个软件包候选项,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 制品上传,并在 GitHub 步骤摘要中打印来源、工作流引用、软件包引用、版本、SHA-256 和配置
2. `docker_acceptance` 使用 `ref=workflow_ref``package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该制品,验证压缩包清单,在需要时准备 package-digest Docker 镜像,并针对该软件包运行所选 Docker 线路,而不是打包工作流检出内容。当某个配置档选择多个目标 `docker_lanes` 时,可复用工作流会一次性准备软件包和共享镜像,然后将这些线路分发为并行的目标 Docker 作业,并为它们生成唯一制品
3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果 Package Acceptance 解析出了软件包,它会安装同一个 `package-under-test` 制品;独立的 Telegram 调度仍可安装已发布的 npm 规格。
4. 如果软件包解析、Docker 验收或可选 Telegram 线路失败,`summary` 会让工作流失败。
### 候选来源
- `source=npm` 接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将其用于已发布 beta/稳定版验收。
- `source=npm` 接受 `openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将其用于已发布 beta/稳定版验收。
- `source=ref` 会打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证所选提交可从仓库分支历史或发布标签到达,在分离工作树中安装依赖,并使用 `scripts/package-openclaw-for-docker.mjs` 打包。
- `source=url` 下载 HTTPS `.tgz`;必须提供 `package_sha256`
- `source=artifact``artifact_run_id``artifact_name` 下载一个 `.tgz``package_sha256` 是可选的,但对于外部共享构件应提供。
- `source=artifact``artifact_run_id``artifact_name` 下载一个 `.tgz``package_sha256` 可选,但对于外部共享的制品应提供。
保持 `workflow_ref``package_ref` 分离。`workflow_ref` 是运行测试的受信任工作流/测试框架代码。`package_ref` 是 `source=ref` 时会被打包的源提交。这样当前测试框架就能验证较旧的受信任源提交,而无需运行旧的工作流逻辑。
保持 `workflow_ref``package_ref` 分离。`workflow_ref` 是运行测试的受信任工作流/测试框架代码。`package_ref` 是 `source=ref` 时会被打包的源提交。这样当前测试框架就能验证较旧的受信任源提交,而运行旧的工作流逻辑。
### 套件配置
### 套件配置
- `smoke``npm-onboard-channel-agent`、`gateway-network`、`config-reload`
- `package``npm-onboard-channel-agent`、`doctor-switch`、`update-channel-switch`、`upgrade-survivor`、`published-upgrade-survivor`、`bundled-channel-deps-compat`、`plugins-offline`、`plugin-update`
@ -185,21 +185,21 @@ Docker 支撑的 live 模型/后端分片会为每个所选提交使用单独的
- `full` — 带 OpenWebUI 的完整 Docker 发布路径分块
- `custom` — 精确的 `docker_lanes`;当 `suite_profile=custom` 时必需
`package` 配置使用离线插件覆盖,因此已发布包验证不会受实时 ClawHub 可用性限制。可选 Telegram 运行道会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 构件,同时保留已发布 npm 规格路径以供独立调度使用。
`package` 配置使用离线插件覆盖,因此已发布软件包验证不会受实时 ClawHub 可用性限制。可选 Telegram 线路会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 制品,并保留已发布 npm 规格路径以供独立调度使用。
发布检查调用 Package Acceptance并使用 `source=ref`、`package_ref=<release-ref>`、`workflow_ref=<release workflow ref>`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai`。发布路径 Docker 分块覆盖重叠的包/更新/插件运行道Package Acceptance 会针对同一个已解析的包 tarball 保留构件原生的内置渠道兼容性、离线插件和 Telegram 证明。跨操作系统发布检查仍覆盖操作系统特定的新手引导、安装器和平台行为;包/更新产品验证应从 Package Acceptance 开始。`published-upgrade-survivor` Docker 运行道每次运行验证一个已发布包基线。在 Package Acceptance 中,解析出的 `package-under-test` tarball 始终是候选项,`published_upgrade_survivor_baseline` 选择回退的已发布基线,默认值为 `openclaw@latest`;失败运行道的重跑命令会保留该基线。设置 `published_upgrade_survivor_baselines=release-history` 可将该运行道扩展到去重后的历史矩阵:最新六个稳定版本、`2026.4.23`,以及 `2026-03-15` 之前的最新稳定版本。设置 `published_upgrade_survivor_scenarios=reported-issues` 可将同一组基线扩展到按 issue 形态构建的夹具,覆盖 Feishu 配置/运行时依赖、保留的 bootstrap/persona 文件、波浪号日志路径,以及过期的带版本运行时依赖根目录。本地聚合运行可以通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确包规格,使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保持单个运行道,例如 `openclaw@2026.4.15`,或设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS`启用场景矩阵。已发布运行道通过内置的 `openclaw config set` 命令配方配置基线,将配方步骤记录到 `summary.json`,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC 状态。Windows 打包和安装器全新运行道还会验证已安装包可以从原始绝对 Windows 路径导入 browser-control 覆盖。OpenAI 跨操作系统智能体回合冒烟在设置 `OPENCLAW_CROSS_OS_OPENAI_MODEL` 时默认使用它,否则使用 `openai/gpt-5.4-mini`,因此安装和 Gateway 网关证明保持快速且确定。
发布检查会以 `source=ref`、`package_ref=<release-ref>`、`workflow_ref=<release workflow ref>`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai` 调用 Package Acceptance。发布路径 Docker 分块覆盖重叠的软件包/更新/插件线路Package Acceptance 会针对同一个已解析软件包压缩包保留制品原生的内置渠道兼容性、离线插件和 Telegram 证明。Cross-OS 发布检查仍覆盖特定操作系统的新手引导、安装器和平台行为;软件包/更新产品验证应从 Package Acceptance 开始。`published-upgrade-survivor` Docker 线路会在每次运行中验证一个已发布软件包基线。在 Package Acceptance 中,已解析的 `package-under-test` 压缩包始终是候选项,`published_upgrade_survivor_baseline` 选择回退的已发布基线,默认值为 `openclaw@latest`;失败线路的重跑命令会保留该基线。设置 `published_upgrade_survivor_baselines=release-history` 可将该线路扩展到去重后的历史矩阵:最新六个稳定版本、`2026.4.23`,以及 `2026-03-15` 之前的最新稳定版本。设置 `published_upgrade_survivor_scenarios=reported-issues` 可将同一组基线扩展到问题形状的夹具,覆盖 Feishu 配置/运行时依赖、保留的 bootstrap/persona 文件、波浪号日志路径,以及陈旧的带版本运行时依赖根。局部聚合运行可以使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确软件包规格,使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保持单一线路,例如 `openclaw@2026.4.15`,或设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS`使用场景矩阵。已发布线路会用内置的 `openclaw config set` 命令配方配置基线,在 `summary.json` 中记录配方步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC 状态。Windows 打包版和安装器全新线路还会验证已安装软件包可以从原始 Windows 绝对路径导入 browser-control 覆盖。OpenAI 跨操作系统 agent-turn 冒烟测试在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4-mini`,从而让安装和 Gateway 网关证明保持快速且确定。
### 旧版兼容窗口
Package Acceptance 对已发布包有受限的旧版兼容窗口。直到 `2026.4.25` 的包(包括 `2026.4.25-beta.*`)可使用兼容路径:
Package Acceptance 对已经发布的软件包有有界的旧版兼容窗口。到 `2026.4.25` 为止的软件包,包括 `2026.4.25-beta.*`,可以使用兼容路径:
- `dist/postinstall-inventory.json` 中已知的私有 QA 条目可以指向 tarball 省略的文件;
- 当包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过持久化子用例;
- `update-channel-switch` 可以从 tarball 派生的假 git 夹具中剪除缺失的 `pnpm.patchedDependencies`,并可记录缺失的持久化 `update.channel`
- 插件冒烟可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化;
- `dist/postinstall-inventory.json` 中已知的私有 QA 条目可以指向压缩包省略的文件;
- 当软件包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过持久化子用例;
- `update-channel-switch` 可以从压缩包派生的伪 git 夹具中裁剪缺失的 `pnpm.patchedDependencies`,并可记录缺失的持久化 `update.channel`
- 插件冒烟测试可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化;
- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和不重新安装行为保持不变。
已发布的 `2026.4.26` 包也可能会对已经发布的本地构建元数据戳文件发出警告。更晚的包必须满足现代契约;相同条件会失败,而不是警告或跳过。
已发布的 `2026.4.26` 软件包也可以对已随包发布的本地构建元数据戳文件发出警告。之后的软件包必须满足现代契约;相同条件会失败,而不是警告或跳过。
### 示例
@ -242,111 +242,111 @@ gh workflow run package-acceptance.yml \
-f docker_lanes='install-e2e plugin-update'
```
调试失败的包验收运行时,先从 `resolve_package` 摘要开始,确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 构件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、运行道日志、阶段耗时和重跑命令。优先重跑失败的包配置或精确 Docker 运行道,而不是重跑完整发布验证。
调试失败的软件包验收运行时,先查看 `resolve_package` 摘要,确认软件包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 制品:`.artifacts/docker-tests/**/summary.json`、`failures.json`、线路日志、阶段耗时和重跑命令。优先重跑失败的软件包配置档或精确 Docker 线路,而不是重跑完整发布验证。
## 安装冒烟
## 安装冒烟测试
单独的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke``run_full_install_smoke`
单独的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke``run_full_install_smoke`
- **快速路径** 会在 pull request 触及 Docker/包表面、内置插件包/清单变更,或 Docker 冒烟作业覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会占用 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI运行 agents delete shared-workspace CLI 冒烟,运行容器 gateway-network e2e,验证内置扩展构建参数,并在 240 秒聚合命令超时内运行有界的内置插件 Docker 配置(每个场景的 Docker 运行单独设上限)。
- **完整路径** 保留 QR 包安装以及安装器 Docker/更新覆盖用于夜间定时运行、手动调度、workflow-call 发布检查,以及真正触及安装器/包/Docker 表面的 pull request。在完整模式下install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关冒烟、安装器/更新冒烟,以及快速内置插件 Docker E2E 作为独立作业运行,这样安装器工作不会排在根镜像冒烟之后等待。
- **快速路径**会在拉取请求触及 Docker/软件包表面、内置插件软件包/清单变更,或 Docker 冒烟作业会执行的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会占用 Docker 工作器。快速路径会构建一次根 Dockerfile 镜像,检查 CLI运行 agents delete shared-workspace CLI 冒烟测试,运行容器 gateway-network 端到端测试,验证内置扩展构建参数,并在 240 秒聚合命令超时内运行有界的内置插件 Docker 配置(每个场景的 Docker 运行单独设上限)。
- **完整路径**会为夜间定时运行、手动调度、workflow-call 发布检查,以及真正触及安装器/软件包/Docker 表面的拉取请求保留 QR 软件包安装和安装器 Docker/更新覆盖。在完整模式中install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 软件包安装、根 Dockerfile/Gateway 网关冒烟测试、安装器/更新冒烟测试,以及快速内置插件 Docker E2E 作为单独作业运行,使安装器工作不会排在根镜像冒烟测试之后等待。
`main` 推送(包括合并提交)不会强制完整路径;当变更范围逻辑在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟,并将完整安装冒烟留给夜间或发布验证。
`main` 推送(包括合并提交)不会强制完整路径;当变更范围逻辑在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟测试,并将完整安装冒烟测试留给夜间或发布验证。
较慢的 Bun 全局安装 image-provider 冒烟由 `run_bun_global_install_smoke` 单独控制。它会在夜间计划和发布检查工作流中运行,手动 `Install Smoke` 调度可以选择启用它,但 pull request 和 `main` 推送不会启用。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。
较慢的 Bun 全局安装 image-provider 冒烟测试`run_bun_global_install_smoke` 单独控制。它会在夜间计划任务和发布检查工作流中运行,手动 `Install Smoke` 调度也可以选择启用它,但拉取请求和 `main` 推送不会运行它。QR 和安装器 Docker 测试保留各自专注安装的 Dockerfile。
## 本地 Docker E2E
`pnpm test:docker:all` 预构建一个共享实时测试镜像,将 OpenClaw 打包一次为 npm tarball并构建两个共享的 `scripts/e2e/Dockerfile` 镜像:
`pnpm test:docker:all` 预构建一个共享实时测试镜像,将 OpenClaw 打包一次为 npm 压缩包,并构建两个共享 `scripts/e2e/Dockerfile` 镜像:
- 用于安装器/更新/插件依赖运行道的裸 Node/Git 运行器;
- 一个功能镜像,会将同一个 tarball 安装到 `/app`,用于普通功能运行道
- 一个用于安装器/更新/插件依赖线路的裸 Node/Git 运行器;
- 一个将同一压缩包安装到 `/app` 的功能镜像,用于普通功能线路
Docker 运行道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,运行器只执行选计划。调度器使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE``OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每个运行道选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行运行道
Docker 线路定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,运行器只执行选计划。调度器使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE``OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每条线路选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行线路
### 可调
### 可调参数
| 变量 | 默认值 | 用途 |
| -------------------------------------- | ------ | --------------------------------------------------------------------------------------------- |
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通 lane 的主池槽位数量。 |
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 对提供商敏感的尾池槽位数。 |
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发 live lane 上限,避免提供商限流。 |
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm install lane 上限。 |
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务 lane 上限。 |
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | lane 启动之间的错峰间,用于避免 Docker 守护进程创建风暴;设为 `0` 表示不做错峰。 |
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每个 lane 的兜底超时120 分钟);选定的 live/tail lane 使用更严格的上限。 |
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | 未设置 | `1` 会打印调度器计划,而不运行 lane。 |
| `OPENCLAW_DOCKER_ALL_LANES` | 未设置 | 逗号分隔的精确 lane 列表;跳过清理 smoke以便智能体复现某个失败的 lane。 |
| 变量 | 默认值 | 用途 |
| -------------------------------------- | ------- | ---------------------------------------------------------------------------------------------- |
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 常规 lane 的主池槽位数。 |
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 对提供商敏感的尾池槽位数。 |
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发实时 lane 上限,避免提供商限流。 |
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm 安装 lane 上限。 |
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务 lane 上限。 |
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | lane 启动之间的错峰间,用于避免 Docker 守护进程创建风暴;设为 `0` 表示不做错峰。 |
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每个 lane 的兜底超时120 分钟);选定的实时/尾部 lane 使用更严格的上限。 |
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 会打印调度器计划,但不运行 lane。 |
| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗号分隔的精确 lane 列表;跳过清理冒烟测试,以便智能体复现某个失败 lane。 |
比其有效上限更重的 lane 仍可从空池启动,然后独占运行,直到释放容量。本地聚合会预检 Docker移除过期的 OpenClaw E2E 容器,输出活跃 lane Status持久化 lane 耗时以便按最长优先排序,并且默认在首次失败后停止调度新的池化 lane。
比其有效上限更重的 lane 仍然可以从空池启动,然后独占运行,直到它释放容量。本地聚合会预检 Docker、移除陈旧的 OpenClaw E2E 容器、输出活动 lane 状态、持久化 lane 用时以便按最长优先排序,并且默认在第一次失败后停止调度新的池化 lane。
### 可复用 live/E2E 工作流
### 可复用的实时/E2E 工作流
可复用 live/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些包、镜像类型、live 镜像、lane 和凭证覆盖范围。随后 `scripts/docker-e2e.mjs` 会把该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw,或下载当前运行的包产物,或从 `package_artifact_run_id` 下载包产物;校验 tarball 清单;当计划需要已安装包的 lane 时,通过 Blacksmith 的 Docker 层缓存构建并推送带包摘要标签的 bare/functional GHCR Docker E2E 镜像;并且复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有包摘要镜像而不是重新构建。Docker 镜像拉取会每次尝试 180 秒的有界超时进行重试,这样卡住的 registry/cache 流会快速重试,而不会消耗大部分 CI 关键路径时间
可复用的实时/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些包、镜像类型、实时镜像、lane 和凭证覆盖范围。随后 `scripts/docker-e2e.mjs` 会把该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw、下载当前运行的包构件,或从 `package_artifact_run_id` 下载包构件;验证 tarball 清单;当计划需要已安装包的 lane 时,通过 Blacksmith 的 Docker 层缓存构建并推送带包摘要标签的 bare/functional GHCR Docker E2E 镜像;并且复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有包摘要镜像而不是重新构建。Docker 镜像拉取会使用每次尝试 180 秒的有界超时进行重试,这样卡住的 registry/cache 流会快速重试,而不是消耗大部分 CI 关键路径
### 发布路径分块
发布 Docker 覆盖会使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行更小的分块作业,这样每个分块只拉取它需要的镜像类型,并通过同一个加权调度器执行多个 lane
发布 Docker 覆盖会运行更小的分块作业,并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1`,使每个分块只拉取它需要的镜像类型,并通过同一个加权调度器执行多个 lane
- `OPENCLAW_DOCKER_ALL_PROFILE=release-path`
- `OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h | bundled-channels`
当前发布 Docker 分块包括 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a``plugins-runtime-install-h`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b` 和 `bundled-channels-contracts`。聚合的 `bundled-channels` 分块仍可用于手动一次性重跑,`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 也仍保留为聚合插件/运行时别名。`install-e2e` lane 别名仍是两个提供商安装器 lane 的聚合手动重跑别名。`bundled-channels` 分块运行拆分后的 `bundled-channel-*``bundled-channel-update-*` lane而不是串行的一体 `bundled-channel-deps` lane。
当前发布 Docker 分块包括 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a` 到 `plugins-runtime-install-h`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b` 和 `bundled-channels-contracts`。聚合的 `bundled-channels` 分块仍可用于手动一次性重跑,`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍作为聚合的插件/运行时别名保留。`install-e2e` lane 别名仍然是两个提供商安装器 lane 的聚合手动重跑别名。`bundled-channels` 分块运行拆分后的 `bundled-channel-*``bundled-channel-update-*` lane而不是串行的一体 `bundled-channel-deps` lane。
当完整发布路径覆盖请求 OpenWebUI 时,OpenWebUI 会并入 `plugins-runtime-services`,并且仅为 OpenWebUI 专用调度保留独立的 `openwebui` 分块。内置渠道更新 lane 会针对短暂的 npm 网络故障重试一次。
当完整发布路径覆盖请求 OpenWebUI 时,它会被并入 `plugins-runtime-services`;只有 OpenWebUI 专用调度才保留独立的 `openwebui` 分块。内置渠道更新 lane 会针对临时性 npm 网络失败重试一次。
每个分块都会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢 lane 表,以及每个 lane 的重跑命令。工作流 `docker_lanes` 输入会使用准备好的镜像运行选定的 lane而不是运行分块作业这样失败 lane 的调试会被限制在一个有针对性的 Docker 作业内,并且会为该运行准备、下载或复用包产物;如果选定的 lane 是 live Docker lane目标作业会在本地为该次重跑构建 live-test 镜像。生成的每 lane GitHub 重跑命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和准备的镜像输入,因此失败 lane 可以复用失败运行中的精确包和镜像。
每个分块都会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、用时、`summary.json`、`failures.json`、阶段用时、调度器计划 JSON、慢 lane 表格以及每个 lane 的重跑命令。工作流的 `docker_lanes` 输入会使用准备好的镜像运行选定 lane而不是运行分块作业这会把失败 lane 调试限制在一个定向 Docker 作业内,并为该运行准备、下载或复用包构件;如果选定 lane 是实时 Docker lane定向作业会在本地为该重跑构建实时测试镜像。生成的每个 lane GitHub 重跑命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和准备的镜像输入,因此失败 lane 可以复用失败运行中的精确包和镜像。
```bash
pnpm test:docker:rerun <run-id> # download Docker artifacts and print combined/per-lane targeted rerun commands
pnpm test:docker:timings <summary> # slow-lane and phase critical-path summaries
```
定时 live/E2E 工作流每天运行完整的发布路径 Docker 套件。
定时的实时/E2E 工作流每天运行完整发布路径 Docker 套件。
## 插件预发布
`Plugin Prerelease` 是成本更高的产品/包覆盖,因此它是一个独立工作流,由 `Full Release Validation` 或显式操作员触发。普通拉取请求、`main` 推送和独立的手动 CI 调度会关闭该套件。它会把内置插件测试均衡分配到八个扩展 worker这些扩展分片作业每次最多运行两个插件配置组每组使用一个 Vitest worker 和更大的 Node 堆,因此导入密集的插件批次不会创建额外的 CI 作业。仅发布使用的 Docker 预发布路径会把目标 Docker lane 分小组批处理,避免为一到三分钟的作业预留数十个 runner。
`Plugin Prerelease` 是成本更高的产品/包覆盖,因此它是一个独立工作流,由 `Full Release Validation` 或显式操作员调度。普通 pull request、`main` 推送和独立的手动 CI 调度都会关闭该套件。它会把内置插件测试平衡分配到八个扩展 worker这些扩展分片作业每次最多运行两个插件配置组每组使用一个 Vitest worker 和更大的 Node 堆,以便导入密集型插件批次不会创建额外的 CI 作业。仅发布的 Docker 预发布路径会把定向 Docker lane 按小组批处理,避免为一到三分钟的作业预留数十个 runner。
## QA Lab
## QA 实验室
QA Lab 在主智能作用域工作流之外有专用 CI lane。
QA 实验室在主智能作用域工作流之外有专用的 CI lane。
- `Parity gate` 工作流会在匹配的拉取请求变更和手动调度时运行;它会构建私有 QA 运行时,并比较模拟 GPT-5.5 和 Opus 4.6 智能体包。
- `QA-Lab - All Lanes` 工作流每晚在 `main` 上运行,也可手动调度;它会把模拟 parity gate、live Matrix lane以及 live Telegram 和 Discord lane 作为并行作业展开。Live 作业使用 `qa-live-shared` 环境Telegram/Discord 使用 Convex leases
- `Parity gate` 工作流会在匹配的 PR 变更和手动调度时运行;它会构建私有 QA 运行时,并比较模拟 GPT-5.5 和 Opus 4.6 智能体包。
- `QA-Lab - All Lanes` 工作流每晚在 `main` 上运行,也可手动调度;它会把模拟 parity gate、实时 Matrix lane以及实时 Telegram 和 Discord lane 扇出为并行作业。实时作业使用 `qa-live-shared` 环境Telegram/Discord 使用 Convex 租约
发布检查会使用确定性模拟提供商和模拟限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram live 传输 lane因此渠道契约会与 live 模型延迟和普通提供商插件启动隔离。live 传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连通性由独立的 live 模型、原生提供商和 Docker 提供商套件覆盖。
发布检查会使用确定性的模拟提供商和符合模拟条件的模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输 lane因此渠道契约与实时模型延迟和常规提供商插件启动隔离。实时传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连通性由单独的实时模型、原生提供商和 Docker 提供商套件覆盖。
Matrix 对定时和发布 gate 使用 `--profile fast`,仅在检出的 CLI 支持时添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 调度始终会把完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。
Matrix 会在定时和发布 gate 中使用 `--profile fast`,只有在检出的 CLI 支持时才添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 调度始终会把完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。
`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab lane它的 QA parity gate 会把候选包和基线包作为并行 lane 作业运行,然后把两个产物下载到一个小型报告作业中,用于最终 parity 比较。
`OpenClaw Release Checks` 还会在发布审批前运行发布关键的 QA 实验室 lane它的 QA parity gate 会把候选包和基线包作为并行 lane 作业运行,然后把两个构件下载到一个小型报告作业中,用于最终 parity 比较。
不要把 PR 落地路径置于 `Parity gate` 之后,除非变更确实触及 QA 运行时、模型包 parity或 parity 工作流拥有的表面。对于普通渠道、配置、文档或单元测试修复,应把它视为可选信号,并遵循有作用域的 CI/检查证据。
不要把 PR 合入路径放在 `Parity gate` 后面,除非变更确实触及 QA 运行时、模型包 parity或 parity 工作流拥有的表面。对于常规渠道、配置、文档或单元测试修复,把它视为可选信号,并遵循有作用域的 CI/检查证据。
## CodeQL
`CodeQL` 工作流有意作为一个范围较窄的首轮安全扫描器,而不是完整的仓库扫描。每日、手动和非草稿拉取请求保护运行会扫描 Actions 工作流代码,以及最高风险的 JavaScript/TypeScript 表面,并使用高置信度安全查询,筛选高/严重 `security-severity`
`CodeQL` 工作流有意作为窄范围的第一轮安全扫描器,而不是完整仓库扫描。每日、手动和非草稿 pull request guard 运行会扫描 Actions 工作流代码,以及风险最高的 JavaScript/TypeScript 表面,并使用高置信度安全查询,筛选到 high/critical `security-severity`
拉取请求保护保持轻量:它只会在 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src`有变更时启动并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不包含在 PR 默认项中。
pull request guard 保持轻量:它只会对 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src`的变更启动并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不包含在 PR 默认项中。
### 安全类别
| 类别 | 表面 |
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `/codeql-security-high/core-auth-secrets` | 认证、密钥、沙箱、cron 和 gateway 基线 |
| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约加上渠道插件运行时、Gateway 网关、插件 SDK、密钥、审计接触点 |
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络防护、web-fetch 和插件 SDK SSRF 策略表面 |
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行助手、出站投递,以及智能体工具执行 gate |
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、manifest、registry、运行时依赖 staging、source-loading,以及插件 SDK 包契约信任表面 |
| `/codeql-security-high/core-auth-secrets` | 凭证、secret、沙箱、cron 和 gateway 基线 |
| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约加上渠道插件运行时、Gateway 网关、插件 SDK、secret、审计触点 |
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络 guard、web-fetch 和插件 SDK SSRF 策略表面 |
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行 helper、出站投递和智能体工具执行 gate |
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、manifest、registry、运行时依赖 staging、source-loading 和插件 SDK 包契约信任表面 |
### 平台特定安全分片
- `CodeQL Android Critical Security` — 定时 Android 安全分片。在工作流完整性检查接受的最小 Blacksmith Linux runner 上,为 CodeQL 手动构建 Android 应用。上传到 `/codeql-critical-security/android`
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 `/codeql-critical-security/macos`。由于 macOS 构建即使在干净状态下也主导运行时间,因此它保持在每日默认项之外。
- `CodeQL Android Critical Security` — 定时 Android 安全分片。在 workflow sanity 接受的最小 Blacksmith Linux runner 上手动为 CodeQL 构建 Android 应用。上传到 `/codeql-critical-security/android`
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上手动为 CodeQL 构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 `/codeql-critical-security/macos`。由于 macOS 构建即使在干净状态下也主导运行时间,因此保留在每日默认项之外。
### 关键质量类别
`CodeQL Critical Quality` 是对应的非安全分片。它在较小的 Blacksmith Linux runner 上,对范围较窄的高价值表面运行错误严重级别的非安全 JavaScript/TypeScript 质量查询。它的拉取请求保护有意小于定时配置:非草稿 PR 只会为智能体命令/模型/工具执行和回复派发代码、配置 schema/迁移/IO 代码、认证/密钥/沙箱/安全代码、核心渠道和内置渠道插件运行时、Gateway 网关协议/服务器方法、记忆运行时/SDK 胶水层、MCP/进程/出站投递、提供商运行时/模型目录、会话诊断/投递队列、插件加载器、插件 SDK/包契约,或插件 SDK 回复运行时变更,运行匹配的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。
`CodeQL Critical Quality` 是对应的非安全分片。它在较小的 Blacksmith Linux runner 上,范围高价值表面运行错误严重级别的非安全 JavaScript/TypeScript 质量查询。它的 pull request guard 有意比定时配置更小:非草稿 PR 只会针对智能体命令/模型/工具执行与回复调度代码、配置 schema/迁移/IO 代码、凭证/secret/沙箱/安全代码、核心渠道和内置渠道插件运行时、Gateway 网关协议/服务器方法、记忆运行时/SDK 粘合层、MCP/进程/出站投递、提供商运行时/模型目录、会话诊断/投递队列、插件加载器、插件 SDK/包契约,或插件 SDK 回复运行时变更,运行匹配的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。
手动调度接受:
@ -354,40 +354,40 @@ Matrix 对定时和发布 gate 使用 `--profile fast`,仅在检出的 CLI 支
profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary
```
窄配置文件是用于单独运行一个质量分片的教学/迭代钩子
范围配置文件是教学/迭代钩子,用于单独运行一个质量分片。
| 类别 | 表面 |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/codeql-critical-quality/core-auth-secrets` | 证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
| `/codeql-critical-quality/config-boundary` | 配置架构、迁移、规范化和 IO 契约 |
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议架构和服务器方法契约 |
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约 |
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥、进程监督辅助工具,以及出站投递契约 |
| `/codeql-critical-quality/memory-runtime-boundary` | 记忆宿主 SDK、记忆运行时外观、记忆插件 SDK 别名、记忆运行时激活胶水代码,以及记忆 Doctor 命令 |
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话投递队列、出站会话绑定/投递辅助工具、诊断事件/日志包表面,以及会话 Doctor CLI 契约 |
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复载/分块/运行时辅助工具、渠道回复选项、投递队列,以及会话/线程绑定辅助工具 |
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商凭证和设备发现、提供商运行时注册、提供商默认值/目录,以及 web/search/fetch/embedding 注册表 |
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 引导、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心网页抓取/搜索、媒体 IO、媒体理解、图像生成以及媒体生成运行时契约 |
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公开表面和插件 SDK 入口点契约 |
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/codeql-critical-quality/core-auth-secrets` | 身份验证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
| `/codeql-critical-quality/config-boundary` | 配置 schema、迁移、规范化和 IO 契约 |
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议 schema 和服务器方法契约 |
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约 |
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥、进程监督辅助工具,以及出站投递契约 |
| `/codeql-critical-quality/memory-runtime-boundary` | 记忆主机 SDK、记忆运行时门面、记忆插件 SDK 别名、记忆运行时激活胶水代码,以及记忆 Doctor 命令 |
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话投递队列、出站会话绑定/投递辅助工具、诊断事件/日志包表面,以及会话 Doctor CLI 契约 |
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复载/分块/运行时辅助工具、渠道回复选项、投递队列,以及会话/thread 绑定辅助工具 |
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商身份验证和设备发现、提供商运行时注册、提供商默认值/目录,以及 Web/搜索/获取/嵌入注册表 |
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 引导、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 Web 获取/搜索、媒体 IO、媒体理解、图像生成和媒体生成运行时契约 |
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公开表面和插件 SDK 入口点契约 |
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 |
质量与安全保持分离,这样质量发现就可以在不遮蔽安全信号的情况下被调度、度量、禁用或扩展。Swift、Python 和内置插件 CodeQL 扩展应仅在窄配置文件拥有稳定运行时和信号之后,作为有范围或分片的后续工作重新加
质量与安全保持分离,这样质量发现就可以被排期、度量、禁用或扩展而不会掩盖安全信号。Swift、Python 和内置插件 CodeQL 扩展只应在窄范围配置文件具备稳定运行时和信号之后,作为有范围或分片的后续工作重新加。
## 维护工作流
### Docs Agent
### 文档 Agent
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的更保持一致。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已经前移,或者过去一小时内已创建另一个未跳过的 Docs Agent 运行时,工作流运行调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档处理以来累的所有 main 更
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的更保持一致。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已经继续前进,或者过去一小时内已经创建过另一个未跳过的 Docs Agent 运行时workflow-run 调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档处理以来累的所有 main 更。
### Test Performance Agent
### 测试性能 Agent
`Test Performance Agent` 工作流是一个事件驱动的 Codex 慢测试维护通道。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,但如果当天 UTC 已经有另一个工作流运行调用完成或正在运行,它会跳过。手动分发会绕过这个每日活动门禁。该通道会构建完整套件的分组 Vitest 性能报告,让 Codex 只做小型、保留覆盖率的测试性能修复,而不是大范围重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的更改。如果基线存在失败测试Codex 只能修复明显故障,并且代理后的完整套件报告必须通过后才能提交任何内容。当机器人推送落地前 `main` 前移时,该通道会变基已验证的补丁,重新运行 `pnpm check:changed`,然后重试推送;有冲突的陈旧补丁会被跳过。它使用 GitHub 托管的 Ubuntu因此 Codex action 可以保持与文档代理相同的 drop-sudo 安全姿态。
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,但如果同一个 UTC 日已经有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动分发会绕过该每日活动门禁。该通道会构建完整套件分组 Vitest 性能报告,让 Codex 只做保持覆盖率的小型测试性能修复,而不是大范围重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的变更。如果基线中存在失败测试Codex 只能修复明显失败项,并且 agent 后的完整套件报告必须通过,之后才会提交任何内容。当 `main` 在机器人 push 落地前前进时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,并重试 push有冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu因此 Codex action 可以保持与文档 agent 相同的 drop-sudo 安全姿态。
### 合并后的重复 PR
`Duplicate PRs After Merge` 工作流是一个供维护者使用的手动工作流,用于落地后的重复项清理。它默认是 dry-run并且只有在 `apply=true` 时才会关闭明确列出的 PR。在修改 GitHub 之前,它会验证已落地 PR 已合并,并且每个重复项要么有共享的引用 issue要么有重叠的已更改 hunk。
`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复项清理。它默认 dry-run并且只在 `apply=true` 时关闭显式列出的 PR。在修改 GitHub 之前,它会验证已落地 PR 已合并,并且每个重复项要么有共享的引用 issue要么有重叠的变更 hunk。
```bash
gh workflow run duplicate-after-merge.yml \
@ -398,25 +398,36 @@ gh workflow run duplicate-after-merge.yml \
## 本地检查门禁和变更路由
本地变更通道路由逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。该本地检查门禁在架构边界方面比广泛的 CI 平台范围更严格:
本地变更通道路由逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。该本地检查门禁在架构边界上比宽泛的 CI 平台范围更严格:
- 核心生产更会运行核心生产和核心测试类型检查,以及核心 lint/guard
- 仅核心测试更改只运行核心测试类型检查和核心 lint
- 插件生产更改会运行插件生产和插件测试类型检查,以及插件 lint
- 仅插件测试更改会运行插件测试类型检查和插件 lint
- 公开插件 SDK 或插件契约更改会扩展到插件类型检查因为插件依赖这些核心契约Vitest 插件 sweep 仍然是显式测试工作);
- 仅发布元数据版本提升会运行定向版本/配置/根依赖检查;
- 未知根目录/配置更改会保守失败到所有检查通道。
- 核心生产代码变更会运行核心生产和核心测试类型检查,以及核心 lint/guards
- 仅核心测试变更只运行核心测试类型检查,以及核心 lint
- 扩展生产代码变更会运行扩展生产和扩展测试类型检查,以及扩展 lint
- 仅扩展测试变更会运行扩展测试类型检查,以及扩展 lint
- 公开插件 SDK 或插件契约变更会扩展到扩展类型检查因为扩展依赖这些核心契约Vitest 扩展扫测仍是显式测试工作);
- 仅发布元数据的版本 bump 会运行定向版本/配置/根依赖检查;
- 未知根目录/配置变更会安全失败到所有检查通道。
本地变更测试路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更便宜:直接测试编辑会运行自身,源码编辑优先使用显式映射,然后是同级测试和导入图依赖项。共享群组房间投递配置是显式映射之一:对群组可见回复配置、源回复投递模式或消息工具系统提示的更改,会路由到核心回复测试以及 Discord 和 Slack 投递回归测试,因此共享默认值更改会在第一次 PR 推送前失败。只有当更改在 harness 范围足够广,以至于廉价映射集合不再是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
本地变更测试路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更便宜:直接测试编辑会运行自身,源码编辑优先使用显式映射,然后是同级测试和导入图依赖项。共享群组房间投递配置是显式映射之一:对群组可见回复配置、源回复投递模式或消息工具系统提示的变更,会通过核心回复测试以及 Discord 和 Slack 投递回归测试路由,因此共享默认值变更会在第一次 PR push 之前失败。只有当变更足够覆盖整个 harness以至于便宜的映射集合无法作为可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`
## Testbox 验证
从仓库根目录运行 Testbox且广泛证明优先使用新预热的 box。在对复用、已过期或刚报告了异常大同步的 box 消耗慢门禁之前,先在 box 内运行 `pnpm testbox:sanity`
从仓库根目录运行 Testbox优先使用新预热的 box 来提供宽范围证明。在把慢门禁花到一个复用、过期或刚报告了异常大同步的 box 之前,先在 box 内运行 `pnpm testbox:sanity`
当所需根文件(例如 `pnpm-lock.yaml`)消失,或者 `git status --short` 显示至少 200 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;请停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意的大量删除 PR请为该完整性运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`
当所需根文件(例如 `pnpm-lock.yaml`)消失,或者 `git status --short` 显示至少 200 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;应停止该 box 并预热新的 box而不是调试产品测试失败。对于有意的大规模删除 PR请为该次完整性检查设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`
`pnpm testbox:run` 还会终止在同步阶段停留超过五分钟且没有同步后输出的本地 Blacksmith CLI 调用。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该 guard或者为异常大的本地 diff 使用更大的毫秒值。
如果本地 Blacksmith CLI 调用在同步阶段停留超过五分钟且没有同步后输出,`pnpm testbox:run` 也会终止该调用。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该保护,或者为异常大的本地 diff 使用更大的毫秒值。
当 Blacksmith 不可用或更适合使用自有云容量时Crabbox 是仓库自有的第二条远程 box Linux 验证路径。预热一个 box通过项目工作流 hydrate 它,然后通过 Crabbox CLI 运行命令:
```bash
pnpm crabbox:warmup -- --idle-timeout 90m
pnpm crabbox:hydrate -- --id <cbx_id>
pnpm crabbox:run -- --id <cbx_id> --shell "OPENCLAW_TESTBOX=1 pnpm check:changed"
pnpm crabbox:stop -- <cbx_id>
```
`.crabbox.yaml` 负责提供商、同步和 GitHub Actions hydrate 默认值。它排除本地 `.git`,这样 hydrated Actions checkout 会保留自己的远程 Git 元数据,而不是同步维护者本地的 remote 和 object store它还排除不应传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 负责 checkout、Node/pnpm 设置、`origin/main` fetch以及后续 `crabbox run --id <cbx_id>` 命令 source 的非密钥环境交接。
## 相关

View File

@ -1,14 +1,14 @@
---
read_when:
- 你想安全地更新源代码检出副本
- 你需要理解 `--update` 简写行为
summary: '`openclaw update` 的 CLI 参考(相对安全的源更新 + Gateway 网关自动重启)'
- 你需要了解 `--update`简写行为
summary: CLI 参考:`openclaw update`(较安全的源更新 + Gateway 网关自动重启)
title: 更新
x-i18n:
generated_at: "2026-04-28T11:48:48Z"
generated_at: "2026-05-01T08:52:02Z"
model: gpt-5.5
provider: openai
source_hash: 9cd4be6be8f6ae7df501f8bce3d208dd507ae5a1539f9772101cd844dcd93976
source_hash: bc71740dac6b1af8f695ab60d0ffc1b44a10dd40363538c2a8a37ad518790ce9
source_path: cli/update.md
workflow: 16
---
@ -17,8 +17,8 @@ x-i18n:
安全更新 OpenClaw并在 stable/beta/dev 渠道之间切换。
如果你通过 **npm/pnpm/bun** 安装(全局安装, git 元数据),
更新会通过 [更新](/zh-CN/install/updating) 中的包管理器流程进行。
如果你通过 **npm/pnpm/bun** 安装(全局安装,没有 git 元数据),
更新会通过 [更新](/zh-CN/install/updating) 中的软件包管理器流程进行。
## 用法
@ -39,23 +39,22 @@ openclaw --update
## 选项
- `--no-restart`:成功更新后跳过重启 Gateway 网关服务。会重启 Gateway 网关的包管理器更新会先验证重启后的服务报告预期的已更新版本,然后命令才会成功。
- `--channel <stable|beta|dev>`设置更新渠道git + npm会持久化到配置中
- `--tag <dist-tag|version|spec>`:仅覆盖本次更新的软件包目标。对于软件包安装,`main` 映射到 `github:openclaw/openclaw#main`
- `--dry-run`:预览计划的更新操作(渠道/标签/目标/重启流程),但不写入配置、不安装、不同步插件,也不重启。
- `--json`:打印机器可读的 `UpdateRunResult` JSON包括
在更新后插件同步期间检测到 npm 插件产物漂移时的
- `--no-restart`:成功更新后跳过重启 Gateway 网关服务。会重启 Gateway 网关的软件包管理器更新,会先验证重启后的服务报告预期的更新版本,然后命令才会成功。
- `--channel <stable|beta|dev>`设置更新渠道git + npm持久保存到配置中
- `--tag <dist-tag|version|spec>`:仅为本次更新覆盖软件包目标。对于软件包安装,`main` 映射到 `github:openclaw/openclaw#main`
- `--dry-run`:预览计划的更新操作(渠道/tag/目标/重启流程),但不写入配置、安装、同步插件或重启。
- `--json`:打印机器可读的 `UpdateRunResult` JSON包括在更新后插件同步期间检测到 npm 插件产物漂移时的
`postUpdate.plugins.integrityDrifts`
- `--timeout <seconds>`:每个步骤的超时时间(默认 1800s)。
- `--timeout <seconds>`:每个步骤的超时时间(默认 1800)。
- `--yes`:跳过确认提示(例如降级确认)。
<Warning>
降级需要确认,因为旧版本可能会破坏配置。
降级需要确认,因为旧版本可能会破坏配置。
</Warning>
## `update status`
显示当前更新渠道 + git 标签/分支/SHA用于源码检出以及更新可用性。
显示当前更新渠道 + git tag/分支/SHA用于源码检出以及更新可用性。
```bash
openclaw update status
@ -66,12 +65,11 @@ openclaw update status --timeout 10
选项:
- `--json`:打印机器可读的状态 JSON。
- `--timeout <seconds>`:检查超时时间(默认 3s)。
- `--timeout <seconds>`:检查超时时间(默认 3)。
## `update wizard`
交互式流程,用于选择更新渠道,并确认更新后是否重启 Gateway 网关
(默认会重启)。如果你选择 `dev` 但没有 git 检出,它会提示创建一个。
交互式流程,用于选择更新渠道,并确认更新后是否重启 Gateway 网关(默认重启)。如果你在没有 git 检出的情况下选择 `dev`,它会提示创建一个检出。
选项:
@ -79,94 +77,76 @@ openclaw update status --timeout 10
## 它会做什么
当你显式切换渠道(`--channel ...`OpenClaw 也会保持
安装方式一致:
当你显式切换渠道(`--channel ...`OpenClaw 也会让安装方式保持一致:
- `dev` → 确保存在 git 检出(默认:`~/openclaw`,可用 `OPENCLAW_GIT_DIR` 覆盖),
更新它,并从该检出安装全局 CLI。
- `stable` → 使用 `latest` 从 npm 安装。
- `beta` → 优先使用 npm dist-tag `beta`,但当 beta 缺失或早于当前稳定版时,
回退到 `latest`
- `beta` → 优先使用 npm dist-tag `beta`,但当 beta 缺失或早于当前 stable 版本时回退到 `latest`
Gateway 网关核心自动更新器(通过配置启用时)会复用同一更新路径
Gateway 网关核心自动更新器(通过配置启用时)会在实时 Gateway 网关请求处理程序之外启动 CLI 更新路径。控制平面 `update.run` 软件包管理器更新会在软件包替换后强制执行非延迟更新重启,因为旧的 Gateway 网关进程可能仍有指向新软件包已删除文件的内存中分块
对于包管理器安装,`openclaw update` 会先解析目标软件包
版本然后再调用包管理器。npm 全局安装使用分阶段
安装OpenClaw 会把新软件包安装到临时 npm 前缀中,在那里验证
打包后的 `dist` 清单,然后将这个干净的软件包树替换到
真实的全局前缀中。如果验证失败,更新后的 Doctor、插件同步和
重启工作都不会从可疑的软件包树运行。即使已安装版本
已经匹配目标,命令也会刷新全局软件包安装,
然后运行插件同步、核心命令补全刷新和重启工作。这会
让打包的 sidecar 和渠道拥有的插件记录与已安装的
OpenClaw 构建保持一致,同时把完整的插件命令补全重建留给
显式的 `openclaw completion --write-state` 运行。
对于软件包管理器安装,`openclaw update` 会先解析目标软件包版本再调用软件包管理器。npm 全局安装使用分阶段安装OpenClaw 会把新软件包安装到临时 npm prefix 中,验证其中打包的 `dist` 清单,然后把这个干净的软件包树切换到真实的全局 prefix。如果验证失败更新后 Doctor、插件同步和重启工作不会从可疑的软件包树中运行。即使已安装版本已经匹配目标命令仍会刷新全局软件包安装然后运行插件同步、核心命令补全刷新和重启工作。这会让打包的 sidecar 和渠道拥有的插件记录与已安装的 OpenClaw 构建保持一致,同时把完整的插件命令补全重建留给显式的 `openclaw completion --write-state` 运行。
当已安装本地托管 Gateway 网关服务且启用重启时,
包管理器更新会先停止正在运行的服务,再替换软件包
树,然后从更新后的安装刷新服务元数据,重启
服务,并验证重启后的 Gateway 网关报告预期版本。使用
`--no-restart` 时,仍会执行软件包替换,但不会停止或重启
托管服务,因此正在运行的 Gateway 网关可能会继续使用旧代码,直到你手动
重启它。
当本地托管的 Gateway 网关服务已安装且启用重启时,软件包管理器更新会先停止正在运行的服务,再替换软件包树,然后从更新后的安装刷新服务元数据、重启服务,并验证重启后的 Gateway 网关报告预期版本。使用 `--no-restart` 时,软件包替换仍会运行,但托管服务不会被停止或重启,因此正在运行的 Gateway 网关可能会继续使用旧代码,直到你手动重启它。
## Git 检出流程
### 渠道选择
- `stable`:检出最新的非 beta 标签,然后构建并运行 Doctor。
- `beta`:优先选择最新的 `-beta` 标签,但当 beta 缺失或更旧时回退到最新稳定标签
- `stable`:检出最新的非 beta tag然后构建并运行 Doctor。
- `beta`:优先使用最新的 `-beta` tag但当 beta 缺失或更旧时回退到最新的 stable tag。
- `dev`:检出 `main`,然后 fetch 并 rebase。
### 更新步骤
<Steps>
<Step title="验证干净工作树">
<Step title="验证干净工作树">
要求没有未提交的更改。
</Step>
<Step title="切换渠道">
切换到选定渠道(标签或分支)。
切换到所选渠道tag 或分支)。
</Step>
<Step title="获取上游">
dev。
<Step title="Fetch 上游">
仅 dev。
</Step>
<Step title="预检构建(仅 dev">
在临时工作树中运行 lint 和 TypeScript 构建。如果最新提交失败,会向前回溯最多 10 个提交,以找到最新的干净构建。
<Step title="预检构建(仅 dev">
在临时工作树中运行 lint 和 TypeScript 构建。如果 tip 失败,会向前回退最多 10 个提交,以找到最新的干净构建。
</Step>
<Step title="Rebase">
Rebase 到选提交(仅 dev
Rebase 到选提交(仅 dev
</Step>
<Step title="安装依赖">
使用仓库包管理器。对于 pnpm 检出,更新器会按需引导 `pnpm`(先通过 `corepack`,然后使用临时的 `npm install pnpm@10` 回退),而不是在 pnpm 工作区内运行 `npm run build`
<Step title="安装依赖">
使用仓库的软件包管理器。对于 pnpm 检出,更新器会按需引导 `pnpm`(先通过 `corepack`,然后回退到临时 `npm install pnpm@10`),而不是在 pnpm 工作区内运行 `npm run build`
</Step>
<Step title="构建 Control UI">
构建 Gateway 网关和 Control UI。
构建 gateway 和 Control UI。
</Step>
<Step title="运行 Doctor">
`openclaw doctor` 作为最终的安全更新检查运行。
`openclaw doctor` 作为最终的安全更新检查运行。
</Step>
<Step title="同步插件">
将插件同步到当前渠道。Dev 使用内置插件stable 和 beta 使用 npm。更新通过 npm 安装的插件。
将插件同步到当前渠道。dev 使用内置插件stable 和 beta 使用 npm。更新通过 npm 安装的插件。
</Step>
</Steps>
<Warning>
如果精确固定的 npm 插件更新解析到某个产物,而该产物的完整性与已存储的安装记录不同`openclaw update` 会中止该插件产物更新,而不是安装它。只有在验证你信任新产物后,才应显式重新安装或更新该插件。
如果精确固定的 npm 插件更新解析到的产物完整性不同于已存储的安装记录`openclaw update` 会中止该插件产物更新,而不是安装它。只有在验证你信任新产物后,才应显式重新安装或更新该插件。
</Warning>
<Note>
更新后插件同步失败会使更新结果失败,并停止后续重启工作。修复插件安装或更新错误,然后重新运行 `openclaw update`
更新后的 Gateway 网关启动时,已启用的内置插件运行时依赖会在插件激活前暂存。由更新触发的重启会在关闭 Gateway 网关前排空任何正在进行的运行时依赖暂存,因此服务管理器重启不会中断正在进行的 npm install
更新后的 Gateway 网关启动时,已启用的内置插件运行时依赖会在插件激活前完成暂存。软件包管理器 `update.run` 重启会在软件包树被替换后绕过正常的空闲延迟,因此旧进程不能继续懒加载已删除的分块。服务管理器重启仍会在关闭 Gateway 网关前清空运行时依赖暂存
如果 pnpm 引导仍然失败,更新器会提前停止并给出包管理器特定错误,而不是尝试在检出内运行 `npm run build`
如果 pnpm 引导仍然失败,更新器会提前停止并返回特定于软件包管理器的错误,而不是尝试在检出中运行 `npm run build`
</Note>
## `--update` 简写
`openclaw --update` 会重写为 `openclaw update`(对 shell 和启动器脚本很有用)。
## 相关内容
## 相关
- `openclaw doctor`(在 git 检出上会提示先运行更新)
- [开发渠道](/zh-CN/install/development-channels)

View File

@ -6,15 +6,15 @@ sidebarTitle: Doctor
summary: Doctor 命令:健康检查、配置迁移和修复步骤
title: Doctor
x-i18n:
generated_at: "2026-05-01T07:52:58Z"
generated_at: "2026-05-01T08:51:53Z"
model: gpt-5.5
provider: openai
source_hash: 928f6854d5721e468e5edc01420fc911652f706ef24e47e8d47461bbe8998214
source_hash: eef5715d485609fa60bdb4aa97ee441b053a60519b9dea03b0c8ec09db157474
source_path: gateway/doctor.md
workflow: 16
---
`openclaw doctor` 是 OpenClaw 的修复 + 迁移工具。它会修复过期的配置/状态检查健康状况,并提供可执行的修复步骤。
`openclaw doctor` 是 OpenClaw 的修复 + 迁移工具。它会修复过期的配置/状态检查健康状况,并提供可执行的修复步骤。
## 快速开始
@ -30,7 +30,7 @@ openclaw doctor
openclaw doctor --yes
```
不提示直接接受默认值(适用时包括重启/服务/沙箱修复步骤)。
不提示直接接受默认值(包括适用时的重启/服务/沙箱修复步骤)。
</Tab>
<Tab title="--repair">
@ -38,7 +38,7 @@ openclaw doctor
openclaw doctor --repair
```
不提示直接应用推荐修复(在安全情况下执行修复 + 重启)。
不提示直接应用推荐修复(安全时包括修复 + 重启)。
</Tab>
<Tab title="--repair --force">
@ -46,7 +46,7 @@ openclaw doctor
openclaw doctor --repair --force
```
同时应用激进修复(覆盖自定义 supervisor 配置)。
同时应用激进修复(覆盖自定义 supervisor 配置)。
</Tab>
<Tab title="--non-interactive">
@ -54,7 +54,7 @@ openclaw doctor
openclaw doctor --non-interactive
```
提示运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。检测到旧版状态迁移时会自动运行。
不显示提示运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。检测到旧版状态迁移时会自动运行。
</Tab>
<Tab title="--deep">
@ -67,71 +67,71 @@ openclaw doctor
</Tab>
</Tabs>
如果你想在写入前查看更改,请先打开配置文件:
如果你想在写入前审查变更,请先打开配置文件:
```bash
cat ~/.openclaw/openclaw.json
```
## 它做什么(摘要)
## 它做什么(摘要)
<AccordionGroup>
<Accordion title="健康状态、UI 和更新">
- 针对 git 安装的可选预检更新(仅交互模式)。
<Accordion title="健康检查、UI 和更新">
- git 安装的可选预检更新(仅交互模式)。
- UI 协议新鲜度检查(当协议 schema 更新时重建 Control UI
- 健康检查 + 重启提示。
- Skills 状态摘要(符合条件/缺失/被阻止)和插件状态。
</Accordion>
<Accordion title="配置和迁移">
- 针对旧版值的配置规范化。
- 将旧版扁平 `talk.*` 字段迁移 `talk.provider` + `talk.providers.<provider>` 的 Talk 配置迁移。
- 针对旧版 Chrome 扩展配置和 Chrome MCP 就绪状态的浏览器迁移检查
- OpenCode provider 覆盖警告(`models.providers.opencode` / `models.providers.opencode-go`)。
- 旧版值的配置规范化。
- 将旧版扁平 `talk.*` 字段迁移 `talk.provider` + `talk.providers.<provider>` 的 Talk 配置迁移。
- 检查旧版 Chrome 扩展配置和 Chrome MCP 就绪状态的浏览器迁移。
- OpenCode 提供商覆盖警告(`models.providers.opencode` / `models.providers.opencode-go`)。
- Codex OAuth 遮蔽警告(`models.providers.openai-codex`)。
- OpenAI Codex OAuth 配置文件的 OAuth TLS 前置条件检查。
- 当 `plugins.allow` 具有限制性但工具策略仍请求通配符或插件自有工具时,发出插件/工具允许列表警告。
- 旧版磁盘状态迁移(会话/智能体目录/WhatsApp 证)。
- 旧版插件清单合约键迁移(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders``contracts`)。
- 旧版 cron 存储迁移(`jobId`, `schedule.cron`, 顶层 delivery/payload 字段、payload `provider`简单 `notify: true` webhook 回退任务)。
- 当 `plugins.allow` 具有限制性,但工具策略仍要求通配符或插件自有工具时,给出插件/工具允许列表警告。
- 旧版磁盘状态迁移(会话/智能体目录/WhatsApp 证)。
- 旧版插件 manifest 合约键迁移(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders``contracts`)。
- 旧版 cron 存储迁移(`jobId`, `schedule.cron`, 顶层 delivery/payload 字段payload `provider`简单 `notify: true` webhook 回退任务)。
- 旧版智能体运行时策略迁移到 `agents.defaults.agentRuntime``agents.list[].agentRuntime`
- 启用插件时清理过期插件配置;当 `plugins.enabled=false` 时,过期插件引用会被视为惰性隔离配置并保留。
</Accordion>
<Accordion title="状态和完整性">
- 会话锁文件检查和过期锁清理
- 修复受影响的 2026.4.24 构建创建的重复 prompt-rewrite 分支的会话记录
- 卡住的子智能体重启恢复 tombstone 检测,支持用 `--fix` 清除过期的已中止恢复标记,避免启动持续将子进程视为重启已中止
- 状态完整性和权限检查(会话、记录、状态目录)。
- 检查会话锁文件并清理过期锁
- 修复受影响的 2026.4.24 构建创建的重复 prompt-rewrite 分支的会话 transcript
- 卡住的 subagent 重启恢复 tombstone 检测,支持用 `--fix` 清除过期的 aborted recovery 标记,这样启动时就不会继续把子项视为 restart-aborted
- 状态完整性和权限检查(会话、transcript、状态目录)。
- 本地运行时的配置文件权限检查chmod 600
- 模型认证健康:检查 OAuth 过期情况,可刷新即将过期的令牌,并报告认证配置文件的冷却/禁用状态。
- 模型认证健康状态:检查 OAuth 过期时间,可以刷新即将过期的 token并报告 auth-profile 的 cooldown/disabled 状态。
- 额外工作区目录检测(`~/openclaw`)。
</Accordion>
<Accordion title="Gateway 网关、服务和 supervisors">
- 启用沙箱隔离时进行沙箱镜像修复。
<Accordion title="Gateway 网关、服务和 supervisor">
- 启用沙箱隔离时沙箱镜像修复。
- 旧版服务迁移和额外 Gateway 网关检测。
- Matrix 渠道旧版状态迁移(在 `--fix` / `--repair` 模式)。
- Matrix 渠道旧版状态迁移(在 `--fix` / `--repair` 模式)。
- Gateway 网关运行时检查(服务已安装但未运行;缓存的 launchd 标签)。
- 渠道状态警告(从正在运行的 Gateway 网关探测)。
- Supervisor 配置审计launchd/systemd/schtasks可选修复。
- 清理 Gateway 网关服务的嵌入式代理环境,这些服务在安装或更新期间捕获了 shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 值。
- Gateway 网关运行时最佳实践检查Node 与 Bun、版本管理器路径)。
- 清理 Gateway 网关服务的嵌入式代理环境,这些服务在安装或更新期间捕获了 shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 值。
- Gateway 网关运行时最佳实践检查Node vs Bun版本管理器路径)。
- Gateway 网关端口冲突诊断(默认 `18789`)。
</Accordion>
<Accordion title="认证、安全和配对">
- 针对开放私信策略的安全警告。
- 针对本地令牌模式的 Gateway 网关认证检查(无令牌来源时提供令牌生成;不会覆盖令牌 SecretRef 配置)。
- 设备配对问题检测(待处理的首次配对请求、待处理的角色/作用域升级、过期的本地设备令牌缓存漂移,以及已配对记录的认证漂移)。
- 开放私信策略的安全警告。
- local token 模式的 Gateway 网关认证检查(没有 token 来源时提供 token 生成;不会覆盖 token SecretRef 配置)。
- 设备配对问题检测(待处理的首次配对请求、待处理的角色/范围升级、过期本地 device-token 缓存漂移,以及 paired-record 认证漂移)。
</Accordion>
<Accordion title="工作区和 shell">
- Linux 上的 systemd linger 检查。
- 工作区 bootstrap 文件大小检查(针对上下文文件截断/接近限制警告)。
- 工作区 bootstrap 文件大小检查(上下文文件截断/接近限制警告)。
- Shell 补全状态检查和自动安装/升级。
- 记忆搜索嵌入提供商就绪状态检查(本地模型、远程 API key 或 QMD 二进制)。
- 源码安装检查pnpm 工作区不匹配、缺少 UI 资产、缺少 tsx 二进制)。
- 记忆搜索 embedding 提供商就绪状态检查(本地模型、远程 API key 或 QMD binary)。
- 源码安装检查pnpm 工作区不匹配、缺少 UI 资产、缺少 tsx binary)。
- 写入更新后的配置 + 向导元数据。
</Accordion>
@ -139,38 +139,38 @@ cat ~/.openclaw/openclaw.json
## Dreams UI 回填和重置
Control UI Dreams 场景包含用于 grounded dreaming 工作流的 **回填**、**重置** 和 **清除 Grounded** 操作。这些操作使用 Gateway 网关 doctor 风格的 RPC 方法,但它们**不是** `openclaw doctor` CLI 修复/迁移的一部分。
Control UI Dreams 场景包含用于 grounded dreaming 工作流的 **Backfill**、**Reset** 和 **Clear Grounded** 操作。这些操作使用 Gateway 网关 doctor 风格的 RPC 方法,但它们**不是** `openclaw doctor` CLI 修复/迁移的一部分。
它们会做什么:
- **回填**会扫描活动工作区中的历史 `memory/YYYY-MM-DD.md` 文件,运行 grounded REM 日记流程,并将可逆的回填条目写入 `DREAMS.md`
- **重置**只会从 `DREAMS.md` 中移除那些已标记的回填日记条目。
- **清除 Grounded**只会移除通过历史回放产生、且尚未积累实时召回或每日支持的暂存 grounded-only 短期条目。
- **Backfill** 会扫描活动工作区中的历史 `memory/YYYY-MM-DD.md` 文件,运行 grounded REM diary pass,并将可逆的回填条目写入 `DREAMS.md`
- **Reset** 只会从 `DREAMS.md` 中移除那些标记的回填 diary 条目。
- **Clear Grounded** 只会移除来自历史重放、且尚未积累实时 recall 或每日支撑的 staged grounded-only 短期条目。
它们本身**不会**做什么:
- 它们不会编辑 `MEMORY.md`
- 它们不会运行完整的 doctor 迁移
- 除非你先显式运行暂存 CLI 路径,否则它们不会自动把 grounded 候选项暂存到实时短期提升存储中
- 除非你先显式运行 staged CLI 路径,否则它们不会自动将 grounded candidates stage 到实时短期 promotion store
如果你希望 grounded 历史回放影响正常的深度提升通道,请改用 CLI 流程:
如果你希望 grounded 历史重放影响常规的深度 promotion lane,请改用 CLI 流程:
```bash
openclaw memory rem-backfill --path ./memory --stage-short-term
```
这会将 grounded 持久候选项暂存到短期 dreaming 存储中,同时将 `DREAMS.md` 保持为审查界面。
这会将 grounded durable candidates stage 到短期 dreaming store同时将 `DREAMS.md` 保留为审查界面。
## 详细行为和理由
<AccordionGroup>
<Accordion title="0. 可选更新git 安装)">
如果这是一个 git checkout 且 doctor 正在交互式运行,它会在运行 doctor 前提示更新fetch/rebase/build
如果这是一个 git checkout,并且 doctor 以交互方式运行,它会在运行 doctor 前提供更新fetch/rebase/build选项
</Accordion>
<Accordion title="1. 配置规范化">
如果配置包含旧版值形态(例如没有渠道专属覆盖的 `messages.ackReaction`doctor 会将它们规范化为当前 schema。
如果配置包含旧版值形态(例如没有渠道特定覆盖的 `messages.ackReaction`doctor 会将它们规范化为当前 schema。
这包括旧版 Talk 扁平字段。当前公开 Talk 配置是 `talk.provider` + `talk.providers.<provider>`。Doctor 会旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 形态重写进提供商映射
这包括旧版 Talk 扁平字段。当前公开 Talk 配置是 `talk.provider` + `talk.providers.<provider>`。Doctor 会旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 形态重写到提供商映射中
`plugins.allow` 非空且工具策略使用通配符或插件自有工具条目时Doctor 也会发出警告。`tools.allow: ["*"]` 只匹配实际加载的插件中的工具;它不会绕过排他性插件允许列表。
@ -178,13 +178,13 @@ openclaw memory rem-backfill --path ./memory --stage-short-term
<Accordion title="2. 旧版配置键迁移">
当配置包含已弃用的键时,其他命令会拒绝运行,并要求你运行 `openclaw doctor`
Doctor 会:
Doctor 会:
- 说明发现了哪些旧版键。
- 说明找到了哪些旧版键。
- 显示它应用的迁移。
- 使用更新后的 schema 重写 `~/.openclaw/openclaw.json`
Gateway 网关在启动时检测到旧版配置格式也会自动运行 doctor 迁移因此过期配置无需人工干预即可修复。Cron 任务存储迁移由 `openclaw doctor --fix` 处理。
Gateway 网关在启动时检测到旧版配置格式时,也会自动运行 doctor 迁移因此过期配置无需人工干预即可修复。Cron 任务存储迁移由 `openclaw doctor --fix` 处理。
当前迁移:
@ -198,217 +198,217 @@ openclaw memory rem-backfill --path ./memory --stage-short-term
- 旧版 `talk.voiceId`/`talk.voiceAliases`/`talk.modelId`/`talk.outputFormat`/`talk.apiKey` → `talk.provider` + `talk.providers.<provider>`
- `routing.agentToAgent``tools.agentToAgent`
- `routing.transcribeAudio``tools.media.audio.models`
- `messages.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) `messages.tts.providers.<provider>`
- `messages.tts.<provider>``openai`/`elevenlabs`/`microsoft`/`edge``messages.tts.providers.<provider>`
- `messages.tts.provider: "edge"``messages.tts.providers.edge``messages.tts.provider: "microsoft"``messages.tts.providers.microsoft`
- `channels.discord.voice.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) `channels.discord.voice.tts.providers.<provider>`
- `channels.discord.accounts.<id>.voice.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) `channels.discord.accounts.<id>.voice.tts.providers.<provider>`
- `plugins.entries.voice-call.config.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) `plugins.entries.voice-call.config.tts.providers.<provider>`
- `channels.discord.voice.tts.<provider>``openai`/`elevenlabs`/`microsoft`/`edge``channels.discord.voice.tts.providers.<provider>`
- `channels.discord.accounts.<id>.voice.tts.<provider>``openai`/`elevenlabs`/`microsoft`/`edge``channels.discord.accounts.<id>.voice.tts.providers.<provider>`
- `plugins.entries.voice-call.config.tts.<provider>``openai`/`elevenlabs`/`microsoft`/`edge``plugins.entries.voice-call.config.tts.providers.<provider>`
- `plugins.entries.voice-call.config.tts.provider: "edge"``plugins.entries.voice-call.config.tts.providers.edge``provider: "microsoft"``providers.microsoft`
- `plugins.entries.voice-call.config.provider: "log"``"mock"`
- `plugins.entries.voice-call.config.twilio.from``plugins.entries.voice-call.config.fromNumber`
- `plugins.entries.voice-call.config.streaming.sttProvider``plugins.entries.voice-call.config.streaming.provider`
- `plugins.entries.voice-call.config.streaming.openaiApiKey|sttModel|silenceDurationMs|vadThreshold``plugins.entries.voice-call.config.streaming.providers.openai.*`
- `bindings[].match.accountID``bindings[].match.accountId`
- 对于带有命名 `accounts`、但仍残留单账号顶层渠道值的渠道,将这些账号作用域的值移动到为该渠道选定的提升账号中(大多数渠道使用 `accounts.default`Matrix 可以保留现有匹配的命名/默认目标)
- 对于带有具名 `accounts`、但仍残留单账号顶层渠道值的渠道,将这些账号作用域值移入为该渠道选择的已提升账号(大多数渠道使用 `accounts.default`Matrix 可以保留现有匹配的具名/default 目标)
- `identity``agents.list[].identity`
- `agent.*``agents.defaults` + `tools.*`tools/elevated/exec/sandbox/subagents
- `agent.*``agents.defaults` + `tools.*`工具/elevated/exec/沙箱/subagents
- `agent.model`/`allowedModels`/`modelAliases`/`modelFallbacks`/`imageModelFallbacks` → `agents.defaults.models` + `agents.defaults.model.primary/fallbacks` + `agents.defaults.imageModel.primary/fallbacks`
- 移除 `agents.defaults.llm`;对较慢的提供商/模型超时使用 `models.providers.<id>.timeoutSeconds`
- 移除 `agents.defaults.llm`;对较慢的提供商/模型超时使用 `models.providers.<id>.timeoutSeconds`
- `browser.ssrfPolicy.allowPrivateNetwork``browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`
- `browser.profiles.*.driver: "extension"``"existing-session"`
- 移除 `browser.relayBindHost`(旧版扩展中继设置)
- 旧版 `models.providers.*.api: "openai"``"openai-completions"`Gateway 网关启动时也会跳过 `api` 设置为未来或未知枚举值的提供商,而不是封闭失败
- 旧版 `models.providers.*.api: "openai"``"openai-completions"`Gateway 网关启动时也会跳过 `api` 设置为未来或未知枚举值的提供商,而不是直接失败关闭
Doctor 警告还包含针对多账号渠道的账号默认值指导:
Doctor 警告还包含多账号渠道的账号默认值指导:
- 如果配置了两个或更多 `channels.<channel>.accounts` 条目,但没有配置 `channels.<channel>.defaultAccount``accounts.default`Doctor 会警告备用路由可能选中意外账号。
- 如果 `channels.<channel>.defaultAccount` 设置为未知账号 IDDoctor 会警告并列出已配置的账号 ID。
- 如果配置了两个或更多 `channels.<channel>.accounts` 条目,但没有配置 `channels.<channel>.defaultAccount``accounts.default`doctor 会警告回退路由可能选择意外账号。
- 如果 `channels.<channel>.defaultAccount` 设置为未知账号 IDdoctor 会警告并列出已配置的账号 ID。
</Accordion>
<Accordion title="2b. OpenCode 提供商覆盖设置">
如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`,它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。这可能会强制模型使用错误的 API或将费用归零。Doctor 会发出警告,以便你移除覆盖设置并恢复按模型划分的 API 路由和费用
<Accordion title="2b. OpenCode 提供商覆盖">
如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`,它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。这可能会强制模型使用错误的 API或将成本归零。Doctor 会发出警告,以便你移除该覆盖并恢复按模型的 API 路由和成本
</Accordion>
<Accordion title="2c. 浏览器迁移和 Chrome MCP 就绪状态">
如果你的浏览器配置仍指向已移除的 Chrome 扩展路径,Doctor 会将其规范化为当前的主机本地 Chrome MCP 附加模型:
如果你的浏览器配置仍指向已移除的 Chrome 扩展路径,doctor 会将其规范化为当前主机本地 Chrome MCP 附加模型:
- `browser.profiles.*.driver: "extension"` 变为 `"existing-session"`
- `browser.relayBindHost` 会被移除
当你使用 `defaultProfile: "user"`已配置的 `existing-session` 配置文件时Doctor 还会审计主机本地 Chrome MCP 路径:
当你使用 `defaultProfile: "user"`配置了 `existing-session` 配置文件时Doctor 还会审计主机本地 Chrome MCP 路径:
- 检查同一主机上是否安装了 Google Chrome,以用于默认自动连接配置文件
- 检查默认自动连接配置文件的同一主机上是否安装了 Google Chrome
- 检查检测到的 Chrome 版本,并在低于 Chrome 144 时发出警告
- 提醒你在浏览器检查页面中启用远程调试(例如 `chrome://inspect/#remote-debugging`、`brave://inspect/#remote-debugging` 或 `edge://inspect/#remote-debugging`
Doctor 无法替你启用 Chrome 侧设置。主机本地 Chrome MCP 仍需要:
Doctor 无法替你启用 Chrome 端设置。主机本地 Chrome MCP 仍然需要:
- Gateway 网关/节点主机上有基于 Chromium 的 144+ 浏览器
- Gateway 网关/节点主机上有基于 Chromium 的浏览器 144+
- 浏览器在本地运行
- 该浏览器已启用远程调试
- 在浏览器中批准次附加同意提示
- 该浏览器已启用远程调试
- 在浏览器中批准第一次附加同意提示
这里的就绪状态只涉及本地附加前置条件。Existing-session 保持当前 Chrome MCP 路由限制;`responsebody`、PDF 导出、下载拦截和批量操作等高级路由仍需要托管浏览器或原始 CDP 配置文件。
这里的就绪状态只涉及本地附加前置条件。Existing-session 会保留当前 Chrome MCP 路由限制;`responsebody`、PDF 导出、下载拦截和批量操作等高级路由仍需要托管浏览器或原始 CDP 配置文件。
此检查**不**适用于 Docker、沙箱、远程浏览器或其他无头流程。这些流程继续使用原始 CDP。
此检查**不**适用于 Docker、沙箱、远程浏览器或其他无头流程。它们会继续使用原始 CDP。
</Accordion>
<Accordion title="2d. OAuth TLS 前置条件">
配置了 OpenAI Codex OAuth 配置文件时Doctor 会探测 OpenAI 授权端点,以验证本地 Node/OpenSSL TLS 栈能否验证书链。如果探测因证书错误失败(例如 `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),Doctor 会打印特定平台的修复指导。在使用 Homebrew Node 的 macOS 上,修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,也会运行该探测。
配置 OpenAI Codex OAuth 配置文件时doctor 会探测 OpenAI 授权端点,以验证本地 Node/OpenSSL TLS 栈能否验证书链。如果探测因证书错误失败(例如 `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),doctor 会打印特定平台的修复指导。在使用 Homebrew Node 的 macOS 上,修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,也会运行该探测。
</Accordion>
<Accordion title="2e. Codex OAuth 提供商覆盖设置">
如果你之前在 `models.providers.openai-codex` 下添加过旧版 OpenAI 传输设置,它们可能会遮蔽新版会自动使用的内置 Codex OAuth 提供商路径。Doctor 在看到这些旧传输设置与 Codex OAuth 同时存在时会发出警告,以便你移除或重写过时的传输覆盖设置,并恢复内置路由/备用行为。仍支持自定义代理和仅标头覆盖,且不会触发此警告。
<Accordion title="2e. Codex OAuth 提供商覆盖">
如果你之前在 `models.providers.openai-codex` 下添加了旧版 OpenAI 传输设置,它们可能会遮蔽较新版本自动使用的内置 Codex OAuth 提供商路径。Doctor 在看到这些旧传输设置与 Codex OAuth 同时存在时会发出警告,以便你移除或重写过时的传输覆盖,并恢复内置路由/回退行为。自定义代理和仅标头覆盖仍受支持,且不会触发此警告。
</Accordion>
<Accordion title="2f. Codex 插件路由警告">
启用内置 Codex 插件时,Doctor 还会检查 `openai-codex/*` 主模型引用是否仍通过默认 PI runner 解析。当你想通过 PI 使用 Codex OAuth/订阅凭证时,这种组合是有效的,但很容易与原生 Codex app-server harness 混淆。Doctor 会发出警告,并指向显式 app-server 形态:`openai/*` 加 `agentRuntime.id: "codex"``OPENCLAW_AGENT_RUNTIME=codex`
启用内置 Codex 插件时,doctor 还会检查 `openai-codex/*` 主模型引用是否仍通过默认 PI runner 解析。当你想通过 PI 使用 Codex OAuth/订阅凭证时,这种组合是有效的,但很容易与原生 Codex app-server harness 混淆。Doctor 会发出警告,并指向显式 app-server 形态:`openai/*` 加 `agentRuntime.id: "codex"``OPENCLAW_AGENT_RUNTIME=codex`
Doctor 不会自动修复此项,因为两条路由都有效:
Doctor 不会自动修复这一点,因为两条路由都有效:
- `openai-codex/*` + PI 表示“通过常规 OpenClaw runner 使用 Codex OAuth/订阅凭证。”
- `openai-codex/*` + PI 表示“通过普通 OpenClaw runner 使用 Codex OAuth/订阅凭证。”
- `openai/*` + `runtime: "codex"` 表示“通过原生 Codex app-server 运行嵌入式回合。”
- `/codex ...` 表示“从聊天中控制或绑定原生 Codex 对话。”
- `/acp ...``runtime: "acp"` 表示“使用外部 ACP/acpx 适配器。”
如果出现此警告,请选择你想要的路由并手动编辑配置。当 PI Codex OAuth 是有意设置时,保持该警告不变。
如果出现该警告,请选择你预期的路由并手动编辑配置。当 PI Codex OAuth 是有意为之时,保持该警告不变。
</Accordion>
<Accordion title="3. 旧版状态迁移(磁盘布局)">
Doctor 可以将较旧的磁盘布局迁移到当前结构:
- 会话存储 + 转录记录
- 会话存储 + 转录:
- 从 `~/.openclaw/sessions/``~/.openclaw/agents/<agentId>/sessions/`
- Agent 目录:
- 智能体目录:
- 从 `~/.openclaw/agent/``~/.openclaw/agents/<agentId>/agent/`
- WhatsApp 凭证状态Baileys
- 从旧版 `~/.openclaw/credentials/*.json`(不包括 `oauth.json`
- 到 `~/.openclaw/credentials/whatsapp/<accountId>/...`(默认账号 ID`default`
这些迁移是尽力而为且幂等的;当 Doctor 将任何旧版文件夹作为备份保留下来时会发出警告。Gateway 网关/CLI 也会在启动时自动迁移旧版会话 + Agent 目录,因此历史记录/凭证/模型会落到每个 Agent 的路径中,无需手动运行 Doctor。WhatsApp 凭证有意只通过 `openclaw doctor` 迁移。Talk 提供商/provider-map 规范化现在按结构相等性进行比较,因此仅键顺序不同的 diff 不再触发重复的无操作 `doctor --fix` 更改。
这些迁移会尽力执行且可重复执行;当 doctor 将任何旧版文件夹作为备份保留下来时会发出警告。Gateway 网关/CLI 也会在启动时自动迁移旧版会话和智能体目录,因此历史记录/凭证/模型会落到按智能体划分的路径中,无需手动运行 doctor。WhatsApp 凭证有意只通过 `openclaw doctor` 迁移。Talk 提供商/提供商映射规范化现在按结构相等进行比较,因此仅键顺序不同的差异不再触发重复的无操作 `doctor --fix` 更改。
</Accordion>
<Accordion title="3a. 旧版插件清单迁移">
Doctor 会扫描所有已安装插件清单,查找已弃用的顶层能力键(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders`)。找到后,它会提示将这些键移动到 `contracts` 对象中,并就地重写清单文件。此迁移是幂等的;如果 `contracts` 键已经有相同的值,则会移除旧版键,而不会复制数据。
Doctor 会扫描所有已安装插件清单,查找已弃用的顶层能力键(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders`)。找到后,它会提供将这些键移入 `contracts` 对象,并就地重写清单文件。此迁移可重复执行;如果 `contracts` 键已有相同值,则会移除旧版键,而不会重复数据。
</Accordion>
<Accordion title="3b. 旧版 cron 存储迁移">
Doctor 还会检查 cron 任务存储(默认是 `~/.openclaw/cron/jobs.json`,或覆盖后使用 `cron.store`),查找调度器仍为兼容性接受的旧任务形态。
Doctor 还会检查 cron 作业存储(默认是 `~/.openclaw/cron/jobs.json`,或覆盖时使用 `cron.store`),查找调度器仍为兼容性接受的旧作业形态。
当前 cron 清理包括:
- `jobId``id`
- `schedule.cron``schedule.expr`
- 顶层 payload 字段(`message`、`model`、`thinking` 等)→ `payload`
- 顶层 delivery 字段(`deliver`、`channel`、`to`、`provider` 等)→ `delivery`
- payload `provider` delivery 别名 → 显式 `delivery.channel`
- 简单旧版 `notify: true` webhook 备用任务 → 显式 `delivery.mode="webhook"`,并设置 `delivery.to=cron.webhook`
- 顶层载荷字段(`message`、`model`、`thinking`、...)→ `payload`
- 顶层投递字段(`deliver`、`channel`、`to`、`provider`、...)→ `delivery`
- 载荷 `provider` 投递别名 → 显式 `delivery.channel`
- 简单旧版 `notify: true` webhook 回退作业 → 显式 `delivery.mode="webhook"`,并带有 `delivery.to=cron.webhook`
Doctor 只会在不改变行为的情况下自动迁移 `notify: true` 任务。如果某个任务将旧版 notify 备用行为与现有非 webhook delivery 模式组合使用Doctor 会发出警告,并将该任务留待手动审查。
Doctor 只会在不改变行为的情况下自动迁移 `notify: true` 作业。如果某个作业将旧版 notify 回退与现有非 webhook 投递模式组合使用doctor 会发出警告,并将该作业留待手动审查。
</Accordion>
<Accordion title="3c. 会话锁清理">
Doctor 会扫描每个 Agent 会话目录,查找过期写入锁文件,即会话异常退出后留下的文件。对找到的每个锁文件它会报告路径、PID、PID 是否仍存活、锁龄,以及是否被视为过期PID 已死或超过 30 分钟)。在 `--fix` / `--repair` 模式下,它会自动移除过期锁文件;否则会打印备注,并提示你`--fix` 重新运行。
Doctor 会扫描每个智能体会话目录,查找过期的写入锁文件即会话异常退出后留下的文件。对找到的每个锁文件它会报告路径、PID、该 PID 是否仍存活、锁的年龄,以及是否被认为已过期PID 已死或超过 30 分钟)。在 `--fix` / `--repair` 模式下,它会自动移除过期锁文件;否则会打印说明,并指示你使`--fix` 重新运行。
</Accordion>
<Accordion title="3d. 会话转录分支修复">
Doctor 会扫描 Agent 会话 JSONL 文件,查找由 2026.4.24 提示转录重写 bug 创建的重复分支形态:一个包含 OpenClaw 内部运行时上下文的废弃用户回合,以及一个包含相同可见用户提示的活跃同级分支。在 `--fix` / `--repair` 模式下Doctor 会在原文件旁备份每个受影响文件,并将转录记录重写到活跃分支,使 Gateway 网关历史记录和记忆读取器不再看到重复回合。
Doctor 会扫描智能体会话 JSONL 文件,查找由 2026.4.24 提示转录重写错误创建的重复分支形态:一个废弃的用户回合包含 OpenClaw 内部运行时上下文,旁边还有一个活跃同级分支包含相同的可见用户提示。在 `--fix` / `--repair` 模式下doctor 会在原文件旁备份每个受影响文件,并将转录重写为活跃分支,这样 Gateway 网关历史记录和记忆读取器就不会再看到重复回合。
</Accordion>
<Accordion title="4. 状态完整性检查(会话持久化、路由和安全)">
状态目录是运行中的中枢。如果它消失,你会丢失会话、凭证、日志和配置(除非你在其他地方有备份)。
状态目录是运行时的核心。如果它消失,你会丢失会话、凭证、日志和配置(除非你在别处有备份)。
Doctor 会检查:
- **状态目录缺失**:警告可能发生灾难性状态丢失,提示重新创建目录,并提醒你无法恢复缺失数据。
- **状态目录权限**:验证可写性;提供修复权限选项(并在检测到所有者/组不匹配时输`chown` 提示)。
- **macOS 云同步状态目录**:当状态解析到 iCloud Drive`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或 `~/Library/CloudStorage/...` 下时发出警告,因为同步支持的路径可能导致 I/O 更慢以及锁定/同步竞争
- **Linux SD 或 eMMC 状态目录**:当状态解析到 `mmcblk*` 挂载源时发出警告,因为 SD 或 eMMC 支持的随机 I/O 在写入会话和凭证时可能更慢且磨损更快。
- **会话目录缺失**`sessions/` 和会话存储目录是持久化历史记录并避免 `ENOENT` 崩溃所必需的
- **转录记录不匹配**:当最近的会话条目缺少转录记录文件时发出警告。
- **主会话“1 行 JSONL”**:当主转录记录只有一行时标记(历史记录没有累积)。
- **多个状态目录**:当多个主目录中存在多个 `~/.openclaw` 文件夹,或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史记录可能在多个安装之间拆分)。
- **状态目录缺失**:警告灾难性状态丢失,提示重新创建目录,并提醒你无法恢复缺失数据。
- **状态目录权限**:验证可写性;提供修复权限的选项(检测到所有者/组不匹配时会发`chown` 提示)。
- **macOS 云同步状态目录**:当状态解析到 iCloud Drive`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或 `~/Library/CloudStorage/...` 下时发出警告,因为由同步支持的路径可能导致较慢的 I/O 以及锁定/同步竞态
- **Linux SD 或 eMMC 状态目录**:当状态解析到 `mmcblk*` 挂载源时发出警告,因为基于 SD 或 eMMC 的随机 I/O 在会话和凭证写入下可能更慢且磨损更快。
- **会话目录缺失**需要 `sessions/` 和会话存储目录来持久化历史并避免 `ENOENT` 崩溃
- **转录不匹配**:当最近的会话条目缺少转录文件时发出警告。
- **主会话“单行 JSONL”**:当主转录只有一行时标记(历史未在累积)。
- **多个状态目录**:当多个主目录中存在多个 `~/.openclaw` 文件夹,或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史可能在不同安装之间拆分)。
- **远程模式提醒**:如果 `gateway.mode=remote`Doctor 会提醒你在远程主机上运行它(状态存储在那里)。
- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 对组/所有人可读,会发出警告并提供收紧到 `600` 的选项。
- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 可被组/所有人读取,则发出警告,并提供收紧到 `600` 的选项。
</Accordion>
<Accordion title="5. 模型认证健康状况OAuth 过期)">
Doctor 会检查认证存储中的 OAuth 配置文件,在令牌即将过期/已过期时发出警告,并在安全时刷新它们。如果 Anthropic OAuth/令牌配置文件已过期,它会建议使用 Anthropic API key 或 Anthropic 设置令牌路径。刷新提示仅在交互式运行TTY时出现`--non-interactive` 会跳过刷新尝试。
Doctor 会检查认证存储中的 OAuth 配置文件,在令牌即将过期/已过期时发出警告,并在安全时刷新它们。如果 Anthropic OAuth/令牌配置文件已过期,它会建议使用 Anthropic API key 或 Anthropic setup-token 路径。刷新提示只会在交互式运行TTY时出现`--non-interactive` 会跳过刷新尝试。
当 OAuth 刷新永久失败(例如 `refresh_token_reused`、`invalid_grant`,或提供商要求你重新登录)Doctor 会报告需要重新认证,并打印要运行的确切 `openclaw models auth login --provider ...` 命令。
当 OAuth 刷新永久失败(例如 `refresh_token_reused`、`invalid_grant`或提供商要求你重新登录Doctor 会报告需要重新认证,并打印要运行的确切 `openclaw models auth login --provider ...` 命令。
Doctor 还会报告因以下原因暂时不可用的认证配置文件:
Doctor 还会报告因以下原因暂时不可用的认证配置文件:
- 短暂冷却(速率限制/超时/认证失败)
- 较长时间禁用(计费/额度失败)
- 更长时间的禁用(账单/额度失败)
</Accordion>
<Accordion title="6. 钩子模型验证">
如果设置了 `hooks.gmail.model`Doctor 会根据目录和允许列表验证模型引用,并在无法解析或被禁止时发出警告。
如果设置了 `hooks.gmail.model`Doctor 会根据目录和允许列表验证模型引用,并在无法解析或被禁止时发出警告。
</Accordion>
<Accordion title="7. 沙箱镜像修复">
启用沙箱隔离Doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧名称的选项。
启用沙箱隔离Doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧名称的选项。
</Accordion>
<Accordion title="7b. 内置插件运行时依赖">
Doctor 仅验证当前配置中处于活动状态或由其内置清单默认启用的内置插件的运行时依赖,例如 `plugins.entries.discord.enabled: true`、旧版 `channels.discord.enabled: true`、已配置的 `models.providers.*` / 智能体模型引用,或没有提供商所有权的默认启用内置插件。如果缺少任何依赖Doctor 会报告这些包,并在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下安装它们。外部插件仍然使用 `openclaw plugins install` / `openclaw plugins update`Doctor 不会为任意插件路径安装依赖。
Doctor 只会验证当前配置中处于活动状态,或由其内置清单默认启用的内置插件的运行时依赖,例如 `plugins.entries.discord.enabled: true`、旧版 `channels.discord.enabled: true`、已配置的 `models.providers.*` / 智能体模型引用,或没有提供商所有权的默认启用内置插件。如果有任何缺失Doctor 会报告这些包,并在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下安装它们。外部插件仍然使用 `openclaw plugins install` / `openclaw plugins update`Doctor 不会为任意插件路径安装依赖。
在 Doctor 修复期间,内置运行时依赖的 npm 安装会在 TTY 会话中报告 spinner 进度,并在管道/无头输出中定期输出行进度。Gateway 网关和本地 CLI 也可以在导入内置插件前按需修复活动内置插件的运行时依赖。这些安装限定在插件运行时安装根目录内运行,禁用脚本运行,不写入 package lock并由安装根目录锁保护确保并发 CLI 或 Gateway 网关启动不会同时修改同一个 `node_modules` 树。当来自被终止的 Docker/容器启动的旧版陈旧锁无法通过其所有者元数据证明当前进程实例且锁文件已陈旧时,会被回收。
在 Doctor 修复期间,内置运行时依赖的 npm 安装会在 TTY 会话中报告加载进度,并在管道/无头输出中定期输出行进度。Gateway 网关启动和配置重载会在导入内置插件运行时模块之前进入 plugin-plan 模式;正常运行时导入仅验证,不会生成包管理器修复。这些安装限定在插件运行时安装根目录中运行,禁用脚本,不写入包锁,并由安装根锁保护,因此并发 CLI 或 Gateway 网关启动不会同时修改同一个 `node_modules` 树。当被终止的 Docker/容器启动留下的旧版过期锁,其所有者元数据无法证明当前进程实例且锁文件已过旧时,会被回收。
</Accordion>
<Accordion title="8. Gateway 网关服务迁移和清理提示">
Doctor 会检测旧版 Gateway 网关服务launchd/systemd/schtasks并提供移除它们并使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的 Gateway 网关类服务并打印清理提示。带配置文件名称的 OpenClaw Gateway 网关服务被视为一等服务,不会被标记为“额外”。
Doctor 会检测旧版 Gateway 网关服务launchd/systemd/schtasks并提供移除它们、使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的类似 Gateway 网关的服务并打印清理提示。带有配置文件名称的 OpenClaw Gateway 网关服务被视为一等服务,不会被标记为“额外”。
在 Linux 上,如果用户级 Gateway 网关服务缺失但存在系统级 OpenClaw Gateway 网关服务Doctor 不会自动安装第二个用户级服务。使用 `openclaw gateway status --deep``openclaw doctor --deep` 检查,然后移除重复项;或者在系统级 supervisor 拥有 Gateway 网关生命周期时设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`
在 Linux 上,如果用户级 Gateway 网关服务缺失但存在系统级 OpenClaw Gateway 网关服务Doctor 不会自动安装第二个用户级服务。使用 `openclaw gateway status --deep``openclaw doctor --deep` 检查,然后移除重复项;如果系统级监督器拥有 Gateway 网关生命周期,请设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`
</Accordion>
<Accordion title="8b. 启动 Matrix 迁移">
当 Matrix 渠道账存在待处理或可执行的旧版状态迁移时Doctor`--fix` / `--repair` 模式下)会创建迁移前快照,然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版加密状态准备。这两个步骤都不是致命错误;错误会被记录,启动会继续。在只读模式(不带 `--fix``openclaw doctor`),此检查会完全跳过。
当 Matrix 渠道账存在待处理或可执行的旧版状态迁移时Doctor`--fix` / `--repair` 模式下)会创建迁移前快照,然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版加密状态准备。这两个步骤都不是致命;错误会被记录,启动会继续。在只读模式(不带 `--fix``openclaw doctor`,此检查会完全跳过。
</Accordion>
<Accordion title="8c. 设备配对和认证漂移">
Doctor 现在会在常健康检查中检查设备配对状态。
Doctor 现在会在常健康检查过程中检查设备配对状态。
它会报告:
- 待处理的首次配对请求
- 已配对设备的待处理角色升级
- 已配对设备的待处理范围升级
- 设备 id 仍匹配但设备身份不再匹配已批准记录的公钥不匹配修复
- 缺少已批准角色活动令牌的配对记录
- 范围漂移到已批准配对基线之外的配对令牌
- 当前机器上早于 Gateway 网关侧令牌轮换或携带陈旧范围元数据的本地缓存设备令牌条目
- 已配对设备的待处理作用域升级
- 公钥不匹配修复,其中设备 ID 仍匹配,但设备身份不再匹配已批准记录
- 缺少已批准角色活动令牌的配对记录
- 作用域漂移到已批准配对基线之外的配对令牌
- 当前机器的本地缓存设备令牌条目早于 Gateway 网关侧令牌轮换,或携带过期作用域元数据
Doctor 不会自动批准配对请求或自动轮换设备令牌。它会改为打印确切的后续步骤:
- 使用 `openclaw devices list` 检查待处理请求
- 使用 `openclaw devices approve <requestId>` 批准确切请求
- 使用 `openclaw devices rotate --device <deviceId> --role <role>` 轮换新令牌
- 使用 `openclaw devices remove <deviceId>` 移除并重新批准陈旧记录
- 使用 `openclaw devices remove <deviceId>` 移除并重新批准过期记录
堵住了常见的“已配对但仍收到需要配对提示”漏洞Doctor 现在会区分首次配对、待处理的角色/范围升级,以及陈旧令牌/设备身份漂移。
解决了常见的“已配对但仍提示需要配对”问题Doctor 现在会区分首次配对、待处理的角色/作用域升级,以及过期令牌/设备身份漂移。
</Accordion>
<Accordion title="9. 安全警告">
当提供商对私信开放但没有允许列表或策略以危险方式配置时Doctor 会发出警告。
当提供商在没有允许列表的情况下向私信开放或策略以危险方式配置时Doctor 会发出警告。
</Accordion>
<Accordion title="10. systemd lingerLinux">
如果作为 systemd 用户服务运行Doctor 会确保已启用 lingering使 Gateway 网关在登出后仍保持运行
如果作为 systemd 用户服务运行Doctor 会确保已启用 linger,以便 Gateway 网关在注销后继续保持活动
</Accordion>
<Accordion title="11. 工作区状态Skills、插件和旧版目录">
Doctor 会打印默认智能体的工作区状态摘要:
- **Skills 状态**:统计符合条件、缺少要求以及被允许列表阻止的 Skills。
- **Skills 状态**:统计符合条件、缺少要求被允许列表阻止的 Skills。
- **旧版工作区目录**:当 `~/openclaw` 或其他旧版工作区目录与当前工作区并存时发出警告。
- **插件状态**:统计已启用/已禁用/出错的插件;列出所有错误的插件 ID报告捆绑插件能力。
- **插件状态**:统计已启用/已禁用/出错的插件;列出任何错误的插件 ID报告包插件能力。
- **插件兼容性警告**:标记与当前运行时存在兼容性问题的插件。
- **插件诊断**:显示插件注册表在加载时出的任何警告或错误。
- **插件诊断**:显示插件注册表在加载时出的任何警告或错误。
</Accordion>
<Accordion title="11b. Bootstrap 文件大小">
Doctor 会检查工作区 bootstrap 文件(例如 `AGENTS.md`、`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过配置的字符预算。它会报告每个文件的原始字符数与注入字符数、截断百分比、截断原因(`max/file` 或 `max/total`以及总注入字符数占总预算的比例。当文件被截断或接近限制时Doctor 会打印调优 `agents.defaults.bootstrapMaxChars``agents.defaults.bootstrapTotalMaxChars` 的提示。
Doctor 会检查工作区 bootstrap 文件(例如 `AGENTS.md`、`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过配置的字符预算。它会报告每个文件的原始字符数与注入字符数、截断百分比、截断原因(`max/file` 或 `max/total`以及总注入字符数占总预算的比例。当文件被截断或接近限制时Doctor 会打印用于调整 `agents.defaults.bootstrapMaxChars``agents.defaults.bootstrapTotalMaxChars` 的提示。
</Accordion>
<Accordion title="11d. 陈旧渠道插件清理">
`openclaw doctor --fix` 移除缺失的渠道插件时,它还会移除引用该插件的悬空渠道作用域配置:`channels.<id>` 条目、命名该渠道的 Heartbeat 目标,以及 `agents.*.models["<channel>/*"]` 覆盖项。这可以防止渠道运行时已消失但配置仍要求 Gateway 网关绑定到它而导致的 Gateway 网关启动循环。
<Accordion title="11d. 过期渠道插件清理">
`openclaw doctor --fix` 移除缺失的渠道插件时,它也会移除引用该插件的悬空渠道级配置:`channels.<id>` 条目、命名该渠道的 Heartbeat 目标,以及 `agents.*.models["<channel>/*"]` 覆盖项。这可以防止渠道运行时已消失但配置仍要求 Gateway 网关绑定到它而导致的 Gateway 网关启动循环。
</Accordion>
<Accordion title="11c. Shell 补全">
Doctor 会检查当前 shellzsh、bash、fish 或 PowerShell是否已安装 Tab 补全:
Doctor 会检查当前 shellzsh、bash、fish 或 PowerShell是否已安装 tab 补全:
- 如果 shell 配置文件使用慢的动态补全模式(`source <(openclaw completion ...)`Doctor 会将其升级为更快的缓存文件变体。
- 如果 shell 配置文件使用慢的动态补全模式(`source <(openclaw completion ...)`Doctor 会将其升级为更快的缓存文件变体。
- 如果配置文件中已配置补全但缓存文件缺失Doctor 会自动重新生成缓存。
- 如果完全配置补全Doctor 会提示安装它(仅交互模式;使用 `--non-interactive` 时跳过)。
- 如果完全没有配置补全Doctor 会提示安装它(仅交互模式;使用 `--non-interactive` 时跳过)。
运行 `openclaw completion --write-state` 可手动重新生成缓存。
@ -416,73 +416,73 @@ openclaw memory rem-backfill --path ./memory --stage-short-term
<Accordion title="12. Gateway 网关认证检查(本地令牌)">
Doctor 会检查本地 Gateway 网关令牌认证就绪状态。
- 如果令牌模式需要令牌但没有令牌源Doctor 会提供生成令牌的选项。
- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用Doctor 会发出警告,且不会用明文覆盖它。
- 如果令牌模式需要令牌但不存在令牌源Doctor 会提供生成一个令牌的选项。
- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用Doctor 会发出警告,且不会用明文覆盖它。
- `openclaw doctor --generate-gateway-token` 仅在未配置令牌 SecretRef 时强制生成。
</Accordion>
<Accordion title="12b. 支持只读 SecretRef 的修复">
些修复流程需要检查已配置的凭证,同时不削弱运行时快速失败行为。
<Accordion title="12b. 只读 SecretRef 感知修复">
些修复流程需要检查已配置的凭证,同时不削弱运行时快速失败行为。
- `openclaw doctor --fix` 现在使用与状态类命令相同的只读 SecretRef 摘要模型进行目标配置修复。
- 示例Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在可用时尝试使用已配置的 bot 凭证。
- 如果 Telegram bot 令牌通过 SecretRef 配置但在当前命令路径中不可用Doctor 会报告凭证已配置但不可用,并跳过自动解析,而不是崩溃或误报令牌缺失。
- `openclaw doctor --fix` 现在使用与状态类命令相同的只读 SecretRef 摘要模型,用于定向配置修复。
- 示例Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在可用时尝试使用已配置的机器人凭证。
- 如果 Telegram 机器人令牌通过 SecretRef 配置,但在当前命令路径中不可用Doctor 会报告凭证已配置但不可用,并跳过自动解析,而不是崩溃或误报令牌缺失。
</Accordion>
<Accordion title="13. Gateway 网关健康检查 + 重启">
Doctor 会运行健康检查,并在 Gateway 网关看起来不健康时提供重启选项。
</Accordion>
<Accordion title="13b. 记忆搜索就绪状态">
Doctor 会检查默认智能体已配置的记忆搜索嵌入提供商是否就绪。行为取决于已配置的后端和提供商:
Doctor 会检查已配置的记忆搜索嵌入提供商是否已为默认智能体就绪。行为取决于已配置的后端和提供商:
- **QMD 后端**:探测 `qmd` 二进制文件是否可用且可启动。如果不可用,打印修复指导,包括 npm 包和手动二进制路径选项。
- **显式本地提供商**:检查本地模型文件或可识别的远程/可下载模型 URL。如果缺失建议切换到远程提供商。
- **显式远程提供商**`openai`、`voyage` 等):验证环境或认证存储中是否存在 API key。如果缺失打印可执行的修复提示。
- **QMD 后端**:探测 `qmd` 二进制文件是否可用且可启动。如果不可用,打印修复指导,包括 npm 包和手动二进制路径选项。
- **显式本地提供商**:检查本地模型文件,或已识别的远程/可下载模型 URL。如果缺失建议切换到远程提供商。
- **显式远程提供商**`openai`、`voyage` 等):验证环境或认证存储中是否存在 API key。如果缺失打印可执行的修复提示。
- **自动提供商**:先检查本地模型可用性,然后按自动选择顺序尝试每个远程提供商。
缓存的 Gateway 网关探测结果可用时(检查时 Gateway 网关是健康的Doctor 会将其结果与 CLI 可见的配置交叉核对并记录任何差异。Doctor 不会在默认路径上发起新的嵌入 ping当你需要实时提供商检查时请使用深度记忆 Status 命令。
当缓存的 Gateway 网关探测结果可用时Gateway 网关在检查时是健康的Doctor 会将其结果与 CLI 可见配置交叉核对并指出任何差异。Doctor 不会在默认路径上启动新的嵌入 ping如果你需要实时提供商检查请使用深度记忆状态命令。
使用 `openclaw memory status --deep` 在运行时验证嵌入就绪状态。
</Accordion>
<Accordion title="14. 渠道状态警告">
如果 Gateway 网关健康Doctor 会运行渠道状态探测,并报告带有建议修复方的警告。
如果 Gateway 网关健康Doctor 会运行渠道状态探测,并报告带有建议修复方的警告。
</Accordion>
<Accordion title="15. 监督器配置审计 + 修复">
Doctor 会检查已安装的监督器配置launchd/systemd/schtasks是否缺少默认值或使用了过时默认值(例如 systemd network-online 依赖和重启延迟)。当发现不匹配时,它会建议更新,并可将服务文件/任务重写为当前默认值。
Doctor 会检查已安装的监督器配置launchd/systemd/schtasks,查找缺失或过时的默认值(例如 systemd network-online 依赖项和重启延迟)。发现不匹配时,它会建议更新,并可以将服务文件/任务重写为当前默认值。
注意:
注意事项
- `openclaw doctor` 会在重写监督器配置前提示。
- `openclaw doctor --yes` 接受默认修复提示。
- `openclaw doctor --repair` 会在不提示的情况下应用建议修复。
- `openclaw doctor --repair` 无需提示即可应用建议修复。
- `openclaw doctor --repair --force` 会覆盖自定义监督器配置。
- `OPENCLAW_SERVICE_REPAIR_POLICY=external` 让 Doctor 对 Gateway 网关服务生命周期保持只读。它仍会报告服务健康状态并运行非服务修复,但会跳过服务安装/启动/重启/引导、监督器配置重写以及旧版服务清理,因为该生命周期由外部监督器负责
- 在 Linux 上,当匹配的 systemd Gateway 网关单元处于活动状态时Doctor 不会重写命令/入口点元数据。它还会在重复服务扫描期间忽略非活动的非旧版额外 Gateway 网关类似单元,因此配套服务文件不会产生清理噪声
- `OPENCLAW_SERVICE_REPAIR_POLICY=external` 让 Doctor 对 Gateway 网关服务生命周期保持只读。它仍会报告服务健康状态并运行非服务修复,但会跳过服务安装/启动/重启/bootstrap、监督器配置重写和旧版服务清理因为该生命周期由外部监督器拥有
- 在 Linux 上,当匹配的 systemd Gateway 网关单元处于活动状态时Doctor 不会重写命令/入口点元数据。它还会在重复服务扫描期间忽略非活动的非旧版额外 Gateway 网关类似单元,以免配套服务文件产生清理噪音
- 如果令牌认证需要令牌,并且 `gateway.auth.token` 由 SecretRef 管理Doctor 服务安装/修复会验证 SecretRef但不会将解析后的明文令牌值持久化到监督器服务环境元数据中。
- Doctor 会检测旧版 LaunchAgent、systemd 或 Windows 计划任务安装中内联嵌入的托管 `.env`/SecretRef 后备服务环境值,并重写服务元数据,使这些值从运行时源加载,而不是从监督器定义加载。
- Doctor 会检测服务命令是否`gateway.port` 更改后仍固定旧的 `--port`,并将服务元数据重写为当前端口。
- 如果令牌认证需要令牌,而配置的令牌 SecretRef 未解析Doctor 会阻止安装/修复路径,并提供可操作的指导。
- 如果同时配置了 `gateway.auth.token``gateway.auth.password`,且未设置 `gateway.auth.mode`Doctor 会阻止安装/修复,直到显式设置模式。
- 对于 Linux 用户 systemd 单元Doctor 令牌漂移检查现在会在比较服务认证元数据时同时包含 `Environment=``EnvironmentFile=` 源。
- 当配置最后由较新版本写入时Doctor 服务修复会拒绝使用旧版 OpenClaw 二进制文件重写、停止或重启 Gateway 网关服务。请参阅 [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting#split-brain-installs-and-newer-config-guard)。
- Doctor 会检测旧版 LaunchAgent、systemd 或 Windows Scheduled Task 安装以内联方式嵌入的托管 `.env`/SecretRef 支持的服务环境值,并重写服务元数据,使这些值从运行时源加载,而不是从监督器定义加载。
- Doctor 会检测服务命令在 `gateway.port` 更改后是否仍固定旧的 `--port`,并将服务元数据重写为当前端口。
- 如果令牌认证需要令牌,而配置的令牌 SecretRef 未解析Doctor 会阻止安装/修复路径,并提供可执行的指导。
- 如果同时配置了 `gateway.auth.token``gateway.auth.password`,且 `gateway.auth.mode` 未设置Doctor 会阻止安装/修复,直到显式设置模式。
- 对于 Linux 用户 systemd 单元Doctor 令牌漂移检查现在会在比较服务认证元数据时同时包含 `Environment=``EnvironmentFile=` 源。
- 当配置最后由较新版本写入时Doctor 服务修复会拒绝从较旧的 OpenClaw 二进制文件重写、停止或重启 Gateway 网关服务。请参阅 [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting#split-brain-installs-and-newer-config-guard)。
- 你始终可以通过 `openclaw gateway install --force` 强制完整重写。
</Accordion>
<Accordion title="16. Gateway 网关运行时 + 端口诊断">
Doctor 会检查服务运行时PID、最后退出状态),并在服务已安装但未实际运行时发出警告。它还会检查 Gateway 网关端口(默认 `18789`上的端口冲突并报告可能原因Gateway 网关已在运行、SSH 隧道)。
Doctor 会检查服务运行时PID、上次退出状态),并在服务已安装但未实际运行时发出警告。它还会检查 Gateway 网关端口(默认 `18789`上的端口冲突并报告可能原因Gateway 网关已在运行、SSH 隧道)。
</Accordion>
<Accordion title="17. Gateway 网关运行时最佳实践">
当 Gateway 网关服务运行在 Bun 或版本管理的 Node 路径(`nvm`、`fnm`、`volta`、`asdf` 等上时Doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node并且版本管理器路径可能在升级后失效,因为服务不会加载你的 shell 初始化。Doctor 会在系统 Node 安装可用时Homebrew/apt/choco提供迁移选项。
当 Gateway 网关服务运行在 Bun 或版本管理的 Node 路径(`nvm`、`fnm`、`volta`、`asdf` 等上时Doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node版本管理器路径可能会在升级后中断,因为服务不会加载你的 shell 初始化。Doctor 会在系统 Node 安装可用时Homebrew/apt/choco提供迁移选项。
新安装或修复的服务会保留显式环境根目录(`NVM_DIR`、`FNM_DIR`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`BUN_INSTALL`、`PNPM_HOME`)和稳定的用户 bin 目录,但推测出的版本管理器回退目录只有在这些目录存在于磁盘上时才会写入服务 PATH。这会让生成的监督器 PATH 与 Doctor 稍后运行的同最小 PATH 审计保持一致。
新安装或修复的服务会保留显式环境根目录(`NVM_DIR`、`FNM_DIR`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`BUN_INSTALL`、`PNPM_HOME`)和稳定的用户 bin 目录,但推测出的版本管理器回退目录只有在这些目录存在于磁盘上时才会写入服务 PATH。这会让生成的监督器 PATH 与 Doctor 稍后运行的同一个最小 PATH 审计保持一致。
</Accordion>
<Accordion title="18. 配置写入 + 向导元数据">
Doctor 会持久化任何配置更改,并标记向导元数据以记录本次 Doctor 运行。
Doctor 会持久化任何配置更改,并标记向导元数据以记录 Doctor 运行。
</Accordion>
<Accordion title="19. 工作区提示(备份 + 记忆系统)">
Doctor 会在缺少工作区记忆系统时提出建议,并在工作区尚未纳入 git 管理时打印备份提示。
当工作区缺少记忆系统时Doctor 会建议添加;如果工作区尚未纳入 git 管理,则会打印备份提示。
请参阅 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace),获取工作区结构和 git 备份的完整指南(推荐使用私有 GitHub 或 GitLab

View File

@ -6,32 +6,25 @@ read_when:
summary: Gateway 网关 WebSocket 协议:握手、帧、版本控制
title: Gateway 网关协议
x-i18n:
generated_at: "2026-05-01T08:21:07Z"
generated_at: "2026-05-01T08:52:00Z"
model: gpt-5.5
provider: openai
source_hash: 1b80ee7d9a36f78b05b8ca83d70baf6ec53fc907ca25e8b4c2ab39350ff95c54
source_hash: 8ea0181fda62326ec835ff1f28ef6079e5afff5ffe3f06e08867bf16fb84f967
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
Gateway 网关 → 客户端(连接前质询
Gateway 网关 → 客户端(连接前挑战):
```json
{
@ -102,17 +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` 是可选字段。
`server`、`features`、`snapshot` 和 `policy` 都是架构要求的字段(`src/gateway/protocol/schema/frames.ts`)。`auth` 也是必需的,并报告协商后的角色/作用域。`canvasHostUrl` 是可选的。
未签发设备令牌时,`hello-ok.auth` 会报告协商后的
权限,不包含令牌字段:
当未签发设备令牌时,`hello-ok.auth` 会报告协商后的权限,不包含令牌字段:
```json
{
@ -123,14 +110,9 @@ Gateway 网关 → 客户端:
}
```
受信任的同进程后端客户端(`client.id: "gateway-client"`
`client.mode: "backend"`)在使用共享 Gateway 网关令牌/密码认证时,
可在直接 loopback 连接上省略 `device`。此路径仅保留给内部控制平面 RPC
并避免过期的 CLI/设备配对基线阻塞本地后端工作,例如子智能体会话更新。
远程客户端、浏览器来源客户端、节点客户端,以及显式设备令牌/设备身份
客户端仍使用常规配对和作用域升级检查。
受信任的同进程后端客户端(`client.id: "gateway-client"`、`client.mode: "backend"`)在使用共享 Gateway 网关令牌/密码进行身份验证的直接 loopback 连接上可以省略 `device`。此路径保留给内部控制平面 RPC并避免过期的 CLI/设备配对基线阻塞本地后端工作,例如 subagent 会话更新。远程客户端、浏览器来源客户端、节点客户端以及显式设备令牌/设备身份客户端仍使用常规配对和作用域升级检查。
签发设备令牌时,`hello-ok` 还会包含
当签发设备令牌时,`hello-ok` 还会包括:
```json
{
@ -142,8 +124,7 @@ Gateway 网关 → 客户端:
}
```
在受信任的启动交接期间,`hello-ok.auth` 也可能在 `deviceTokens` 中包含额外的
有界角色条目:
在受信任的引导移交期间,`hello-ok.auth` 也可能在 `deviceTokens` 中包含额外的有界角色条目:
```json
{
@ -162,12 +143,7 @@ Gateway 网关 → 客户端:
}
```
对于内置节点/operator 启动流程,主节点令牌保持
`scopes: []`,任何交接的 operator 令牌都保持受限于启动
operator 允许列表(`operator.approvals`、`operator.read`、
`operator.talk.secrets`、`operator.write`)。启动作用域检查保持
角色前缀约束operator 条目只满足 operator 请求,非 operator
角色仍需要其自身角色前缀下的作用域。
对于内置节点/操作员引导流程,主节点令牌保持 `scopes: []`,任何移交的操作员令牌都保持限制在引导操作员允许列表内(`operator.approvals`、`operator.read`、`operator.talk.secrets`、`operator.write`)。引导作用域检查保持角色前缀:操作员条目只满足操作员请求,非操作员角色仍需要其自身角色前缀下的作用域。
### 节点示例
@ -204,13 +180,13 @@ operator 允许列表(`operator.approvals`、`operator.read`、
}
```
## 帧格式
##
- **请求**`{type:"req", id, method, params}`
- **响应**`{type:"res", id, ok, payload|error}`
- **事件**`{type:"event", event, payload, seq?, stateVersion?}`
有副作用的方法需要**幂等键**见 schema)。
有副作用的方法需要**幂等键**请参见架构)。
## 角色 + 作用域
@ -219,9 +195,9 @@ operator 允许列表(`operator.approvals`、`operator.read`、
- `operator` = 控制平面客户端CLI/UI/自动化)。
- `node` = 能力宿主camera/screen/canvas/system.run
### 作用域(operator
### 作用域(操作员
作用域:
作用域:
- `operator.read`
- `operator.write`
@ -230,47 +206,37 @@ 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 作用域,但
保留的核心管理员前缀(`config.*`、`exec.approvals.*`、`wizard.*`、
`update.*`)始终解析为 `operator.admin`
插件注册的 Gateway 网关 RPC 方法可以请求自己的操作员作用域,但保留的核心管理员前缀(`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`
- 带有非 exec 节点命令的请求:`operator.pairing` + `operator.write`
- 包含 `system.run`、`system.run.prepare` 或 `system.which` 的请求:`operator.pairing` + `operator.admin`
### 能力/命令/权限(节点)
节点在连接时声明能力声明
节点在连接时声明能力主张
- `caps`:高级能力类别。
- `commands`:用于调用的命令允许列表。
- `permissions`:细粒度开关(例如 `screen.record`、`camera.capture`)。
Gateway 网关将这些视为**声明**,并强制执行服务器端允许列表。
Gateway 网关将这些视为**主张**,并强制执行服务器端允许列表。
## 在线状态
## Presence
- `system-presence` 返回按设备身份键控的条目。
- 在线状态条目包含 `deviceId`、`roles` 和 `scopes`,因此 UI 可以为每台设备显示单行,
即使它同时以 **operator****node** 身份连接。
- `node.list` 包含可选的 `lastSeenAtMs``lastSeenReason` 字段。已连接节点会将
其当前连接时间作为 `lastSeenAtMs` 报告,原因是 `connect`;当受信任节点事件更新其配对元数据时,已配对节点也可以报告
持久后台在线状态。
- `system-presence` 返回以设备身份为键的条目。
- Presence 条目包括 `deviceId`、`roles` 和 `scopes`,因此 UI 可以为每台设备显示单行,即使它同时作为**操作员**和**节点**连接。
- `node.list` 包括可选的 `lastSeenAtMs``lastSeenReason` 字段。已连接节点会将其当前连接时间报告为 `lastSeenAtMs`,原因为 `connect`;当受信任的节点事件更新其配对元数据时,已配对节点也可以报告持久化的后台 presence。
### 节点后台存活事件
节点可以调用带 `event: "node.presence.alive"``node.event`,以记录已配对节点在
后台唤醒期间处于存活状态,而不将其标记为已连接。
节点可以调用带有 `event: "node.presence.alive"``node.event`,以记录已配对节点在后台唤醒期间处于存活状态,而不将其标记为已连接。
```json
{
@ -279,10 +245,7 @@ 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 网关会返回结构化结果:
@ -295,58 +258,53 @@ Gateway 网关将这些视为**声明**,并强制执行服务器端允许列
}
```
较旧的 Gateway 网关仍可能为 `node.event` 返回 `{ "ok": true }`;客户端应将其视为
已确认的 RPC而不是持久在线状态的保存结果。
较旧的 Gateway 网关仍可能为 `node.event` 返回 `{ "ok": true }`;客户端应将其视为已确认的 RPC而不是持久化 presence。
## 广播事件作用域限定
## 广播事件作用域
服务器推送的 WebSocket 广播事件受作用域控,因此配对作用域或仅节点会话不会被动接收会话内容。
服务器推送的 WebSocket 广播事件受作用域控,因此配对作用域会话或仅节点会话不会被动接收会话内容。
- **聊天、智能体和工具结果帧**(包括流式 `agent` 事件和工具调用结果)至少需要 `operator.read`。没有 `operator.read` 的会话会完全跳过这些帧。
- **插件定义的 `plugin.*` 广播**会根据插件注册方式受限于 `operator.write``operator.admin`
- **Status 和传输事件**`heartbeat`、`presence`、`tick`、连接/断开连接生命周期等)保持不受限制,以便每个已认证会话都能观察传输健康状况。
- **未知广播事件族**默认受作用域限制(失败关闭),除非注册处理程序明确放宽限制
- **聊天、智能体和工具结果帧**(包括流式传输的 `agent` 事件和工具调用结果)至少需要 `operator.read`。没有 `operator.read` 的会话会完全跳过这些帧。
- **插件定义的 `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` 的完整枚举。
<AccordionGroup>
<Accordion title="系统和身份">
- `health` 返回缓存的或新探测的 Gateway 网关健康快照。
- `diagnostics.stability` 返回最近的有界诊断稳定性记录器。它保留事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID 等操作元数据。它不会保留聊天文本、Webhook 正文、工具输出、原始请求或响应正文、令牌、Cookie 或密钥值。需要 operator 读取作用域。
- `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅包含给具有管理员作用域的 operator 客户端
- `gateway.identity.get` 返回中继和配对流程使用的 Gateway 网关设备身份。
- `system-presence` 返回已连接 operator/node 设备的当前在线状态快照。
- `system-event` 追加系统事件,并可更新/广播在线状态上下文。
- `diagnostics.stability` 返回最近的有界诊断稳定性记录器。它保留操作元数据,例如事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID。它不会保留聊天文本、webhook 正文、工具输出、原始请求或响应正文、令牌、cookie 或秘密值。需要操作员读取作用域。
- `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅对具有管理员作用域的操作员客户端包含
- `gateway.identity.get` 返回 relay 和配对流程使用的 Gateway 网关设备身份。
- `system-presence` 返回已连接操作员/节点设备的当前 presence 快照。
- `system-event` 追加系统事件,并可以更新/广播 presence 上下文。
- `last-heartbeat` 返回最新持久化的 Heartbeat 事件。
- `set-heartbeats` 切换 Gateway 网关上的 Heartbeat 处理。
</Accordion>
<Accordion title="Models 和用量">
- `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` 返回当前默认智能体工作区的向量记忆 / 缓存嵌入就绪状态。只有当调用方明确需要实时嵌入提供商 ping 时,才传入 `{ "probe": true }``{ "deep": true }`
- `doctor.memory.remHarness` 为远程控制平面客户端返回一个有界、只读的 REM harness 预览。它可以包含工作区路径、记忆片段、渲染后的 grounded Markdown以及深度提升候选项因此调用方需要 `operator.read`
- `usage.cost` 返回某个日期范围内的聚合费用用量摘要。
- `doctor.memory.status` 返回当前默认智能体工作区的向量记忆 / 缓存嵌入就绪状态。仅当调用方明确需要实时嵌入提供商探测时,才传入 `{ "probe": true }``{ "deep": true }`
- `doctor.memory.remHarness` 返回面向远程控制平面客户端的有界只读 REM harness 预览。它可以包含工作区路径、记忆片段、渲染后的有依据 Markdown以及深度提升候选项因此调用方需要 `operator.read`
- `sessions.usage` 返回每个会话的用量摘要。
- `sessions.usage.timeseries` 返回一个会话的时间序列用量。
- `sessions.usage.logs` 返回一个会话的用量日志条目。
</Accordion>
<Accordion title="渠道和登录辅助方法">
- `channels.status` 返回内置 + 捆绑渠道/插件的 Status 摘要。
- `channels.logout` 在渠道支持注销时,注销指定渠道/账号。
- `web.login.start` 为当前支持 QR 的 Web 渠道提供商启动 QR/Web 登录流程。
- `web.login.wait` 等待该 QR/Web 登录流程完成,并在成功后启动渠道。
<Accordion title="渠道和登录辅助工具">
- `channels.status` 返回内置 + 捆绑的渠道/插件状态摘要。
- `channels.logout` 会在渠道支持登出的情况下登出特定渠道/账号。
- `web.login.start` 为当前支持 QR 的网页渠道提供商启动 QR/网页登录流程。
- `web.login.wait` 等待该 QR/网页登录流程完成,并在成功时启动渠道。
- `push.test` 向已注册的 iOS 节点发送测试 APNs 推送。
- `voicewake.get` 返回已存储的唤醒词触发器。
- `voicewake.set` 更新唤醒词触发器并广播变更。
@ -354,89 +312,89 @@ Gateway 网关将这些视为**声明**,并强制执行服务器端允许列
</Accordion>
<Accordion title="消息和日志">
- `send`用于在聊天运行器之外,按渠道/账号/线程目标发送消息的直接出站投递 RPC
- `logs.tail` 返回已配置的 Gateway 网关文件日志尾部,并带有游标/限制和最大字节数控制。
- `send`直接出站投递 RPC用于在聊天运行器之外执行面向渠道/账号/线程目标的发送
- `logs.tail` 返回已配置的 Gateway 网关文件日志尾部内容,并带有 cursor/limit 和 max-byte 控制。
</Accordion>
<Accordion title="Talk 和 TTS">
- `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` 运行一次性文本转语音转换。
</Accordion>
<Accordion title="密钥、配置、更新和向导">
- `secrets.reload` 重新解析活动 SecretRefs并且仅在完全成功时替换运行时密钥状态。
- `secrets.resolve` 为特定命令/目标集合解析面向命令目标的密钥赋值
- `secrets.reload` 重新解析活动 SecretRefs并且仅在完全成功时替换运行时密钥状态。
- `secrets.resolve` 为特定命令/目标集合解析命令目标密钥分配
- `config.get` 返回当前配置快照和哈希。
- `config.set` 写入验证的配置载荷。
- `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 节点、匹配的提示 + `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 网关更新流程,并且仅当更新本身成功时安排重启
- `update.status` 返回最新缓存的更新重启哨兵,包括可用时重启后的运行版本。
- `wizard.start`、`wizard.next`、`wizard.status` 和 `wizard.cancel` 通过 WS RPC 暴露新手引导向导。
- `config.schema` 返回 Control UI 和 CLI 工具使用的实时配置 schema 载荷schema、`uiHints`、version 和生成元数据,包括运行时能够加载时的插件 + 渠道 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 公开新手引导向导。
</Accordion>
<Accordion title="智能体和工作区辅助方法">
<Accordion title="智能体和工作区辅助工具">
- `agents.list` 返回已配置的智能体条目,包括有效模型和运行时元数据。
- `agents.create`、`agents.update` 和 `agents.delete` 管理智能体记录和工作区接线
- `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 来源会返回不支持的下载,而不是在服务端获取。
- `artifacts.list`、`artifacts.get` 和 `artifacts.download`明确的 `sessionKey`、`runId` 或 `taskId` 作用域公开从会话记录派生的工件摘要和下载。运行和任务查询会在服务器端解析所属会话,并且只返回来源匹配的会话记录媒体;不安全或本地 URL 来源会返回不支持的下载,而不是在服务器端抓取。
- `agent.identity.get` 返回智能体或会话的有效助手身份。
- `agent.wait` 等待一次运行完成,并在可用时返回终快照。
- `agent.wait` 等待运行完成,并在可用时返回终快照。
</Accordion>
<Accordion title="会话控制">
- `sessions.list` 返回当前会话索引,包括配置了智能体运行时后端时每行的 `agentRuntime` 元数据。
- `sessions.list` 返回当前会话索引,配置了智能体运行时后端时,包括每行的 `agentRuntime` 元数据。
- `sessions.subscribe``sessions.unsubscribe` 为当前 WS 客户端切换会话变更事件订阅。
- `sessions.messages.subscribe``sessions.messages.unsubscribe` 为一个会话切换转录记录/消息事件订阅。
- `sessions.preview` 返回特定会话键的有界转录记录预览。
- `sessions.resolve` 解析会话目标将其规范化。
- `sessions.messages.subscribe``sessions.messages.unsubscribe` 为一个会话切换会话记录/消息事件订阅。
- `sessions.preview` 返回特定会话键的有界会话记录预览。
- `sessions.resolve` 解析或规范化会话目标
- `sessions.create` 创建新的会话条目。
- `sessions.send` 向现有会话发送消息。
- `sessions.steer` 是活动会话的中断并 steering 变体。
- `sessions.abort` 中止会话的活动工作。调用方可以传入 `key` 加可选的 `runId`只为 Gateway 网关可解析到会话的活动运行传入 `runId`
- `sessions.patch` 更新会话元数据/覆盖项,并报告解析的规范模型以及有效的 `agentRuntime`
- `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 载荷(包括 `<tool_call>...</tool_call>`、`<function_call>...</function_call>`、`<tool_calls>...</tool_calls>`、`<function_calls>...</function_calls>`,以及被截断的工具调用块)和泄露的 ASCII/全角模型控制 token省略仅包含静默 token 的助手行,例如精确的 `NO_REPLY` / `no_reply`,并且超大的行可以替换为占位符。
- `sessions.get` 返回完整存储会话行。
- 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。`chat.history` 会为 UI 客户端进行显示标准化:从可见文本中剥离内联指令标签,剥离纯文本工具调用 XML 载荷(包括 `<tool_call>...</tool_call>`、`<function_call>...</function_call>`、`<tool_calls>...</tool_calls>`、`<function_calls>...</function_calls>` 和被截断的工具调用块)以及泄漏的 ASCII/全角模型控制令牌,省略完全为 `NO_REPLY` / `no_reply` 等纯静默令牌的助手行,并且过大的行可替换为占位符。
</Accordion>
<Accordion title="设备配对和设备 token">
<Accordion title="设备配对和设备令牌">
- `device.pair.list` 返回待处理和已批准的配对设备。
- `device.pair.approve`、`device.pair.reject` 和 `device.pair.remove` 管理设备配对记录。
- `device.token.rotate` 在其已批准角色和调用方范围边界内轮换配对设备 token
- `device.token.revoke` 在其已批准角色和调用方范围边界内撤销配对设备 token
- `device.token.rotate` 在其已批准角色和调用方作用域边界内轮换已配对设备令牌
- `device.token.revoke` 在其已批准角色和调用方作用域边界内撤销已配对设备令牌
</Accordion>
<Accordion title="节点配对、调用和待处理工作">
- `node.pair.request`、`node.pair.list`、`node.pair.approve`、`node.pair.reject`、`node.pair.remove` 和 `node.pair.verify` 覆盖节点配对和引导验证。
- `node.list``node.describe` 返回已知/已连接节点状态。
- `node.list``node.describe` 返回已知/已连接节点状态。
- `node.rename` 更新已配对节点标签。
- `node.invoke` 将命令转发到已连接节点
- `node.invoke` 向已连接节点转发命令
- `node.invoke.result` 返回调用请求的结果。
- `node.event` 将节点发起的事件回 Gateway 网关。
- `node.canvas.capability.refresh` 刷新有范围的 canvas 能力 token
- `node.event` 将节点发起的事件回 Gateway 网关。
- `node.canvas.capability.refresh` 刷新作用域限定的 canvas 能力令牌
- `node.pending.pull``node.pending.ack` 是已连接节点队列 API。
- `node.pending.enqueue``node.pending.drain` 管理离线/断开连接节点的持久待处理工作。
</Accordion>
<Accordion title="审批">
- `exec.approval.request`、`exec.approval.get`、`exec.approval.list` 和 `exec.approval.resolve` 覆盖一次性 exec 审批请求以及待处理审批查询/重放。
- `exec.approval.waitDecision` 等待一个待处理 exec 审批,并返回最终决策(或在超时时返回 `null`)。
<Accordion title="审批类别">
- `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` 覆盖插件定义的审批流程。
@ -444,27 +402,27 @@ Gateway 网关将这些视为**声明**,并强制执行服务器端允许列
</Accordion>
<Accordion title="自动化、Skills 和工具">
- 自动化:`wake` 安排立即或下一次 Heartbeat 的唤醒文本注入;`cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、`cron.run`、`cron.runs` 管理定时工作。
- 自动化:`wake` 安排立即或下一次心跳时的唤醒文本注入;`cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、`cron.run`、`cron.runs` 管理定时工作。
- Skills 和工具:`commands.list`、`skills.*`、`tools.catalog`、`tools.effective`、`tools.invoke`。
</Accordion>
</AccordionGroup>
### 常见事件
### 常见事件类别
- `chat`UI 聊天更新,例如 `chat.inject` 和其他仅转录记录的聊天
- `chat`UI 聊天更新,例如 `chat.inject` 和其他仅限会话记录的聊天
事件。
- `session.message``session.tool`:已订阅会话的转录记录/事件流更新。
- `session.message``session.tool`:已订阅会话的会话记录/事件流更新。
- `sessions.changed`:会话索引或元数据已变更。
- `presence`:系统在线状态快照更新。
- `tick`:周期性 keepalive / 活跃性事件。
- `tick`:周期性保活 / 存活事件。
- `health`Gateway 网关健康快照更新。
- `heartbeat`Heartbeat 事件流更新。
- `cron`cron 运行/任务变更事件。
- `heartbeat`心跳事件流更新。
- `cron`cron 运行/作业变更事件。
- `shutdown`Gateway 网关关闭通知。
- `node.pair.requested` / `node.pair.resolved`:节点配对生命周期。
- `node.invoke.request`:节点调用请求广播。
- `device.pair.requested` / `device.pair.resolved`:配对设备生命周期。
- `device.pair.requested` / `device.pair.resolved`配对设备生命周期。
- `voicewake.changed`:唤醒词触发器配置已变更。
- `exec.approval.requested` / `exec.approval.resolved`exec 审批
生命周期。
@ -473,69 +431,69 @@ Gateway 网关将这些视为**声明**,并强制执行服务器端允许列
### 节点辅助方法
- 节点可以调用 `skills.bins` 获取当前 Skills 可执行文件列表,
- 节点可以调用 `skills.bins` 获取当前 Skills 可执行文件列表,
用于自动允许检查。
### 操作辅助方法
### 操作辅助方法
- 操作可以调用 `commands.list``operator.read`)来获取智能体的运行时命令清单。
- `agentId` 是可选的;省略它会读取默认智能体工作区。
- 操作可以调用 `commands.list``operator.read`)来获取智能体的运行时命令清单。
- `agentId` 是可选的;省略它会读取默认 Agent 工作区。
- `scope` 控制主 `name` 面向哪个界面:
- `text` 返回不带前导 `/` 的主文本命令令牌
- `native` 和默认的 `both` 路径会在可用时返回感知提供商的原生命令名
- `native` 和默认的 `both` 路径会在可用时返回感知提供商的原生命令名
- `textAliases` 携带精确的斜杠别名,例如 `/model``/m`
- `nativeName` 在存在时携带感知提供商的原生命令名
- `provider` 是可选的,并且只影响原生命名以及原生插件命令可用性。
- `nativeName` 在存在时携带感知提供商的原生命令名。
- `provider` 是可选的,只影响原生命名以及原生插件命令可用性。
- `includeArgs=false` 会从响应中省略序列化的参数元数据。
- 操作可以调用 `tools.catalog``operator.read`)来获取智能体的运行时工具目录。响应包含分组工具和来源元数据:
- 操作可以调用 `tools.catalog``operator.read`)来获取智能体的运行时工具目录。响应包含分组后的工具和来源元数据:
- `source``core` 或 `plugin`
- `pluginId`:当 `source="plugin"` 时的插件所有者
- `optional`:插件工具是否可选
- 操作者可以调用 `tools.effective``operator.read`)来获取会话的运行时生效工具清单。
- 操作员可以调用 `tools.effective``operator.read`)来获取会话的运行时有效工具清单。
- `sessionKey` 是必需的。
- Gateway 网关会从服务端会话派生受信任的运行时上下文,而不是接受调用方提供的认证或交付上下文。
- 响应限定于会话范围,并反映当前活动对话现在可使用的内容,包括核心、插件和渠道工具。
- 操作可以调用 `tools.invoke``operator.write`),通过与 `/tools/invoke` 相同的 Gateway 网关策略路径调用一个可用工具。
- 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`)来获取智能体的可见 Skills 清单。
- `agentId` 是可选的;省略它会读取默认智能体工作区。
- 响应包含资格、缺失要求、配置检查,以及经过脱敏的安装选项,不会暴露原始密钥值。
- 操作可以调用 `skills.search``skills.detail``operator.read`)获取 ClawHub 发现元数据。
- 操作可以通过两种模式调用 `skills.install``operator.admin`
- ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 会把 Skills 文件夹安装到默认智能体工作区的 `skills/` 目录中。
- 响应是面向 SDK 的封,包含 `ok`、`toolName`、可选的 `output` 和带类型的 `error` 字段。批准或策略拒绝会在载荷中返回 `ok:false`,而不是绕过 Gateway 网关工具策略流水线
- 操作可以调用 `skills.status``operator.read`)来获取智能体的可见 Skills 清单。
- `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更新默认智能体工作区中所有已跟踪的 ClawHub 安装。
- 操作可以通过两种模式调用 `skills.update``operator.admin`
- ClawHub 模式会更新一个已跟踪的 slug默认 Agent 工作区中的所有已跟踪 ClawHub 安装。
- 配置模式会修补 `skills.entries.<skillKey>` 值,例如 `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而不是普通模型选择器。
- `"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 请求需要批准Gateway 网关会广播 `exec.approval.requested`
- 操作员客户端通过调用 `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/会话上下文。
- 如果调用方在准备阶段和最终批`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 会话或不明确的多渠道配置)。
## 版本控制
- `PROTOCOL_VERSION` 位于 `src/gateway/protocol/schema/protocol-schemas.ts`
- 客户端发送 `minProtocol` + `maxProtocol`;服务器会拒绝不匹配
- 客户端发送 `minProtocol` + `maxProtocol`;服务器会拒绝不匹配的情况
- Schema + 模型由 TypeBox 定义生成:
- `pnpm protocol:gen`
- `pnpm protocol:gen:swift`
@ -543,85 +501,101 @@ Gateway 网关将这些视为**声明**,并强制执行服务器端允许列
### 客户端常量
`src/gateway/client.ts` 中的参考客户端使用这些默认值。这些值在 protocol 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` |
| 预认证 / 连接挑战超时 | `15_000` ms | `src/gateway/handshake-timeouts.ts`(配置/环境变量可以提高对的服务器/客户端预算) |
| 预认证 / 连接质询超时 | `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` |
| `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`;客户端应遵守这些值,而不是使用握手前默认值。
##
##
- 共享密钥 Gateway 网关身份验证使用 `connect.params.auth.token`
`connect.params.auth.password`,具体取决于配置的身份验证模式。
- 带身份信息的模式,例如 Tailscale Serve
- 共享密钥 Gateway 网关证使用 `connect.params.auth.token`
`connect.params.auth.password`,具体取决于配置的证模式。
- 带身份的模式,例如 Tailscale Serve
(`gateway.auth.allowTailscale: true`) 或非 loopback
`gateway.auth.mode: "trusted-proxy"`,通过请求头而不是 `connect.params.auth.*`
满足连接身份验证检查。
- 私有入口 `gateway.auth.mode: "none"` 会完全跳过共享密钥连接身份验证;不要在公共/不受信任入口上暴露该模式。
- 配对后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` 条目是 bootstrap 交接令牌。仅当连接在受信任传输上使用 bootstrap 身份验证时才持久化它们,例如 `wss://` 或 loopback/local 配对。
- 如果客户端提供**显式** `deviceToken` 或显式 `scopes`,则该调用方请求的作用域集合仍然具有权威性;仅当客户端复用已存储的按设备令牌时,才会复用缓存的作用域。
`gateway.auth.mode: "trusted-proxy"`,会从请求标头而不是 `connect.params.auth.*`
满足 connect 认证检查。
- 私有入口 `gateway.auth.mode: "none"` 会完全跳过共享密钥 connect 认证;
不要在公开或不受信任的入口上暴露该模式。
- 配对后Gateway 网关会签发一个限定于连接角色 + scopes 的**设备令牌**。
它会在 `hello-ok.auth.deviceToken` 中返回,客户端应将其持久化以供后续连接使用。
- 客户端应在任何成功连接后持久化主 `hello-ok.auth.deviceToken`
- 使用该**已存储**设备令牌重新连接时,也应复用为该令牌存储的已批准 scope 集合。
这样可以保留已授予的读取、探测、Status 访问,并避免重新连接被静默收窄为
更窄的隐式仅管理员 scope。
- 客户端 connect 认证组装(`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` 条目是引导交接令牌。
仅当 connect 在受信任传输上使用引导认证时才持久化它们,例如
`wss://` 或 loopback/local pairing。
- 如果客户端提供**显式** `deviceToken` 或显式 `scopes`
该调用方请求的 scope 集合仍然具有权威性;只有当客户端复用已存储的按设备令牌时,
才会复用缓存的 scopes。
- 设备令牌可通过 `device.token.rotate`
`device.token.revoke` 轮换/撤销(需要 `operator.pairing` 作用域)。
- `device.token.rotate` 返回轮换元数据。它仅对已使用该设备令牌完成身份验证的同一设备调用回显替换 bearer 令牌,因此仅令牌客户端可以在重新连接前持久化其替换令牌。共享/管理员轮换不会回显 bearer 令牌。
- 令牌签发、轮换和撤销都受限于该设备配对条目中记录的已批准角色集合;令牌变更不能扩展或定位到配对批准从未授予的设备角色。
- 对于已配对设备令牌会话,除非调用方同时拥有 `operator.admin`,否则设备管理为自作用域:非管理员调用方只能移除/撤销/轮换其**自己的**设备条目。
- `device.token.rotate``device.token.revoke` 还会根据调用方当前会话作用域检查目标 operator
令牌作用域集合。非管理员调用方不能轮换或撤销比其已持有权限更广的 operator 令牌。
- 身份验证失败包含 `error.details.code` 以及恢复提示:
`device.token.revoke` 轮换/撤销(需要 `operator.pairing` scope
- `device.token.rotate` 返回轮换元数据。只有在同一设备调用且已使用该设备令牌认证时,
它才会回显替换用 bearer token因此仅令牌客户端可以在重新连接前持久化替换令牌。
共享/管理员轮换不会回显 bearer token。
- 令牌签发、轮换和撤销都被限制在该设备配对条目中记录的已批准角色集合内;
令牌变更不能扩展或指向配对批准从未授予的设备角色。
- 对于已配对设备令牌会话,除非调用方还拥有 `operator.admin`
否则设备管理是自限定的:非管理员调用方只能移除/撤销/轮换**自己的**设备条目。
- `device.token.rotate``device.token.revoke` 还会根据调用方当前会话 scopes
检查目标 operator 令牌 scope 集合。非管理员调用方不能轮换或撤销比自己已持有范围更广的 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 操作指引
## 设备身份 + 配对
- 节点应包含一个由密钥对指纹派生的稳定设备身份(`device.id`)。
- 节点应包含稳定设备身份(`device.id`,该身份派生自密钥对指纹
- Gateway 网关按设备 + 角色签发令牌。
- 除非启用了本地自动批准,否则新的设备 ID 需要配对批准。
- 配对自动批准以直接 local loopback 连接为中心。
- OpenClaw 还提供一个狭窄的后端/容器本地自连接路径,用于受信任的共享密钥辅助流程。
- 同主机 tailnet 或 LAN 连接在配对时仍被视为远程连接,并且需要批准。
- 同主机 tailnet 或 LAN 连接在配对时仍被视为远程连接,并且需要批准。
- WS 客户端通常会在 `connect` 期间包含 `device` 身份operator +
node。仅有的无设备 operator 例外是显式信任路径:
- `gateway.controlUi.allowInsecureAuth=true` 用于仅限 localhost 的不安全 HTTP 兼容性。
- 成功的 `gateway.auth.mode: "trusted-proxy"` operator Control UI 身份验证。
- `gateway.controlUi.dangerouslyDisableDeviceAuth=true`破窗选项,严重降低安全性)。
- 使用共享 Gateway 网关令牌/密码完成身份验证的 direct-loopback `gateway-client` 后端 RPC。
- 所有连接都必须签服务器提供的 `connect.challenge` nonce。
节点)。唯一无设备 operator 例外是显式信任路径:
- `gateway.controlUi.allowInsecureAuth=true`用于仅限 localhost 的不安全 HTTP 兼容性。
- 成功的 `gateway.auth.mode: "trusted-proxy"` operator Control UI 证。
- `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 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` 与公钥指纹不匹配。 |
@ -630,24 +604,25 @@ Gateway 网关将这些视为**声明**,并强制执行服务器端允许列
迁移目标:
- 始终等待 `connect.challenge`
- 签包含服务器 nonce 的 v2 载荷。
- 签包含服务器 nonce 的 v2 载荷。
- 在 `connect.params.device.nonce` 中发送相同的 nonce。
- 首选签名载荷是 `v3`,它除了 device/client/role/scopes/token/nonce 字段外,还绑定 `platform``deviceFamily`
- 旧版 `v2` 签名仍会被接受以保持兼容性,但已配对设备的元数据固定仍会控制重连时的命令策略。
- 首选签名载荷是 `v3`,它除设备/客户端/角色/scopes/令牌/nonce 字段外,
还绑定 `platform``deviceFamily`
- 为兼容性仍接受旧版 `v2` 签名,但已配对设备的元数据固定仍会控制重新连接时的命令策略。
## TLS + 固定
- TLS 支持 WS 连接
- 客户端可以选择固定 Gateway 网关证书指纹(请参阅 `gateway.tls`
- WS 连接支持 TLS
- 客户端可以选择固定 Gateway 网关证书指纹(参见 `gateway.tls`
配置以及 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。
## 作用域
## 范围
协议暴露**完整 Gateway 网关 API**Status、渠道、模型、聊天、
智能体、会话、节点、批准等)。确切接口
协议暴露**完整 Gateway 网关 API**Status、渠道、模型、聊天、
智能体、会话、节点、批准等)。确切表面
`src/gateway/protocol/schema.ts` 中的 TypeBox schema 定义。
## 相关
## 相关内容
- [Bridge protocol](/zh-CN/gateway/bridge-protocol)
- [Gateway 网关运行手册](/zh-CN/gateway)
- [Gateway runbook](/zh-CN/gateway)

View File

@ -2,88 +2,88 @@
read_when:
- 更新 OpenClaw
- 更新后出现问题
summary: 安全更新 OpenClaw全局安装或源码安装),以及回滚策略
title: 更新
summary: 安全更新 OpenClaw全局安装或源码以及回滚策略
title: 更新
x-i18n:
generated_at: "2026-04-27T14:31:37Z"
model: gpt-5.4
generated_at: "2026-05-01T08:51:52Z"
model: gpt-5.5
provider: openai
source_hash: 17d4839002b153976e014e0eefcb44f92dcb9bb45b81bf30efb1e8e8c0f30ec3
source_hash: 98631ce432a28af244ec22ce0cf4a23ded356dd93e9c154f502347683eef52d1
source_path: install/updating.md
workflow: 15
workflow: 16
---
让 OpenClaw 保持最新。
## 推荐:`openclaw update`
这是最快的更新方式。它会检测你的安装类型npm 或 git,获取最新版本,运行 `openclaw doctor`,并重启 Gateway 网关。
最快的更新方式。它会检测你的安装类型npm 或 git、拉取最新版本、运行 `openclaw doctor`,并重启 Gateway 网关。
```bash
openclaw update
```
如需切换通道或指定特定版本:
要切换渠道或指定某个版本:
```bash
openclaw update --channel beta
openclaw update --channel dev
openclaw update --tag main
openclaw update --dry-run # 仅预览,不实际应用
openclaw update --dry-run # preview without applying
```
`--channel beta` 会优先选择 beta但当 beta 标签缺失或版本比最新 stable 发布版更旧时,运行时会回退到 stable/latest。如果你想进行一次性的包更新并使用原始的 npm beta dist-tag请使用 `--tag beta`
`--channel beta` 优先使用 beta但当 beta 标签缺失或早于最新稳定版时,运行时会回退到 stable/latest。如果你想对一次性包更新使用原始 npm beta dist-tag请使用 `--tag beta`
通道语义请参阅 [Development channels](/zh-CN/install/development-channels)。
有关渠道语义,请参阅[开发渠道](/zh-CN/install/development-channels)。
## 在 npm 安装和 git 安装之间切换
## 在 npm 和 git 安装之间切换
当你想更改安装类型时,请使用道。更新器会保留你在 `~/.openclaw` 中的状态、配置、凭证和工作区;它只会更改 CLI 和 Gateway 网关所使用的 OpenClaw 代码安装方式
当你想更改安装类型时,请使用道。更新器会保留你在 `~/.openclaw` 中的状态、配置、凭证和工作区;它只会更改 CLI 和 Gateway 网关使用哪一份 OpenClaw 代码安装
```bash
# npm 包安装 -> 可编辑 git 检出
# npm package install -> editable git checkout
openclaw update --channel dev
# git 检出 -> npm 包安装
# git checkout -> npm package install
openclaw update --channel stable
```
先使用 `--dry-run` 预览确切的安装模式切换:
先使用 `--dry-run` 运行,以预览确切的安装模式切换:
```bash
openclaw update --channel dev --dry-run
openclaw update --channel stable --dry-run
```
`dev` 通道会确保存在一个 git 检出,对其进行构建,并从该检出安装全局 CLI。`stable` 和 `beta`道使用包安装。如果 Gateway 网关已经安装,`openclaw update` 会刷新服务元数据并重启它,除非你传入 `--no-restart`
`dev` 渠道会确保存在 git 检出副本、构建它,并从该检出副本安装全局 CLI。`stable` 和 `beta`道使用包安装。如果 Gateway 网关已经安装,`openclaw update` 会刷新服务元数据并重启它,除非你传入 `--no-restart`
## 另一种方式:重新运行安装脚本
## 备选方案:重新运行安装程序
```bash
curl -fsSL https://openclaw.ai/install.sh | bash
```
添加 `--no-onboard` 可跳过新手引导。如需通过安装器强制指定安装类型,传入 `--install-method git --no-onboard``--install-method npm --no-onboard`
添加 `--no-onboard` 可跳过新手引导。要通过安装程序强制指定安装类型,请传入 `--install-method git --no-onboard``--install-method npm --no-onboard`
如果 `openclaw update` 在 npm 包安装阶段之后失败,请重新运行安装器。安装器不会调用旧的更新器;它会直接运行全局包安装,因此可以恢复部分更新失败的 npm 安装。
如果 `openclaw update` 在 npm 包安装阶段后失败,请重新运行安装程序。安装程序不会调用旧更新器;它会直接运行全局包安装,并且可以恢复部分更新的 npm 安装。
```bash
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method npm
```
如需将恢复固定到特定版本或 dist-tag请添加 `--version`
将恢复固定到特定版本或 dist-tag请添加 `--version`
```bash
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method npm --version <version-or-dist-tag>
```
## 另一种方式:手动使用 npm、pnpm 或 bun
## 备选方案:手动使用 npm、pnpm 或 bun
```bash
npm i -g openclaw@latest
```
`openclaw update` 管理全局 npm 安装时,它会先将目标版本安装到一个临时 npm prefix 中,验证已打包的 `dist` 清单,然后再将干净的包树替换到真实的全局 prefix 中。这样可以避免 npm 把新包覆盖到旧包遗留文件之上。如果安装命令失败OpenClaw 会使用 `--omit=optional` 重试一次。这个重试有助于处理那些无法编译原生可选依赖的主机,同时如果回退方案也失败,仍会保留原始失败信息
`openclaw update` 管理全局 npm 安装时,它会先把目标安装到临时 npm 前缀中,验证打包后的 `dist` 清单,然后将干净的包树切换到真正的全局前缀中。这样可以避免 npm 将新包覆盖到旧包的过期文件上。如果安装命令失败OpenClaw 会使用 `--omit=optional` 重试一次。该重试有助于原生可选依赖无法编译的主机,同时如果回退也失败,仍会保留原始失败可见
```bash
pnpm add -g openclaw@latest
@ -97,9 +97,9 @@ bun add -g openclaw@latest
<AccordionGroup>
<Accordion title="只读包树">
OpenClaw 在运行时打包的全局安装视为只读,即使当前用户对全局包目录有写权限也是如此。内置插件的运行时依赖会暂存到一个可写的运行时目录,而不是修改包树本身。这样可以避免在同一次安装期间,`openclaw update` 与正在修复插件依赖的运行中 Gateway 网关或本地智能体发生竞争
OpenClaw 在运行时将打包的全局安装视为只读,即使当前用户可写入全局包目录也是如此。内置插件的运行时依赖会被暂存到可写的运行时目录,而不是修改包树。这可以避免 `openclaw update` 与正在运行的 Gateway 网关或本地智能体发生竞争,因为后者可能在同一次安装期间修复插件依赖
某些 Linux npm 配置会将全局包安装到 root 拥有的目录中,例如 `/usr/lib/node_modules/openclaw`。OpenClaw 通过同的外部暂存路径支持这种布局。
一些 Linux npm 设置会把全局包安装到 root 拥有的目录下,例如 `/usr/lib/node_modules/openclaw`。OpenClaw 通过同的外部暂存路径支持这种布局。
</Accordion>
<Accordion title="加固的 systemd 单元">
@ -110,30 +110,30 @@ bun add -g openclaw@latest
ReadWritePaths=/var/lib/openclaw /home/openclaw/.openclaw /tmp
```
`OPENCLAW_PLUGIN_STAGE_DIR` 也接受路径列表。OpenClaw 会按照从左到右的顺序在列出的根路径中解析内置插件运行时依赖,将较前面的根视为只读的预安装层,并且只在最后一个可写根中进行安装或修复
`OPENCLAW_PLUGIN_STAGE_DIR` 也接受路径列表。OpenClaw 会从左到右解析列出的根目录中的内置插件运行时依赖,将较早的根目录视为只读的预安装层,并且只安装或修复到最后一个可写根目录中
```ini
Environment=OPENCLAW_PLUGIN_STAGE_DIR=/opt/openclaw/plugin-runtime-deps:/var/lib/openclaw/plugin-runtime-deps
ReadWritePaths=/var/lib/openclaw /home/openclaw/.openclaw /tmp
```
如果未设置 `OPENCLAW_PLUGIN_STAGE_DIR`当 systemd 提供 `$STATE_DIRECTORY`OpenClaw 会使用它;否则回退到 `~/.openclaw/plugin-runtime-deps`。修复步骤会将该暂存区视为一个由 OpenClaw 拥有的本地包根目录,并忽略用户的 npm prefix 和全局设置,因此全局安装的 npm 配置不会将内置插件依赖重定向到 `~/node_modules` 或全局包树中。
如果未设置 `OPENCLAW_PLUGIN_STAGE_DIR`OpenClaw 会在 systemd 提供 `$STATE_DIRECTORY` 时使用它,然后回退到 `~/.openclaw/plugin-runtime-deps`。修复步骤会将该暂存目录视为 OpenClaw 拥有的本地包根目录,并忽略用户 npm 前缀和全局设置,因此全局安装 npm 配置不会把内置插件依赖重定向到 `~/node_modules` 或全局包树中。
</Accordion>
<Accordion title="磁盘空间预检">
在包更新和内置运行时依赖修复之前OpenClaw 会尽力对目标卷执行磁盘空间检查。空间不足会生成一条警告,其中包含被检查的路径,但不会阻止更新,因为文件系统配额、快照和网络卷可能会在检查后发生变化。实际的 npm 安装、复制和安装后验证仍然是最终依据
在包更新和内置运行时依赖修复之前OpenClaw 会尽力检查目标卷的磁盘空间。空间不足会产生一条包含所检查路径的警告,但不会阻止更新,因为文件系统配额、快照和网络卷可能会在检查后发生变化。实际的 npm 安装、复制和安装后验证仍是权威结果
</Accordion>
<Accordion title="内置插件运行时依赖">
已打包安装会将内置插件运行时依赖保留在只读包树之外。在启动时以及执行 `openclaw doctor --fix` 期间OpenClaw 只会为以下内置插件修复运行时依赖:在配置中处于活跃状态、通过旧版渠道配置处于活跃状态,或由其内置清单默认启用的插件。仅有持久化的渠道认证状态,并不会触发 Gateway 网关启动时的运行时依赖修复。
打包安装会让内置插件运行时依赖保持在只读包树之外。在启动时以及运行 `openclaw doctor --fix` 期间OpenClaw 只会修复满足以下条件的内置插件的运行时依赖:在配置中处于活动状态、通过旧版渠道配置处于活动状态,或由其内置 manifest 默认启用。仅持久化的渠道认证状态不会触发 Gateway 网关启动时的运行时依赖修复。
显式禁用具有最高优先。被禁用的插件或渠道不会仅因为存在于包中就修复其运行时依赖。外部插件和自定义加载路径仍使用 `openclaw plugins install``openclaw plugins update`
显式禁用优先。被禁用的插件或渠道不会仅因为存在于包中就修复其运行时依赖。外部插件和自定义加载路径仍使用 `openclaw plugins install``openclaw plugins update`
</Accordion>
</AccordionGroup>
## 自动更新器
自动更新器默认关闭。请在 `~/.openclaw/openclaw.json` 中启用:
自动更新器默认关闭。请在 `~/.openclaw/openclaw.json` 中启用
```json5
{
@ -149,14 +149,15 @@ bun add -g openclaw@latest
}
```
| Channel | 行为 |
| -------- | ---- |
| `stable` | 等待 `stableDelayHours`,然后在 `stableJitterHours` 范围内按确定性抖动应用(分散发布)。 |
| `beta` | 每隔 `betaCheckIntervalHours` 检查一次(默认:每小时)并立即应用。 |
| `dev` | 不自动应用。请手动使用 `openclaw update`。 |
| 渠道 | 行为 |
| -------- | ------------------------------------------------------------------------------------------------------------- |
| `stable` | 等待 `stableDelayHours`,然后在 `stableJitterHours` 范围内通过确定性抖动应用更新(分散发布)。 |
| `beta` | 每隔 `betaCheckIntervalHours` 检查一次(默认:每小时)并立即应用。 |
| `dev` | 不自动应用。请手动使用 `openclaw update` |
Gateway 网关也会在启动时记录更新提示(可使用 `update.checkOnStart: false` 禁用)。
如需降级或进行事故恢复,请在 Gateway 网关环境中设置 `OPENCLAW_NO_AUTO_UPDATE=1`,即使已配置 `update.auto.enabled`,也能阻止自动应用。除非同时禁用 `update.checkOnStart`,否则启动时的更新提示仍可能运行。
Gateway 网关还会在启动时记录更新提示(使用 `update.checkOnStart: false` 禁用)。对于降级或事故恢复,请在 Gateway 网关环境中设置 `OPENCLAW_NO_AUTO_UPDATE=1`,以便即使配置了 `update.auto.enabled` 也阻止自动应用。启动更新提示仍可运行,除非同时禁用了 `update.checkOnStart`
通过实时 Gateway 网关控制平面处理程序请求的包管理器更新会在包切换后强制执行非延迟的更新重启。这样可以避免旧的内存中进程停留过久并从已经被替换的包树中延迟加载代码块。对于受监管的安装Shell `openclaw update` 仍是首选路径,因为它可以围绕更新停止并重启服务。
## 更新后
@ -168,7 +169,7 @@ Gateway 网关也会在启动时记录更新提示(可使用 `update.checkOnSt
openclaw doctor
```
迁移配置、审计私信策略并检查 Gateway 网关健康状态。详情请参阅[Doctor](/zh-CN/gateway/doctor)
迁移配置、审计私信策略,并检查 Gateway 网关健康状况。详情[Doctor](/zh-CN/gateway/doctor)
### 重启 Gateway 网关
@ -195,7 +196,7 @@ openclaw gateway restart
```
<Tip>
`npm view openclaw version` 会显示当前已发布版本。
`npm view openclaw version` 会显示当前已发布版本。
</Tip>
### 固定提交(源码)
@ -207,17 +208,17 @@ pnpm install && pnpm build
openclaw gateway restart
```
如需回到最新版本:`git checkout main && git pull`。
要返回最新版本:`git checkout main && git pull`。
## 如果你卡住了
- 再次运行 `openclaw doctor`,并仔细阅读输出内容
- 对于源码检出的 `openclaw update --channel dev`,更新器会在需要时自动引导安装 `pnpm`。如果你看到 pnpm/corepack 引导错误,请手动安装 `pnpm`(或重新启用 `corepack`,然后重新运行更新。
- 再次运行 `openclaw doctor`,并仔细阅读输出。
- 对于源码检出副本上`openclaw update --channel dev`,更新器会在需要时自动引导 `pnpm`。如果你看到 pnpm/corepack 引导错误,请手动安装 `pnpm`(或重新启用 `corepack`重新运行更新。
- 查看:[故障排除](/zh-CN/gateway/troubleshooting)
- 在 Discord 中提问:[https://discord.gg/clawd](https://discord.gg/clawd)
- 在 Discord 问:[https://discord.gg/clawd](https://discord.gg/clawd)
## 相关内容
## 相关
- [Install overview](/zh-CN/install):所有安装方式
- [安装概览](/zh-CN/install):所有安装方法
- [Doctor](/zh-CN/gateway/doctor):更新后的健康检查。
- [迁移](/zh-CN/install/migrating):主版本迁移指南。
- [迁移](/zh-CN/install/migrating):主版本迁移指南。

View File

@ -2,31 +2,25 @@
read_when:
- 你想从 OpenClaw 发起外拨语音通话
- 你正在配置或开发语音通话插件
- 你需要在电话通信中使用实时语音或流式转录
- 你需要电话通信中的实时语音或流式转录
sidebarTitle: Voice call
summary: 通过 Twilio、Telnyx 或 Plivo 发起外呼并接听呼入语音通话,可选择启用实时语音和流式转录
summary: 通过 Twilio、Telnyx 或 Plivo 发起出站并接听入站语音通话,并可选启用实时语音和流式转写
title: 语音通话插件
x-i18n:
generated_at: "2026-05-01T06:42:53Z"
generated_at: "2026-05-01T08:52:09Z"
model: gpt-5.5
provider: openai
source_hash: 2fc13bcfcab09cf1118c851b56ca3bf870720f5a419e86c3c91138ff6c33f2be
source_hash: 6334e5418e0fb530fc5d372ee1ada06ba987ce86bbf70746ee4ffe4c3ed4844e
source_path: plugins/voice-call.md
workflow: 16
---
通过插件为 OpenClaw 提供语音通话。支持外呼通知、
多轮对话、全双工实时语音、流式
转录,以及带允许列表策略的呼入电话。
通过插件为 OpenClaw 提供语音通话。支持出站通知、多轮对话、全双工实时语音、流式转录,以及带允许名单策略的入站呼叫。
**当前提供商:** `twilio`Programmable Voice + Media Streams
`telnyx`Call Control v2、`plivo`Voice API + XML transfer + GetInput
speech、`mock`(开发/无网络)。
**当前提供商:** `twilio`Programmable Voice + Media Streams、`telnyx`Call Control v2、`plivo`Voice API + XML 转接 + GetInput 语音)、`mock`(开发/无网络)。
<Note>
Voice Call 插件运行在 **Gateway 网关进程内**。如果你使用
远程 Gateway 网关,请在运行 Gateway 网关的机器上安装并配置该插件,
然后重启 Gateway 网关以加载它。
Voice Call 插件运行在 **Gateway 网关进程内部**。如果你使用远程 Gateway 网关,请在运行 Gateway 网关的机器上安装并配置该插件,然后重启 Gateway 网关以加载它。
</Note>
## 快速开始
@ -48,28 +42,20 @@ Voice Call 插件运行在 **Gateway 网关进程内**。如果你使用
</Tab>
</Tabs>
如果 npm 报告 OpenClaw 拥有的包已弃用,该包版本
来自较旧的外部包发布线;请使用当前打包的 OpenClaw
构建,或在更新的 npm 包发布前使用本地文件夹路径。
如果 npm 报告 OpenClaw 拥有的包已弃用,该包版本来自较旧的外部包发布线;在发布更新的 npm 包之前,请使用当前打包的 OpenClaw 构建或本地文件夹路径。
之后重启 Gateway 网关,以便插件加载。
之后重启 Gateway 网关,让插件加载。
</Step>
<Step title="配置提供商和 webhook">
`plugins.entries.voice-call.config` 下设置配置(完整结构见下方
[配置](#configuration))。最低要求:
`provider`、提供商凭证、`fromNumber`,以及可公开
访问的 webhook URL。
`plugins.entries.voice-call.config` 下设置配置(完整结构见下方[配置](#configuration))。至少需要:`provider`、提供商凭证、`fromNumber`,以及可公开访问的 webhook URL。
</Step>
<Step title="验证设置">
```bash
openclaw voicecall setup
```
默认输出适合在聊天日志和终端中阅读。它会检查
插件启用状态、提供商凭证、webhook 暴露情况,以及
是否只有一种音频模式(`streaming` 或 `realtime`)处于活动状态。
脚本请使用 `--json`
默认输出适合在聊天日志和终端中阅读。它会检查插件启用状态、提供商凭证、webhook 暴露情况,以及是否只有一种音频模式(`streaming` 或 `realtime`)处于活动状态。脚本可使用 `--json`
</Step>
<Step title="冒烟测试">
@ -78,8 +64,7 @@ Voice Call 插件运行在 **Gateway 网关进程内**。如果你使用
openclaw voicecall smoke --to "+15555550123"
```
两者默认都是试运行。添加 `--yes` 才会实际发起一次简短的
外呼通知电话:
两者默认都是试运行。添加 `--yes` 才会实际发起一次简短的出站通知通话:
```bash
openclaw voicecall smoke --to "+15555550123" --yes
@ -89,21 +74,15 @@ Voice Call 插件运行在 **Gateway 网关进程内**。如果你使用
</Steps>
<Warning>
对于 Twilio、Telnyx 和 Plivo设置必须解析为**公开 webhook URL**。
如果 `publicUrl`、隧道 URL、Tailscale URL或 serve 回退
解析到 loopback 或私有网络空间,设置会失败,而不是
启动一个无法接收运营商 webhook 的提供商。
对于 Twilio、Telnyx 和 Plivo设置必须解析到一个**公开 webhook URL**。如果 `publicUrl`、隧道 URL、Tailscale URL 或 serve 回退解析到回环或专用网络地址空间,设置会失败,而不是启动一个无法接收运营商 webhook 的提供商。
</Warning>
## 配置
如果 `enabled: true` 但所选提供商缺少凭证,
Gateway 网关启动会记录包含缺失键名的设置未完成警告,并
跳过启动运行时。命令、RPC 调用和智能体工具在使用时仍会
返回确切缺失的提供商配置。
如果 `enabled: true` 但所选提供商缺少凭证Gateway 网关启动时会记录 setup-incomplete 警告包含缺失键名并跳过启动运行时。命令、RPC 调用和智能体工具在使用时仍会返回确切缺失的提供商配置。
<Note>
语音通话凭证接受 SecretRefs。`plugins.entries.voice-call.config.twilio.authToken`、`plugins.entries.voice-call.config.realtime.providers.*.apiKey`、`plugins.entries.voice-call.config.streaming.providers.*.apiKey` 和 `plugins.entries.voice-call.config.tts.providers.*.apiKey` 会通过标准 SecretRef 表面解析;请参阅 [SecretRef 凭证表面](/zh-CN/reference/secretref-credential-surface)。
语音通话凭证接受 SecretRef。`plugins.entries.voice-call.config.twilio.authToken`、`plugins.entries.voice-call.config.realtime.providers.*.apiKey`、`plugins.entries.voice-call.config.streaming.providers.*.apiKey` 和 `plugins.entries.voice-call.config.tts.providers.*.apiKey` 会通过标准 SecretRef 表面解析;请参阅 [SecretRef 凭证表面](/zh-CN/reference/secretref-credential-surface)。
</Note>
```json5
@ -164,29 +143,25 @@ Gateway 网关启动会记录包含缺失键名的设置未完成警告,并
```
<AccordionGroup>
<Accordion title="提供商暴露安全说明">
- Twilio、Telnyx 和 Plivo 都需要一个**可公开访问** webhook URL。
- `mock` 是本地开发提供商(不进行网络调用)。
<Accordion title="提供商暴露安全说明">
- Twilio、Telnyx 和 Plivo 都需要一个**可公开访问** webhook URL。
- `mock` 是本地开发提供商(网络调用)。
- Telnyx 需要 `telnyx.publicKey`(或 `TELNYX_PUBLIC_KEY`),除非 `skipSignatureVerification` 为 true。
- `skipSignatureVerification` 仅用于本地测试。
- 在 ngrok 免费层,将 `publicUrl` 设置为确切的 ngrok URL签名验证始终强制执行。
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅当 `tunnel.provider="ngrok"``serve.bind` 为 loopbackngrok 本地代理)时,允许带无效签名的 Twilio webhook。仅限本地开发。
- Ngrok 免费层 URL 可能变化或添加插页行为;如果 `publicUrl` 漂移Twilio 签名会失败。生产环境:优先使用稳定域名或 Tailscale funnel。
- 在 ngrok 免费层,`publicUrl` 设置为确切的 ngrok URL始终强制执行签名验证
- 仅当 `tunnel.provider="ngrok"``serve.bind` 是回环地址ngrok 本地代理)时,`tunnel.allowNgrokFreeTierLoopbackBypass: true` 才允许带无效签名的 Twilio webhook。仅限本地开发。
- Ngrok 免费层 URL 可能变化或添加插页行为;如果 `publicUrl` 漂移Twilio 签名会失败。生产环境:优先使用稳定域名或 Tailscale funnel。
</Accordion>
<Accordion title="流式连接上限">
- `streaming.preStartTimeoutMs` 会关闭从未发送有效 `start` 帧的 socket
- `streaming.maxPendingConnections` 限制未认证的启动前 socket 总数。
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未认证启动前 socket 数量。
- `streaming.maxConnections` 限制打开的媒体流 socket 总数(待处理 + 活跃)。
- `streaming.preStartTimeoutMs` 会关闭从未发送有效 `start` 帧的套接字
- `streaming.maxPendingConnections` 限制未经身份验证的预启动套接字总数。
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未经身份验证预启动套接字数量。
- `streaming.maxConnections` 限制打开的媒体流套接字总数(待处理 + 活动)。
</Accordion>
<Accordion title="旧版配置迁移">
使用 `provider: "log"`、`twilio.from` 或旧版
`streaming.*` OpenAI 键的较旧配置会由 `openclaw doctor --fix` 重写。
运行时回退目前仍接受旧的 voice-call 键,但
重写路径是 `openclaw doctor --fix`,兼容垫片是
临时的。
使用 `provider: "log"`、`twilio.from` 或旧版 `streaming.*` OpenAI 键的较旧配置会由 `openclaw doctor --fix` 重写。运行时回退目前仍接受旧的 voice-call 键,但重写路径是 `openclaw doctor --fix`,兼容垫片是临时的。
自动迁移的流式键:
@ -201,42 +176,38 @@ Gateway 网关启动会记录包含缺失键名的设置未完成警告,并
## 实时语音对话
`realtime` 为实时通话音频选择一个全双工实时语音提供商。
它与 `streaming` 分离,后者只会将音频转发给
实时转录提供商。
`realtime` 为实时通话音频选择一个全双工实时语音提供商。它独立于 `streaming`,后者只会将音频转发给实时转录提供商。
<Warning>
`realtime.enabled` 不能与 `streaming.enabled` 组合使用。每次通话
请选择一种音频模式。
`realtime.enabled` 不能与 `streaming.enabled` 组合使用。每次通话选择一种音频模式。
</Warning>
当前运行时行为:
- Twilio Media Streams 支持 `realtime.enabled`
- `realtime.provider` 是可选。如果未设置Voice Call 会使用第一个已注册的实时语音提供商。
- `realtime.provider` 是可选。如果未设置Voice Call 会使用第一个已注册的实时语音提供商。
- 内置实时语音提供商Google Gemini Live`google`)和 OpenAI`openai`),由它们的提供商插件注册。
- 提供商拥有的原始配置位于 `realtime.providers.<providerId>` 下。
- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者请求更深入的推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当呼叫者要求更深入的推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
- `realtime.fastContext.enabled` 默认关闭。启用后Voice Call 会先为咨询问题搜索已索引的记忆/会话上下文,并在 `realtime.fastContext.timeoutMs` 内将这些片段返回给实时模型;只有当 `realtime.fastContext.fallbackToConsult` 为 true 时,才会回退到完整咨询智能体。
- 如果 `realtime.provider` 指向未注册的提供商或根本没有注册实时语音提供商Voice Call 会记录警告并跳过实时媒体,而不是让整个插件失败。
- 咨询会话键在可用时复用现有语音会话,然后回退到主叫/被叫电话号码,以便后续咨询调用在通话期间保持上下文。
- 咨询会话键在可用时复用现有语音会话,然后回退到主叫/被叫电话号码,使后续咨询调用在通话期间保留上下文。
### 工具策略
`realtime.toolPolicy` 控制咨询运行:
| 策略 | 行为 |
| 策略 | 行为 |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `safe-read-only` | 暴露咨询工具,并将常规智能体限制为 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`。 |
| `owner` | 暴露咨询工具,并让常规智能体使用正常的智能体工具策略。 |
| `none` | 不暴露咨询工具。自定义 `realtime.tools` 仍会传递给实时提供商。 |
| `owner` | 暴露咨询工具,并允许常规智能体使用正常的智能体工具策略。 |
| `none` | 不暴露咨询工具。自定义 `realtime.tools` 仍会传递给实时提供商。 |
### 实时提供商示例
<Tabs>
<Tab title="Google Gemini Live">
默认值API key 来自 `realtime.providers.google.apiKey`
`GEMINI_API_KEY``GOOGLE_GENERATIVE_AI_API_KEY`;模型
`gemini-2.5-flash-native-audio-preview-12-2025`;语音 `Kore`
默认值API key 来自 `realtime.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_GENERATIVE_AI_API_KEY`;模型 `gemini-2.5-flash-native-audio-preview-12-2025`;语音 `Kore`
```json5
{
@ -291,9 +262,7 @@ Gateway 网关启动会记录包含缺失键名的设置未完成警告,并
</Tab>
</Tabs>
请参阅 [Google 提供商](/zh-CN/providers/google) 和
[OpenAI provider](/zh-CN/providers/openai),了解提供商特定的实时语音
选项。
有关提供商特定的实时语音选项,请参阅 [Google 提供商](/zh-CN/providers/google) 和 [OpenAI provider](/zh-CN/providers/openai)。
## 流式转录
@ -301,19 +270,19 @@ Gateway 网关启动会记录包含缺失键名的设置未完成警告,并
当前运行时行为:
- `streaming.provider` 是可选。如果未设置Voice Call 会使用第一个注册的实时转录提供商。
- 内置实时转录提供商Deepgram`deepgram`、ElevenLabs`elevenlabs`、Mistral`mistral`、OpenAI`openai`)和 xAI`xai`),由它们的提供商插件注册。
- `streaming.provider` 是可选。如果未设置Voice Call 会使用第一个注册的实时转录提供商。
- 内置实时转录提供商Deepgram (`deepgram`)、ElevenLabs (`elevenlabs`)、Mistral (`mistral`)、OpenAI (`openai`) 和 xAI (`xai`),由各自的提供商插件注册。
- 提供商拥有的原始配置位于 `streaming.providers.<providerId>` 下。
- Twilio 发送已接受`start` 消息后Voice Call 会立即注册该流,在提供商连接期间通过转录提供商排队呼入媒体,并且只会在实时转录准备就绪后开始初始问候
- 如果 `streaming.provider` 指向未注册的提供商,或没有注册任何提供商Voice Call 会记录警告并跳过媒体流,而不是让整个插件失败。
- Twilio 发送已接受流 `start` 消息后Voice Call 会立即注册该流,在提供商连接期间通过转录提供商排队入站媒体,并且仅在实时转录就绪后才开始初始问候语
- 如果 `streaming.provider` 指向未注册的提供商,或没有任何提供商已注册Voice Call 会记录警告并跳过媒体流式传输,而不是让整个插件失败。
### 流式提供商示例
### 流式传输提供商示例
<Tabs>
<Tab title="OpenAI">
默认值API key `streaming.providers.openai.apiKey`
`OPENAI_API_KEY`;模型 `gpt-4o-transcribe``silenceDurationMs: 800`
`vadThreshold: 0.5`.
`vadThreshold: 0.5`
```json5
{
@ -375,9 +344,11 @@ Gateway 网关启动会记录包含缺失键名的设置未完成警告,并
</Tab>
</Tabs>
## 通话 TTS
## 通话 TTS
Voice Call 使用核心 `messages.tts` 配置为通话提供流式语音。你可以在插件配置下用**相同结构**覆盖它,它会与 `messages.tts` 深度合并。
Voice Call 使用核心 `messages.tts` 配置来为通话提供流式
语音。你可以在插件配置下用**相同结构**覆盖它,它会与 `messages.tts`
进行深度合并。
```json5
{
@ -394,21 +365,22 @@ Voice Call 使用核心 `messages.tts` 配置为通话提供流式语音。你
```
<Warning>
**Microsoft speech 会被 voice calls 忽略。** 电话音频需要 PCM当前 Microsoft 传输不暴露电话 PCM 输出。
**Microsoft speech 在语音通话中会被忽略。** 电话音频需要 PCM
当前 Microsoft 传输未暴露电话 PCM 输出。
</Warning>
行为说明:
- 插件配置中的旧版 `tts.<provider>` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)会由 `openclaw doctor --fix` 修复;提交的配置应使用 `tts.providers.<provider>`
- 启用 Twilio media streaming 时会使用核心 TTS否则通话会回退到提供商原生语音。
- 如果 Twilio media stream 已经处于活跃状态Voice Call 不会回退到 TwiML `<Say>`。如果在该状态下电话 TTS 不可用,播放请求会失败,而不是混用两条播放路径。
- 启用 Twilio 媒体流式传输时会使用核心 TTS否则通话会回退到提供商原生语音。
- 如果 Twilio 媒体流已处于活动状态Voice Call 不会回退到 TwiML `<Say>`。如果此状态下电话 TTS 不可用,播放请求会失败,而不是混用两条播放路径。
- 当电话 TTS 回退到次级提供商时Voice Call 会记录一条包含提供商链(`from`、`to`、`attempts`)的警告,便于调试。
- 当 Twilio barge-in 或流拆除清空待处理 TTS 队列时,已排队的播放请求会完成结算,而不会让呼叫者在等待播放完成时一直挂起
- 当 Twilio 插话或流拆除清空待处理 TTS 队列时,已排队的播放请求会完成结算,而不是让来电者一直等待播放完成
### TTS 示例
<Tabs>
<Tab title="Core TTS only">
<Tab title="仅核心 TTS">
```json5
{
messages: {
@ -422,7 +394,7 @@ Voice Call 使用核心 `messages.tts` 配置为通话提供流式语音。你
}
```
</Tab>
<Tab title="Override to ElevenLabs (calls only)">
<Tab title="覆盖为 ElevenLabs仅通话">
```json5
{
plugins: {
@ -446,7 +418,7 @@ Voice Call 使用核心 `messages.tts` 配置为通话提供流式语音。你
}
```
</Tab>
<Tab title="OpenAI model override (deep-merge)">
<Tab title="OpenAI 模型覆盖(深度合并)">
```json5
{
plugins: {
@ -472,7 +444,7 @@ Voice Call 使用核心 `messages.tts` 配置为通话提供流式语音。你
## 入站通话
入站策略默认为 `disabled`。要启用入站通话,请设置:
入站策略默认`disabled`。要启用入站通话,请设置:
```json5
{
@ -483,14 +455,20 @@ Voice Call 使用核心 `messages.tts` 配置为通话提供流式语音。你
```
<Warning>
`inboundPolicy: "allowlist"` 是一种低保障的来电号码筛选。插件会规范化提供商提供的 `From` 值,并将它与 `allowFrom` 比较。Webhook 验证会认证提供商投递和载荷完整性,但它**不能**证明 PSTN/VoIP 主叫号码所有权。请将 `allowFrom` 视为来电号码过滤,而不是强身份认证。
`inboundPolicy: "allowlist"` 是低保障的主叫号码筛选。
插件会规范化提供商提供的 `From` 值,并将其与
`allowFrom` 比较。Webhook 验证会认证提供商投递和
载荷完整性,但它**不能**证明 PSTN/VoIP 主叫号码
所有权。请将 `allowFrom` 视为主叫号码过滤,而不是强主叫
身份。
</Warning>
自动回复使用智能体系统。可通过 `responseModel`、`responseSystemPrompt` 和 `responseTimeoutMs` 调整。
自动响应使用智能体系统。可使用 `responseModel`
`responseSystemPrompt``responseTimeoutMs` 进行调优。
### 语音输出契约
### 语音输出约
对于自动回复Voice Call 会向系统提示追加严格的语音输出约:
对于自动响应Voice Call 会向系统提示追加严格的语音输出约
```text
{"spoken":"..."}
@ -500,35 +478,39 @@ Voice Call 会防御性地提取语音文本:
- 忽略标记为推理/错误内容的载荷。
- 解析直接 JSON、围栏 JSON 或内联 `"spoken"` 键。
- 回退到纯文本,并移除可能的划/元信息开头段落。
- 回退到纯文本,并移除可能的划/元信息开头段落。
这会让语音播放专注于面向来电者的文本,并避免把规划文本泄露到音频中。
这会让语音播放聚焦于面向来电者的文本,并避免将计划文本泄漏到音频中。
### 对话启动行为
对于出站 `conversation` 通话,首条消息处理与实时播放状态绑定:
对于出站 `conversation` 通话,首条消息处理与实时
播放状态绑定:
- 只有在初始问候正在主动播报时,才会抑制 barge-in 队列清空和自动回复
- 如果初始播放失败,通话会回 `listening`,初始消息仍会排队等待重试。
- Twilio streaming 的初始播放会在流连接时开始,不额外延迟。
- Barge-in 会中止活跃播放,并清空已排队但尚未播放的 Twilio TTS 条目。被清空的条目会解析为已跳过,因此后续响应逻辑可以继续,而无需等待永远不会播放的音频。
- Realtime 语音对话使用 realtime 流自己的开场轮次。Voice Call **不会**为该初始消息发布旧版 `<Say>` TwiML 更新,因此出站 `<Connect><Stream>` 会话会保持附加状态
- 仅在初始问候语正在主动播报时,才会抑制插话队列清空和自动响应
- 如果初始播放失败,通话会`listening`并且初始消息仍会排队等待重试。
- Twilio 流式传输的初始播放会在流连接时开始,不会有额外延迟。
- 插话会中止活动播放,并清除已排队但尚未播放的 Twilio TTS 条目。被清除的条目会解析为已跳过,因此后续响应逻辑可以继续,而无需等待永远不会播放的音频。
- 实时语音对话使用实时流自己的开场轮次。Voice Call 不会为该初始消息发布旧版 `<Say>` TwiML 更新,因此出站 `<Connect><Stream>` 会话会保持连接
### Twilio 流断开宽限期
当 Twilio media stream 断开连接时Voice Call 会等待 **2000 ms**,然后自动结束通话:
当 Twilio 媒体流断开连接时Voice Call 会等待 **2000 ms**,然后
自动结束通话:
- 如果流在该窗口内重新连接,则取消自动结束。
- 如果宽限期后没有流重新注册,则结束通话,以防出现卡住的活跃通话
- 如果流在该窗口内重新连接,自动结束会被取消
- 如果宽限期后没有流重新注册,则结束通话,以防止活动通话卡住
## 过期通话清理器
使用 `staleCallReaperSeconds` 结束从未收到终止 webhook 的通话(例如从未完成的 notify-mode 通话)。默认值为 `0`(禁用)。
使用 `staleCallReaperSeconds` 结束从未收到终止
webhook 的通话(例如从未完成的通知模式通话)。默认值
`0`(禁用)。
推荐范围:
- **生产环境:** 对 notify 风格流程使用 `120``300` 秒。
- 保持该值**高于 `maxDurationSeconds`**,以便正常通话可以完成。一个合适的起点是 `maxDurationSeconds + 3060` 秒。
- **生产** 对于通知式流程,使用 `120``300` 秒。
- 保持此值**高于 `maxDurationSeconds`**,以便正常通话能够结束。一个不错的起点是 `maxDurationSeconds + 3060` 秒。
```json5
{
@ -545,28 +527,29 @@ Voice Call 会防御性地提取语音文本:
}
```
## Webhook 安全
## Webhook 安全
当代理或隧道位于 Gateway 网关前面时,插件会重建公开 URL 以进行签名验证。这些选项控制信任哪些转发头:
当代理或隧道位于 Gateway 网关前面时,插件会
重构用于签名验证的公共 URL。这些选项控制信任哪些转发头
<ParamField path="webhookSecurity.allowedHosts" type="string[]">
允许来自转发头的主机名单。
</ParamField>
<ParamField path="webhookSecurity.trustForwardingHeaders" type="boolean">
在没有 allowlist 的情况下信任转发头。
在没有允许名单的情况下信任转发头。
</ParamField>
<ParamField path="webhookSecurity.trustedProxyIPs" type="string[]">
只有当请求远程 IP 与列表匹配时才信任转发头。
仅当请求远端 IP 匹配列表时才信任转发头。
</ParamField>
其他保护:
- Twilio 和 Plivo 启用 Webhook **重放保护**。重放的有效 webhook 请求会被确认,但跳过副作用处理
- Twilio 对话轮次`<Gather>` 回调中包含逐轮 token因此过期/重放的语音回调无法满足更新的待处理转录轮次。
- 当缺少提供商要求的签名头时,未经认证的 webhook 请求会在读取正文前被拒绝。
- voice-call webhook 使用共享的预认证正文配置64 KB / 5 秒),并在签名验证前附加按 IP 限制的并发上限。
- Twilio 和 Plivo 启用 Webhook **重放保护**重放的有效 webhook 请求会被确认,但跳过副作用。
- Twilio 对话轮次会在 `<Gather>` 回调中包含每轮令牌,因此过期/重放的语音回调无法满足较新的待处理转录轮次。
- 当缺少提供商所需的签名头时,未经认证的 webhook 请求会在读取正文前被拒绝。
- voice-call webhook 使用共享的预认证正文配置64 KB / 5 秒),并在签名验证前增加按 IP 统计的在途请求上限。
使用稳定公主机的示例:
使用稳定公主机的示例:
```json5
{
@ -600,9 +583,15 @@ openclaw voicecall latency # summarize turn latency from lo
openclaw voicecall expose --mode funnel
```
当 Gateway 网关已在运行时,操作类 `voicecall` 命令会委托给 Gateway 网关拥有的 voice-call 运行时,因此 CLI 不会绑定第二个 webhook 服务器。如果无法访问 Gateway 网关,这些命令会回退到独立 CLI 运行时。
当 Gateway 网关已在运行时,操作性的 `voicecall` 命令会委托给
Gateway 网关拥有的 voice-call 运行时,因此 CLI 不会绑定第二个
webhook 服务器。如果无法访问 Gateway 网关,这些命令会回退到
独立 CLI 运行时。
`latency` 会从默认 voice-call 存储路径读取 `calls.jsonl`。使用 `--file <path>` 指向其他日志,并使用 `--last <n>` 将分析限制为最后 N 条记录(默认 200。输出包含轮次延迟和监听等待时间的 p50/p90/p99。
`latency` 会从默认 voice-call 存储路径读取 `calls.jsonl`
使用 `--file <path>` 指向不同日志,并使用 `--last <n>`
分析限制在最后 N 条记录(默认 200。输出包含轮次延迟和监听等待时间的
p50/p90/p99。
## 智能体工具
@ -617,7 +606,7 @@ openclaw voicecall expose --mode funnel
| `end_call` | `callId` |
| `get_status` | `callId` |
此仓库在 `skills/voice-call/SKILL.md` 提供匹配的 skill 文档。
此仓库在 `skills/voice-call/SKILL.md` 提供匹配的 skill 文档。
## Gateway 网关 RPC
@ -630,22 +619,23 @@ openclaw voicecall expose --mode funnel
| `voicecall.end` | `callId` |
| `voicecall.status` | `callId` |
`dtmfSequence` 仅在 `mode: "conversation"` 下有效。Notify-mode 通话如果需要在接通后发送数字,应在通话存在后使用 `voicecall.dtmf`
`dtmfSequence` 仅在 `mode: "conversation"` 中有效。通知模式通话
如果需要连接后的按键数字,应在通话存在后使用 `voicecall.dtmf`
## 故障排除
### 设置 webhook 暴露失败
### 设置无法暴露 webhook
从运行 Gateway 网关的同一环境运行设置:
从运行 Gateway 网关的同一环境运行设置:
```bash
openclaw voicecall setup
openclaw voicecall setup --json
```
对于 `twilio`、`telnyx` 和 `plivo``webhook-exposure` 必须为绿色。已配置的 `publicUrl` 指向本地或专用网络空间时仍会失败,因为运营商无法回拨这些地址。不要将 `localhost`、`127.0.0.1`、`0.0.0.0`、`10.x`、`172.16.x`-`172.31.x`、`192.168.x`、`169.254.x`、`fc00::/7` 或 `fd00::/8` 用作 `publicUrl`
对于 `twilio`、`telnyx` 和 `plivo``webhook-exposure` 必须为绿色。已配置的 `publicUrl` 在指向本地或私有网络地址空间时仍会失败,因为运营商无法回调这些地址。不要将 `localhost`、`127.0.0.1`、`0.0.0.0`、`10.x`、`172.16.x`-`172.31.x`、`192.168.x`、`169.254.x`、`fc00::/7` 或 `fd00::/8` 用作 `publicUrl`
使用一种公开暴露路径:
使用一个公网暴露路径:
```json5
{
@ -676,19 +666,17 @@ openclaw voicecall smoke
### 提供商凭证失败
检查所选提供商和必凭证字段:
检查所选提供商和必需的凭证字段:
- Twilio`twilio.accountSid`、`twilio.authToken` 和 `fromNumber`,或
`TWILIO_ACCOUNT_SID`、`TWILIO_AUTH_TOKEN` 和 `TWILIO_FROM_NUMBER`
- Telnyx`telnyx.apiKey`、`telnyx.connectionId`、`telnyx.publicKey` 和
`fromNumber`
- Twilio`twilio.accountSid`、`twilio.authToken` 和 `fromNumber`,或 `TWILIO_ACCOUNT_SID`、`TWILIO_AUTH_TOKEN` 和 `TWILIO_FROM_NUMBER`
- Telnyx`telnyx.apiKey`、`telnyx.connectionId`、`telnyx.publicKey` 和 `fromNumber`
- Plivo`plivo.authId`、`plivo.authToken` 和 `fromNumber`
凭证必须存在于 Gateway 网关主机上。编辑本地 shell 配置文件不会影响已经运行的 Gateway 网关,除非它重启或重新加载其环境。
凭证必须存在于 Gateway 网关主机上。编辑本地 shell 配置文件不会影响已经运行的 Gateway 网关,直到它重启或重新加载其环境。
### 呼叫开始但提供商 webhook 未到达
### 呼叫开始但提供商 webhook 未到达
确认提供商控制台指向确的公开 webhook URL
确认提供商控制台指向确的公开 webhook URL
```text
https://voice.example.com/voice/webhook
@ -704,20 +692,20 @@ openclaw logs --follow
常见原因:
- `publicUrl` 指向的路径`serve.path` 不同
- 隧道 URL 在 Gateway 网关启动后发生了变化。
- 代理转发了请求,但剥离或写了 host/proto 标头。
- `publicUrl` 指向的路径不同于 `serve.path`
- Gateway 网关启动后,隧道 URL 发生了变化。
- 代理转发了请求,但剥离或写了 host/proto 标头。
- 防火墙或 DNS 将公开主机名路由到了 Gateway 网关以外的位置。
- Gateway 网关重启时未启用 Voice Call 插件。
当反向代理或隧道位于 Gateway 网关前面时,将 `webhookSecurity.allowedHosts` 设置为公开主机名,或对已知代理地址使用 `webhookSecurity.trustedProxyIPs`。仅在代理边界由你控制时才使用 `webhookSecurity.trustForwardingHeaders`
当反向代理或隧道位于 Gateway 网关前面时,将 `webhookSecurity.allowedHosts` 设置为公开主机名,或对已知代理地址使用 `webhookSecurity.trustedProxyIPs`。仅当代理边界由你控制时,才使用 `webhookSecurity.trustForwardingHeaders`
### 签名验证失败
提供商签名会根据 OpenClaw 从传入请求重建的公开 URL 进行检查。如果签名失败:
- 确认提供商 webhook URL 与 `publicUrl` 完全匹配,包括 scheme、host 和 path。
- 对于 ngrok 免费层 URL当隧道主机名变化时更新 `publicUrl`
- 对于 ngrok 免费层 URL当隧道主机名变化时更新 `publicUrl`
- 确保代理保留原始 host 和 proto 标头,或配置 `webhookSecurity.allowedHosts`
- 不要在本地测试之外启用 `skipSignatureVerification`
@ -736,33 +724,33 @@ openclaw voicecall smoke --to "+15555550123"
openclaw googlemeet setup --transport twilio
```
如果 Voice Call 正常,但 Meet 参与者始终未加入,请检查 Meet 拨入号码、PIN 和 `--dtmf-sequence`。电话呼叫可能正常,但会议会拒绝或忽略不正确的 DTMF 序列。
如果 Voice Call 为绿色,但 Meet 参与者从未加入,请检查 Meet 拨入号码、PIN 和 `--dtmf-sequence`。电话呼叫可以是健康的,而会议仍可能拒绝或忽略不正确的 DTMF 序列。
Google Meet 会将 Meet DTMF 序列和介绍文本传递给 `voicecall.start`。对于 Twilio 呼叫Voice Call 会先提供 DTMF TwiML重定向回 webhook然后打开实时媒体流因此保存的介绍会在电话参与者加入会议后生成。
Google Meet 会将 Meet DTMF 序列和介绍文本传递给 `voicecall.start`。对于 Twilio 呼叫Voice Call 会先提供 DTMF TwiML重定向回 webhook然后打开实时媒体流以便保存的介绍在电话参与者加入会议后生成。
使用 `openclaw logs --follow` 查看实时阶段跟踪。正常的 Twilio Meet 加入会按以下顺序记录日志:
使用 `openclaw logs --follow` 查看实时阶段追踪。健康的 Twilio Meet 加入会按以下顺序记录日志:
- Google Meet 将 Twilio 加入委给 Voice Call。
- Voice Call 存储连接 DTMF TwiML。
- Twilio 初始 TwiML 会在实时处理前被消费并提供。
- Google Meet 将 Twilio 加入委给 Voice Call。
- Voice Call 存储连接 DTMF TwiML。
- Twilio 初始 TwiML 在实时处理前被使用并提供。
- Voice Call 为 Twilio 呼叫提供实时 TwiML。
- 实时桥接启动,并将初始问候语加入队列。
`openclaw voicecall tail` 仍会显示持久化的呼叫记录;它对呼叫状态和转录很有用,但并非每个 webhook/实时转换都会出现在那里
`openclaw voicecall tail` 仍会显示持久化的呼叫记录;它对呼叫状态和转录很有用,但并非每个 webhook/实时转换都会出现在其中
### 实时呼叫没有语音
确认只启用了一音频模式。`realtime.enabled` 和 `streaming.enabled` 不能同时为 true。
确认只启用了一音频模式。`realtime.enabled` 和 `streaming.enabled` 不能同时为 true。
对于实时 Twilio 呼叫,还要验证:
- 已加载并注册实时提供商插件。
- `realtime.provider` 未设置,或命名的是已注册提供商。
- `realtime.provider` 未设置,或命名了一个已注册的提供商。
- 提供商 API key 可供 Gateway 网关进程使用。
- `openclaw logs --follow` 显示已提供实时 TwiML、实时桥接已启动并且初始问候语已加入队列。
## 相关内容
- [通话模式](/zh-CN/nodes/talk)
- [Talk 模式](/zh-CN/nodes/talk)
- [文本转语音](/zh-CN/tools/tts)
- [语音唤醒](/zh-CN/nodes/voicewake)