From cbdf2a81117e6abe400177a29bebe298c7d48aa9 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Sat, 25 Apr 2026 18:44:13 +0000 Subject: [PATCH] chore(i18n): refresh zh-CN translations --- docs/zh-CN/cli/plugins.md | 140 ++-- docs/zh-CN/gateway/configuration-reference.md | 645 ++++++++-------- docs/zh-CN/plugins/architecture-internals.md | 700 ++++++++++-------- 3 files changed, 803 insertions(+), 682 deletions(-) diff --git a/docs/zh-CN/cli/plugins.md b/docs/zh-CN/cli/plugins.md index 9e1a1173b..7c72a12eb 100644 --- a/docs/zh-CN/cli/plugins.md +++ b/docs/zh-CN/cli/plugins.md @@ -1,14 +1,14 @@ --- read_when: - - 你想要安装或管理 Gateway 网关插件或兼容的捆绑包 - - 你想要调试插件加载失败问题 + - 你想安装或管理 Gateway 网关插件或兼容的捆绑包 + - 你想调试插件加载失败问题 summary: '`openclaw plugins` 的 CLI 参考(list、install、marketplace、uninstall、enable/disable、doctor)' -title: 插件 +title: Plugins x-i18n: - generated_at: "2026-04-25T17:39:04Z" + generated_at: "2026-04-25T18:41:14Z" model: gpt-5.4 provider: openai - source_hash: 2ae8f71873fb90dc7acde2ac522228cc60603ba34322e5b6d031e8de7545684e + source_hash: 9536d2df20b9284855878dbfc649d7905d6440e9fe8d8d00e63b97c4e428194d source_path: cli/plugins.md workflow: 15 --- @@ -19,7 +19,7 @@ x-i18n: 相关内容: -- 插件系统:[插件](/zh-CN/tools/plugin) +- 插件系统:[Plugins](/zh-CN/tools/plugin) - 捆绑包兼容性:[插件捆绑包](/zh-CN/plugins/bundles) - 插件清单 + schema:[插件清单](/zh-CN/plugins/manifest) - 安全加固:[安全](/zh-CN/gateway/security) @@ -48,49 +48,49 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -内置插件会随 OpenClaw 一起提供。其中一些默认启用(例如内置模型提供商、内置语音提供商,以及内置浏览器插件);另一些则需要运行 `plugins enable`。 +内置插件会随 OpenClaw 一起提供。其中一些默认启用(例如内置模型提供商、内置语音提供商以及内置浏览器插件);其他插件则需要执行 `plugins enable`。 -原生 OpenClaw 插件必须提供 `openclaw.plugin.json`,并包含内联 JSON Schema(`configSchema`,即使为空也需要)。兼容捆绑包则改为使用它们自己的 bundle manifest。 +原生 OpenClaw 插件必须提供 `openclaw.plugin.json`,并带有内联 JSON Schema(`configSchema`,即使为空也需要提供)。兼容的捆绑包则改用它们自己的 bundle manifest。 -`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细 list/info 输出还会显示捆绑包子类型(`codex`、`claude` 或 `cursor`)以及检测到的捆绑包能力。 +`plugins list` 会显示 `Format: openclaw` 或 `Format: bundle`。详细的 list/info 输出还会显示捆绑包子类型(`codex`、`claude` 或 `cursor`),以及检测到的捆绑包能力。 ### 安装 ```bash -openclaw plugins install # 先尝试 ClawHub,再尝试 npm -openclaw plugins install clawhub: # 仅使用 ClawHub +openclaw plugins install # 先查 ClawHub,再查 npm +openclaw plugins install clawhub: # 仅 ClawHub openclaw plugins install --force # 覆盖现有安装 openclaw plugins install --pin # 固定版本 openclaw plugins install --dangerously-force-unsafe-install openclaw plugins install # 本地路径 openclaw plugins install @ # marketplace -openclaw plugins install --marketplace # marketplace(显式指定) +openclaw plugins install --marketplace # marketplace(显式) openclaw plugins install --marketplace https://github.com// ``` -裸包名会先在 ClawHub 中检查,然后再查 npm。安全提示:安装插件应被视为运行代码。建议优先使用固定版本。 +裸包名会先在 ClawHub 中检查,然后再查 npm。安全说明:应将插件安装视为运行代码。建议优先使用固定版本。 -如果你的 `plugins` 部分由单文件 `$include` 提供支持,那么 `plugins install/update/enable/disable/uninstall` 会直接写入该被包含文件,而不会修改 `openclaw.json`。根级 include、include 数组,以及带有同级覆盖项的 include 都会以失败关闭的方式处理,而不会被展平。支持的形式见 [配置 includes](/zh-CN/gateway/configuration)。 +如果你的 `plugins` 部分由单文件 `$include` 支持,那么 `plugins install/update/enable/disable/uninstall` 会直接写入该被包含文件,而不会修改 `openclaw.json`。根级 include、include 数组,以及带有同级覆盖项的 include 都会以失败关闭方式处理,而不会被展平。支持的形态请参见 [配置 include](/zh-CN/gateway/configuration)。 -如果配置无效,`plugins install` 通常会以失败关闭的方式终止,并提示你先运行 `openclaw doctor --fix`。唯一有文档说明的例外,是一条针对明确选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件的狭义内置插件恢复路径。 +如果配置无效,`plugins install` 通常会以失败关闭方式终止,并提示你先运行 `openclaw doctor --fix`。唯一有文档说明的例外,是一个针对显式选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件的狭窄内置插件恢复路径。 -`--force` 会复用现有安装目标,并原地覆盖已安装的插件或 hook 包。当你有意从新的本地路径、归档文件、ClawHub 包或 npm 构件重新安装相同 id 时,应使用它。对于已被跟踪的 npm 插件的常规升级,更推荐使用 `openclaw plugins update `。 +`--force` 会复用现有安装目标,并原地覆盖一个已安装的插件或 hook 包。当你有意使用新的本地路径、归档、ClawHub 包或 npm 制品重新安装同一 id 时,可使用此选项。对于已跟踪的 npm 插件的常规升级,建议优先使用 `openclaw plugins update `。 -如果你对一个已经安装的插件 id 运行 `plugins install`,OpenClaw 会停止并提示你:正常升级请使用 `plugins update `;如果你确实想从不同来源覆盖当前安装,则使用 `plugins install --force`。 +如果你对一个已安装的插件 id 运行 `plugins install`,OpenClaw 会停止并提示你:常规升级应使用 `plugins update `;如果你确实想从不同来源覆盖当前安装,则使用 `plugins install --force`。 -`--pin` 仅适用于 npm 安装。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 来源元数据,而不是 npm spec。 +`--pin` 仅适用于 npm 安装。不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久保存 marketplace 来源元数据,而不是 npm spec。 -`--dangerously-force-unsafe-install` 是一个用于应对内置危险代码扫描器误报的破窗选项。即使内置扫描器报告了 `critical` 级别发现,它也允许安装继续进行,但它**不会**绕过插件 `before_install` hook 策略阻止,也**不会**绕过扫描失败。 +`--dangerously-force-unsafe-install` 是一个用于紧急情况的选项,用于处理内置危险代码扫描器的误报。即使内置扫描器报告 `critical` 级发现,它也允许安装继续进行,但它**不会**绕过插件 `before_install` hook 策略拦截,也**不会**绕过扫描失败。 这个 CLI 标志适用于插件 install/update 流程。由 Gateway 网关支持的 Skills 依赖安装会使用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖项,而 `openclaw skills install` 仍然是单独的 ClawHub Skills 下载/安装流程。 -`plugins install` 也是暴露 `openclaw.hooks` 于 `package.json` 中的 hook 包的安装入口。请使用 `openclaw hooks` 查看经过筛选的 hook 可见性以及按 hook 启用,而不是用于包安装。 +`plugins install` 也是暴露了 `openclaw.hooks` 的 hook 包在 `package.json` 中的安装入口。使用 `openclaw hooks` 可查看经过过滤的 hook 可见性以及对单个 hook 的启用设置,而不是用于安装包。 -npm spec **仅限 registry**(包名 + 可选的**精确版本**或 **dist-tag**)。Git/URL/file spec 和 semver 范围都会被拒绝。出于安全考虑,依赖安装会使用 `--ignore-scripts` 运行。 +Npm spec **仅支持 registry**(包名 + 可选的**精确版本**或 **dist-tag**)。Git/URL/file spec 和 semver 范围会被拒绝。为确保安全,依赖安装会使用 `--ignore-scripts` 运行。 -裸 spec 和 `@latest` 会停留在稳定发布轨道上。如果 npm 将这两者中的任一解析为预发布版本,OpenClaw 会停止并要求你显式选择加入,例如使用 `@beta`/`@rc` 这样的预发布标签,或 `@1.2.3-beta.4` 这样的精确预发布版本。 +裸 spec 和 `@latest` 会保持在稳定通道上。如果 npm 将其中任意一种解析为预发布版本,OpenClaw 会停止,并要求你通过预发布标签(如 `@beta`/`@rc`)或精确预发布版本(如 `@1.2.3-beta.4`)显式选择加入。 -如果一个裸安装 spec 与某个内置插件 id 匹配(例如 `diffs`),OpenClaw 会直接安装该内置插件。若要安装同名 npm 包,请使用显式的带作用域 spec(例如 `@scope/diffs`)。 +如果一个裸安装 spec 与某个内置插件 id 匹配(例如 `diffs`),OpenClaw 会直接安装该内置插件。若要安装同名 npm 包,请使用显式作用域 spec(例如 `@scope/diffs`)。 支持的归档格式:`.zip`、`.tgz`、`.tar.gz`、`.tar`。 @@ -103,22 +103,22 @@ openclaw plugins install clawhub:openclaw-codex-app-server openclaw plugins install clawhub:openclaw-codex-app-server@1.2.3 ``` -OpenClaw 现在对于符合 npm 安全要求的裸插件 spec 也会优先使用 ClawHub。只有当 ClawHub 中没有该包或该版本时,它才会回退到 npm: +OpenClaw 现在也会优先为裸的 npm-safe 插件 spec 使用 ClawHub。只有当 ClawHub 中不存在该包或版本时,才会回退到 npm: ```bash openclaw plugins install openclaw-codex-app-server ``` -OpenClaw 会从 ClawHub 下载包归档,检查已声明的插件 API / 最低 Gateway 网关兼容性,然后通过常规归档路径安装。记录下来的安装会保留其 ClawHub 来源元数据,供后续更新使用。 +OpenClaw 会从 ClawHub 下载包归档,检查已声明的插件 API / 最低网关兼容性,然后通过常规归档路径进行安装。记录下来的安装会保留其 ClawHub 来源元数据,以便后续更新。 -当 marketplace 名称存在于 Claude 的本地 registry 缓存 `~/.claude/plugins/known_marketplaces.json` 中时,可使用 `plugin@marketplace` 简写: +当 marketplace 名称存在于 Claude 的本地注册表缓存 `~/.claude/plugins/known_marketplaces.json` 中时,可使用 `plugin@marketplace` 简写: ```bash openclaw plugins marketplace list openclaw plugins install @ ``` -当你想显式传入 marketplace 来源时,请使用 `--marketplace`: +如果你想显式传入 marketplace 来源,请使用 `--marketplace`: ```bash openclaw plugins install --marketplace @@ -131,20 +131,20 @@ Marketplace 来源可以是: - `~/.claude/plugins/known_marketplaces.json` 中的 Claude 已知 marketplace 名称 - 本地 marketplace 根目录或 `marketplace.json` 路径 -- 形如 `owner/repo` 的 GitHub 仓库简写 -- 形如 `https://github.com/owner/repo` 的 GitHub 仓库 URL +- GitHub 仓库简写,例如 `owner/repo` +- GitHub 仓库 URL,例如 `https://github.com/owner/repo` - git URL -对于从 GitHub 或 git 加载的远程 marketplace,插件条目必须保持在克隆得到的 marketplace 仓库内部。OpenClaw 接受来自该仓库的相对路径来源,并拒绝远程 manifest 中的 HTTP(S)、绝对路径、git、GitHub 以及其他非路径类插件来源。 +对于从 GitHub 或 git 加载的远程 marketplace,插件条目必须保持在克隆得到的 marketplace 仓库内部。OpenClaw 接受来自该仓库的相对路径来源,并拒绝远程 manifest 中的 HTTP(S)、绝对路径、git、GitHub 以及其他非路径插件来源。 -对于本地路径和归档文件,OpenClaw 会自动检测: +对于本地路径和归档,OpenClaw 会自动检测: - 原生 OpenClaw 插件(`openclaw.plugin.json`) -- 与 Codex 兼容的捆绑包(`.codex-plugin/plugin.json`) -- 与 Claude 兼容的捆绑包(`.claude-plugin/plugin.json` 或默认的 Claude 组件布局) -- 与 Cursor 兼容的捆绑包(`.cursor-plugin/plugin.json`) +- Codex 兼容捆绑包(`.codex-plugin/plugin.json`) +- Claude 兼容捆绑包(`.claude-plugin/plugin.json` 或默认的 Claude 组件布局) +- Cursor 兼容捆绑包(`.cursor-plugin/plugin.json`) -兼容捆绑包会安装到常规插件根目录中,并参与相同的 list/info/enable/disable 流程。目前已支持 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` / manifest 声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录;其他已检测到的捆绑包能力会显示在 diagnostics/info 中,但尚未接入运行时执行。 +兼容的捆绑包会安装到常规插件根目录中,并参与相同的 list/info/enable/disable 流程。目前已支持 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` / manifest 声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录;其他检测到的捆绑包能力会显示在诊断/info 中,但尚未接入运行时执行。 ### 列表 @@ -155,15 +155,15 @@ openclaw plugins list --verbose openclaw plugins list --json ``` -使用 `--enabled` 仅显示已启用的插件。使用 `--verbose` 可从表格视图切换为逐插件详细信息行,展示 source/origin/version/activation 元数据。使用 `--json` 获取机器可读的清单以及 registry diagnostics。 +使用 `--enabled` 仅显示已启用插件。使用 `--verbose` 可从表格视图切换到按插件显示详细行,其中包含 source/origin/version/activation 元数据。使用 `--json` 可获取机器可读的清单和注册表诊断信息。 -`plugins list` 会先读取持久化的本地插件 registry;如果 registry 缺失或无效,则回退为仅基于 manifest 推导的结果。它适合用于检查某个插件是否已安装、已启用,以及在冷启动规划中是否可见,但它并不是对已运行 Gateway 网关进程的实时运行时探测。更改插件代码、启用状态、hook 策略或 `plugins.load.paths` 后,在期望新的 `register(api)` 代码或 hook 开始生效之前,请重启为该渠道提供服务的 Gateway 网关。对于远程/容器部署,请确认你重启的是真正的 `openclaw gateway run` 子进程,而不只是一个包装进程。 +`plugins list` 会先读取持久化的本地插件注册表;如果注册表缺失或无效,则回退到仅基于 manifest 推导的结果。它适合用来检查某个插件是否已安装、已启用,以及在冷启动规划中是否可见,但它并不是针对已运行 Gateway 网关进程的实时运行时探针。修改插件代码、启用状态、hook 策略或 `plugins.load.paths` 后,在期待新的 `register(api)` 代码或 hook 生效之前,请重启为该渠道提供服务的 Gateway 网关。对于远程/容器部署,请确认你重启的是实际的 `openclaw gateway run` 子进程,而不仅仅是包装进程。 对于运行时 hook 调试: -- `openclaw plugins inspect --json` 会显示来自模块加载检查过程的已注册 hook 和 diagnostics -- `openclaw gateway status --deep --require-rpc` 会确认可访问的 Gateway 网关、service/process 提示、配置路径和 RPC 健康状态 -- 非内置的对话 hook(`llm_input`、`llm_output`、`agent_end`)要求设置 `plugins.entries..hooks.allowConversationAccess=true` +- `openclaw plugins inspect --json` 会显示模块加载检查过程中注册的 hook 和诊断信息。 +- `openclaw gateway status --deep --require-rpc` 可确认可访问的 Gateway 网关、服务/进程提示、配置路径和 RPC 健康状态。 +- 非内置的会话 hook(`llm_input`、`llm_output`、`agent_end`)要求设置 `plugins.entries..hooks.allowConversationAccess=true`。 使用 `--link` 可避免复制本地目录(会添加到 `plugins.load.paths`): @@ -173,7 +173,13 @@ openclaw plugins install -l ./my-plugin `--force` 不支持与 `--link` 一起使用,因为链接安装会复用源路径,而不是复制到受管理的安装目标上。 -在 npm 安装中使用 `--pin`,可将解析出的精确 spec(`name@version`)保存到 `plugins.installs`,同时保留默认行为的不固定版本模式。 +在 npm 安装中使用 `--pin`,可以将解析后的精确 spec(`name@version`)保存到受管理的安装台账中,同时保留默认的非固定行为。 + +### 安装台账 + +插件安装元数据是机器管理状态,而不是用户配置。新的安装和更新会将其写入活动 OpenClaw 状态目录下的 `plugins/installs.json`。该文件包含“请勿手动编辑”的警告,并被 `openclaw plugins update`、卸载、诊断和冷插件注册表使用。 + +`openclaw.json` 中旧版的 `plugins.installs` 条目仍可作为已弃用的兼容性回退被读取。当 install/update/uninstall 路径重写插件安装状态时,OpenClaw 会写入该台账文件,并从持久化配置负载中移除 `plugins.installs`。 ### 卸载 @@ -183,11 +189,13 @@ openclaw plugins uninstall --dry-run openclaw plugins uninstall --keep-files ``` -`uninstall` 会从 `plugins.entries`、`plugins.installs`、插件 allowlist,以及相关的已链接 `plugins.load.paths` 条目中删除插件记录。对于处于激活状态的 memory 插件,memory 插槽会重置为 `memory-core`。 +`uninstall` 会在适用时从 `plugins.entries`、受管理的安装台账、插件 allowlist 以及已链接的 `plugins.load.paths` 条目中移除插件记录。 +对于处于活动状态的 memory 插件,memory 槽位会重置为 `memory-core`。 -默认情况下,卸载还会删除活动 state-dir 插件根目录下的插件安装目录。使用 `--keep-files` 可保留磁盘上的文件。 +默认情况下,卸载还会删除活动 state-dir 插件根目录下的插件安装目录。使用 +`--keep-files` 可保留磁盘上的文件。 -`--keep-config` 仍受支持,但作为 `--keep-files` 的已弃用别名。 +`--keep-config` 作为 `--keep-files` 的已弃用别名仍受支持。 ### 更新 @@ -199,19 +207,19 @@ openclaw plugins update @openclaw/voice-call@beta openclaw plugins update openclaw-codex-app-server --dangerously-force-unsafe-install ``` -更新会应用于 `plugins.installs` 中已跟踪的安装,以及 `hooks.internal.installs` 中已跟踪的 hook 包安装。 +更新会应用到受管理安装台账中已跟踪的插件安装,以及 `hooks.internal.installs` 中已跟踪的 hook 包安装。 -当你传入插件 id 时,OpenClaw 会复用该插件记录下来的安装 spec。这意味着先前保存的 dist-tag(例如 `@beta`)和精确固定版本,在后续运行 `update ` 时仍会继续使用。 +当你传入插件 id 时,OpenClaw 会复用该插件记录下来的安装 spec。这意味着先前存储的 dist-tag(如 `@beta`)和精确固定版本,在后续执行 `update ` 时仍会继续使用。 -对于 npm 安装,你也可以传入带 dist-tag 或精确版本的显式 npm package spec。OpenClaw 会将该包名重新解析回已跟踪的插件记录,更新对应已安装插件,并为将来基于 id 的更新记录新的 npm spec。 +对于 npm 安装,你也可以传入带有 dist-tag 或精确版本的显式 npm 包 spec。OpenClaw 会将该包名重新解析回已跟踪的插件记录,更新该已安装插件,并记录新的 npm spec,以供未来基于 id 的更新使用。 -传入不带版本或标签的 npm 包名,也会重新解析回已跟踪的插件记录。当某个插件被固定到精确版本,而你想将其切回 registry 默认发布线时,可使用这种方式。 +直接传入不带版本或标签的 npm 包名,也会解析回已跟踪的插件记录。当某个插件被固定到精确版本,而你想让它回到注册表默认发布线时,可使用这种方式。 -在执行实际 npm 更新之前,OpenClaw 会根据 npm registry 元数据检查已安装包版本。如果已安装版本和已记录的构件标识与解析出的目标已经一致,则会跳过更新,不会下载、重新安装,也不会改写 `openclaw.json`。 +在执行实时 npm 更新之前,OpenClaw 会根据 npm 注册表元数据检查已安装的包版本。如果已安装版本和记录的制品标识已与解析出的目标一致,则会跳过更新,不会下载、重新安装,也不会重写 `openclaw.json`。 -当存在已存储的完整性哈希,而获取到的构件哈希发生变化时,OpenClaw 会将其视为 npm 构件漂移。交互式 `openclaw plugins update` 命令会打印预期哈希和实际哈希,并在继续之前请求确认。非交互式更新辅助工具会以失败关闭的方式终止,除非调用方提供了显式的继续策略。 +当存在已存储的完整性哈希,而获取到的制品哈希发生变化时,OpenClaw 会将其视为 npm 制品漂移。交互式的 `openclaw plugins update` 命令会打印预期哈希和实际哈希,并在继续之前请求确认。非交互式更新辅助工具会以失败关闭方式终止,除非调用方提供显式的继续策略。 -`--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为在插件更新期间应对内置危险代码扫描误报的破窗覆盖项。它仍然不会绕过插件 `before_install` 策略阻止或扫描失败阻止,并且它仅适用于插件更新,不适用于 hook 包更新。 +`--dangerously-force-unsafe-install` 也可用于 `plugins update`,作为插件更新期间内置危险代码扫描误报的紧急覆盖选项。它仍然不会绕过插件 `before_install` 策略拦截或扫描失败拦截,并且它仅适用于插件更新,不适用于 hook 包更新。 ### 检查 @@ -220,20 +228,20 @@ openclaw plugins inspect openclaw plugins inspect --json ``` -针对单个插件的深度检查。会显示身份、加载状态、来源、已注册能力、hooks、工具、命令、服务、gateway 方法、HTTP 路由、策略标志、diagnostics、安装元数据、捆绑包能力,以及任何检测到的 MCP 或 LSP 服务器支持。 +针对单个插件的深度自省。会显示身份信息、加载状态、来源、已注册能力、hooks、工具、命令、服务、网关方法、HTTP 路由、策略标志、诊断信息、安装元数据、捆绑包能力,以及任何检测到的 MCP 或 LSP 服务器支持。 -每个插件都会根据其在运行时实际注册的内容进行分类: +每个插件都会根据它在运行时实际注册的内容进行分类: -- **plain-capability** — 一种能力类型(例如仅 provider 的插件) -- **hybrid-capability** — 多种能力类型(例如文本 + 语音 + 图像) -- **hook-only** — 只有 hooks,没有能力或其他 surface +- **plain-capability** — 一种能力类型(例如,仅提供商插件) +- **hybrid-capability** — 多种能力类型(例如,文本 + 语音 + 图像) +- **hook-only** — 只有 hooks,没有能力或表面 - **non-capability** — 有工具/命令/服务,但没有能力 有关能力模型的更多信息,请参见 [插件形态](/zh-CN/plugins/architecture#plugin-shapes)。 -`--json` 标志会输出适合脚本处理和审计的机器可读报告。 +`--json` 标志会输出适合脚本和审计的机器可读报告。 -`inspect --all` 会渲染一个面向整个插件集合的表格,其中包含 shape、capability kinds、兼容性提示、捆绑包能力和 hook 摘要列。 +`inspect --all` 会渲染一个全局表格,包含 shape、capability kinds、兼容性提示、捆绑包能力和 hook 摘要列。 `info` 是 `inspect` 的别名。 @@ -243,11 +251,11 @@ openclaw plugins inspect --json openclaw plugins doctor ``` -`doctor` 会报告插件加载错误、manifest/设备发现 diagnostics,以及兼容性提示。当一切正常时,它会打印 `No plugin issues detected.`。 +`doctor` 会报告插件加载错误、manifest/设备发现 诊断信息以及兼容性提示。当一切正常时,它会打印 `No plugin issues detected.`。 -对于缺少 `register`/`activate` 导出之类的模块形态失败,请使用 `OPENCLAW_PLUGIN_LOAD_DEBUG=1` 重新运行,以便在诊断输出中包含紧凑的导出形态摘要。 +对于缺少 `register`/`activate` 导出等模块形态失败,可使用 `OPENCLAW_PLUGIN_LOAD_DEBUG=1` 重新运行,以便在诊断输出中包含紧凑的导出形态摘要。 -### Registry +### 注册表 ```bash openclaw plugins registry @@ -255,11 +263,11 @@ openclaw plugins registry --refresh openclaw plugins registry --json ``` -本地插件 registry 是 OpenClaw 针对已安装插件身份、启用状态、来源元数据和贡献归属关系的持久化冷读取模型。正常启动、provider 所有者查找、渠道设置分类以及插件清单都可以在不导入插件运行时模块的情况下读取它。 +本地插件注册表是 OpenClaw 针对已安装插件身份、启用状态、来源元数据和贡献归属的持久化冷读模型。正常启动、提供商所有者查找、渠道设置分类和插件清单都可以在不导入插件运行时模块的情况下读取它。 -使用 `plugins registry` 可检查持久化 registry 是否存在、是否为最新,或是否已过期。使用 `--refresh` 可根据持久化安装账本、配置策略以及 manifest/package 元数据重建它。这是一条修复路径,而不是运行时激活路径。 +使用 `plugins registry` 可检查持久化注册表是否存在、是否最新或是否过时。使用 `--refresh` 可根据持久化安装台账、配置策略以及 manifest/package 元数据重新构建它。这是一条修复路径,而不是运行时激活路径。 -`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` 是一个已弃用的破窗兼容性开关,用于处理 registry 读取失败。更推荐使用 `plugins registry --refresh` 或 `openclaw doctor --fix`;这个环境变量回退仅用于迁移发布期间的紧急启动恢复。 +`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1` 是针对注册表读取失败的已弃用紧急兼容性开关。建议优先使用 `plugins registry --refresh` 或 `openclaw doctor --fix`;这个环境变量回退仅用于迁移推进期间的紧急启动恢复。 ### Marketplace @@ -268,9 +276,9 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -Marketplace list 接受本地 marketplace 路径、`marketplace.json` 路径、形如 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL 或 git URL。`--json` 会打印解析后的来源标签,以及已解析的 marketplace manifest 和插件条目。 +Marketplace list 接受本地 marketplace 路径、`marketplace.json` 路径、如 `owner/repo` 这样的 GitHub 简写、GitHub 仓库 URL 或 git URL。`--json` 会打印解析后的来源标签,以及已解析的 marketplace manifest 和插件条目。 -## 相关内容 +## 相关 - [CLI 参考](/zh-CN/cli) - [构建插件](/zh-CN/plugins/building-plugins) diff --git a/docs/zh-CN/gateway/configuration-reference.md b/docs/zh-CN/gateway/configuration-reference.md index 8a9412084..69f28d970 100644 --- a/docs/zh-CN/gateway/configuration-reference.md +++ b/docs/zh-CN/gateway/configuration-reference.md @@ -1,51 +1,51 @@ --- read_when: - - 你需要精确到字段级别的配置语义或默认值 - - 你正在验证渠道、模型、Gateway 网关或工具配置块 -summary: Gateway 网关配置参考,涵盖核心 OpenClaw 键名、默认值以及指向各专用子系统参考的链接 + - 你需要精确到字段级别的配置语义或默认值。 + - 你正在验证渠道、模型、Gateway 网关或工具配置块。 +summary: 用于核心 OpenClaw 键名、默认值以及专用子系统参考链接的 Gateway 网关配置参考。 title: 配置参考 x-i18n: - generated_at: "2026-04-25T18:12:20Z" + generated_at: "2026-04-25T18:41:14Z" model: gpt-5.4 provider: openai - source_hash: 0b7e904455845a9559a0a8ed67b217597819f4a8abc38e6c8ecb69b6481528e8 + source_hash: 20618b101b5c287343e0f97cd2536f42950d855ba8a8ca5f6f5b5eb10cba749d source_path: gateway/configuration-reference.md workflow: 15 --- -`~/.openclaw/openclaw.json` 的核心配置参考。若需面向任务的概览,请参阅 [Configuration](/zh-CN/gateway/configuration)。 +`~/.openclaw/openclaw.json` 的核心配置参考。若要查看面向任务的概览,请参阅 [配置](/zh-CN/gateway/configuration)。 -本页涵盖 OpenClaw 的主要配置面,并在某个子系统拥有更深入的独立参考时提供外链。由渠道和插件拥有的命令目录,以及深层的 memory/QMD 调整项,分别位于它们自己的页面,而不在本页中说明。 +涵盖 OpenClaw 的主要配置面,并在某个子系统拥有更深入的独立参考时提供跳转链接。由渠道和插件拥有的命令目录,以及更深入的 memory/QMD 细节配置,位于各自的页面中,而不是本页。 -代码中的真实定义: +代码事实依据: - `openclaw config schema` 会打印用于验证和 Control UI 的实时 JSON Schema,并在可用时合并内置/插件/渠道元数据 -- `config.schema.lookup` 会返回一个按路径限定的 schema 节点,供下钻工具使用 -- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 表面验证配置文档基线哈希 +- `config.schema.lookup` 返回单个按路径限定的 schema 节点,供深入查看工具使用 +- `pnpm config:docs:check` / `pnpm config:docs:gen` 会根据当前 schema 范围,验证配置文档基线哈希 专用深度参考: -- [Memory configuration reference](/zh-CN/reference/memory-config),用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations` 以及位于 `plugins.entries.memory-core.config.dreaming` 下的 dreaming 配置 -- [Slash commands](/zh-CN/tools/slash-commands),用于当前内建 + 内置的命令目录 -- 各归属渠道/插件页面,用于渠道特定的命令面 +- [内存配置参考](/zh-CN/reference/memory-config),适用于 `agents.defaults.memorySearch.*`、`memory.qmd.*`、`memory.citations`,以及位于 `plugins.entries.memory-core.config.dreaming` 下的 Dreaming 配置 +- [斜杠命令](/zh-CN/tools/slash-commands),适用于当前内置 + 内置打包的命令目录 +- 各归属渠道/插件页面,适用于特定渠道的命令面 -配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的 —— 省略时,OpenClaw 会使用安全默认值。 +配置格式为 **JSON5**(允许注释和尾随逗号)。所有字段都是可选的——省略时,OpenClaw 会使用安全默认值。 --- ## 渠道 -各渠道配置键已移至独立页面 —— 请参阅 -[Configuration — channels](/zh-CN/gateway/config-channels),了解 `channels.*`, +每个渠道的配置键已移至专门页面——请参阅 +[配置——渠道](/zh-CN/gateway/config-channels),了解 `channels.*`, 包括 Slack、Discord、Telegram、WhatsApp、Matrix、iMessage 及其他 -内置渠道(认证、访问控制、多账户、提及门控)。 +内置渠道(认证、访问控制、多账号、提及门控)。 -## 智能体默认值、多智能体、会话与消息 +## 智能体默认值、多智能体、会话和消息 -已移至独立页面 —— 请参阅 -[Configuration — agents](/zh-CN/gateway/config-agents),其中包括: +已移至专门页面——请参阅 +[配置——智能体](/zh-CN/gateway/config-agents),内容包括: -- `agents.defaults.*`(工作区、模型、思考、心跳、memory、媒体、skills、沙箱) +- `agents.defaults.*`(工作区、模型、思考、心跳、内存、媒体、Skills、沙箱) - `multiAgent.*`(多智能体路由与绑定) - `session.*`(会话生命周期、压缩、清理) - `messages.*`(消息投递、TTS、Markdown 渲染) @@ -55,20 +55,20 @@ x-i18n: ## 工具和自定义提供商 工具策略、实验性开关、由提供商支持的工具配置,以及自定义 -提供商 / base-URL 设置已移至独立页面 —— 请参阅 -[Configuration — tools and custom providers](/zh-CN/gateway/config-tools)。 +provider / base-URL 设置已移至专门页面——请参阅 +[配置——工具和自定义提供商](/zh-CN/gateway/config-tools)。 ## MCP 由 OpenClaw 管理的 MCP 服务器定义位于 `mcp.servers` 下, -供嵌入式 Pi 和其他运行时适配器使用。`openclaw mcp list`、 -`show`、`set` 和 `unset` 命令可管理此配置块,而无需在编辑配置时连接到 -目标服务器。 +并由嵌入式 Pi 及其他运行时适配器使用。`openclaw mcp list`、 +`show`、`set` 和 `unset` 命令在编辑配置时管理此配置块, +且不会连接到目标服务器。 ```json5 { mcp: { - // Optional. Default: 600000 ms (10 minutes). Set 0 to disable idle eviction. + // 可选。默认值:600000 ms(10 分钟)。设为 0 可禁用空闲驱逐。 sessionIdleTtlMs: 600000, servers: { docs: { @@ -87,16 +87,16 @@ x-i18n: } ``` -- `mcp.servers`:供运行时暴露已配置 MCP 工具的具名 stdio 或远程 MCP 服务器定义。 -- `mcp.sessionIdleTtlMs`:面向会话作用域内置 MCP 运行时的空闲 TTL。 - 一次性嵌入式运行会请求在运行结束时清理;此 TTL 是面向 - 长生命周期会话和未来调用方的兜底机制。 -- `mcp.*` 下的更改会通过释放已缓存的会话 MCP 运行时来热应用。 +- `mcp.servers`:为暴露已配置 MCP 工具的运行时提供命名的 stdio 或远程 MCP 服务器定义。 +- `mcp.sessionIdleTtlMs`:用于按会话作用域划分的内置 MCP 运行时的空闲 TTL。 + 一次性嵌入式运行会请求在运行结束时清理;这个 TTL 是为 + 长生命周期会话和未来调用方提供的兜底机制。 +- `mcp.*` 下的更改会通过释放缓存的会话 MCP 运行时来热应用。 下一次工具发现/使用时会根据新配置重新创建它们,因此被移除的 - `mcp.servers` 条目会被立即清理,而不是等待空闲 TTL 到期。 + `mcp.servers` 条目会立即被清理,而不是等待空闲 TTL 到期。 -运行时行为请参阅 [MCP](/zh-CN/cli/mcp#openclaw-as-an-mcp-client-registry) 和 -[CLI backends](/zh-CN/gateway/cli-backends#bundle-mcp-overlays)。 +有关运行时行为,请参阅 [MCP](/zh-CN/cli/mcp#openclaw-as-an-mcp-client-registry) 和 +[CLI 后端](/zh-CN/gateway/cli-backends#bundle-mcp-overlays)。 ## Skills @@ -113,7 +113,7 @@ x-i18n: }, entries: { "image-lab": { - apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // or plaintext string + apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // 或明文字符串 env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" }, }, peekaboo: { enabled: true }, @@ -123,13 +123,13 @@ x-i18n: } ``` -- `allowBundled`:仅针对内置 Skills 的可选允许列表(托管/工作区 Skills 不受影响)。 +- `allowBundled`:仅适用于内置 Skills 的可选允许列表(受管理/工作区 Skills 不受影响)。 - `load.extraDirs`:额外的共享 Skills 根目录(优先级最低)。 -- `install.preferBrew`:为 `true` 时,若 `brew` 可用,则优先使用 Homebrew 安装器,再回退到其他安装器类型。 +- `install.preferBrew`:为 true 时,如果 `brew` 可用,则优先使用 Homebrew 安装器,再回退到其他安装器类型。 - `install.nodeManager`:用于 `metadata.openclaw.install` - 规范的 Node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。 -- `entries..enabled: false`:即使某个 skill 已内置/已安装,也会禁用它。 -- `entries..apiKey`:针对声明了主环境变量的 skills 提供的便捷字段(明文字符串或 SecretRef 对象)。 + 规格的 Node 安装器偏好(`npm` | `pnpm` | `yarn` | `bun`)。 +- `entries..enabled: false`:即使某个 Skills 已内置/已安装,也会禁用它。 +- `entries..apiKey`:为声明主要环境变量的 Skills 提供的便捷字段(明文字符串或 SecretRef 对象)。 --- @@ -158,44 +158,49 @@ x-i18n: ``` - 从 `~/.openclaw/extensions`、`/.openclaw/extensions` 以及 `plugins.load.paths` 加载。 -- 设备发现可接受原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。 +- 发现机制接受原生 OpenClaw 插件,以及兼容的 Codex bundle 和 Claude bundle,包括无 manifest 的 Claude 默认布局 bundle。 - **配置更改需要重启 Gateway 网关。** - `allow`:可选允许列表(仅加载列出的插件)。`deny` 优先。 -- `plugins.entries..apiKey`:插件级 API 密钥便捷字段(插件支持时可用)。 -- `plugins.entries..env`:插件作用域环境变量映射。 -- `plugins.entries..hooks.allowPromptInjection`:为 `false` 时,核心会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件钩子以及受支持 bundle 提供的钩子目录。 -- `plugins.entries..hooks.allowConversationAccess`:为 `true` 时,受信任的非内置插件可从 `llm_input`、`llm_output` 和 `agent_end` 等类型化钩子中读取原始会话内容。 -- `plugins.entries..subagent.allowModelOverride`:显式信任此插件,使其可为后台子智能体运行请求逐次运行级别的 `provider` 和 `model` 覆盖。 -- `plugins.entries..subagent.allowedModels`:面向受信任子智能体覆盖的规范 `provider/model` 目标可选允许列表。仅在你确实有意允许任意模型时使用 `"*"`。 -- `plugins.entries..config`:插件定义的配置对象(可在原生 OpenClaw 插件 schema 可用时按其验证)。 -- 渠道插件的账户/运行时设置位于 `channels.` 下,应由归属插件 manifest 的 `channelConfigs` 元数据描述,而不是由中央 OpenClaw 选项注册表描述。 -- `plugins.entries.firecrawl.config.webFetch`:Firecrawl web-fetch 提供商设置。 +- `plugins.entries..apiKey`:插件级 API 密钥便捷字段(当插件支持时)。 +- `plugins.entries..env`:插件作用域的环境变量映射。 +- `plugins.entries..hooks.allowPromptInjection`:为 `false` 时,核心会阻止 `before_prompt_build`,并忽略旧版 `before_agent_start` 中会修改提示词的字段,同时保留旧版 `modelOverride` 和 `providerOverride`。适用于原生插件钩子和受支持的 bundle 提供的钩子目录。 +- `plugins.entries..hooks.allowConversationAccess`:为 `true` 时,受信任的非内置插件可从 `llm_input`、`llm_output` 和 `agent_end` 等类型化钩子中读取原始对话内容。 +- `plugins.entries..subagent.allowModelOverride`:显式信任此插件,使其可为后台子智能体运行请求按次运行的 `provider` 和 `model` 覆盖。 +- `plugins.entries..subagent.allowedModels`:受信任子智能体覆盖可使用的规范 `provider/model` 目标的可选允许列表。仅当你明确希望允许任意模型时,才使用 `"*"`。 +- `plugins.entries..config`:插件定义的配置对象(如可用,会根据原生 OpenClaw 插件 schema 验证)。 +- 渠道插件的账号/运行时设置位于 `channels.` 下,应由归属插件的 manifest `channelConfigs` 元数据描述,而不是由中央 OpenClaw 选项注册表描述。 +- `plugins.entries.firecrawl.config.webFetch`:Firecrawl 网页抓取提供商设置。 - `apiKey`:Firecrawl API 密钥(接受 SecretRef)。会回退到 `plugins.entries.firecrawl.config.webSearch.apiKey`、旧版 `tools.web.fetch.firecrawl.apiKey` 或 `FIRECRAWL_API_KEY` 环境变量。 - - `baseUrl`:Firecrawl API base URL(默认值:`https://api.firecrawl.dev`)。 - - `onlyMainContent`:仅提取页面主体内容(默认值:`true`)。 - - `maxAgeMs`:最大缓存时长,单位为毫秒(默认值:`172800000` / 2 天)。 - - `timeoutSeconds`:抓取请求超时秒数(默认值:`60`)。 -- `plugins.entries.xai.config.xSearch`:xAI X Search(Grok web 搜索)设置。 + - `baseUrl`:Firecrawl API 基础 URL(默认值:`https://api.firecrawl.dev`)。 + - `onlyMainContent`:仅提取页面主内容(默认值:`true`)。 + - `maxAgeMs`:缓存最大有效时长(毫秒)(默认值:`172800000` / 2 天)。 + - `timeoutSeconds`:抓取请求超时(秒)(默认值:`60`)。 +- `plugins.entries.xai.config.xSearch`:xAI X Search(Grok 网页搜索)设置。 - `enabled`:启用 X Search 提供商。 - `model`:用于搜索的 Grok 模型(例如 `"grok-4-1-fast"`)。 -- `plugins.entries.memory-core.config.dreaming`:memory dreaming 设置。阶段和阈值请参阅 [Dreaming](/zh-CN/concepts/dreaming)。 - - `enabled`:dreaming 总开关(默认值 `false`)。 - - `frequency`:每次完整 dreaming 扫描的 cron 频率(默认值为 `"0 3 * * *"`)。 +- `plugins.entries.memory-core.config.dreaming`:内存 Dreaming 设置。有关阶段和阈值,请参阅 [Dreaming](/zh-CN/concepts/dreaming)。 + - `enabled`:Dreaming 主开关(默认值为 `false`)。 + - `frequency`:每次完整 Dreaming 扫描的 cron 频率(默认值为 `"0 3 * * *"`)。 - 阶段策略和阈值属于实现细节(不是面向用户的配置键)。 -- 完整 memory 配置位于 [Memory configuration reference](/zh-CN/reference/memory-config): +- 完整的内存配置位于 [内存配置参考](/zh-CN/reference/memory-config): - `agents.defaults.memorySearch.*` - `memory.backend` - `memory.citations` - `memory.qmd.*` - `plugins.entries.memory-core.config.dreaming` - 已启用的 Claude bundle 插件也可通过 `settings.json` 提供嵌入式 Pi 默认值;OpenClaw 会将其作为已清理的智能体设置应用,而不是作为原始 OpenClaw 配置补丁。 -- `plugins.slots.memory`:选择活动 memory 插件 id,或使用 `"none"` 以禁用 memory 插件。 -- `plugins.slots.contextEngine`:选择活动 context engine 插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。 -- `plugins.installs`:由 CLI 管理的安装元数据,供 `openclaw plugins update` 使用。 - - 包括 `source`、`spec`、`sourcePath`、`installPath`、`version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、`shasum`、`resolvedAt`、`installedAt`。 - - 将 `plugins.installs.*` 视为托管状态;优先使用 CLI 命令,而不是手动编辑。 +- `plugins.slots.memory`:选择活动内存插件 id,或使用 `"none"` 禁用内存插件。 +- `plugins.slots.contextEngine`:选择活动上下文引擎插件 id;默认值为 `"legacy"`,除非你安装并选择了其他引擎。 +- `plugins.installs`:已弃用的兼容性回退字段,用于旧版 + CLI 管理的安装元数据。新的插件安装会改为写入受管理的 + `plugins/installs.json` 状态账本。 + - 旧版记录包括 `source`、`spec`、`sourcePath`、`installPath`、 + `version`、`resolvedName`、`resolvedVersion`、`resolvedSpec`、`integrity`、 + `shasum`、`resolvedAt`、`installedAt`。 + - 将 `plugins.installs.*` 视为受管理状态;优先使用 CLI 命令,而非 + 手动编辑。 -请参阅 [Plugins](/zh-CN/tools/plugin)。 +请参阅 [插件](/zh-CN/tools/plugin)。 --- @@ -208,8 +213,8 @@ x-i18n: evaluateEnabled: true, defaultProfile: "user", ssrfPolicy: { - // dangerouslyAllowPrivateNetwork: true, // opt in only for trusted private-network access - // allowPrivateNetwork: true, // legacy alias + // dangerouslyAllowPrivateNetwork: true, // 仅在受信任的私有网络访问场景中启用 + // allowPrivateNetwork: true, // 旧版别名 // hostnameAllowlist: ["*.example.com", "example.com"], // allowedHostnames: ["localhost"], }, @@ -246,46 +251,46 @@ x-i18n: ``` - `evaluateEnabled: false` 会禁用 `act:evaluate` 和 `wait --fn`。 -- `tabCleanup` 会在空闲一段时间后,或当某个 - 会话超过其上限时,回收已跟踪的主智能体标签页。将 `idleMinutes: 0` 或 `maxTabsPerSession: 0` 设为 - 可禁用对应的单独清理模式。 -- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时为禁用状态,因此浏览器导航默认保持严格模式。 +- `tabCleanup` 会在空闲时间到达后,或当某个 + 会话超过上限时,回收已跟踪的主智能体标签页。将 `idleMinutes: 0` 或 `maxTabsPerSession: 0` 设为 + 可禁用各自对应的清理模式。 +- `ssrfPolicy.dangerouslyAllowPrivateNetwork` 在未设置时默认禁用,因此浏览器导航默认保持严格模式。 - 仅当你明确信任私有网络浏览器导航时,才设置 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`。 -- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性/发现检查期间也会受到相同的私有网络阻止限制。 -- `ssrfPolicy.allowPrivateNetwork` 仍然作为旧版别名受到支持。 -- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 作为显式例外。 -- 远程配置文件仅支持附加模式(禁用启动/停止/重置)。 +- 在严格模式下,远程 CDP 配置文件端点(`profiles.*.cdpUrl`)在可达性/发现检查期间也会受到相同的私有网络阻止策略约束。 +- `ssrfPolicy.allowPrivateNetwork` 仍然作为旧版别名受支持。 +- 在严格模式下,使用 `ssrfPolicy.hostnameAllowlist` 和 `ssrfPolicy.allowedHostnames` 来设置显式例外。 +- 远程配置文件为仅附加模式(禁用 start/stop/reset)。 - `profiles.*.cdpUrl` 接受 `http://`、`https://`、`ws://` 和 `wss://`。 - 当你希望 OpenClaw 发现 `/json/version` 时,使用 HTTP(S);使用 WS(S) - 则适用于你的提供商直接给出 DevTools WebSocket URL 的情况。 -- `remoteCdpTimeoutMs` 和 `remoteCdpHandshakeTimeoutMs` 适用于远程以及 - `attachOnly` CDP 的可达性检查和标签页打开请求。托管的 local loopback - 配置文件会保留本地 CDP 默认值。 + 当你希望 OpenClaw 发现 `/json/version` 时,请使用 HTTP(S);使用 WS(S) + 则适用于提供商直接给你 DevTools WebSocket URL 的场景。 +- `remoteCdpTimeoutMs` 和 `remoteCdpHandshakeTimeoutMs` 适用于远程和 + `attachOnly` CDP 可达性检查,以及标签页打开请求。受管理的 local loopback + 配置文件仍使用本地 CDP 默认值。 - 如果某个外部管理的 CDP 服务可通过 local loopback 访问,请将该 - 配置文件的 `attachOnly: true` 打开;否则 OpenClaw 会将该 loopback 端口视为 - 本地托管浏览器配置文件,并可能报告本地端口归属错误。 -- `existing-session` 配置文件使用 Chrome MCP 而不是 CDP,并且可在 - 所选主机上附加,或通过已连接的浏览器节点附加。 -- `existing-session` 配置文件可以设置 `userDataDir`,以指向特定的 - 基于 Chromium 的浏览器配置文件,例如 Brave 或 Edge。 + 配置文件的 `attachOnly: true` 设为 true;否则 OpenClaw 会将该 loopback 端口视为 + 本地受管理浏览器配置文件,并可能报告本地端口归属错误。 +- `existing-session` 配置文件使用 Chrome MCP 而不是 CDP,并且可以附加到 + 所选主机上,或通过已连接的浏览器节点进行附加。 +- `existing-session` 配置文件可以设置 `userDataDir`,以指定某个特定的 + Chromium 内核浏览器配置文件,例如 Brave 或 Edge。 - `existing-session` 配置文件保留当前 Chrome MCP 路由限制: - 使用 snapshot/ref 驱动的操作而非 CSS 选择器定位、单文件上传 - 钩子、不支持对话框超时覆盖、不支持 `wait --load networkidle`,且不支持 + 使用 snapshot/ref 驱动的操作,而不是 CSS 选择器定位;单文件上传 + 钩子;不支持对话框超时覆盖;不支持 `wait --load networkidle`;也不支持 `responsebody`、PDF 导出、下载拦截或批量操作。 -- 本地托管的 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;只有在远程 CDP 场景下 +- 本地受管理的 `openclaw` 配置文件会自动分配 `cdpPort` 和 `cdpUrl`;仅在远程 CDP 场景下 才需要显式设置 `cdpUrl`。 -- 本地托管配置文件可以设置 `executablePath`,以覆盖该配置文件的全局 - `browser.executablePath`。可用它让一个配置文件运行在 - Chrome 中,而另一个运行在 Brave 中。 -- 本地托管配置文件在进程启动后会使用 `browser.localLaunchTimeoutMs` 进行 Chrome CDP HTTP +- 本地受管理配置文件可以设置 `executablePath`,以覆盖该配置文件的全局 + `browser.executablePath`。用它可以让一个配置文件运行在 + Chrome 中,另一个运行在 Brave 中。 +- 本地受管理配置文件在进程启动后,使用 `browser.localLaunchTimeoutMs` 进行 Chrome CDP HTTP 发现,并使用 `browser.localCdpReadyTimeoutMs` 检查 - 启动后 CDP websocket 就绪情况。在较慢主机上,如果 Chrome 能成功启动 - 但就绪检查与启动过程发生竞争,请提高这些值。 -- 自动检测顺序:默认浏览器(如果基于 Chromium)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 -- `browser.executablePath` 接受 `~` 作为你的操作系统主目录。 -- 控制服务:仅限 loopback(端口由 `gateway.port` 派生,默认值为 `18791`)。 -- `extraArgs` 会向本地 Chromium 启动附加额外启动标志(例如 - `--disable-gpu`、窗口大小设置或调试标志)。 + 启动后 CDP websocket 就绪情况。在较慢的主机上,如果 Chrome 能成功启动, + 但就绪检查与启动过程竞争,请适当调高这些值。 +- 自动检测顺序:默认浏览器(如果为 Chromium 内核)→ Chrome → Brave → Edge → Chromium → Chrome Canary。 +- `browser.executablePath` 接受 `~`,表示你操作系统的主目录。 +- 控制服务:仅限 loopback(端口由 `gateway.port` 推导,默认值为 `18791`)。 +- `extraArgs` 会向本地 Chromium 启动附加额外的启动参数(例如 + `--disable-gpu`、窗口尺寸设置或调试标志)。 --- @@ -297,7 +302,7 @@ x-i18n: seamColor: "#FF4500", assistant: { name: "OpenClaw", - avatar: "CB", // emoji, short text, image URL, or data URI + avatar: "CB", // emoji、短文本、图片 URL 或 data URI }, }, } @@ -319,8 +324,8 @@ x-i18n: auth: { mode: "token", // none | token | password | trusted-proxy token: "your-token", - // password: "your-password", // or OPENCLAW_GATEWAY_PASSWORD - // trustedProxy: { userHeader: "x-forwarded-user" }, // for mode=trusted-proxy; see /gateway/trusted-proxy-auth + // password: "your-password", // 或 OPENCLAW_GATEWAY_PASSWORD + // trustedProxy: { userHeader: "x-forwarded-user" }, // 用于 mode=trusted-proxy;参见 /gateway/trusted-proxy-auth allowTailscale: true, rateLimit: { maxAttempts: 10, @@ -338,9 +343,9 @@ x-i18n: basePath: "/openclaw", // root: "dist/control-ui", // embedSandbox: "scripts", // strict | scripts | trusted - // allowExternalEmbedUrls: false, // dangerous: allow absolute external http(s) embed URLs - // allowedOrigins: ["https://control.example.com"], // required for non-loopback Control UI - // dangerouslyAllowHostHeaderOriginFallback: false, // dangerous Host-header origin fallback mode + // allowExternalEmbedUrls: false, // 危险:允许绝对外部 http(s) 嵌入 URL + // allowedOrigins: ["https://control.example.com"], // 非 loopback Control UI 必填 + // dangerouslyAllowHostHeaderOriginFallback: false, // 危险的 Host 标头 origin 回退模式 // allowInsecureAuth: false, // dangerouslyDisableDeviceAuth: false, }, @@ -351,20 +356,20 @@ x-i18n: // password: "your-password", }, trustedProxies: ["10.0.0.1"], - // Optional. Default false. + // 可选。默认值为 false。 allowRealIpFallback: false, nodes: { pairing: { - // Optional. Default unset/disabled. + // 可选。默认未设置/禁用。 autoApproveCidrs: ["192.168.1.0/24", "fd00:1234:5678::/64"], }, allowCommands: ["canvas.navigate"], denyCommands: ["system.run"], }, tools: { - // Additional /tools/invoke HTTP denies + // 额外的 /tools/invoke HTTP 拒绝项 deny: ["browser"], - // Remove tools from the default HTTP deny list + // 从默认 HTTP 拒绝列表中移除工具 allow: ["gateway"], }, push: { @@ -384,48 +389,48 @@ x-i18n: - `mode`:`local`(运行 Gateway 网关)或 `remote`(连接到远程 Gateway 网关)。只有在 `local` 模式下,Gateway 网关才允许启动。 - `port`:用于 WS + HTTP 的单一复用端口。优先级:`--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`。 - `bind`:`auto`、`loopback`(默认)、`lan`(`0.0.0.0`)、`tailnet`(仅 Tailscale IP)或 `custom`。 -- **旧版 bind 别名**:请在 `gateway.bind` 中使用 bind 模式值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用主机别名(`0.0.0.0`、`127.0.0.1`、`localhost`、`::`、`::1`)。 -- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。在 Docker bridge 网络(`-p 18789:18789`)下,流量会到达 `eth0`,因此 Gateway 网关无法访问。请使用 `--network host`,或设置 `bind: "lan"`(或使用 `bind: "custom"` 且 `customBindHost: "0.0.0.0"`)以监听所有接口。 +- **旧版 bind 别名**:在 `gateway.bind` 中使用 bind 模式值(`auto`、`loopback`、`lan`、`tailnet`、`custom`),不要使用主机别名(`0.0.0.0`、`127.0.0.1`、`localhost`、`::`、`::1`)。 +- **Docker 注意事项**:默认的 `loopback` bind 会在容器内监听 `127.0.0.1`。使用 Docker bridge 网络(`-p 18789:18789`)时,流量会到达 `eth0`,因此 Gateway 网关无法访问。请使用 `--network host`,或设置 `bind: "lan"`(或使用 `bind: "custom"` 并设置 `customBindHost: "0.0.0.0"`)以监听所有网络接口。 - **认证**:默认必须启用。非 loopback bind 要求 Gateway 网关认证。实际中,这意味着使用共享 token/password,或使用设置了 `gateway.auth.mode: "trusted-proxy"` 的身份感知型反向代理。新手引导向导默认会生成一个 token。 -- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请显式将 `gateway.auth.mode` 设为 `token` 或 `password`。如果两者都已配置但未设置 mode,启动以及服务安装/修复流程都会失败。 -- `gateway.auth.mode: "none"`:显式无认证模式。仅应用于可信的本地 loopback 环境;新手引导提示中不会提供此选项。 -- `gateway.auth.mode: "trusted-proxy"`:将认证委托给身份感知型反向代理,并信任来自 `gateway.trustedProxies` 的身份头(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。此模式要求 **非 loopback** 的代理来源;同机 loopback 反向代理不满足 trusted-proxy 认证要求。 -- `gateway.auth.allowTailscale`:为 `true` 时,Tailscale Serve 身份头可满足 Control UI/WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点 **不会** 使用该 Tailscale 头认证;它们仍遵循 Gateway 网关的常规 HTTP 认证模式。此无 token 流程假定 Gateway 网关主机是可信的。当 `tailscale.mode = "serve"` 时,默认值为 `true`。 -- `gateway.auth.rateLimit`:可选的认证失败限速器。按客户端 IP 和认证作用域生效(共享密钥和设备 token 分别独立跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。 - - 在异步 Tailscale Serve Control UI 路径中,对于相同 `{scope, clientIp}` 的失败尝试,会在写入失败状态前串行化。因此,同一客户端的并发错误尝试可能会在第二个请求时触发限速,而不是两个请求都作为普通不匹配并发通过。 - - `gateway.auth.rateLimit.exemptLoopback` 默认值为 `true`;如果你有意也要对 localhost 流量做限速(例如用于测试环境或严格代理部署),请设为 `false`。 -- 来自浏览器源的 WS 认证尝试始终会启用限速,且不会豁免 loopback(作为针对基于浏览器的 localhost 暴力破解的纵深防御)。 -- 在 loopback 上,这些来自浏览器源的锁定会按规范化后的 `Origin` - 值彼此隔离,因此某个 localhost 源的反复失败不会自动 - 锁定另一个源。 -- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开访问,需要认证)。 -- `controlUi.allowedOrigins`:用于 Gateway 网关 WebSocket 连接的显式浏览器源允许列表。当预期浏览器客户端来自非 loopback 源时,此项为必需。 -- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,启用 Host 请求头源回退,适用于有意依赖 Host 请求头源策略的部署。 +- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`(包括 SecretRef),请显式将 `gateway.auth.mode` 设置为 `token` 或 `password`。如果两者都已配置但 mode 未设置,启动以及服务安装/修复流程都会失败。 +- `gateway.auth.mode: "none"`:显式无认证模式。仅用于受信任的本地 local loopback 设置;新手引导提示中不会提供此选项,这是有意设计的。 +- `gateway.auth.mode: "trusted-proxy"`:将认证委托给身份感知型反向代理,并信任来自 `gateway.trustedProxies` 的身份头(参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth))。此模式要求代理来源是 **非 loopback**;同机 loopback 反向代理不满足 trusted-proxy 认证要求。 +- `gateway.auth.allowTailscale`:当为 `true` 时,Tailscale Serve 身份头可以满足 Control UI/WebSocket 认证(通过 `tailscale whois` 验证)。HTTP API 端点 **不会** 使用这种 Tailscale 头认证;它们仍遵循 Gateway 网关的常规 HTTP 认证模式。当 `tailscale.mode = "serve"` 时,默认值为 `true`。这种无 token 流程假定 Gateway 网关主机是受信任的。 +- `gateway.auth.rateLimit`:可选的认证失败限速器。按客户端 IP 和认证范围生效(共享密钥与设备 token 分别独立跟踪)。被阻止的尝试会返回 `429` + `Retry-After`。 + - 在异步 Tailscale Serve Control UI 路径中,相同 `{scope, clientIp}` 的失败尝试会在记录失败前串行化。因此,同一客户端的并发错误尝试可能会在第二个请求时触发限速器,而不是两个请求都作为普通不匹配同时通过。 + - `gateway.auth.rateLimit.exemptLoopback` 默认为 `true`;如果你明确希望 localhost 流量也受到限速(例如测试环境或严格代理部署),请将其设为 `false`。 +- 来自浏览器来源的 WS 认证尝试始终会启用节流,并禁用 loopback 豁免(作为抵御基于浏览器的 localhost 暴力破解的纵深防御)。 +- 在 loopback 上,这些来自浏览器来源的锁定会按归一化后的 `Origin` + 值彼此隔离,因此某个 localhost origin 的重复失败不会自动 + 锁定另一个 origin。 +- `tailscale.mode`:`serve`(仅 tailnet,loopback bind)或 `funnel`(公开访问,要求认证)。 +- `controlUi.allowedOrigins`:显式的浏览器来源允许列表,用于 Gateway 网关 WebSocket 连接。当预期浏览器客户端来自非 loopback 来源时,这是必需项。 +- `controlUi.dangerouslyAllowHostHeaderOriginFallback`:危险模式,启用基于 Host 标头的 origin 回退,适用于有意依赖 Host 标头 origin 策略的部署。 - `remote.transport`:`ssh`(默认)或 `direct`(ws/wss)。对于 `direct`,`remote.url` 必须是 `ws://` 或 `wss://`。 -- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端进程环境级的 - 紧急放行覆盖项,允许向可信私有网络 IP 使用明文 `ws://`; - 默认情况下,明文连接仍仅限于 loopback。没有对应的 `openclaw.json` - 配置项,并且诸如 - `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 之类的浏览器私有网络配置,也不会影响 Gateway 网关 +- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`:客户端进程环境变量级别的 + 紧急放行覆盖项,允许对受信任私有网络 IP 使用明文 `ws://`; + 默认仍然仅允许在 loopback 上使用明文。`openclaw.json` 中没有对应项, + 且浏览器私有网络配置(如 + `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`)不会影响 Gateway 网关 WebSocket 客户端。 - `gateway.remote.token` / `.password` 是远程客户端凭证字段。它们本身不会配置 Gateway 网关认证。 -- `gateway.push.apns.relay.baseUrl`:外部 APNs relay 的基础 HTTPS URL,供官方/TestFlight iOS 构建在将基于 relay 的注册信息发布到 Gateway 网关后使用。此 URL 必须与编译进 iOS 构建中的 relay URL 一致。 -- `gateway.push.apns.relay.timeoutMs`:Gateway 网关到 relay 的发送超时时间,单位为毫秒。默认值为 `10000`。 -- 基于 relay 的注册会委派给某个特定 Gateway 网关身份。已配对的 iOS 应用会获取 `gateway.identity.get`,在 relay 注册中包含该身份,并将注册作用域的发送授权转发给 Gateway 网关。另一个 Gateway 网关无法复用该已存储注册。 -- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:针对上述 relay 配置的临时环境变量覆盖项。 -- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅限开发环境的逃生开关,用于 loopback HTTP relay URL。生产 relay URL 应保持为 HTTPS。 -- `gateway.channelHealthCheckMinutes`:渠道健康监控间隔,单位为分钟。设为 `0` 可全局禁用健康监控重启。默认值:`5`。 -- `gateway.channelStaleEventThresholdMinutes`:陈旧 socket 阈值,单位为分钟。请保持其大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。 -- `gateway.channelMaxRestartsPerHour`:在滚动一小时内,每个渠道/账户允许的健康监控最大重启次数。默认值:`10`。 -- `channels..healthMonitor.enabled`:渠道级别的健康监控重启退出设置,同时保留全局监控启用。 -- `channels..accounts..healthMonitor.enabled`:多账户渠道中的账户级覆盖。设置后,其优先级高于渠道级覆盖。 -- 本地 Gateway 网关调用路径仅会在 `gateway.auth.*` 未设置时,将 `gateway.remote.*` 用作回退。 -- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 且未解析成功,则解析会以失败关闭方式处理(不会由远程回退掩盖)。 -- `trustedProxies`:终止 TLS 或注入转发客户端头的反向代理 IP。只应列出你控制的代理。loopback 条目对同机代理/本地检测场景依然有效(例如 Tailscale Serve 或本地反向代理),但它们 **不会** 让 loopback 请求满足 `gateway.auth.mode: "trusted-proxy"` 的条件。 -- `allowRealIpFallback`:为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关会接受 `X-Real-IP`。默认值为 `false`,以保持失败关闭行为。 -- `gateway.nodes.pairing.autoApproveCidrs`:可选的 CIDR/IP 允许列表,用于在未请求任何作用域时自动批准首次节点设备配对。未设置时为禁用。此项不会自动批准 operator/browser/Control UI/WebChat 配对,也不会自动批准角色、作用域、元数据或公钥升级。 -- `gateway.nodes.allowCommands` / `gateway.nodes.denyCommands`:在配对和允许列表评估之后,对已声明节点命令进行全局允许/拒绝整形。 -- `gateway.tools.deny`:为 HTTP `POST /tools/invoke` 额外屏蔽的工具名称(扩展默认拒绝列表)。 +- `gateway.push.apns.relay.baseUrl`:外部 APNs 中继的基础 HTTPS URL,供官方/TestFlight iOS 构建在将基于中继的注册发布到 Gateway 网关后使用。此 URL 必须与编译进 iOS 构建中的中继 URL 一致。 +- `gateway.push.apns.relay.timeoutMs`:Gateway 网关到中继的发送超时(毫秒)。默认值为 `10000`。 +- 基于中继的注册会委托给某个特定的 Gateway 网关身份。已配对的 iOS 应用会获取 `gateway.identity.get`,将该身份包含在中继注册中,并向 Gateway 网关转发一个按注册范围限定的发送授权。另一个 Gateway 网关无法复用该已存储注册。 +- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`:上述中继配置的临时环境变量覆盖项。 +- `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`:仅供开发使用的放行开关,允许 loopback HTTP 中继 URL。生产环境中继 URL 应保持使用 HTTPS。 +- `gateway.channelHealthCheckMinutes`:渠道健康监控间隔(分钟)。设为 `0` 可在全局范围内禁用健康监控重启。默认值:`5`。 +- `gateway.channelStaleEventThresholdMinutes`:陈旧 socket 阈值(分钟)。请保持其大于或等于 `gateway.channelHealthCheckMinutes`。默认值:`30`。 +- `gateway.channelMaxRestartsPerHour`:滚动一小时内每个渠道/账号允许的最大健康监控重启次数。默认值:`10`。 +- `channels..healthMonitor.enabled`:在保持全局监控启用的前提下,按渠道选择退出健康监控重启。 +- `channels..accounts..healthMonitor.enabled`:多账号渠道的按账号覆盖项。设置后,其优先级高于渠道级覆盖。 +- 仅当 `gateway.auth.*` 未设置时,本地 Gateway 网关调用路径才可将 `gateway.remote.*` 用作回退。 +- 如果通过 SecretRef 显式配置了 `gateway.auth.token` / `gateway.auth.password` 但未能解析,则解析会以失败关闭方式处理(不会被远程回退掩盖)。 +- `trustedProxies`:用于终止 TLS 或注入转发客户端头的反向代理 IP。仅列出你可控的代理。loopback 条目对于同机代理/本地检测设置仍然有效(例如 Tailscale Serve 或本地反向代理),但它们 **不会** 让 loopback 请求符合 `gateway.auth.mode: "trusted-proxy"` 的条件。 +- `allowRealIpFallback`:当为 `true` 时,如果缺少 `X-Forwarded-For`,Gateway 网关将接受 `X-Real-IP`。默认值为 `false`,以保持失败关闭行为。 +- `gateway.nodes.pairing.autoApproveCidrs`:用于自动批准首次节点设备配对的可选 CIDR/IP 允许列表,前提是未请求任何作用域。未设置时为禁用状态。它不会自动批准 operator/browser/Control UI/WebChat 配对,也不会自动批准角色、作用域、元数据或公钥升级。 +- `gateway.nodes.allowCommands` / `gateway.nodes.denyCommands`:在完成配对和允许列表评估后,对已声明节点命令进行全局允许/拒绝整形。 +- `gateway.tools.deny`:对 HTTP `POST /tools/invoke` 额外阻止的工具名称(扩展默认拒绝列表)。 - `gateway.tools.allow`:从默认 HTTP 拒绝列表中移除工具名称。 @@ -438,14 +443,14 @@ x-i18n: - `gateway.http.endpoints.responses.maxUrlParts` - `gateway.http.endpoints.responses.files.urlAllowlist` - `gateway.http.endpoints.responses.images.urlAllowlist` - 空允许列表会被视为未设置;请使用 `gateway.http.endpoints.responses.files.allowUrl=false` - 和/或 `gateway.http.endpoints.responses.images.allowUrl=false` 来禁用 URL 获取。 -- 可选的响应加固请求头: - - `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS 源设置;参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)) + 空允许列表会被视为未设置;使用 `gateway.http.endpoints.responses.files.allowUrl=false` + 和/或 `gateway.http.endpoints.responses.images.allowUrl=false` 可禁用 URL 抓取。 +- 可选的响应加固标头: + - `gateway.http.securityHeaders.strictTransportSecurity`(仅对你控制的 HTTPS 来源设置;参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)) ### 多实例隔离 -在同一主机上运行多个 Gateway 网关时,请使用不同的端口和状态目录: +在同一主机上运行多个 Gateway 网关时,请使用唯一端口和状态目录: ```bash OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \ @@ -455,7 +460,7 @@ openclaw gateway --port 19001 便捷标志:`--dev`(使用 `~/.openclaw-dev` + 端口 `19001`)、`--profile `(使用 `~/.openclaw-`)。 -请参阅 [Multiple Gateways](/zh-CN/gateway/multiple-gateways)。 +参见 [Multiple Gateways](/zh-CN/gateway/multiple-gateways)。 ### `gateway.tls` @@ -474,7 +479,7 @@ openclaw gateway --port 19001 ``` - `enabled`:在 Gateway 网关监听器处启用 TLS 终止(HTTPS/WSS)(默认值:`false`)。 -- `autoGenerate`:在未配置显式文件时,自动生成本地自签名 cert/key 对;仅用于本地/开发环境。 +- `autoGenerate`:当未配置显式文件时,自动生成本地自签名证书/密钥对;仅用于本地/开发环境。 - `certPath`:TLS 证书文件的文件系统路径。 - `keyPath`:TLS 私钥文件的文件系统路径;应限制访问权限。 - `caPath`:可选的 CA bundle 路径,用于客户端验证或自定义信任链。 @@ -493,17 +498,17 @@ openclaw gateway --port 19001 } ``` -- `mode`:控制配置编辑在运行时如何应用。 +- `mode`:控制在运行时如何应用配置编辑。 - `"off"`:忽略实时编辑;更改需要显式重启。 - - `"restart"`:配置变更时始终重启 Gateway 网关进程。 + - `"restart"`:配置更改时始终重启 Gateway 网关进程。 - `"hot"`:在不重启的情况下于进程内应用更改。 - - `"hybrid"`(默认):优先尝试热重载;必要时回退到重启。 -- `debounceMs`:应用配置更改前的防抖窗口,单位为毫秒(非负整数)。 -- `deferralTimeoutMs`:可选的最长等待时间,单位为毫秒,用于等待进行中的操作完成后再强制重启。省略或设为 `0` 表示无限期等待,并定期记录仍在挂起的警告。 + - `"hybrid"`(默认):先尝试热重载;如有需要则回退为重启。 +- `debounceMs`:应用配置更改前的防抖窗口(毫秒)(非负整数)。 +- `deferralTimeoutMs`:可选的最大等待时间(毫秒),用于等待正在进行中的操作完成后再强制重启。省略或设为 `0` 表示无限等待,并定期记录“仍在等待”的警告日志。 --- -## Hooks +## 钩子 ```json5 { @@ -539,13 +544,13 @@ openclaw gateway --port 19001 认证:`Authorization: Bearer ` 或 `x-openclaw-token: `。 拒绝使用查询字符串中的 hook token。 -验证和安全说明: +验证与安全说明: -- `hooks.enabled=true` 要求 `hooks.token` 为非空。 -- `hooks.token` 必须与 `gateway.auth.token` **不同**;重复使用 Gateway 网关 token 会被拒绝。 +- `hooks.enabled=true` 要求提供非空的 `hooks.token`。 +- `hooks.token` 必须与 `gateway.auth.token` **不同**;复用 Gateway 网关 token 会被拒绝。 - `hooks.path` 不能为 `/`;请使用专用子路径,例如 `/hooks`。 -- 如果 `hooks.allowRequestSessionKey=true`,请约束 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。 -- 如果某个映射或预设使用模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 和 `hooks.allowRequestSessionKey=true`。静态映射键不需要该显式启用。 +- 如果 `hooks.allowRequestSessionKey=true`,请限制 `hooks.allowedSessionKeyPrefixes`(例如 `["hook:"]`)。 +- 如果某个映射或预设使用了模板化的 `sessionKey`,请设置 `hooks.allowedSessionKeyPrefixes` 和 `hooks.allowRequestSessionKey=true`。静态映射键不需要此启用项。 **端点:** @@ -553,29 +558,29 @@ openclaw gateway --port 19001 - `POST /hooks/agent` → `{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }` - 仅当 `hooks.allowRequestSessionKey=true`(默认值:`false`)时,才接受请求负载中的 `sessionKey`。 - `POST /hooks/` → 通过 `hooks.mappings` 解析 - - 模板渲染得到的映射 `sessionKey` 值会被视为外部提供,因此同样要求 `hooks.allowRequestSessionKey=true`。 + - 通过模板渲染得到的映射 `sessionKey` 值会被视为外部提供,因此同样要求 `hooks.allowRequestSessionKey=true`。 - `match.path` 匹配 `/hooks` 之后的子路径(例如 `/hooks/gmail` → `gmail`)。 - `match.source` 匹配通用路径中的某个负载字段。 -- 类似 `{{messages[0].subject}}` 的模板会从负载中读取。 -- `transform` 可指向一个返回 hook 动作的 JS/TS 模块。 +- 类似 `{{messages[0].subject}}` 的模板会从负载中读取内容。 +- `transform` 可以指向一个返回 hook action 的 JS/TS 模块。 - `transform.module` 必须是相对路径,并且必须位于 `hooks.transformsDir` 内(绝对路径和路径穿越会被拒绝)。 - `agentId` 会路由到特定智能体;未知 ID 会回退到默认值。 - `allowedAgentIds`:限制显式路由(`*` 或省略 = 允许全部,`[]` = 全部拒绝)。 -- `defaultSessionKey`:可选的固定会话键,用于 hook 智能体运行时未显式提供 `sessionKey` 的情况。 +- `defaultSessionKey`:可选的固定会话键,用于没有显式 `sessionKey` 的 hook 智能体运行。 - `allowRequestSessionKey`:允许 `/hooks/agent` 调用方以及模板驱动的映射会话键设置 `sessionKey`(默认值:`false`)。 -- `allowedSessionKeyPrefixes`:用于显式 `sessionKey` 值(请求 + 映射)的可选前缀允许列表,例如 `["hook:"]`。当任一映射或预设使用模板化 `sessionKey` 时,它就成为必填项。 -- `deliver: true` 会将最终回复发送到某个渠道;`channel` 默认值为 `last`。 -- `model` 会为本次 hook 运行覆盖 LLM(如果已设置模型目录,则该模型必须被允许)。 +- `allowedSessionKeyPrefixes`:用于显式 `sessionKey` 值(请求 + 映射)的可选前缀允许列表,例如 `["hook:"]`。当任一映射或预设使用模板化 `sessionKey` 时,它会成为必填项。 +- `deliver: true` 会将最终回复发送到某个渠道;`channel` 默认为 `last`。 +- `model`:覆盖此次 hook 运行所用的 LLM(如果设置了模型目录,则该模型必须被允许)。 ### Gmail 集成 -- 内建 Gmail 预设使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。 -- 如果你保留这种按消息路由的方式,请设置 `hooks.allowRequestSessionKey: true`,并将 `hooks.allowedSessionKeyPrefixes` 约束到匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。 +- 内置 Gmail 预设使用 `sessionKey: "hook:gmail:{{messages[0].id}}"`。 +- 如果你保留这种按消息路由的方式,请设置 `hooks.allowRequestSessionKey: true`,并限制 `hooks.allowedSessionKeyPrefixes` 以匹配 Gmail 命名空间,例如 `["hook:", "hook:gmail:"]`。 - 如果你需要 `hooks.allowRequestSessionKey: false`,请用静态 `sessionKey` 覆盖该预设,而不是使用默认的模板化值。 ```json5 @@ -600,7 +605,7 @@ openclaw gateway --port 19001 ``` - 配置后,Gateway 网关会在启动时自动启动 `gog gmail watch serve`。设置 `OPENCLAW_SKIP_GMAIL_WATCHER=1` 可禁用。 -- 不要在 Gateway 网关旁边单独运行另一个 `gog gmail watch serve`。 +- 不要在 Gateway 网关旁边另外运行一个独立的 `gog gmail watch serve`。 --- @@ -611,21 +616,21 @@ openclaw gateway --port 19001 canvasHost: { root: "~/.openclaw/workspace/canvas", liveReload: true, - // enabled: false, // or OPENCLAW_SKIP_CANVAS_HOST=1 + // enabled: false, // 或 OPENCLAW_SKIP_CANVAS_HOST=1 }, } ``` -- 通过 Gateway 网关端口下的 HTTP 提供可由智能体编辑的 HTML/CSS/JS 和 A2UI: +- 在 Gateway 网关端口下通过 HTTP 提供可由智能体编辑的 HTML/CSS/JS 和 A2UI: - `http://:/__openclaw__/canvas/` - `http://:/__openclaw__/a2ui/` -- 仅限本地:保持 `gateway.bind: "loopback"`(默认)。 -- 非 loopback bind:canvas 路由与其他 Gateway 网关 HTTP 面一样,需要 Gateway 网关认证(token/password/trusted-proxy)。 -- 节点 WebView 通常不会发送认证头;当节点已完成配对并连接后,Gateway 网关会为 canvas/A2UI 访问广播节点作用域的 capability URL。 -- capability URL 会绑定到当前活动的节点 WS 会话,并会很快过期。不使用基于 IP 的回退。 -- 会向所提供的 HTML 中注入 live-reload 客户端。 -- 在目录为空时自动创建起始 `index.html`。 -- 也会在 `/__openclaw__/a2ui/` 提供 A2UI。 +- 仅限本地:保持 `gateway.bind: "loopback"`(默认值)。 +- 非 loopback bind:canvas 路由与其他 Gateway 网关 HTTP 面一样,都要求 Gateway 网关认证(token/password/trusted-proxy)。 +- 节点 WebView 通常不会发送认证头;节点完成配对并连接后,Gateway 网关会为 canvas/A2UI 访问公布节点作用域能力 URL。 +- 能力 URL 绑定到当前活动的节点 WS 会话,并且很快过期。不使用基于 IP 的回退。 +- 会将 live reload 客户端注入到已提供的 HTML 中。 +- 当目录为空时,会自动创建起始 `index.html`。 +- 还会在 `/__openclaw__/a2ui/` 提供 A2UI。 - 更改需要重启 Gateway 网关。 - 对于大型目录或出现 `EMFILE` 错误时,请禁用 live reload。 @@ -645,9 +650,9 @@ openclaw gateway --port 19001 } ``` -- `minimal`(默认):从 TXT 记录中省略 `cliPath` + `sshPort`。 -- `full`:包含 `cliPath` + `sshPort`。 -- 主机名默认值为 `openclaw`。可通过 `OPENCLAW_MDNS_HOSTNAME` 覆盖。 +- `minimal`(默认):从 TXT 记录中省略 `cliPath` 和 `sshPort`。 +- `full`:包含 `cliPath` 和 `sshPort`。 +- 主机名默认为 `openclaw`。可通过 `OPENCLAW_MDNS_HOSTNAME` 覆盖。 ### 广域网(DNS-SD) @@ -659,7 +664,7 @@ openclaw gateway --port 19001 } ``` -会在 `~/.openclaw/dns/` 下写入一个单播 DNS-SD 区域。若要实现跨网络设备发现,请搭配 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS。 +会在 `~/.openclaw/dns/` 下写入单播 DNS-SD 区域。对于跨网络设备发现,请与 DNS 服务器(推荐 CoreDNS)+ Tailscale split DNS 搭配使用。 设置:`openclaw dns setup --apply`。 @@ -684,14 +689,14 @@ openclaw gateway --port 19001 } ``` -- 仅当进程环境中缺少某个键时,才会应用内联环境变量。 +- 只有当进程环境中缺少某个键时,才会应用内联环境变量。 - `.env` 文件:当前工作目录下的 `.env` + `~/.openclaw/.env`(两者都不会覆盖现有变量)。 - `shellEnv`:从你的登录 shell 配置文件中导入缺失的预期键名。 -- 完整优先级请参阅 [Environment](/zh-CN/help/environment)。 +- 完整优先级请参阅 [环境](/zh-CN/help/environment)。 ### 环境变量替换 -你可以在任意配置字符串中使用 `${VAR_NAME}` 引用环境变量: +可在任意配置字符串中使用 `${VAR_NAME}` 引用环境变量: ```json5 { @@ -702,19 +707,19 @@ openclaw gateway --port 19001 ``` - 仅匹配全大写名称:`[A-Z_][A-Z0-9_]*`。 -- 缺失或为空的变量会在配置加载时报错。 +- 缺失或为空的变量会在配置加载时抛出错误。 - 使用 `$${VAR}` 可转义为字面量 `${VAR}`。 -- 对 `$include` 同样有效。 +- 可与 `$include` 配合使用。 --- ## Secrets -SecretRef 采用增量方式:明文值仍然可用。 +SecretRef 是增量式的:明文值仍然可用。 ### `SecretRef` -请使用以下对象结构: +使用以下对象形态之一: ```json5 { source: "env" | "file" | "exec", provider: "default", id: "..." } @@ -726,21 +731,21 @@ SecretRef 采用增量方式:明文值仍然可用。 - `source: "env"` 的 id 模式:`^[A-Z][A-Z0-9_]{0,127}$` - `source: "file"` 的 id:绝对 JSON pointer(例如 `"/providers/openai/apiKey"`) - `source: "exec"` 的 id 模式:`^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$` -- `source: "exec"` 的 id 不能包含 `.` 或 `..` 这样的斜杠分隔路径段(例如 `a/../b` 会被拒绝) +- `source: "exec"` 的 id 不能包含 `.` 或 `..` 这类按斜杠分隔的路径段(例如 `a/../b` 会被拒绝) -### 支持的凭证面 +### 支持的凭证范围 - 规范矩阵:[SecretRef Credential Surface](/zh-CN/reference/secretref-credential-surface) - `secrets apply` 以受支持的 `openclaw.json` 凭证路径为目标。 -- `auth-profiles.json` 中的 ref 已纳入运行时解析和审计覆盖范围。 +- `auth-profiles.json` 中的引用也包含在运行时解析和审计覆盖范围内。 -### Secret 提供商配置 +### Secret providers 配置 ```json5 { secrets: { providers: { - default: { source: "env" }, // optional explicit env provider + default: { source: "env" }, // 可选的显式 env provider filemain: { source: "file", path: "~/.openclaw/secrets.json", @@ -764,14 +769,14 @@ SecretRef 采用增量方式:明文值仍然可用。 说明: -- `file` 提供商支持 `mode: "json"` 和 `mode: "singleValue"`(在 singleValue 模式下,`id` 必须为 `"value"`)。 -- 当无法验证 Windows ACL 时,文件和 exec 提供商路径会以失败关闭方式处理。仅在路径可信但无法验证时,才设置 `allowInsecurePath: true`。 -- `exec` 提供商要求使用绝对 `command` 路径,并通过 stdin/stdout 传输协议负载。 -- 默认情况下,符号链接命令路径会被拒绝。设置 `allowSymlinkCommand: true` 可允许符号链接路径,同时仍验证解析后的目标路径。 -- 如果配置了 `trustedDirs`,则可信目录检查会作用于解析后的目标路径。 -- `exec` 子进程环境默认最小化;请通过 `passEnv` 显式传递所需变量。 -- Secret ref 会在激活时解析为内存中的快照,之后请求路径只读取该快照。 -- 激活期间会应用活动面过滤:已启用面上的未解析 ref 会导致启动/重载失败,而非活动面则会被跳过并输出诊断信息。 +- `file` provider 支持 `mode: "json"` 和 `mode: "singleValue"`(在 singleValue 模式下,`id` 必须为 `"value"`)。 +- 当无法验证 Windows ACL 时,file 和 exec provider 路径会以失败关闭方式处理。仅对无法验证但受信任的路径设置 `allowInsecurePath: true`。 +- `exec` provider 要求使用绝对 `command` 路径,并通过 stdin/stdout 传输协议负载。 +- 默认情况下,符号链接命令路径会被拒绝。设置 `allowSymlinkCommand: true` 可允许符号链接路径,同时仍验证其解析后的目标路径。 +- 如果配置了 `trustedDirs`,则受信任目录检查会应用到解析后的目标路径。 +- `exec` 子进程环境默认是最小化的;请使用 `passEnv` 显式传入所需变量。 +- Secret 引用会在激活时解析到内存快照中,之后请求路径只读取该快照。 +- 激活期间会应用活动范围过滤:已启用范围中的未解析引用会导致启动/重载失败,而非活动范围会被跳过并记录诊断信息。 --- @@ -793,13 +798,13 @@ SecretRef 采用增量方式:明文值仍然可用。 } ``` -- 每个智能体的 profile 存储在 `/auth-profiles.json`。 -- `auth-profiles.json` 支持静态凭证模式的值级 ref(`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。 -- OAuth 模式 profile(`auth.profiles..mode = "oauth"`)不支持由 SecretRef 提供支持的 auth-profile 凭证。 +- 每个智能体的配置文件存储在 `/auth-profiles.json`。 +- `auth-profiles.json` 支持值级引用(静态凭证模式下,`api_key` 使用 `keyRef`,`token` 使用 `tokenRef`)。 +- OAuth 模式配置文件(`auth.profiles..mode = "oauth"`)不支持由 SecretRef 支持的 auth-profile 凭证。 - 静态运行时凭证来自内存中的已解析快照;发现旧版静态 `auth.json` 条目时会进行清理。 - 旧版 OAuth 会从 `~/.openclaw/credentials/oauth.json` 导入。 -- 请参阅 [OAuth](/zh-CN/concepts/oauth)。 -- Secrets 运行时行为以及 `audit/configure/apply` 工具:请参阅 [Secrets Management](/zh-CN/gateway/secrets)。 +- 参见 [OAuth](/zh-CN/concepts/oauth)。 +- Secrets 运行时行为,以及 `audit/configure/apply` 工具:参见 [Secrets Management](/zh-CN/gateway/secrets)。 ### `auth.cooldowns` @@ -821,20 +826,20 @@ SecretRef 采用增量方式:明文值仍然可用。 } ``` -- `billingBackoffHours`:当 profile 因真正的 - 计费/余额不足错误而失败时的基础回退时长,单位为小时(默认值:`5`)。即使在 `401`/`403` 响应上,只要出现显式计费文本 - 也仍会归入此类,但提供商特定文本 - 匹配器仍只作用于拥有它们的提供商(例如 OpenRouter +- `billingBackoffHours`:当某个配置文件因真正的 + 账单/额度不足错误而失败时,使用的基础退避时长(小时)(默认值:`5`)。即使在 `401`/`403` 响应中,显式账单文本 + 仍可能归入这里,但提供商特定文本 + 匹配器仍限定在拥有它们的提供商范围内(例如 OpenRouter `Key limit exceeded`)。可重试的 HTTP `402` 用量窗口或 - 组织/工作区支出限制消息则仍归入 `rate_limit` 路径。 -- `billingBackoffHoursByProvider`:可选的按提供商覆盖计费回退小时数。 -- `billingMaxHours`:计费回退指数增长的小时上限(默认值:`24`)。 -- `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础回退时长,单位为分钟(默认值:`10`)。 -- `authPermanentMaxMinutes`:`auth_permanent` 回退增长的分钟上限(默认值:`60`)。 -- `failureWindowHours`:用于回退计数器的滚动时间窗口,单位为小时(默认值:`24`)。 -- `overloadedProfileRotations`:对于过载错误,在切换到模型回退之前,同一提供商 auth-profile 允许轮换的最大次数(默认值:`1`)。诸如 `ModelNotReadyException` 之类的提供商繁忙形态归入此类。 -- `overloadedBackoffMs`:在重试过载提供商/profile 轮换前的固定延迟,单位为毫秒(默认值:`0`)。 -- `rateLimitedProfileRotations`:对于限流错误,在切换到模型回退之前,同一提供商 auth-profile 允许轮换的最大次数(默认值:`1`)。该限流桶包括提供商形态文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。 + organization/workspace 支出上限消息则仍归入 `rate_limit` 路径。 +- `billingBackoffHoursByProvider`:可选的按 provider 划分的账单退避时长覆盖项(小时)。 +- `billingMaxHours`:账单退避指数增长的最大上限(小时)(默认值:`24`)。 +- `authPermanentBackoffMinutes`:高置信度 `auth_permanent` 失败的基础退避时长(分钟)(默认值:`10`)。 +- `authPermanentMaxMinutes`:`auth_permanent` 退避增长的最大上限(分钟)(默认值:`60`)。 +- `failureWindowHours`:用于退避计数器的滚动窗口(小时)(默认值:`24`)。 +- `overloadedProfileRotations`:对于过载错误,在切换到模型回退前,同一 provider 的 auth-profile 最多轮换次数(默认值:`1`)。像 `ModelNotReadyException` 这类 provider 忙碌形态会归入这里。 +- `overloadedBackoffMs`:在重试某个过载的 provider/profile 轮换前使用的固定延迟(默认值:`0`)。 +- `rateLimitedProfileRotations`:对于限流错误,在切换到模型回退前,同一 provider 的 auth-profile 最多轮换次数(默认值:`1`)。该限流类别包括提供商形态文本,例如 `Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded` 和 `resource exhausted`。 --- @@ -856,7 +861,7 @@ SecretRef 采用增量方式:明文值仍然可用。 - 默认日志文件:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`。 - 设置 `logging.file` 可使用稳定路径。 - 使用 `--verbose` 时,`consoleLevel` 会提升为 `debug`。 -- `maxFileBytes`:在抑制写入前允许的最大日志文件大小,单位为字节(正整数;默认值:`524288000` = 500 MB)。生产部署请使用外部日志轮转。 +- `maxFileBytes`:在停止写入前允许的最大日志文件大小(字节)(正整数;默认值:`524288000` = 500 MB)。生产部署请使用外部日志轮转。 --- @@ -902,21 +907,21 @@ SecretRef 采用增量方式:明文值仍然可用。 ``` - `enabled`:instrumentation 输出的总开关(默认值:`true`)。 -- `flags`:启用定向日志输出的标志字符串数组(支持诸如 `"telegram.*"` 或 `"*"` 的通配符)。 -- `stuckSessionWarnMs`:当会话保持在处理中状态时,用于发出卡住会话警告的时长阈值,单位为毫秒。 +- `flags`:用于启用定向日志输出的标志字符串数组(支持 `"telegram.*"` 或 `"*"` 这类通配符)。 +- `stuckSessionWarnMs`:当某个会话持续处于处理中状态时,发出卡住会话警告的时长阈值(毫秒)。 - `otel.enabled`:启用 OpenTelemetry 导出管道(默认值:`false`)。 - `otel.endpoint`:用于 OTel 导出的 collector URL。 - `otel.protocol`:`"http/protobuf"`(默认)或 `"grpc"`。 -- `otel.headers`:随 OTel 导出请求发送的额外 HTTP/gRPC 元数据头。 -- `otel.serviceName`:资源属性使用的服务名。 +- `otel.headers`:随 OTel 导出请求发送的额外 HTTP/gRPC 元数据标头。 +- `otel.serviceName`:resource attributes 使用的服务名称。 - `otel.traces` / `otel.metrics` / `otel.logs`:启用 trace、metrics 或 log 导出。 -- `otel.sampleRate`:trace 采样率,范围 `0`–`1`。 -- `otel.flushIntervalMs`:定期刷出 telemetry 的时间间隔,单位为毫秒。 -- `otel.captureContent`:用于 OTel span 属性的原始内容捕获显式开启项。默认关闭。布尔值 `true` 会捕获非 system 消息/工具内容;对象形式则允许你显式启用 `inputMessages`、`outputMessages`、`toolInputs`、`toolOutputs` 和 `systemPrompt`。 -- `OPENCLAW_OTEL_PRELOADED=1`:适用于已经注册了全局 OpenTelemetry SDK 的主机的环境开关。此时 OpenClaw 会跳过由插件拥有的 SDK 启动/关闭,但仍保持诊断监听器处于活动状态。 -- `cacheTrace.enabled`:为嵌入式运行记录 cache trace 快照(默认值:`false`)。 -- `cacheTrace.filePath`:cache trace JSONL 的输出路径(默认值:`$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`)。 -- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制 cache trace 输出中包含的内容(默认全为 `true`)。 +- `otel.sampleRate`:trace 采样率,范围为 `0`–`1`。 +- `otel.flushIntervalMs`:周期性 telemetry 刷新间隔(毫秒)。 +- `otel.captureContent`:为 OTEL span attributes 选择性启用原始内容捕获。默认关闭。布尔值 `true` 会捕获非 system 的消息/工具内容;对象形式则允许你显式启用 `inputMessages`、`outputMessages`、`toolInputs`、`toolOutputs` 和 `systemPrompt`。 +- `OPENCLAW_OTEL_PRELOADED=1`:适用于已注册全局 OpenTelemetry SDK 的主机的环境开关。OpenClaw 会跳过插件拥有的 SDK 启动/关闭流程,同时保持诊断监听器处于活动状态。 +- `cacheTrace.enabled`:为嵌入式运行记录缓存跟踪快照(默认值:`false`)。 +- `cacheTrace.filePath`:缓存跟踪 JSONL 的输出路径(默认值:`$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`)。 +- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`:控制缓存跟踪输出中包含哪些内容(默认都为 `true`)。 --- @@ -938,12 +943,12 @@ SecretRef 采用增量方式:明文值仍然可用。 } ``` -- `channel`:npm/git 安装的发布渠道 —— `"stable"`、`"beta"` 或 `"dev"`。 +- `channel`:用于 npm/git 安装的发布渠道——`"stable"`、`"beta"` 或 `"dev"`。 - `checkOnStart`:Gateway 网关启动时检查 npm 更新(默认值:`true`)。 - `auto.enabled`:为包安装启用后台自动更新(默认值:`false`)。 -- `auto.stableDelayHours`:stable 渠道自动应用前的最小时延,单位为小时(默认值:`6`;最大值:`168`)。 -- `auto.stableJitterHours`:stable 渠道发布扩散的额外时间窗口,单位为小时(默认值:`12`;最大值:`168`)。 -- `auto.betaCheckIntervalHours`:beta 渠道检查运行频率,单位为小时(默认值:`1`;最大值:`24`)。 +- `auto.stableDelayHours`:稳定渠道自动应用前的最小时延(小时)(默认值:`6`;最大值:`168`)。 +- `auto.stableJitterHours`:稳定渠道发布扩散窗口的额外时长(小时)(默认值:`12`;最大值:`168`)。 +- `auto.betaCheckIntervalHours`:beta 渠道检查运行频率(小时)(默认值:`1`;最大值:`24`)。 --- @@ -978,20 +983,20 @@ SecretRef 采用增量方式:明文值仍然可用。 - `enabled`:全局 ACP 功能开关(默认值:`false`)。 - `dispatch.enabled`:ACP 会话轮次分发的独立开关(默认值:`true`)。设为 `false` 可在阻止执行的同时保留 ACP 命令可用。 -- `backend`:默认 ACP 运行时后端 id(必须匹配已注册的 ACP 运行时插件)。 -- `defaultAgent`:当 spawn 未指定显式目标时使用的 ACP 目标智能体 id 回退值。 -- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id 列表;为空表示不做额外限制。 +- `backend`:默认 ACP 运行时后端 id(必须与已注册的 ACP 运行时插件匹配)。 +- `defaultAgent`:当生成操作未指定显式目标时,使用的回退 ACP 目标智能体 id。 +- `allowedAgents`:允许用于 ACP 运行时会话的智能体 id 允许列表;空表示不施加额外限制。 - `maxConcurrentSessions`:同时处于活动状态的 ACP 会话最大数量。 -- `stream.coalesceIdleMs`:流式文本的空闲刷出窗口,单位为毫秒。 -- `stream.maxChunkChars`:分割流式 block 投影前允许的最大块大小。 -- `stream.repeatSuppression`:每轮抑制重复的状态/工具行(默认值:`true`)。 -- `stream.deliveryMode`:`"live"` 为增量流式传输;`"final_only"` 则缓冲直到轮次终止事件。 -- `stream.hiddenBoundarySeparator`:隐藏工具事件之后、可见文本之前的分隔符(默认值:`"paragraph"`)。 -- `stream.maxOutputChars`:每个 ACP 轮次投影的最大智能体输出字符数。 +- `stream.coalesceIdleMs`:流式文本的空闲合并刷新窗口(毫秒)。 +- `stream.maxChunkChars`:流式分块投影前的最大块大小。 +- `stream.repeatSuppression`:在每轮中抑制重复的状态/工具行(默认值:`true`)。 +- `stream.deliveryMode`:`"live"` 表示增量流式传输;`"final_only"` 表示缓冲到轮次终结事件后再发送。 +- `stream.hiddenBoundarySeparator`:在隐藏工具事件后的可见文本前使用的分隔符(默认值:`"paragraph"`)。 +- `stream.maxOutputChars`:每个 ACP 轮次投影的智能体输出最大字符数。 - `stream.maxSessionUpdateChars`:投影的 ACP 状态/更新行最大字符数。 -- `stream.tagVisibility`:记录标签名称到布尔可见性覆盖值的映射,用于流式事件。 -- `runtime.ttlMinutes`:ACP 会话 worker 在可被清理前的空闲 TTL,单位为分钟。 -- `runtime.installCommand`:在引导 ACP 运行时环境时执行的可选安装命令。 +- `stream.tagVisibility`:用于记录标签名称到布尔可见性覆盖项的映射,作用于流式事件。 +- `runtime.ttlMinutes`:ACP 会话工作进程在符合清理条件前的空闲 TTL(分钟)。 +- `runtime.installCommand`:可选安装命令,用于在引导 ACP 运行时环境时执行。 --- @@ -1008,10 +1013,10 @@ SecretRef 采用增量方式:明文值仍然可用。 ``` - `cli.banner.taglineMode` 控制 banner 标语样式: - - `"random"`(默认):轮换的有趣/节日标语。 - - `"default"`:固定的中性标语(`All your chats, one OpenClaw.`)。 + - `"random"`(默认):轮换显示有趣/季节性标语。 + - `"default"`:固定中性标语(`All your chats, one OpenClaw.`)。 - `"off"`:不显示标语文本(仍显示 banner 标题/版本)。 -- 若要隐藏整个 banner(而不只是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 +- 若要隐藏整个 banner(而不仅是标语),请设置环境变量 `OPENCLAW_HIDE_BANNER=1`。 --- @@ -1035,13 +1040,13 @@ SecretRef 采用增量方式:明文值仍然可用。 ## 身份 -请参阅 [Agent defaults](/zh-CN/gateway/config-agents#agent-defaults) 下的 `agents.list` 身份字段。 +请参阅 [智能体默认值](/zh-CN/gateway/config-agents#agent-defaults) 下的 `agents.list` 身份字段。 --- -## Bridge protocol(旧版节点,历史参考) +## Bridge protocol(旧版节点,历史参考)(旧版,已移除) -当前构建已不再包含 TCP bridge。节点通过 Gateway 网关 WebSocket 连接。`bridge.*` 键已不再属于配置 schema 的一部分(在移除前验证会失败;`openclaw doctor --fix` 可以清除未知键)。 +当前构建已不再包含 TCP bridge。节点通过 Gateway 网关 WebSocket 连接。`bridge.*` 键已不再属于配置 schema 的一部分(在移除前,验证会失败;`openclaw doctor --fix` 可以移除未知键)。 @@ -1070,22 +1075,22 @@ SecretRef 采用增量方式:明文值仍然可用。 cron: { enabled: true, maxConcurrentRuns: 2, - webhook: "https://example.invalid/legacy", // deprecated fallback for stored notify:true jobs - webhookToken: "replace-with-dedicated-token", // optional bearer token for outbound webhook auth - sessionRetention: "24h", // duration string or false + webhook: "https://example.invalid/legacy", // 已弃用:用于已存储 notify:true 作业的回退项 + webhookToken: "replace-with-dedicated-token", // 可选:用于出站 webhook 认证的 bearer token + sessionRetention: "24h", // 时长字符串或 false runLog: { - maxBytes: "2mb", // default 2_000_000 bytes - keepLines: 2000, // default 2000 + maxBytes: "2mb", // 默认 2_000_000 字节 + keepLines: 2000, // 默认 2000 }, }, } ``` -- `sessionRetention`:完成后的隔离 cron 运行会话在从 `sessions.json` 清理前保留多久。也控制已归档的已删除 cron 转录内容的清理。默认值:`24h`;设为 `false` 可禁用。 -- `runLog.maxBytes`:每个运行日志文件(`cron/runs/.jsonl`)在清理前允许的最大大小。默认值:`2_000_000` 字节。 -- `runLog.keepLines`:触发运行日志清理时保留的最新行数。默认值:`2000`。 -- `webhookToken`:用于 cron webhook POST 投递的 bearer token(`delivery.mode = "webhook"`);若省略则不发送认证头。 -- `webhook`:已弃用的旧版回退 webhook URL(http/https),仅用于仍设置了 `notify: true` 的已存储任务。 +- `sessionRetention`:在从 `sessions.json` 清理前,已完成的隔离 cron 运行会话保留多长时间。也控制已归档的已删除 cron 转录内容的清理。默认值:`24h`;设为 `false` 可禁用。 +- `runLog.maxBytes`:每个运行日志文件(`cron/runs/.jsonl`)在修剪前允许的最大大小。默认值:`2_000_000` 字节。 +- `runLog.keepLines`:触发运行日志修剪时保留的最新行数。默认值:`2000`。 +- `webhookToken`:用于 cron webhook POST 投递(`delivery.mode = "webhook"`)的 bearer token;如果省略,则不会发送认证标头。 +- `webhook`:已弃用的旧版回退 webhook URL(http/https),仅用于仍然设置了 `notify: true` 的已存储作业。 ### `cron.retry` @@ -1101,11 +1106,11 @@ SecretRef 采用增量方式:明文值仍然可用。 } ``` -- `maxAttempts`:一次性任务在瞬时错误上的最大重试次数(默认值:`3`;范围:`0`–`10`)。 -- `backoffMs`:每次重试尝试使用的回退延迟数组,单位为毫秒(默认值:`[30000, 60000, 300000]`;1–10 个条目)。 -- `retryOn`:触发重试的错误类型 —— `"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略则会对所有瞬时类型重试。 +- `maxAttempts`:一次性作业在遇到瞬时错误时的最大重试次数(默认值:`3`;范围:`0`–`10`)。 +- `backoffMs`:每次重试尝试使用的退避延迟数组(毫秒)(默认值:`[30000, 60000, 300000]`;1–10 个条目)。 +- `retryOn`:会触发重试的错误类型——`"rate_limit"`、`"overloaded"`、`"network"`、`"timeout"`、`"server_error"`。省略时表示重试所有瞬时类型。 -仅适用于一次性 cron 任务。周期性任务使用单独的失败处理方式。 +仅适用于一次性 cron 作业。周期性作业使用独立的失败处理机制。 ### `cron.failureAlert` @@ -1123,11 +1128,11 @@ SecretRef 采用增量方式:明文值仍然可用。 } ``` -- `enabled`:为 cron 任务启用失败告警(默认值:`false`)。 -- `after`:触发告警前所需的连续失败次数(正整数,最小值:`1`)。 -- `cooldownMs`:同一任务重复告警之间的最小间隔,单位为毫秒(非负整数)。 -- `mode`:投递模式 —— `"announce"` 通过渠道消息发送;`"webhook"` 则 POST 到已配置的 webhook。 -- `accountId`:可选的账户或渠道 id,用于限定告警投递范围。 +- `enabled`:为 cron 作业启用失败告警(默认值:`false`)。 +- `after`:连续失败多少次后触发告警(正整数,最小值:`1`)。 +- `cooldownMs`:同一作业重复告警之间的最小间隔(毫秒)(非负整数)。 +- `mode`:投递模式——`"announce"` 通过渠道消息发送;`"webhook"` 则向已配置的 webhook 发起 POST。 +- `accountId`:可选的账号或渠道 id,用于限定告警投递范围。 ### `cron.failureDestination` @@ -1144,16 +1149,16 @@ SecretRef 采用增量方式:明文值仍然可用。 } ``` -- 所有任务共用的 cron 失败通知默认目标。 +- 所有作业的 cron 失败通知默认目标。 - `mode`:`"announce"` 或 `"webhook"`;当存在足够的目标数据时,默认值为 `"announce"`。 -- `channel`:announce 投递的渠道覆盖值。`"last"` 会复用最后已知的投递渠道。 -- `to`:显式的 announce 目标或 webhook URL。webhook 模式下必填。 -- `accountId`:可选的投递账户覆盖值。 -- 每个任务的 `delivery.failureDestination` 会覆盖这个全局默认值。 -- 当既未设置全局也未设置每个任务的失败目标时,已经通过 `announce` 投递的任务在失败时会回退到其主 announce 目标。 -- `delivery.failureDestination` 仅支持 `sessionTarget="isolated"` 的任务,除非该任务的主 `delivery.mode` 为 `"webhook"`。 +- `channel`:用于 announce 投递的渠道覆盖项。`"last"` 会复用上一次已知的投递渠道。 +- `to`:显式 announce 目标或 webhook URL。webhook 模式下为必填。 +- `accountId`:可选的投递账号覆盖项。 +- 每个作业的 `delivery.failureDestination` 会覆盖此全局默认值。 +- 当既未设置全局失败目标,也未设置每作业失败目标时,已经通过 `announce` 投递的作业在失败时会回退到其主 announce 目标。 +- `delivery.failureDestination` 仅支持 `sessionTarget="isolated"` 的作业,除非该作业的主 `delivery.mode` 为 `"webhook"`。 -请参阅 [Cron Jobs](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为 [background tasks](/zh-CN/automation/tasks) 进行跟踪。 +参见 [Cron Jobs](/zh-CN/automation/cron-jobs)。隔离的 cron 执行会作为[后台任务](/zh-CN/automation/tasks)进行跟踪。 --- @@ -1161,28 +1166,28 @@ SecretRef 采用增量方式:明文值仍然可用。 在 `tools.media.models[].args` 中展开的模板占位符: -| Variable | 描述 | -| ------------------ | ------------------------------------------------- | -| `{{Body}}` | 完整的入站消息正文 | -| `{{RawBody}}` | 原始正文(不含历史记录/发送者包装) | -| `{{BodyStripped}}` | 去除群组提及后的正文 | -| `{{From}}` | 发送者标识符 | -| `{{To}}` | 目标标识符 | -| `{{MessageSid}}` | 渠道消息 id | -| `{{SessionId}}` | 当前会话 UUID | -| `{{IsNewSession}}` | 新会话已创建时为 `"true"` | -| `{{MediaUrl}}` | 入站媒体伪 URL | -| `{{MediaPath}}` | 本地媒体路径 | -| `{{MediaType}}` | 媒体类型(图片/音频/文档/……) | -| `{{Transcript}}` | 音频转录文本 | -| `{{Prompt}}` | 用于 CLI 条目的已解析媒体提示词 | -| `{{MaxChars}}` | 用于 CLI 条目的已解析最大输出字符数 | -| `{{ChatType}}` | `"direct"` 或 `"group"` | -| `{{GroupSubject}}` | 群组主题(尽力而为) | -| `{{GroupMembers}}` | 群组成员预览(尽力而为) | -| `{{SenderName}}` | 发送者显示名称(尽力而为) | -| `{{SenderE164}}` | 发送者电话号码(尽力而为) | -| `{{Provider}}` | 提供商提示(whatsapp、telegram、discord 等) | +| Variable | 描述 | +| ------------------ | ---- | +| `{{Body}}` | 完整的入站消息正文 | +| `{{RawBody}}` | 原始正文(不含历史记录/发送者包装) | +| `{{BodyStripped}}` | 去除群组提及后的正文 | +| `{{From}}` | 发送者标识符 | +| `{{To}}` | 目标标识符 | +| `{{MessageSid}}` | 渠道消息 id | +| `{{SessionId}}` | 当前会话 UUID | +| `{{IsNewSession}}` | 新建会话时为 `"true"` | +| `{{MediaUrl}}` | 入站媒体伪 URL | +| `{{MediaPath}}` | 本地媒体路径 | +| `{{MediaType}}` | 媒体类型(image/audio/document/…) | +| `{{Transcript}}` | 音频转录文本 | +| `{{Prompt}}` | CLI 条目的已解析媒体提示词 | +| `{{MaxChars}}` | CLI 条目的已解析最大输出字符数 | +| `{{ChatType}}` | `"direct"` 或 `"group"` | +| `{{GroupSubject}}` | 群组主题(尽力而为) | +| `{{GroupMembers}}` | 群组成员预览(尽力而为) | +| `{{SenderName}}` | 发送者显示名称(尽力而为) | +| `{{SenderE164}}` | 发送者电话号码(尽力而为) | +| `{{Provider}}` | provider 提示(whatsapp、telegram、discord 等) | --- @@ -1203,20 +1208,20 @@ SecretRef 采用增量方式:明文值仍然可用。 **合并行为:** -- 单个文件:替换其所在的包含对象。 +- 单个文件:替换其所在的对象。 - 文件数组:按顺序深度合并(后者覆盖前者)。 -- 同级键:在 includes 之后合并(覆盖 include 中的值)。 -- 嵌套 include:最多支持 10 层深度。 -- 路径:相对于包含它的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)内。只有在最终解析结果仍位于该边界内时,才允许使用绝对路径或 `../` 形式。 -- OpenClaw 自有写入在仅变更某个由单文件 include 支持的顶层区段时,会直接写回该 include 文件。例如,`plugins install` 会将 `plugins: { $include: "./plugins.json5" }` 的更新写入 `plugins.json5`,并保持 `openclaw.json` 不变。 -- 根级 include、include 数组,以及带有同级覆盖的 include,对 OpenClaw 自有写入而言是只读的;这些写入会以失败关闭方式处理,而不是将配置展平。 +- 同级键:在 include 之后合并(覆盖被 include 的值)。 +- 嵌套 include:最多 10 层。 +- 路径:相对于发起 include 的文件解析,但必须保持在顶层配置目录(`openclaw.json` 的 `dirname`)内。只有在最终仍解析到该边界内时,才允许使用绝对路径或 `../` 形式。 +- 当 OpenClaw 自有写入只更改由单文件 include 支持的一个顶层 section 时,会直写到该被 include 的文件。例如,`plugins install` 会将 `plugins: { $include: "./plugins.json5" }` 写入 `plugins.json5`,并保持 `openclaw.json` 不变。 +- 根级 include、include 数组,以及带有同级覆盖的 include 对于 OpenClaw 自有写入是只读的;这些写入会以失败关闭方式处理,而不会将配置展平。 - 错误:对缺失文件、解析错误和循环 include 提供清晰的错误消息。 --- -_相关内容:[Configuration](/zh-CN/gateway/configuration) · [Configuration Examples](/zh-CN/gateway/configuration-examples) · [Doctor](/zh-CN/gateway/doctor)_ +_相关:[配置](/zh-CN/gateway/configuration) · [配置示例](/zh-CN/gateway/configuration-examples) · [Doctor](/zh-CN/gateway/doctor)_ ## 相关 -- [Configuration](/zh-CN/gateway/configuration) -- [Configuration examples](/zh-CN/gateway/configuration-examples) +- [配置](/zh-CN/gateway/configuration) +- [配置示例](/zh-CN/gateway/configuration-examples) diff --git a/docs/zh-CN/plugins/architecture-internals.md b/docs/zh-CN/plugins/architecture-internals.md index 53b33324d..02243b155 100644 --- a/docs/zh-CN/plugins/architecture-internals.md +++ b/docs/zh-CN/plugins/architecture-internals.md @@ -1,20 +1,20 @@ --- read_when: - - 实现提供商运行时钩子、渠道生命周期或软件包打包 + - 实现提供商运行时钩子、渠道生命周期或软件包打包集 - 调试插件加载顺序或注册表状态 - 添加新的插件能力或上下文引擎插件 summary: 插件架构内部机制:加载管线、注册表、运行时钩子、HTTP 路由和参考表格 title: 插件架构内部机制 x-i18n: - generated_at: "2026-04-24T20:18:26Z" + generated_at: "2026-04-25T18:41:17Z" model: gpt-5.4 provider: openai - source_hash: 0e505155ee2acc84f7f26fa81b62121f03a998b249886d74f798c0f258bd8da4 + source_hash: 074b0a0fb1678b73a2c9236fb9fbc208d8e39dcbba39c904b2bd7b5ceac473b6 source_path: plugins/architecture-internals.md workflow: 15 --- -对于公开的能力模型、插件形态,以及所有权 / 执行契约,请参见 [Plugin architecture](/zh-CN/plugins/architecture)。本页是内部机制的参考文档:加载管线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和架构表。 +关于公开的能力模型、插件形态以及所有权/执行契约,请参见 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考:加载管线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。 ## 加载管线 @@ -23,86 +23,111 @@ x-i18n: 1. 发现候选插件根目录 2. 读取原生或兼容 bundle 清单以及软件包元数据 3. 拒绝不安全的候选项 -4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`) -5. 为每个候选项决定是否启用 -6. 加载已启用的原生模块:已构建的内置模块使用原生加载器;未构建的原生插件使用 `jiti` +4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、 + `slots`、`load.paths`) +5. 决定每个候选项是否启用 +6. 加载已启用的原生模块:已构建的内置模块使用原生加载器; + 未构建的原生插件使用 `jiti` 7. 调用原生 `register(api)` 钩子,并将注册内容收集到插件注册表中 -8. 将注册表暴露给命令 / 运行时表面 +8. 将注册表暴露给命令/运行时表面 -`activate` 是 `register` 的旧别名 —— 加载器会解析存在的那个(`def.register ?? def.activate`),并在同一时机调用它。所有内置插件都使用 `register`;新插件请优先使用 `register`。 +`activate` 是 `register` 的旧别名——加载器会解析当前存在的那个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`;新插件优先使用 `register`。 -安全门禁会在运行时执行**之前**发生。当入口逃逸出插件根目录、路径对所有用户可写,或对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。 +安全门会在运行时执行**之前**发生。当入口逃离插件根目录、路径对所有用户可写,或对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。 -### Manifest 优先行为 +### 清单优先行为 -manifest 是控制平面的事实来源。OpenClaw 会用它来: +清单是控制面的事实来源。OpenClaw 使用它来: - 标识插件 -- 发现已声明的渠道 / Skills / 配置 schema 或 bundle 能力 +- 发现声明的 channels/Skills/配置模式或 bundle 能力 - 验证 `plugins.entries..config` -- 增强 Control UI 标签 / 占位文本 -- 显示安装 / 目录元数据 -- 在不加载插件运行时的情况下保留轻量的激活和设置描述符 +- 增强 Control UI 标签/占位符 +- 显示安装/目录元数据 +- 在不加载插件运行时的情况下保留低成本激活和设置描述符 -对于原生插件,运行时模块是数据平面部分。它负责注册实际行为,例如钩子、工具、命令或提供商流程。 +对于原生插件,运行时模块是数据面部分。它会注册实际行为,例如钩子、工具、命令或 provider 流程。 -可选的 manifest `activation` 和 `setup` 块仍然留在控制平面。它们只是用于激活规划和设置发现的元数据描述符;不会替代运行时注册、`register(...)` 或 `setupEntry`。 -首批实时激活消费者现在会使用 manifest 中的命令、渠道和提供商提示,在更广泛的注册表实例化之前缩小插件加载范围: +可选的清单 `activation` 和 `setup` 块保留在控制面中。 +它们只是用于激活规划和设置发现的元数据描述符; +不会替代运行时注册、`register(...)` 或 `setupEntry`。 +当前第一批实时激活消费者会使用清单中的命令、渠道和提供商提示, +在更广泛的注册表实体化之前先缩小插件加载范围: - CLI 加载会缩小到拥有所请求主命令的插件 -- 渠道设置 / 插件解析会缩小到拥有所请求渠道 id 的插件 -- 显式的提供商设置 / 运行时解析会缩小到拥有所请求提供商 id 的插件 +- channel 设置/插件解析会缩小到拥有所请求 + channel id 的插件 +- 显式 provider 设置/运行时解析会缩小到拥有所请求 + provider id 的插件 -激活规划器既为现有调用方暴露仅含 id 的 API,也为新的诊断功能暴露 plan API。Plan 条目会报告某个插件为何被选中,并将显式的 `activation.*` 规划提示与 manifest 所有权回退原因分开,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks。这种原因拆分就是兼容性边界:现有插件元数据会继续工作,而新代码则可以检测宽泛提示或回退行为,而无需改变运行时加载语义。 +激活规划器既为现有调用方暴露仅含 id 的 API,也为新的诊断场景暴露 +plan API。Plan 条目会报告某个插件为何被选中, +并区分显式 `activation.*` 规划器提示与清单所有权 +回退,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、 +`contracts.tools` 和钩子。这种原因拆分就是兼容性边界: +现有插件元数据仍然可用,而新代码可以检测宽泛提示 +或回退行为,而不改变运行时加载语义。 -设置发现现在会优先使用描述符拥有的 id,例如 `setup.providers` 和 `setup.cliBackends`,先缩小候选插件范围;然后才会回退到 `setup-api`,以兼容仍然需要设置阶段运行时钩子的插件。提供商设置流程会先使用 manifest `providerAuthChoices`,然后出于兼容性考虑再回退到运行时向导选项和安装目录选项。显式的 `setup.requiresRuntime: false` 是仅限描述符的截断;如果省略 `requiresRuntime`,则会保留旧版 `setup-api` 回退逻辑以确保兼容。如果发现多个插件声明了同一个规范化后的设置提供商或 CLI 后端 id,设置查找会拒绝这个有歧义的所有者,而不是依赖发现顺序。当设置运行时确实执行时,注册表诊断会报告 `setup.providers` / `setup.cliBackends` 与由 `setup-api` 注册的提供商或 CLI 后端之间的漂移,但不会阻止旧版插件。 +设置发现现在优先使用描述符拥有的 id,例如 `setup.providers` 和 +`setup.cliBackends`,在回退到 `setup-api` 之前先缩小候选插件范围, +以兼容那些仍然需要设置时运行时钩子的插件。Provider 设置流程优先使用清单中的 `providerAuthChoices`,然后为了兼容性再回退到 +运行时向导选项和安装目录选项。显式 +`setup.requiresRuntime: false` 是仅描述符层面的截断条件;省略 +`requiresRuntime` 则为了兼容性保留旧版 `setup-api` 回退。如果有多个 +已发现插件声称拥有同一个规范化后的设置 provider 或 CLI +backend id,设置查找会拒绝这个歧义所有者,而不是依赖 +发现顺序。当设置运行时确实执行时,注册表诊断会报告 +`setup.providers` / `setup.cliBackends` 与由 `setup-api` 注册的 providers 或 CLI +backends 之间的漂移,但不会阻止旧版插件。 ### 加载器会缓存什么 -OpenClaw 会保留短生命周期的进程内缓存,用于: +OpenClaw 会为以下内容保留短生命周期的进程内缓存: - 发现结果 -- manifest 注册表数据 +- 清单注册表数据 - 已加载的插件注册表 -这些缓存可减少突发启动开销和重复命令开销。你可以把它们理解为短期性能缓存,而不是持久化存储。 +这些缓存可以减少突发启动成本和重复命令开销。可以安全地将它们视为短生命周期的性能缓存,而不是持久化。 性能说明: -- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。 -- 可使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。 +- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` 或 + `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。 +- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` 和 + `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。 ## 注册表模型 -已加载的插件不会直接修改随意的核心全局状态。它们会注册到一个中心化的插件注册表中。 +已加载的插件不会直接随意修改 core 的全局状态。它们会注册到一个中心插件注册表中。 注册表会跟踪: -- 插件记录(标识、来源、源头、状态、诊断) +- 插件记录(标识、来源、origin、状态、诊断) - 工具 -- 旧版 hooks 和类型化 hooks +- 旧版钩子和类型化钩子 - 渠道 - 提供商 -- gateway RPC 处理器 +- Gateway 网关 RPC 处理器 - HTTP 路由 - CLI 注册器 - 后台服务 - 插件拥有的命令 -随后,核心功能会从该注册表读取内容,而不是直接与插件模块交互。这样可以让加载保持单向: +然后,core 功能会从该注册表读取,而不是直接与插件模块交互。这样可保持单向加载: - 插件模块 -> 注册表注册 -- 核心运行时 -> 注册表消费 +- core 运行时 -> 注册表消费 -这种分离对可维护性非常重要。它意味着大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。 +这种分离对可维护性很重要。它意味着大多数 core 表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。 ## 会话绑定回调 -绑定会话的插件可以在批准结果确定后作出响应。 +绑定会话的插件可以在审批被处理后作出响应。 -使用 `api.onConversationBindingResolved(...)`,可在绑定请求被批准或拒绝后收到回调: +使用 `api.onConversationBindingResolved(...)` 可在绑定请求被批准或拒绝后接收回调: ```ts export default { @@ -110,7 +135,7 @@ export default { register(api) { api.onConversationBindingResolved(async (event) => { if (event.status === "approved") { - // 现在已为此插件 + 会话创建绑定。 + // 现在此插件 + 会话已存在一个绑定。 console.log(event.binding?.conversationId); return; } @@ -126,89 +151,100 @@ export default { - `status`:`"approved"` 或 `"denied"` - `decision`:`"allow-once"`、`"allow-always"` 或 `"deny"` -- `binding`:已批准请求对应的解析后绑定 -- `request`:原始请求摘要、分离提示、发送者 id 和会话元数据 +- `binding`:已批准请求的已解析绑定 +- `request`:原始请求摘要、detach 提示、发送者 id 和 + 会话元数据 -此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在核心审批处理完成后运行。 +此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在 core 审批处理完成后运行。 -## 提供商运行时钩子 +## provider 运行时钩子 -提供商插件分为三层: +Provider 插件有三层: -- **Manifest 元数据**,用于廉价的运行时前查找: +- **清单元数据**,用于低成本的预运行时查找: `setup.providers[].envVars`、已弃用的兼容字段 `providerAuthEnvVars`、 `providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`。 -- **配置阶段钩子**:`catalog`(旧称 `discovery`)以及 +- **配置时钩子**:`catalog`(旧版 `discovery`)以及 `applyConfigDefaults`。 -- **运行时钩子**:40 多个可选钩子,覆盖认证、模型解析、 - 流包装、思考级别、重放策略和使用量端点。完整列表请参见 - [Hook order and usage](#hook-order-and-usage)。 +- **运行时钩子**:40 多个可选钩子,涵盖身份验证、模型解析、 + 流包装、思考等级、重放策略和用量端点。请参见 + [钩子顺序和用法](#hook-order-and-usage) 下的完整列表。 -OpenClaw 仍然负责通用的智能体循环、故障转移、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,因此无需整套自定义推理传输也能实现扩展。 +OpenClaw 仍然负责通用的 Agent loop、故障切换、转录处理和工具策略。这些钩子是 provider 特定行为的扩展表面,因此无需整个自定义推理传输层。 -当提供商具有基于环境变量的凭证,并且希望通用认证 / 状态 / 模型选择器路径无需加载插件运行时就能看到这些凭证时,请使用 manifest `setup.providers[].envVars`。已弃用的 `providerAuthEnvVars` 在弃用窗口期内仍会被兼容适配器读取,而使用它的非内置插件会收到 manifest 诊断。当某个提供商 id 应复用另一个提供商 id 的环境变量、认证配置文件、基于配置的认证以及 API 密钥新手引导选项时,请使用 manifest `providerAuthAliases`。当新手引导 / 认证选项 CLI 表面需要在不加载提供商运行时的情况下知道该提供商的 choice id、分组标签和简单的单标志认证接线时,请使用 manifest `providerAuthChoices`。提供商运行时的 `envVars` 应保留给面向运维人员的提示,例如新手引导标签或 OAuth 客户端 id / 客户端密钥设置变量。 +当 provider 使用基于环境变量的凭证,并且通用身份验证/状态/模型选择器路径需要在不加载插件运行时的情况下看到这些凭证时,使用清单 `setup.providers[].envVars`。已弃用的 `providerAuthEnvVars` 在弃用窗口期间仍会由兼容适配器读取,而使用它的非内置插件会收到清单诊断。当一个 provider id 应复用另一个 provider id 的环境变量、认证配置文件、基于配置的身份验证和 API 密钥新手引导选项时,使用清单 `providerAuthAliases`。当新手引导/认证选择 CLI 表面需要在不加载 provider 运行时的情况下知道 provider 的 choice id、分组标签和简单单 flag 身份验证接线时,使用清单 `providerAuthChoices`。将 provider 运行时中的 +`envVars` 保留给面向运维者的提示,例如新手引导标签或 OAuth +client-id/client-secret 设置变量。 -当某个渠道具有由环境变量驱动的认证或设置,并且通用 shell 环境回退、配置 / 状态检查或设置提示需要在不加载渠道运行时的情况下看到这些信息时,请使用 manifest `channelEnvVars`。 +当某个渠道具有由环境变量驱动的身份验证或设置,并且通用 shell 环境变量回退、配置/状态检查或设置提示需要在不加载渠道运行时的情况下看到这些信息时,使用清单 `channelEnvVars`。 -### Hook 顺序和用法 +### 钩子顺序和用法 -对于模型 / 提供商插件,OpenClaw 会大致按以下顺序调用 hooks。 -“何时使用”这一列是快速决策指南。 +对于模型/provider 插件,OpenClaw 大致按以下顺序调用钩子。 +“何时使用”列是快速决策指南。 -| # | Hook | 作用 | 何时使用 | -| --- | --------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------ | -| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers` 中 | 提供商拥有目录或基础 URL 默认值 | -| 2 | `applyConfigDefaults` | 在配置实例化期间应用由提供商拥有的全局配置默认值 | 默认值依赖于认证模式、环境或提供商模型族语义 | -| -- | _(built-in model lookup)_ | OpenClaw 会先尝试常规注册表 / 目录路径 | _(不是插件 hook)_ | -| 3 | `normalizeModelId` | 在查找前规范化旧版或预览版 model-id 别名 | 提供商拥有在规范模型解析前进行别名清理的逻辑 | -| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商族的 `api` / `baseUrl` | 提供商拥有同一传输族中自定义提供商 id 的传输清理逻辑 | -| 5 | `normalizeConfig` | 在运行时 / 提供商解析前规范化 `models.providers.` | 提供商需要应与插件放在一起的配置清理;内置的 Google 族辅助逻辑也会为受支持的 Google 配置项提供兜底 | -| 6 | `applyNativeStreamingUsageCompat` | 将原生流式使用量兼容性重写应用到配置提供商 | 提供商需要基于端点驱动的原生流式使用量元数据修复 | -| 7 | `resolveConfigApiKey` | 在加载运行时认证前,为配置提供商解析 env-marker 认证 | 提供商拥有由提供商控制的 env-marker API 密钥解析;`amazon-bedrock` 这里也有内置的 AWS env-marker 解析器 | -| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露本地 / 自托管或基于配置的认证 | 提供商可以使用合成 / 本地凭证标记运行 | -| 9 | `resolveExternalAuthProfiles` | 叠加由提供商拥有的外部认证配置文件;默认 `persistence` 为 `runtime-only`,适用于由 CLI / 应用拥有的凭证 | 提供商可复用外部认证凭证,而无需持久化复制的刷新令牌;请在 manifest 中声明 `contracts.externalAuthProviders` | -| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成配置文件占位符优先级降到环境 / 基于配置的认证之后 | 提供商会存储合成占位配置文件,而这些配置文件不应具有更高优先级 | -| 11 | `resolveDynamicModel` | 为本地注册表中尚不存在的由提供商拥有的模型 id 提供同步回退 | 提供商接受任意上游模型 id | -| 12 | `prepareDynamicModel` | 先进行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 | -| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型前执行最终重写 | 提供商需要传输重写,但仍使用核心传输 | -| 14 | `contributeResolvedModelCompat` | 为位于其他兼容传输后的供应商模型提供兼容标记 | 提供商能够在代理传输上识别自己的模型,而无需接管该提供商 | -| 15 | `capabilities` | 由共享核心逻辑使用的、由提供商拥有的转录 / 工具元数据 | 提供商需要处理转录 / 提供商族特有行为 | -| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具 schema 之前对其进行规范化 | 提供商需要针对传输族进行 schema 清理 | -| 17 | `inspectToolSchemas` | 在规范化后暴露由提供商拥有的 schema 诊断 | 提供商希望给出关键字警告,而不需要让核心学习提供商特定规则 | -| 18 | `resolveReasoningOutputMode` | 选择原生或带标签的推理输出契约 | 提供商需要带标签的推理 / 最终输出,而不是原生字段 | -| 19 | `prepareExtraParams` | 在通用流选项包装器之前进行请求参数规范化 | 提供商需要默认请求参数或按提供商进行参数清理 | -| 20 | `createStreamFn` | 用自定义传输完全替换常规流路径 | 提供商需要自定义线协议,而不只是包装器 | -| 21 | `wrapStreamFn` | 在应用通用包装器后再包装流函数 | 提供商需要请求头 / 请求体 / 模型兼容包装器,但不需要自定义传输 | -| 22 | `resolveTransportTurnState` | 附加原生的每轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次标识 | -| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 头或会话冷却策略 | 提供商希望通用 WS 传输调整会话头或回退策略 | -| 24 | `formatApiKey` | 认证配置文件格式化器:已存储的配置文件会变成运行时 `apiKey` 字符串 | 提供商存储了额外认证元数据,并需要自定义运行时令牌形态 | -| 25 | `refreshOAuth` | 为自定义刷新端点或刷新失败策略覆盖 OAuth 刷新逻辑 | 提供商不适用共享的 `pi-ai` 刷新器 | -| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加修复提示 | 提供商在刷新失败后需要由提供商控制的认证修复指导 | -| 27 | `matchesContextOverflowError` | 由提供商拥有的上下文窗口溢出匹配器 | 提供商存在原始溢出错误,而通用启发式无法识别 | -| 28 | `classifyFailoverReason` | 由提供商拥有的故障转移原因分类 | 提供商可以将原始 API / 传输错误映射为限流 / 过载等 | -| 29 | `isCacheTtlEligible` | 面向代理 / 回程提供商的提示缓存策略 | 提供商需要代理特定的缓存 TTL 门控 | -| 30 | `buildMissingAuthMessage` | 替换通用的缺失认证恢复消息 | 提供商需要提供商特定的缺失认证恢复提示 | -| 31 | `suppressBuiltInModel` | 过时上游模型抑制,并可附带面向用户的错误提示 | 提供商需要隐藏过时的上游条目,或用供应商提示替换它们 | -| 32 | `augmentModelCatalog` | 在发现后附加合成 / 最终目录条目 | 提供商需要在 `models list` 和选择器中提供合成的前向兼容条目 | -| 33 | `resolveThinkingProfile` | 为特定模型设置 `/think` 级别、显示标签和默认值 | 提供商为选定模型提供自定义思考层级或二元标签 | -| 34 | `isBinaryThinking` | 开 / 关推理切换兼容性 hook | 提供商只暴露二元的思考开 / 关 | -| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性 hook | 提供商只希望在部分模型上启用 `xhigh` | -| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容性 hook | 提供商拥有某个模型族的默认 `/think` 策略 | -| 37 | `isModernModelRef` | 用于实时配置文件过滤和 smoke 选择的现代模型匹配器 | 提供商拥有实时 / smoke 首选模型匹配逻辑 | -| 38 | `prepareRuntimeAuth` | 在推理前将已配置的凭证交换为实际运行时令牌 / 密钥 | 提供商需要令牌交换或短期请求凭证 | -| 39 | `resolveUsageAuth` | 为 `/usage` 及相关状态表面解析使用量 / 计费凭证 | 提供商需要自定义使用量 / 配额令牌解析,或需要不同的使用量凭证 | -| 40 | `fetchUsageSnapshot` | 在认证解析后获取并规范化提供商特定的使用量 / 配额快照 | 提供商需要提供商特定的使用量端点或负载解析器 | -| 41 | `createEmbeddingProvider` | 为 memory / 搜索构建由提供商拥有的嵌入适配器 | Memory 嵌入行为应归属于提供商插件 | -| 42 | `buildReplayPolicy` | 返回一个重放策略,用于控制该提供商的转录处理 | 提供商需要自定义转录策略(例如移除 thinking 块) | -| 43 | `sanitizeReplayHistory` | 在通用转录清理后重写重放历史 | 提供商需要超出共享压缩辅助逻辑之外的、提供商特定的重放重写 | -| 44 | `validateReplayTurns` | 在嵌入式运行器之前,对重放轮次进行最终验证或重塑 | 提供商传输在通用净化后需要更严格的轮次验证 | -| 45 | `onModelSelected` | 运行由提供商拥有的选择后副作用 | 当某个模型变为活动状态时,提供商需要遥测或由提供商拥有的状态 | +| # | 钩子 | 作用 | 何时使用 | +| --- | --------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | +| 1 | `catalog` | 在生成 `models.json` 期间,将 provider 配置发布到 `models.providers` | provider 拥有目录,或拥有基础 URL 默认值 | +| 2 | `applyConfigDefaults` | 在配置实体化期间应用 provider 拥有的全局配置默认值 | 默认值依赖于身份验证模式、环境变量或 provider 模型家族语义 | +| -- | _(内置模型查找)_ | OpenClaw 会先尝试正常的注册表/目录路径 | _(不是插件钩子)_ | +| 3 | `normalizeModelId` | 在查找前规范化旧版或预览版 model-id 别名 | provider 在规范模型解析之前负责清理别名 | +| 4 | `normalizeTransport` | 在通用模型组装前,规范化 provider 家族的 `api` / `baseUrl` | provider 负责清理同一传输家族中自定义 provider id 的传输配置 | +| 5 | `normalizeConfig` | 在运行时/provider 解析前规范化 `models.providers.` | provider 需要将配置清理逻辑放在插件中;内置的 Google 家族辅助逻辑也会为受支持的 Google 配置项提供兜底 | +| 6 | `applyNativeStreamingUsageCompat` | 对配置 providers 应用原生流式用量兼容性改写 | provider 需要基于端点的原生流式用量元数据修复 | +| 7 | `resolveConfigApiKey` | 在加载运行时身份验证前,为配置 providers 解析 env-marker 身份验证 | provider 拥有自己的 env-marker API 密钥解析;`amazon-bedrock` 在这里也有一个内置 AWS env-marker 解析器 | +| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露 local/自托管或基于配置的身份验证 | provider 可以使用合成/local 凭证标记运行 | +| 9 | `resolveExternalAuthProfiles` | 叠加 provider 拥有的外部认证配置文件;CLI/应用拥有的凭证默认 `persistence` 为 `runtime-only` | provider 复用外部认证凭证,而不持久化复制的刷新令牌;需在清单中声明 `contracts.externalAuthProviders` | +| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成配置文件占位符优先级降到环境变量/基于配置的身份验证之后 | provider 存储了合成占位配置文件,这些占位项不应获得更高优先级 | +| 11 | `resolveDynamicModel` | 为本地注册表中尚不存在的 provider 拥有的模型 id 提供同步回退 | provider 接受任意上游模型 id | +| 12 | `prepareDynamicModel` | 先进行异步预热,然后再次运行 `resolveDynamicModel` | provider 在解析未知 id 之前需要网络元数据 | +| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型之前进行最终改写 | provider 需要进行传输改写,但仍使用 core 传输 | +| 14 | `contributeResolvedModelCompat` | 为另一种兼容传输背后的 vendor 模型提供兼容性标记 | provider 能在不接管 provider 本身的情况下识别自己的模型在代理传输上的运行 | +| 15 | `capabilities` | 由共享 core 逻辑使用的 provider 拥有的转录/工具元数据 | provider 需要处理转录或 provider 家族特有行为 | +| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式之前,对工具模式进行规范化 | provider 需要进行传输家族级别的模式清理 | +| 17 | `inspectToolSchemas` | 在规范化后暴露 provider 拥有的模式诊断 | provider 希望给出关键字警告,而不必让 core 学会 provider 特定规则 | +| 18 | `resolveReasoningOutputMode` | 选择原生或带标签的推理输出契约 | provider 需要使用带标签的推理/最终输出,而不是原生字段 | +| 19 | `prepareExtraParams` | 在通用流选项包装器之前,规范化请求参数 | provider 需要默认请求参数或按 provider 清理参数 | +| 20 | `createStreamFn` | 用自定义传输完全替换正常流路径 | provider 需要自定义线协议,而不仅仅是包装器 | +| 21 | `wrapStreamFn` | 在应用通用包装器之后再包装流函数 | provider 需要请求头/请求体/模型兼容包装,而不是自定义传输 | +| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输请求头或元数据 | provider 希望通用传输发送 provider 原生轮次标识 | +| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 请求头或会话冷却策略 | provider 希望通用 WS 传输调整会话请求头或回退策略 | +| 24 | `formatApiKey` | 认证配置文件格式化器:将已存储配置文件转换为运行时 `apiKey` 字符串 | provider 存储了额外认证元数据,并需要自定义运行时令牌形态 | +| 25 | `refreshOAuth` | 为自定义刷新端点或刷新失败策略覆盖 OAuth 刷新 | provider 不适配共享的 `pi-ai` 刷新器 | +| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时追加修复提示 | provider 需要在刷新失败后提供 provider 自有的身份验证修复指导 | +| 27 | `matchesContextOverflowError` | provider 拥有的上下文窗口溢出错误匹配器 | provider 存在通用启发式无法识别的原始溢出错误 | +| 28 | `classifyFailoverReason` | provider 拥有的故障切换原因分类 | provider 可以将原始 API/传输错误映射为限流、过载等 | +| 29 | `isCacheTtlEligible` | 面向代理/回传 providers 的提示缓存策略 | provider 需要针对代理场景的缓存 TTL 控制 | +| 30 | `buildMissingAuthMessage` | 替换通用的缺失身份验证恢复消息 | provider 需要 provider 特定的缺失身份验证恢复提示 | +| 31 | `suppressBuiltInModel` | 过期上游模型抑制,并可附加面向用户的错误提示 | provider 需要隐藏过期上游条目,或用 vendor 提示替代它们 | +| 32 | `augmentModelCatalog` | 在发现之后追加合成/最终目录条目 | provider 需要在 `models list` 和选择器中添加合成的前向兼容条目 | +| 33 | `resolveThinkingProfile` | 设置特定模型的 `/think` 等级、显示标签和默认值 | provider 为选定模型暴露自定义思考层级或二元标签 | +| 34 | `isBinaryThinking` | 开/关推理切换兼容性钩子 | provider 只暴露二元的思考开/关 | +| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | provider 希望仅对部分模型启用 `xhigh` | +| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 等级兼容性钩子 | provider 负责某个模型家族的默认 `/think` 策略 | +| 37 | `isModernModelRef` | 用于实时配置文件过滤和 smoke 选择的现代模型匹配器 | provider 负责实时/smoke 首选模型匹配 | +| 38 | `prepareRuntimeAuth` | 在推理前将已配置的凭证交换为实际运行时令牌/密钥 | provider 需要进行令牌交换,或需要短生命周期的请求凭证 | +| 39 | `resolveUsageAuth` | 为 `/usage` 及相关状态表面解析用量/计费凭证 | provider 需要自定义用量/配额令牌解析,或使用不同的用量凭证 | +| 40 | `fetchUsageSnapshot` | 在身份验证解析后获取并规范化 provider 特定的用量/配额快照 | provider 需要 provider 特定的用量端点或负载解析器 | +| 41 | `createEmbeddingProvider` | 为 memory/search 构建 provider 拥有的嵌入适配器 | Memory 嵌入行为应归属于 provider 插件 | +| 42 | `buildReplayPolicy` | 返回一个重放策略,用于控制该 provider 的转录处理 | provider 需要自定义转录策略(例如剥离 thinking 块) | +| 43 | `sanitizeReplayHistory` | 在通用转录清理后重写重放历史 | provider 需要在共享压缩辅助逻辑之外执行 provider 特定的重放改写 | +| 44 | `validateReplayTurns` | 在嵌入式运行器之前,对重放轮次进行最终验证或重塑 | provider 传输在通用净化后需要更严格的轮次验证 | +| 45 | `onModelSelected` | 在模型被选中后运行 provider 拥有的副作用 | provider 需要在模型激活时执行遥测或维护 provider 拥有的状态 | -`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配到的提供商插件,然后继续回退到其他具备 hook 能力的提供商插件,直到某个插件实际更改了模型 id 或传输 / 配置。这样可以让别名 / 兼容性提供商 shim 继续工作,而不要求调用方知道哪个内置插件拥有该重写逻辑。如果没有任何提供商 hook 重写受支持的 Google 族配置项,那么内置的 Google 配置规范化器仍会应用该兼容性清理。 +`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查已匹配的 +provider 插件,然后继续尝试其他具备相应钩子能力的 provider 插件, +直到有插件实际改写模型 id 或传输/配置。这样可以保持 +别名/兼容 provider shim 正常工作,而不要求调用方知道是哪个 +内置插件拥有该改写逻辑。如果没有任何 provider 钩子改写受支持的 +Google 家族配置项,内置的 Google 配置规范化器仍会应用 +那一层兼容性清理。 -如果提供商需要完全自定义的线协议或自定义请求执行器,那就是另一类扩展。这些 hooks 适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。 +如果 provider 需要完全自定义的线协议或自定义请求执行器, +那属于另一类扩展。这些钩子适用于仍运行在 OpenClaw +常规推理循环上的 provider 行为。 -### 提供商示例 +### provider 示例 ```ts api.registerProvider({ @@ -264,41 +300,44 @@ api.registerProvider({ ### 内置示例 -内置提供商插件会组合使用上述 hooks,以适配各个供应商在目录、认证、思考、重放和使用量方面的需求。权威的 hook 集合位于各插件在 `extensions/` 下的实现中;本页旨在说明这些形态,而不是镜像整份列表。 +内置的 provider 插件会组合使用上述钩子,以适配各个供应商在目录、 +身份验证、思考、重放和用量方面的需求。权威的钩子集合与各插件一起 +存放在 `extensions/` 下;本页用于说明其形态,而不是镜像那份列表。 - + OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog` 以及 `resolveDynamicModel` / `prepareDynamicModel`,以便它们能在 OpenClaw 的静态目录之前暴露上游模型 id。 - + GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 会将 `prepareRuntimeAuth` 或 `formatApiKey` 与 `resolveUsageAuth` + - `fetchUsageSnapshot` 配合使用,以控制令牌交换和 `/usage` 集成。 + `fetchUsageSnapshot` 配对使用,以管理令牌交换和 `/usage` 集成。 共享的命名家族(`google-gemini`、`passthrough-gemini`、 - `anthropic-by-model`、`hybrid-anthropic-openai`)允许提供商通过 - `buildReplayPolicy` 选择加入转录策略,而不需要每个插件都重新实现清理逻辑。 + `anthropic-by-model`、`hybrid-anthropic-openai`)允许 providers 通过 + `buildReplayPolicy` 选择加入转录策略,而不是让每个插件 + 重新实现清理逻辑。 - + `byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、 `qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 - `volcengine` 只注册 `catalog`,并复用共享推理循环。 + `volcengine` 仅注册 `catalog`,并复用共享推理循环。 - - Beta 头、`/fast` / `serviceTier` 和 `context1m` 位于 + + Beta 请求头、`/fast` / `serviceTier` 以及 `context1m` 位于 Anthropic 插件公开的 `api.ts` / `contract-api.ts` 接缝中 (`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、 - `resolveAnthropicFastMode`、`resolveAnthropicServiceTier`), - 而不在通用 SDK 中。 + `resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不是位于 + 通用 SDK 中。 ## 运行时辅助工具 -插件可以通过 `api.runtime` 访问部分核心辅助工具。以 TTS 为例: +插件可以通过 `api.runtime` 访问部分 core 辅助工具。对于 TTS: ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -319,14 +358,14 @@ const voices = await api.runtime.tts.listVoices({ 说明: -- `textToSpeech` 返回文件 / 语音便笺表面使用的常规核心 TTS 输出负载。 -- 使用核心 `messages.tts` 配置和提供商选择逻辑。 -- 返回 PCM 音频缓冲区 + 采样率。插件必须自行针对提供商执行重采样 / 编码。 -- `listVoices` 对每个提供商而言是可选的。可用于由供应商拥有的语音选择器或设置流程。 -- 语音列表可包含更丰富的元数据,例如语言区域、性别和个性标签,以支持提供商感知型选择器。 -- 目前只有 OpenAI 和 ElevenLabs 支持电话语音。Microsoft 不支持。 +- `textToSpeech` 会返回用于文件/语音便笺表面的常规 core TTS 输出负载。 +- 使用 core `messages.tts` 配置和 provider 选择逻辑。 +- 返回 PCM 音频缓冲区 + 采样率。插件必须为 providers 进行重采样/编码。 +- `listVoices` 对每个 provider 来说都是可选的。可用于供应商自有的语音选择器或设置流程。 +- 语音列表可以包含更丰富的元数据,例如区域设置、性别和个性标签,以支持 provider 感知的选择器。 +- 目前 OpenAI 和 ElevenLabs 支持电话语音。Microsoft 不支持。 -插件也可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。 +插件也可以通过 `api.registerSpeechProvider(...)` 注册语音 providers。 ```ts api.registerSpeechProvider({ @@ -346,12 +385,14 @@ api.registerSpeechProvider({ 说明: -- 将 TTS 策略、回退和回复投递保留在核心中。 -- 使用语音提供商实现由供应商拥有的合成行为。 -- 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` 提供商 id。 -- 推荐的所有权模型以公司为导向:随着 OpenClaw 增加这些能力契约,一个供应商插件可以统一拥有文本、语音、图像以及未来的媒体提供商。 +- 将 TTS 策略、回退和回复投递保留在 core 中。 +- 使用语音 providers 承载供应商自有的合成行为。 +- 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` provider id。 +- 推荐的所有权模型是面向公司的:随着 OpenClaw 增加这些 + 能力契约,一个供应商插件可以拥有文本、语音、图像以及未来的媒体 providers。 -对于图像 / 音频 / 视频理解,插件应注册一个类型化的媒体理解提供商,而不是通用键 / 值包: +对于图像/音频/视频理解,插件会注册一个类型化的 +媒体理解 provider,而不是通用的键值包: ```ts api.registerMediaUnderstandingProvider({ @@ -365,13 +406,14 @@ api.registerMediaUnderstandingProvider({ 说明: -- 将编排、回退、配置和渠道接线保留在核心中。 -- 将供应商行为保留在提供商插件中。 -- 增量扩展应保持类型化:新增可选方法、新增可选结果字段、新增可选能力。 +- 将编排、回退、配置和渠道接线保留在 core 中。 +- 将供应商行为保留在 provider 插件中。 +- 增量扩展应保持类型化:新的可选方法、新的可选 + 结果字段、新的可选能力。 - 视频生成已经遵循相同模式: - - 核心拥有能力契约和运行时辅助工具 + - core 拥有能力契约和运行时辅助工具 - 供应商插件注册 `api.registerVideoGenerationProvider(...)` - - 功能 / 渠道插件消费 `api.runtime.videoGeneration.*` + - 功能/渠道插件消费 `api.runtime.videoGeneration.*` 对于媒体理解运行时辅助工具,插件可以调用: @@ -388,7 +430,8 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -对于音频转录,插件既可以使用媒体理解运行时,也可以使用较旧的 STT 别名: +对于音频转录,插件既可以使用媒体理解运行时, +也可以使用旧版 STT 别名: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ @@ -401,12 +444,12 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ 说明: -- `api.runtime.mediaUnderstanding.*` 是图像 / 音频 / 视频理解的首选共享表面。 -- 使用核心媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。 -- 当未产生转录输出时返回 `{ text: undefined }`(例如输入被跳过 / 不受支持)。 +- `api.runtime.mediaUnderstanding.*` 是图像/音频/视频理解的首选共享表面。 +- 使用 core 媒体理解音频配置(`tools.media.audio`)和 provider 回退顺序。 +- 当未生成转录输出时(例如输入被跳过/不受支持),返回 `{ text: undefined }`。 - `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容性别名。 -插件也可以通过 `api.runtime.subagent` 启动后台子智能体运行: +插件还可以通过 `api.runtime.subagent` 启动后台子智能体运行: ```ts const result = await api.runtime.subagent.run({ @@ -420,13 +463,14 @@ const result = await api.runtime.subagent.run({ 说明: -- `provider` 和 `model` 是每次运行可选的覆盖项,不是持久化的会话变更。 -- OpenClaw 只会为受信任调用方接受这些覆盖字段。 -- 对于插件拥有的回退运行,运维人员必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。 -- 使用 `plugins.entries..subagent.allowedModels` 将受信任插件限制到特定规范 `provider/model` 目标,或设为 `"*"` 以显式允许任意目标。 -- 非受信任插件的子智能体运行仍可正常工作,但覆盖请求会被拒绝,而不是静默回退。 +- `provider` 和 `model` 是按次运行的可选覆盖项,不是持久性的会话变更。 +- OpenClaw 只会为受信任调用方启用这些覆盖字段。 +- 对于插件自有的回退运行,运维者必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。 +- 使用 `plugins.entries..subagent.allowedModels` 可将受信任插件限制为特定的规范 `provider/model` 目标,或使用 `"*"` 以显式允许任意目标。 +- 不受信任插件的 subagent 运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。 -对于 Web 搜索,插件可以使用共享运行时辅助工具,而不必深入智能体工具接线: +对于 Web 搜索,插件可以使用共享运行时辅助工具,而不是 +深入到智能体工具接线中: ```ts const providers = api.runtime.webSearch.listProviders({ @@ -442,13 +486,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -插件也可以通过 `api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。 +插件也可以通过 +`api.registerWebSearchProvider(...)` 注册 Web 搜索 providers。 说明: -- 将提供商选择、凭证解析和共享请求语义保留在核心中。 -- 使用 Web 搜索提供商实现供应商特定的搜索传输。 -- `api.runtime.webSearch.*` 是需要搜索行为但不依赖智能体工具包装器的功能 / 渠道插件首选共享表面。 +- 将 provider 选择、凭证解析和共享请求语义保留在 core 中。 +- 使用 Web 搜索 providers 承载供应商特定的搜索传输。 +- `api.runtime.webSearch.*` 是功能/渠道插件在需要搜索能力且不依赖智能体工具包装器时的首选共享表面。 ### `api.runtime.imageGeneration` @@ -463,12 +508,12 @@ const providers = api.runtime.imageGeneration.listProviders({ }); ``` -- `generate(...)`:使用已配置的图像生成提供商链生成图像。 -- `listProviders(...)`:列出可用的图像生成提供商及其能力。 +- `generate(...)`:使用已配置的图像生成 provider 链生成图像。 +- `listProviders(...)`:列出可用的图像生成 providers 及其能力。 ## Gateway 网关 HTTP 路由 -插件可以使用 `api.registerHttpRoute(...)` 暴露 HTTP 端点。 +插件可以通过 `api.registerHttpRoute(...)` 暴露 HTTP 端点。 ```ts api.registerHttpRoute({ @@ -486,9 +531,9 @@ api.registerHttpRoute({ 路由字段: - `path`:Gateway 网关 HTTP 服务器下的路由路径。 -- `auth`:必填。使用 `"gateway"` 要求常规 Gateway 网关认证,或使用 `"plugin"` 进行插件管理的认证 / webhook 验证。 +- `auth`:必填。使用 `"gateway"` 要求常规 Gateway 网关身份验证,或使用 `"plugin"` 表示插件自管身份验证/Webhook 校验。 - `match`:可选。`"exact"`(默认)或 `"prefix"`。 -- `replaceExisting`:可选。允许同一插件替换自己已存在的路由注册。 +- `replaceExisting`:可选。允许同一插件替换其自身现有的路由注册。 - `handler`:当路由处理了请求时返回 `true`。 说明: @@ -496,157 +541,177 @@ api.registerHttpRoute({ - `api.registerHttpHandler(...)` 已被移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。 - 插件路由必须显式声明 `auth`。 - 精确的 `path + match` 冲突会被拒绝,除非设置了 `replaceExisting: true`,并且一个插件不能替换另一个插件的路由。 -- 具有不同 `auth` 级别的重叠路由会被拒绝。请仅在相同认证级别上保留 `exact` / `prefix` 贯穿链。 -- `auth: "plugin"` 路由**不会**自动接收运维人员运行时作用域。它们用于插件管理的 webhook / 签名验证,而不是特权 Gateway 网关辅助调用。 -- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域内运行,但该作用域有意保持保守: - - 共享密钥 bearer 认证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` 也是如此 - - 受信任的携带身份 HTTP 模式(例如 `trusted-proxy` 或私有入口上的 `gateway.auth.mode = "none"`)只有在显式存在该头时,才会接受 `x-openclaw-scopes` - - 如果这些携带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退到 `operator.write` -- 实际规则:不要假设使用 gateway 认证的插件路由天然就是隐式管理员表面。如果你的路由需要仅管理员可用的行为,请要求使用携带身份的认证模式,并记录显式的 `x-openclaw-scopes` 头契约。 +- 具有不同 `auth` 级别的重叠路由会被拒绝。`exact`/`prefix` 贯通链必须保持在同一 auth 级别内。 +- `auth: "plugin"` 路由**不会**自动接收运维者运行时作用域。它们用于插件自管的 Webhook/签名校验,而不是特权 Gateway 网关辅助调用。 +- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域内运行,但该作用域刻意保持保守: + - 共享密钥 bearer 身份验证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` + - 受信任的携带身份 HTTP 模式(例如 `trusted-proxy` 或私有入口上的 `gateway.auth.mode = "none"`)仅在显式提供该请求头时才会认可 `x-openclaw-scopes` + - 如果这些携带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退为 `operator.write` +- 实际规则:不要假设经过 gateway 身份验证的插件路由就是隐式管理面。如果你的路由需要仅管理员可用的行为,请要求使用携带身份的身份验证模式,并记录显式的 `x-openclaw-scopes` 请求头契约。 ## 插件 SDK 导入路径 -编写新插件时,请使用窄化的 SDK 子路径,而不是单体式的 `openclaw/plugin-sdk` 根 barrel。核心子路径如下: +编写新插件时,请使用更窄的 SDK 子路径,而不是单体的 `openclaw/plugin-sdk` 根 +barrel。Core 子路径包括: -| 子路径 | 用途 | -| ----------------------------------- | ---------------------------- | -| `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 | -| `openclaw/plugin-sdk/channel-core` | 渠道入口 / 构建辅助工具 | -| `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 | -| `openclaw/plugin-sdk/config-schema` | 根 `openclaw.json` Zod schema(`OpenClawSchema`) | +| 子路径 | 用途 | +| ----------------------------------- | -------------------------------------------------- | +| `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 | +| `openclaw/plugin-sdk/channel-core` | 渠道入口/构建辅助工具 | +| `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 | +| `openclaw/plugin-sdk/config-schema` | 根 `openclaw.json` Zod 模式(`OpenClawSchema`) | -渠道插件可从一组窄化接缝中选择 —— `channel-setup`、 +渠道插件可从一组更窄的接缝中选择——`channel-setup`、 `setup-runtime`、`setup-adapter-runtime`、`setup-tools`、`channel-pairing`、 `channel-contract`、`channel-feedback`、`channel-inbound`、`channel-lifecycle`、 `channel-reply-pipeline`、`command-auth`、`secret-input`、`webhook-ingress`、 -`channel-targets` 和 `channel-actions`。审批行为应统一到单一的 `approvalCapability` 契约上,而不是混杂在不相关的插件字段之间。参见 [Channel Plugins](/zh-CN/plugins/sdk-channel-plugins)。 +`channel-targets` 和 `channel-actions`。审批行为应统一收敛到一个 +`approvalCapability` 契约,而不是分散混用在不相关的 +插件字段中。参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。 运行时和配置辅助工具位于对应的 `*-runtime` 子路径下 (`approval-runtime`、`config-runtime`、`infra-runtime`、`agent-runtime`、 `lazy-runtime`、`directory-runtime`、`text-runtime`、`runtime-store` 等)。 -`openclaw/plugin-sdk/channel-runtime` 已弃用 —— 它只是面向旧插件的兼容性 shim。新代码应改为导入更窄化的通用原语。 +`openclaw/plugin-sdk/channel-runtime` 已弃用——它只是为旧插件提供的兼容 shim。 +新代码应改为导入更窄的通用原语。 仓库内部入口点(按每个内置插件软件包根目录划分): - `index.js` —— 内置插件入口 -- `api.js` —— 辅助工具 / 类型 barrel +- `api.js` —— 辅助工具/类型 barrel - `runtime-api.js` —— 仅运行时 barrel - `setup-entry.js` —— 设置插件入口 -外部插件只能导入 `openclaw/plugin-sdk/*` 子路径。切勿从核心或另一个插件中导入其他插件软件包的 `src/*`。 -通过 facade 加载的入口点会优先使用当前活动的运行时配置快照;如果不存在,则回退到磁盘上的已解析配置文件。 +外部插件应只导入 `openclaw/plugin-sdk/*` 子路径。绝不要从 core 或另一个插件中导入其他插件软件包的 `src/*`。 +由 facade 加载的入口点会优先使用当前活动的运行时配置快照; +如果不存在,再回退到磁盘上已解析的配置文件。 -像 `image-generation`、`media-understanding` 和 `speech` 这样的能力专用子路径之所以存在,是因为内置插件目前在使用它们。它们并不自动构成长期冻结的外部契约 —— 在依赖这些路径时,请查阅相应的 SDK 参考页。 +诸如 `image-generation`、`media-understanding` +和 `speech` 之类的能力专用子路径之所以存在,是因为内置插件目前就在使用它们。它们并不自动构成长期冻结的外部契约——依赖它们时,请查看相关的 SDK 参考页。 -## 消息工具 schema +## 消息工具模式 -对于表情反应、已读和投票等非消息原语,插件应自行负责渠道特定的 `describeMessageTool(...)` schema 扩展。共享发送展示应使用通用 `MessagePresentation` 契约,而不是提供商原生的按钮、组件、块或卡片字段。 -有关契约、回退规则、提供商映射和插件作者检查清单,请参见 [Message Presentation](/zh-CN/plugins/message-presentation)。 +对于 reaction、read 和 Polls 等非消息原语,插件应自行拥有渠道特定的 `describeMessageTool(...)` 模式 +贡献。共享发送呈现应使用通用的 `MessagePresentation` 契约, +而不是 provider 原生的按钮、组件、分块或卡片字段。 +关于该契约、回退规则、provider 映射和插件作者检查清单,请参见 [Message Presentation](/zh-CN/plugins/message-presentation)。 -具备发送能力的插件会通过消息能力声明它们可以渲染的内容: +具备发送能力的插件通过消息能力声明其可渲染内容: -- `presentation`,用于语义化展示块(`text`、`context`、`divider`、`buttons`、`select`) -- `delivery-pin`,用于固定投递请求 +- `presentation` 用于语义化呈现块(`text`、`context`、`divider`、`buttons`、`select`) +- `delivery-pin` 用于固定投递请求 -核心决定是原生渲染该展示,还是将其降级为文本。 -不要从通用消息工具中暴露提供商原生 UI 的逃生舱。 -面向旧版原生 schema 的已弃用 SDK 辅助工具仍会为现有第三方插件导出,但新插件不应使用它们。 +Core 会决定是原生渲染该呈现,还是将其降级为文本。 +不要从通用消息工具中暴露 provider 原生 UI 逃生通道。 +面向旧原生模式的已弃用 SDK 辅助工具仍会为现有 +第三方插件导出,但新插件不应使用它们。 ## 渠道目标解析 -渠道插件应自行负责渠道特定的目标语义。保持共享出站宿主通用,并使用消息适配器表面来处理提供商规则: +渠道插件应自行拥有渠道特定的目标语义。保持共享 +outbound host 通用,并通过消息适配器表面承载 provider 规则: -- `messaging.inferTargetChatType({ to })` 决定在目录查找之前,规范化目标应被视为 `direct`、`group` 还是 `channel`。 -- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉核心某个输入是否应直接跳到类 id 解析,而不是目录搜索。 -- `messaging.targetResolver.resolveTarget(...)` 是当核心在规范化之后或目录未命中之后需要最终由提供商拥有的解析时,插件提供的回退逻辑。 -- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后负责提供商特定的会话路由构建。 +- `messaging.inferTargetChatType({ to })` 用于在目录查找前决定规范化目标 + 应被视为 `direct`、`group` 还是 `channel`。 +- `messaging.targetResolver.looksLikeId(raw, normalized)` 用于告知 core 某个 + 输入是否应跳过目录搜索,直接进入类似 id 的解析。 +- `messaging.targetResolver.resolveTarget(...)` 是当 core 在规范化之后或目录未命中之后, + 需要最终由 provider 自行解析时的插件回退入口。 +- `messaging.resolveOutboundSessionRoute(...)` 则在目标解析完成后, + 负责 provider 特定的会话路由构造。 -推荐拆分方式: +推荐划分方式: -- 将 `inferTargetChatType` 用于应在搜索联系人 / 群组之前发生的类别决策。 -- 将 `looksLikeId` 用于“将其视为显式 / 原生目标 id”的检查。 -- 将 `resolveTarget` 用于提供商特定的规范化回退,而不是用于广泛的目录搜索。 -- 将 chat id、thread id、JID、handle 和 room id 等提供商原生 id 保留在 `target` 值或提供商特定参数中,而不是放入通用 SDK 字段。 +- 使用 `inferTargetChatType` 处理应在搜索 peers/groups 之前发生的类别判定。 +- 使用 `looksLikeId` 进行“将其视为显式/原生目标 id”的检查。 +- 使用 `resolveTarget` 处理 provider 特定的规范化回退,而不是进行广泛的目录搜索。 +- 将 chat id、thread id、JID、handle 和 room + id 等 provider 原生 id 保留在 `target` 值或 provider 特定参数中,而不是放在通用 SDK + 字段里。 ## 基于配置的目录 -如果插件根据配置派生目录条目,应将这部分逻辑保留在插件中,并复用 -`openclaw/plugin-sdk/directory-runtime` 提供的共享辅助工具。 +如果插件从配置派生目录条目,应将该逻辑保留在插件中, +并复用 `openclaw/plugin-sdk/directory-runtime` +中的共享辅助工具。 -适用场景包括:当某个渠道需要基于配置的联系人 / 群组时,例如: +适用场景包括某个渠道需要基于配置的 peers/groups,例如: -- 基于 allowlist 的私信联系人 -- 已配置的渠道 / 群组映射 -- 按账户作用域划分的静态目录回退 +- 基于 allowlist 的私信 peers +- 已配置的渠道/群组映射 +- 基于账户范围的静态目录回退 `directory-runtime` 中的共享辅助工具只处理通用操作: - 查询过滤 -- 限制数量应用 -- 去重 / 规范化辅助工具 +- 限制项应用 +- 去重/规范化辅助工具 - 构建 `ChannelDirectoryEntry[]` 渠道特定的账户检查和 id 规范化应保留在插件实现中。 -## 提供商目录 +## provider 目录 -提供商插件可以通过 -`registerProvider({ catalog: { run(...) { ... } } })` -定义用于推理的模型目录。 +Provider 插件可以通过 +`registerProvider({ catalog: { run(...) { ... } } })` 定义用于推理的模型目录。 -`catalog.run(...)` 返回与 OpenClaw 写入 -`models.providers` 中相同的结构: +`catalog.run(...)` 返回的形态与 OpenClaw 写入 +`models.providers` 的内容相同: -- `{ provider }`:单个提供商条目 -- `{ providers }`:多个提供商条目 +- `{ provider }` 表示一个 provider 条目 +- `{ providers }` 表示多个 provider 条目 -当插件拥有提供商特定的模型 id、基础 URL 默认值或受认证门控的模型元数据时,请使用 `catalog`。 +当插件拥有 provider 特定的模型 id、基础 URL 默认值或受身份验证保护的模型元数据时,应使用 `catalog`。 -`catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机: +`catalog.order` 控制插件目录相对于 OpenClaw +内置隐式 providers 的合并时机: -- `simple`:普通 API 密钥或环境变量驱动的提供商 -- `profile`:存在认证配置文件时出现的提供商 -- `paired`:合成多个相关提供商条目的提供商 -- `late`:最后一轮,在其他隐式提供商之后 +- `simple`:纯 API 密钥或环境变量驱动的 providers +- `profile`:认证配置文件存在时出现的 providers +- `paired`:合成多个相关 provider 条目的 providers +- `late`:最后一轮,在其他隐式 providers 之后 -后面的提供商会在键冲突时胜出,因此插件可以有意用相同的提供商 id 覆盖内置提供商条目。 +后出现的 provider 会在键冲突时胜出,因此插件可以有意用相同 provider id +覆盖内置 provider 条目。 -兼容性说明: +兼容性: -- `discovery` 仍作为旧别名可用 +- `discovery` 仍可作为旧别名使用 - 如果同时注册了 `catalog` 和 `discovery`,OpenClaw 会使用 `catalog` ## 只读渠道检查 -如果你的插件注册了一个渠道,请优先实现 -`plugin.config.inspectAccount(cfg, accountId)`,并与 `resolveAccount(...)` 配套使用。 +如果你的插件注册了一个渠道,优先同时实现 +`plugin.config.inspectAccount(cfg, accountId)` 和 `resolveAccount(...)`。 -原因如下: +原因: -- `resolveAccount(...)` 是运行时路径。它可以假设凭证已完全实例化,并在缺少必需密钥时快速失败。 -- 像 `openclaw status`、`openclaw status --all`、 - `openclaw channels status`、`openclaw channels resolve` 以及 doctor / config 修复流程这样的只读命令路径,不应仅为了描述配置就去实例化运行时凭证。 +- `resolveAccount(...)` 是运行时路径。它可以假定凭证 + 已完全实体化,并在缺少必需 secret 时快速失败。 +- 只读命令路径,例如 `openclaw status`、`openclaw status --all`、 + `openclaw channels status`、`openclaw channels resolve`,以及 Doctor/配置 + 修复流程,不应仅为了描述配置就去实体化运行时凭证。 推荐的 `inspectAccount(...)` 行为: - 只返回描述性的账户状态。 - 保留 `enabled` 和 `configured`。 -- 在相关时包含凭证来源 / 状态字段,例如: +- 在相关时包含凭证来源/状态字段,例如: - `tokenSource`、`tokenStatus` - `botTokenSource`、`botTokenStatus` - `appTokenSource`、`appTokenStatus` - `signingSecretSource`、`signingSecretStatus` -- 你无需返回原始令牌值来报告只读可用性。返回 `tokenStatus: "available"`(以及对应的来源字段)就足以用于状态类命令。 -- 当凭证通过 SecretRef 配置但在当前命令路径中不可用时,请使用 `configured_unavailable`。 +- 你无需为了报告只读可用性而返回原始令牌值。返回 `tokenStatus: "available"`(以及对应的来源字段)就足以支持状态类命令。 +- 当凭证通过 SecretRef 配置,但在当前命令路径中不可用时,使用 `configured_unavailable`。 -这样,只读命令就能报告“已配置,但在当前命令路径中不可用”,而不是崩溃或误报该账户未配置。 +这样,只读命令就可以报告“已配置,但在当前命令路径中不可用”,而不是崩溃或错误地将账户报告为未配置。 -## 软件包打包 +## 软件包打包集 -插件目录可以包含一个带有 `openclaw.extensions` 的 `package.json`: +插件目录可以包含带有 `openclaw.extensions` 的 `package.json`: ```json { @@ -658,46 +723,58 @@ api.registerHttpRoute({ } ``` -每个条目都会成为一个插件。如果该 pack 列出了多个扩展,插件 id +每个条目都会成为一个插件。如果该打包集列出多个扩展,插件 id 会变成 `name/`。 -如果你的插件导入了 npm 依赖,请在该目录中安装它们,以确保 -`node_modules` 可用(`npm install` / `pnpm install`)。 +如果你的插件导入了 npm 依赖,请在该目录中安装它们, +以便 `node_modules` 可用(`npm install` / `pnpm install`)。 -安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须仍位于插件目录内。任何逃逸出软件包目录的条目都会被拒绝。 +安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须保留在插件 +目录内。任何逃离软件包目录的条目都会被拒绝。 安全说明:`openclaw plugins install` 会使用 `npm install --omit=dev --ignore-scripts` 安装插件依赖 -(无生命周期脚本,运行时不安装开发依赖)。 -请保持插件依赖树为“纯 JS/TS”,并避免依赖需要 `postinstall` 构建的包。 +(无生命周期脚本,运行时无开发依赖)。请保持插件依赖树为“纯 JS/TS”,并避免依赖需要 `postinstall` 构建的软件包。 -可选:`openclaw.setupEntry` 可以指向一个轻量级的仅设置模块。 -当 OpenClaw 需要为已禁用的渠道插件提供设置表面,或某个渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整插件入口。这样当你的主插件入口还会接线工具、hooks 或其他仅运行时代码时,就能让启动和设置过程更轻量。 +可选项:`openclaw.setupEntry` 可以指向一个轻量级的仅设置模块。 +当 OpenClaw 需要为已禁用的渠道插件提供设置表面时,或者 +当某个渠道插件已启用但仍未配置时,它会加载 `setupEntry` +而不是完整插件入口。这样当主插件入口还会接入工具、钩子或其他仅运行时代码时,就能让启动和设置更轻量。 -可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` -可以让渠道插件在 Gateway 网关监听前的启动阶段,也使用同一个 -`setupEntry` 路径,即使该渠道已经配置完成。 +可选项:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` +可以让某个渠道插件在 Gateway 网关 +监听前启动阶段中也选择同样的 `setupEntry` 路径,即使该渠道已经配置完成。 -仅当 `setupEntry` 完全覆盖 Gateway 网关开始监听前必须存在的启动表面时,才应使用此选项。实际上,这意味着设置入口必须注册启动所依赖的每一项由渠道拥有的能力,例如: +只有当 `setupEntry` 完整覆盖了网关开始监听之前必须存在的启动表面时,才使用此选项。实际上,这意味着设置入口 +必须注册启动所依赖的每个渠道自有能力,例如: - 渠道注册本身 -- 在 Gateway 网关开始监听之前必须可用的任何 HTTP 路由 -- 在同一时间窗口内必须存在的任何 gateway 方法、工具或服务 +- 任何必须在网关开始监听前可用的 HTTP 路由 +- 任何必须在同一时间窗口内存在的 Gateway 网关方法、工具或服务 -如果你的完整入口仍拥有任何必需的启动能力,就不要启用此标志。请保持插件采用默认行为,并让 OpenClaw 在启动期间加载完整入口。 +如果你的完整入口仍然拥有任何必需的启动能力,请不要启用 +此标志。保持插件使用默认行为,让 OpenClaw 在启动期间加载完整入口。 -内置渠道还可以发布仅设置的契约表面辅助工具,供核心在完整渠道运行时加载之前查询。当前的设置提升表面包括: +内置渠道还可以发布仅设置阶段的契约表面辅助工具,供 core 在完整渠道运行时尚未加载前查询。当前的设置提升表面包括: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -当核心需要在不加载完整插件入口的情况下,将旧版单账户渠道配置提升到 `channels..accounts.*` 时,就会使用这套表面。 -Matrix 是当前的内置示例:当已存在命名账户时,它只会把认证 / 引导键移动到某个命名的提升账户中;并且它可以保留已配置的非规范默认账户键,而不是总是创建 `accounts.default`。 +当 core 需要在不加载完整插件入口的情况下,将旧版单账户渠道 +配置提升到 `channels..accounts.*` 时,会使用该表面。 +Matrix 是当前的内置示例:当已存在命名账户时,它只会将身份验证/引导键移动到 +一个已命名的提升账户中,并且可以保留一个已配置的非规范默认账户键,而不是总是创建 +`accounts.default`。 -这些设置补丁适配器让内置契约表面发现保持惰性。导入时开销保持轻量;提升表面只会在首次使用时加载,而不是在模块导入时重新进入内置渠道启动流程。 +这些设置补丁适配器让内置契约表面发现保持懒加载。 +导入时保持轻量;提升表面只在首次使用时加载, +而不会在模块导入时重新进入内置渠道启动流程。 -当这些启动表面包含 gateway RPC 方法时,请将它们保留在插件专用前缀下。核心管理员命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)仍然是保留的,并且始终解析为 `operator.admin`,即使插件请求了更窄的作用域也是如此。 +当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在 +插件特定的前缀下。Core 管理命名空间(`config.*`、 +`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为 +`operator.admin`,即使插件请求更窄的作用域也是如此。 示例: @@ -716,7 +793,7 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会把认 ### 渠道目录元数据 -渠道插件可以通过 `openclaw.channel` 宣传设置 / 发现元数据,并通过 `openclaw.install` 宣传安装提示。这样可以让核心目录不携带数据。 +渠道插件可以通过 `openclaw.channel` 声明设置/发现元数据,并通过 `openclaw.install` 声明安装提示。这样可以让 core 目录保持无数据。 示例: @@ -731,7 +808,7 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会把认 "selectionLabel": "Nextcloud Talk(自托管)", "docsPath": "/channels/nextcloud-talk", "docsLabel": "nextcloud-talk", - "blurb": "通过 Nextcloud Talk webhook bot 实现的自托管聊天。", + "blurb": "通过 Nextcloud Talk webhook 机器人提供自托管聊天。", "order": 65, "aliases": ["nc-talk", "nc"] }, @@ -744,40 +821,66 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会把认 } ``` -除了最小示例外,`openclaw.channel` 还有一些实用字段: +除最小示例外,有用的 `openclaw.channel` 字段还包括: -- `detailLabel`:用于更丰富目录 / 状态表面的次级标签 +- `detailLabel`:用于更丰富目录/状态表面的次级标签 - `docsLabel`:覆盖文档链接的链接文本 -- `preferOver`:该目录条目应优先于哪些更低优先级的插件 / 渠道 id -- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面的文案控制 -- `markdownCapable`:将该渠道标记为支持 Markdown,以供出站格式化决策使用 -- `exposure.configured`:设为 `false` 时,在已配置渠道列表表面中隐藏该渠道 -- `exposure.setup`:设为 `false` 时,在交互式设置 / 配置选择器中隐藏该渠道 -- `exposure.docs`:将该渠道标记为内部 / 私有,以供文档导航表面使用 -- `showConfigured` / `showInSetup`:为兼容性保留的旧别名;优先使用 `exposure` +- `preferOver`:该目录条目应优先于的低优先级插件/渠道 id +- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面文案控制 +- `markdownCapable`:将该渠道标记为支持 Markdown,以便进行 outbound 格式决策 +- `exposure.configured`:设置为 `false` 时,在已配置渠道列表表面中隐藏该渠道 +- `exposure.setup`:设置为 `false` 时,在交互式设置/配置选择器中隐藏该渠道 +- `exposure.docs`:将该渠道标记为内部/私有,用于文档导航表面 +- `showConfigured` / `showInSetup`:为兼容性仍接受的旧别名;优先使用 `exposure` - `quickstartAllowFrom`:让该渠道选择加入标准快速开始 `allowFrom` 流程 - `forceAccountBinding`:即使只存在一个账户,也要求显式账户绑定 - `preferSessionLookupForAnnounceTarget`:在解析公告目标时优先使用会话查找 -OpenClaw 还可以合并**外部渠道目录**(例如 MPM 注册表导出)。将 JSON 文件放到以下任一位置: +OpenClaw 还可以合并**外部渠道目录**(例如 MPM +注册表导出)。将 JSON 文件放在以下任一位置: - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` - `~/.openclaw/plugins/catalog.json` -或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(用逗号 / 分号 / `PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的旧别名。 +或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向 +一个或多个 JSON 文件(以逗号/分号/`PATH` 分隔)。每个文件应 +包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"` 或 `"plugins"` 作为 `"entries"` 键的旧别名。 -生成的渠道目录条目和提供商安装目录条目会在原始 `openclaw.install` 块旁边暴露规范化后的安装源事实。这些规范化事实可标识 npm spec 是精确版本还是浮动选择器、是否存在预期的完整性元数据,以及本地源路径是否也可用。当已知目录 / 软件包标识时,如果解析出的 npm 包名偏离该标识,规范化事实会发出警告。它们还会在 `defaultChoice` 无效、指向不可用源,或存在 npm 完整性元数据却没有有效 npm 源时发出警告。消费者应将 `installSource` 视为附加的可选字段,这样较旧的手工构建条目和兼容性 shim 就不必合成它。这样,新手引导和诊断就能解释源平面状态,而无需导入插件运行时。 +生成的渠道目录条目和 provider 安装目录条目会在原始 `openclaw.install` 块旁边暴露 +规范化后的安装来源事实。这些 +规范化事实可标识 npm 规范是否为精确版本或浮动选择器、 +是否存在预期完整性元数据,以及是否还提供本地 +来源路径。当目录/软件包标识已知时,规范化事实还会在 +解析得到的 npm 软件包名与该标识不一致时发出警告。 +如果 `defaultChoice` 无效、指向不可用来源,或存在 npm 完整性元数据 +却没有有效的 npm 来源,它们也会发出警告。使用方应将 `installSource` +视为附加的可选字段,这样旧的手工构建条目和兼容 shim 就不必合成它。 +这使得新手引导和诊断可以解释来源层状态,而无需 +导入插件运行时。 -官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 `expectedIntegrity`。仅包名和 dist-tag 仍可用于兼容性,但它们会暴露源平面警告,以便目录逐步迁移到固定版本、带完整性校验的安装方式,而不会破坏现有插件。当新手引导从本地目录路径安装时,它会记录一个带有 `source: "path"` 的 `plugins.installs` 条目,并在可能时记录工作区相对的 `sourcePath`。绝对的实际加载路径仍保留在 `plugins.load.paths` 中;安装记录会避免将本地工作站路径重复写入长期配置。这使本地开发安装对源平面诊断可见,同时不会新增第二个原始文件系统路径暴露表面。 +官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 +`expectedIntegrity`。仅使用裸软件包名和 dist-tag 为兼容性仍然有效, +但它们会暴露来源层警告,以便目录可以逐步转向固定版本、带完整性检查的安装, +同时不破坏现有插件。 +当新手引导从本地目录路径安装时,它会记录一条托管插件 +安装账本条目,带有 `source: "path"`,并在可能时记录相对工作区的 +`sourcePath`。绝对的实际加载路径仍保留在 +`plugins.load.paths` 中;安装记录会避免将本地工作站路径重复写入长期配置。 +这样可以让本地开发安装对来源层诊断保持可见,同时不增加第二个原始文件系统路径暴露表面。 +旧版 `plugins.installs` 配置条目仍会作为 +兼容性回退继续读取,而状态管理的 `plugins/installs.json` 账本 +会成为安装来源的事实来源。 ## 上下文引擎插件 -上下文引擎插件负责会话上下文编排,包括摄取、组装和压缩。通过 -`api.registerContextEngine(id, factory)` 从你的插件中注册它们,然后通过 +上下文引擎插件负责会话上下文编排,包括摄取、组装 +和压缩。可通过你的插件使用 +`api.registerContextEngine(id, factory)` 注册它们,然后通过 `plugins.slots.contextEngine` 选择活动引擎。 -当你的插件需要替换或扩展默认上下文管线,而不只是添加 memory 搜索或 hooks 时,请使用这种方式。 +当你的插件需要替换或扩展默认上下文 +管线,而不仅仅是添加 memory 搜索或钩子时,请使用此方式。 ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; @@ -843,37 +946,42 @@ export default function (api) { ## 添加新能力 -当插件需要当前 API 无法容纳的行为时,不要通过私有直连绕过插件系统。请补充缺失的能力。 +当插件需要当前 API 无法适配的行为时,不要通过私有方式绕过 +插件系统。应添加缺失的能力。 推荐顺序: -1. 定义核心契约 - 决定哪些共享行为应由核心拥有:策略、回退、配置合并、生命周期、面向渠道的语义,以及运行时辅助工具形态。 -2. 添加类型化的插件注册 / 运行时表面 - 使用最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和 / 或 `api.runtime`。 -3. 连接核心 + 渠道 / 功能消费者 - 渠道和功能插件应通过核心消费该新能力,而不是直接导入某个供应商实现。 -4. 注册供应商实现 - 然后由供应商插件针对该能力注册其后端实现。 -5. 添加契约覆盖 - 添加测试,以便随着时间推移,所有权和注册形态始终保持明确。 +1. 定义 core 契约 + 决定共享行为中哪些应由 core 拥有:策略、回退、配置合并、 + 生命周期、面向渠道的语义,以及运行时辅助工具形态。 +2. 添加类型化的插件注册/运行时表面 + 用最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和/或 `api.runtime`。 +3. 接入 core + 渠道/功能使用方 + 渠道和功能插件应通过 core 消费新能力, + 而不是直接导入某个供应商实现。 +4. 注册供应商实现 + 然后由供应商插件将其后端注册到该能力上。 +5. 添加契约覆盖 + 添加测试,以便随着时间推移,所有权和注册形态仍保持明确。 -这就是 OpenClaw 在保持明确主张的同时,不会被硬编码到某一个提供商世界观中的方式。有关具体文件检查清单和完整示例,请参见 [能力扩展手册](/zh-CN/plugins/architecture)。 +这正是 OpenClaw 能保持鲜明主张、同时又不被硬编码到某个 +provider 世界观中的方式。有关具体的文件检查清单和完整示例,请参见 [能力扩展手册](/zh-CN/plugins/architecture)。 ### 能力检查清单 当你添加新能力时,实现通常应同时涉及以下表面: -- `src//types.ts` 中的核心契约类型 -- `src//runtime.ts` 中的核心运行器 / 运行时辅助工具 +- `src//types.ts` 中的 core 契约类型 +- `src//runtime.ts` 中的 core 运行器/运行时辅助工具 - `src/plugins/types.ts` 中的插件 API 注册表面 - `src/plugins/registry.ts` 中的插件注册表接线 -- 当功能 / 渠道插件需要消费它时,位于 `src/plugins/runtime/*` 中的插件运行时暴露层 -- `src/test-utils/plugin-registration.ts` 中的捕获 / 测试辅助工具 -- `src/plugins/contracts/registry.ts` 中的所有权 / 契约断言 -- `docs/` 中面向运维人员 / 插件作者的文档 +- 当功能/渠道插件需要消费该能力时,`src/plugins/runtime/*` 中的插件运行时暴露 +- `src/test-utils/plugin-registration.ts` 中的捕获/测试辅助工具 +- `src/plugins/contracts/registry.ts` 中的所有权/契约断言 +- `docs/` 中面向运维者/插件作者的文档 -如果其中某个表面缺失,通常说明该能力尚未完全集成。 +如果其中某个表面缺失,通常说明该能力 +尚未完全集成。 ### 能力模板 @@ -909,16 +1017,16 @@ const clip = await api.runtime.videoGeneration.generate({ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); ``` -这样可保持规则简单明了: +这样规则就很简单: -- 核心拥有能力契约 + 编排 +- core 拥有能力契约 + 编排 - 供应商插件拥有供应商实现 -- 功能 / 渠道插件消费运行时辅助工具 -- 契约测试让所有权始终明确 +- 功能/渠道插件消费运行时辅助工具 +- 契约测试使所有权保持明确 ## 相关内容 -- [Plugin architecture](/zh-CN/plugins/architecture) —— 公开能力模型和形态 -- [Plugin SDK subpaths](/zh-CN/plugins/sdk-subpaths) -- [Plugin SDK setup](/zh-CN/plugins/sdk-setup) +- [插件架构](/zh-CN/plugins/architecture) —— 公开能力模型和形态 +- [插件 SDK 子路径](/zh-CN/plugins/sdk-subpaths) +- [插件 SDK 设置](/zh-CN/plugins/sdk-setup) - [构建插件](/zh-CN/plugins/building-plugins)