diff --git a/docs/zh-CN/plugins/architecture-internals.md b/docs/zh-CN/plugins/architecture-internals.md
index 02243b155..e83468573 100644
--- a/docs/zh-CN/plugins/architecture-internals.md
+++ b/docs/zh-CN/plugins/architecture-internals.md
@@ -3,109 +3,84 @@ read_when:
- 实现提供商运行时钩子、渠道生命周期或软件包打包集
- 调试插件加载顺序或注册表状态
- 添加新的插件能力或上下文引擎插件
-summary: 插件架构内部机制:加载管线、注册表、运行时钩子、HTTP 路由和参考表格
+summary: 插件架构内部机制:加载流水线、注册表、运行时钩子、HTTP 路由和参考表格
title: 插件架构内部机制
x-i18n:
- generated_at: "2026-04-25T18:41:17Z"
+ generated_at: "2026-04-25T19:49:15Z"
model: gpt-5.4
provider: openai
- source_hash: 074b0a0fb1678b73a2c9236fb9fbc208d8e39dcbba39c904b2bd7b5ceac473b6
+ source_hash: 2a653dfdf6c3f81872b72e246ea5e760da4ce8d643767c38663da18025e5842a
source_path: plugins/architecture-internals.md
workflow: 15
---
-关于公开的能力模型、插件形态以及所有权/执行契约,请参见 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考:加载管线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。
+对于公共能力模型、插件形态以及归属/执行契约,请参阅 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考:加载流水线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。
-## 加载管线
+## 加载流水线
启动时,OpenClaw 大致会执行以下步骤:
1. 发现候选插件根目录
-2. 读取原生或兼容 bundle 清单以及软件包元数据
+2. 读取原生或兼容打包清单以及软件包元数据
3. 拒绝不安全的候选项
-4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、
- `slots`、`load.paths`)
+4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`)
5. 决定每个候选项是否启用
-6. 加载已启用的原生模块:已构建的内置模块使用原生加载器;
- 未构建的原生插件使用 `jiti`
-7. 调用原生 `register(api)` 钩子,并将注册内容收集到插件注册表中
+6. 加载已启用的原生模块:已构建的内置模块使用原生加载器;未构建的原生插件使用 `jiti`
+7. 调用原生 `register(api)` 钩子,并将注册项收集到插件注册表中
8. 将注册表暴露给命令/运行时表面
-`activate` 是 `register` 的旧别名——加载器会解析当前存在的那个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`;新插件优先使用 `register`。
+`activate` 是 `register` 的旧别名——加载器会解析两者中存在的那个(`def.register ?? def.activate`),并在相同的时机调用它。所有内置插件都使用 `register`;新插件也应优先使用 `register`。
-安全门会在运行时执行**之前**发生。当入口逃离插件根目录、路径对所有用户可写,或对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。
+安全门槛发生在运行时执行**之前**。在以下情况下,候选项会被阻止:入口逃逸出插件根目录、路径对所有用户可写,或对于非内置插件而言路径所有权看起来可疑。
### 清单优先行为
-清单是控制面的事实来源。OpenClaw 使用它来:
+清单是控制平面的事实来源。OpenClaw 用它来:
- 标识插件
-- 发现声明的 channels/Skills/配置模式或 bundle 能力
+- 发现声明的渠道/Skills/配置模式或打包能力
- 验证 `plugins.entries..config`
-- 增强 Control UI 标签/占位符
+- 补充 Control UI 标签/占位符
- 显示安装/目录元数据
-- 在不加载插件运行时的情况下保留低成本激活和设置描述符
+- 在不加载插件运行时的情况下保留轻量的激活和设置描述符
-对于原生插件,运行时模块是数据面部分。它会注册实际行为,例如钩子、工具、命令或 provider 流程。
+对于原生插件,运行时模块是数据平面部分。它负责注册实际行为,例如钩子、工具、命令或提供商流程。
-可选的清单 `activation` 和 `setup` 块保留在控制面中。
-它们只是用于激活规划和设置发现的元数据描述符;
-不会替代运行时注册、`register(...)` 或 `setupEntry`。
-当前第一批实时激活消费者会使用清单中的命令、渠道和提供商提示,
-在更广泛的注册表实体化之前先缩小插件加载范围:
+可选的清单 `activation` 和 `setup` 块仍然属于控制平面。它们只是用于激活规划和设置发现的仅元数据描述符;不会替代运行时注册、`register(...)` 或 `setupEntry`。
+首批实时激活使用方现在会使用清单中的命令、渠道和提供商提示,在更广泛的注册表实体化之前缩小插件加载范围:
- CLI 加载会缩小到拥有所请求主命令的插件
-- channel 设置/插件解析会缩小到拥有所请求
- channel id 的插件
-- 显式 provider 设置/运行时解析会缩小到拥有所请求
- provider id 的插件
+- 渠道设置/插件解析会缩小到拥有所请求渠道 id 的插件
+- 显式的提供商设置/运行时解析会缩小到拥有所请求提供商 id 的插件
-激活规划器既为现有调用方暴露仅含 id 的 API,也为新的诊断场景暴露
-plan API。Plan 条目会报告某个插件为何被选中,
-并区分显式 `activation.*` 规划器提示与清单所有权
-回退,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、
-`contracts.tools` 和钩子。这种原因拆分就是兼容性边界:
-现有插件元数据仍然可用,而新代码可以检测宽泛提示
-或回退行为,而不改变运行时加载语义。
+激活规划器同时暴露面向现有调用方的仅 ids API,以及面向新诊断的 plan API。Plan 条目会报告插件为何被选中,将显式 `activation.*` 规划器提示与清单归属回退区分开来,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和钩子。这种原因拆分就是兼容性边界:现有插件元数据仍可继续工作,而新代码可以检测宽泛提示或回退行为,而无需改变运行时加载语义。
-设置发现现在优先使用描述符拥有的 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 之间的漂移,但不会阻止旧版插件。
+设置发现现在优先使用描述符拥有的 id,例如 `setup.providers` 和 `setup.cliBackends`,以便在回退到 `setup-api` 之前先缩小候选插件范围;后者用于那些仍需要设置时运行时钩子的插件。提供商设置流程优先使用清单中的 `providerAuthChoices`,然后为了兼容性再回退到运行时向导选项和安装目录选项。显式的 `setup.requiresRuntime: false` 是仅描述符的截止点;省略 `requiresRuntime` 则会为了兼容性保留旧版 `setup-api` 回退。如果多个已发现插件声明了相同的规范化设置提供商或 CLI 后端 id,设置查找会拒绝这个有歧义的归属者,而不是依赖发现顺序。当设置运行时确实执行时,注册表诊断会报告 `setup.providers` / `setup.cliBackends` 与由 `setup-api` 注册的提供商或 CLI 后端之间的漂移,但不会阻止旧版插件。
-### 加载器会缓存什么
+### 加载器缓存的内容
-OpenClaw 会为以下内容保留短生命周期的进程内缓存:
+OpenClaw 会为以下内容保留短期的进程内缓存:
- 发现结果
- 清单注册表数据
- 已加载的插件注册表
-这些缓存可以减少突发启动成本和重复命令开销。可以安全地将它们视为短生命周期的性能缓存,而不是持久化。
+这些缓存可减少突发启动和重复命令开销。可以将它们视为短生命周期的性能缓存,而不是持久化。
性能说明:
-- 设置 `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、状态、诊断)
+- 插件记录(标识、来源、源头、状态、诊断)
- 工具
- 旧版钩子和类型化钩子
- 渠道
@@ -116,18 +91,18 @@ OpenClaw 会为以下内容保留短生命周期的进程内缓存:
- 后台服务
- 插件拥有的命令
-然后,core 功能会从该注册表读取,而不是直接与插件模块交互。这样可保持单向加载:
+随后,核心功能从该注册表中读取,而不是直接与插件模块通信。这使加载保持单向:
- 插件模块 -> 注册表注册
-- core 运行时 -> 注册表消费
+- 核心运行时 -> 注册表消费
-这种分离对可维护性很重要。它意味着大多数 core 表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。
+这种分离对可维护性很重要。这意味着大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块做特殊处理”。
## 会话绑定回调
-绑定会话的插件可以在审批被处理后作出响应。
+绑定会话的插件可以在批准结果确定后作出反应。
-使用 `api.onConversationBindingResolved(...)` 可在绑定请求被批准或拒绝后接收回调:
+使用 `api.onConversationBindingResolved(...)` 在绑定请求被批准或拒绝后接收回调:
```ts
export default {
@@ -135,7 +110,7 @@ export default {
register(api) {
api.onConversationBindingResolved(async (event) => {
if (event.status === "approved") {
- // 现在此插件 + 会话已存在一个绑定。
+ // 这个插件 + 会话现在已经存在一个绑定。
console.log(event.binding?.conversationId);
return;
}
@@ -151,100 +126,89 @@ export default {
- `status`:`"approved"` 或 `"denied"`
- `decision`:`"allow-once"`、`"allow-always"` 或 `"deny"`
-- `binding`:已批准请求的已解析绑定
-- `request`:原始请求摘要、detach 提示、发送者 id 和
- 会话元数据
+- `binding`:已批准请求对应的解析后绑定
+- `request`:原始请求摘要、detach 提示、发送者 id 和会话元数据
-此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在 core 审批处理完成后运行。
+这个回调仅用于通知。它不会改变谁被允许绑定会话,并且会在核心审批处理完成后运行。
-## provider 运行时钩子
+## 提供商运行时钩子
-Provider 插件有三层:
+提供商插件有三层:
-- **清单元数据**,用于低成本的预运行时查找:
- `setup.providers[].envVars`、已弃用的兼容字段 `providerAuthEnvVars`、
+- **清单元数据**,用于低成本的运行时前查找:
+ `setup.providers[].envVars`、已弃用的兼容项 `providerAuthEnvVars`、
`providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`。
-- **配置时钩子**:`catalog`(旧版 `discovery`)以及
+- **配置时钩子**:`catalog`(旧称 `discovery`)以及
`applyConfigDefaults`。
-- **运行时钩子**:40 多个可选钩子,涵盖身份验证、模型解析、
- 流包装、思考等级、重放策略和用量端点。请参见
- [钩子顺序和用法](#hook-order-and-usage) 下的完整列表。
+- **运行时钩子**:40 多个可选钩子,涵盖认证、模型解析、
+ 流包装、思考级别、重放策略和用量端点。完整列表请参见
+ [钩子顺序和用法](#hook-order-and-usage)。
-OpenClaw 仍然负责通用的 Agent loop、故障切换、转录处理和工具策略。这些钩子是 provider 特定行为的扩展表面,因此无需整个自定义推理传输层。
+OpenClaw 仍然负责通用的智能体循环、故障转移、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,而无需实现完整的自定义推理传输。
-当 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 设置变量。
+当提供商具有基于环境变量的凭证,并且希望通用认证/Status/模型选择器路径在不加载插件运行时的情况下也能识别时,请使用清单中的 `setup.providers[].envVars`。已弃用的 `providerAuthEnvVars` 在弃用窗口期间仍会被兼容适配器读取,使用它的非内置插件会收到清单诊断。当一个提供商 id 需要复用另一个提供商 id 的环境变量、认证配置文件、配置支持的认证和 API 密钥新手引导选项时,请使用清单 `providerAuthAliases`。当新手引导/认证选项 CLI 表面需要在不加载提供商运行时的情况下知道该提供商的选项 id、分组标签和简单的单标志认证接线时,请使用清单 `providerAuthChoices`。将提供商运行时的 `envVars` 保留给面向操作员的提示,例如新手引导标签或 OAuth client-id/client-secret 设置变量。
-当某个渠道具有由环境变量驱动的身份验证或设置,并且通用 shell 环境变量回退、配置/状态检查或设置提示需要在不加载渠道运行时的情况下看到这些信息时,使用清单 `channelEnvVars`。
+当渠道具有由环境变量驱动的认证或设置,并且希望通用 shell 环境变量回退、配置/Status 检查或设置提示在不加载渠道运行时的情况下也能识别时,请使用清单 `channelEnvVars`。
### 钩子顺序和用法
-对于模型/provider 插件,OpenClaw 大致按以下顺序调用钩子。
-“何时使用”列是快速决策指南。
+对于模型/提供商插件,OpenClaw 大致按以下顺序调用钩子。
+“何时使用”这一列是快速决策指南。
-| # | 钩子 | 作用 | 何时使用 |
-| --- | --------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
-| 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 拥有的状态 |
+| # | 钩子 | 作用 | 何时使用 |
+| --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
+| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers` 中 | 提供商拥有目录,或拥有 base URL 默认值 |
+| 2 | `applyConfigDefaults` | 在配置实体化期间应用由提供商拥有的全局配置默认值 | 默认值依赖于认证模式、环境变量或提供商模型家族语义 |
+| -- | _(内置模型查找)_ | OpenClaw 会先尝试常规的注册表/目录路径 | _(不是插件钩子)_ |
+| 3 | `normalizeModelId` | 在查找之前规范化旧版或预览版模型 id 别名 | 提供商在规范模型解析之前拥有别名清理逻辑 |
+| 4 | `normalizeTransport` | 在通用模型组装之前规范化提供商家族的 `api` / `baseUrl` | 提供商需要为同一传输家族中的自定义提供商 id 清理传输配置 |
+| 5 | `normalizeConfig` | 在运行时/提供商解析之前规范化 `models.providers.` | 提供商需要将应由插件负责的配置清理逻辑放在插件内;内置的 Google 家族辅助逻辑也会为受支持的 Google 配置项提供兜底 |
+| 6 | `applyNativeStreamingUsageCompat` | 将原生流式用量兼容性重写应用到配置提供商 | 提供商需要基于端点的原生流式用量元数据修复 |
+| 7 | `resolveConfigApiKey` | 在加载运行时认证之前,为配置提供商解析环境变量标记认证 | 提供商拥有自己的环境变量标记 API 密钥解析逻辑;`amazon-bedrock` 在这里也有一个内置的 AWS 环境变量标记解析器 |
+| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露 local/self-hosted 或配置支持的认证 | 提供商可以使用合成/local 凭证标记运行 |
+| 9 | `resolveExternalAuthProfiles` | 叠加由提供商拥有的外部认证配置文件;CLI/应用拥有的凭证默认 `persistence` 为 `runtime-only` | 提供商在不持久化复制的刷新令牌的情况下复用外部认证凭证;请在清单中声明 `contracts.externalAuthProviders` |
+| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成配置文件占位符优先级降低到环境变量/配置支持认证之后 | 提供商会存储不应具有更高优先级的合成占位配置文件 |
+| 11 | `resolveDynamicModel` | 为本地注册表中尚不存在的、由提供商拥有的模型 id 提供同步回退 | 提供商接受任意上游模型 id |
+| 12 | `prepareDynamicModel` | 先执行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 |
+| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型之前进行最终重写 | 提供商需要传输重写,但仍使用核心传输 |
+| 14 | `contributeResolvedModelCompat` | 为位于另一个兼容传输之后的供应商模型提供兼容性标志 | 提供商能够在代理传输上识别自己的模型,而无需接管该提供商 |
+| 15 | `capabilities` | 由共享核心逻辑使用的、由提供商拥有的转录/工具元数据 | 提供商需要处理转录或提供商家族特有问题 |
+| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式之前规范化这些模式 | 提供商需要清理传输家族的模式 |
+| 17 | `inspectToolSchemas` | 在规范化之后暴露由提供商拥有的模式诊断 | 提供商希望提供关键字警告,而不必让核心学习特定于提供商的规则 |
+| 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` | 开/关推理切换兼容性钩子 | 提供商只暴露二元思考开/关 |
+| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | 提供商希望仅对部分模型启用 `xhigh` |
+| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容性钩子 | 提供商拥有某个模型家族的默认 `/think` 策略 |
+| 37 | `isModernModelRef` | 用于实时配置文件过滤和 smoke 选择的现代模型匹配器 | 提供商拥有 live/smoke 首选模型匹配逻辑 |
+| 38 | `prepareRuntimeAuth` | 在推理前将已配置的凭证交换为实际运行时令牌/密钥 | 提供商需要令牌交换或短时请求凭证 |
+| 39 | `resolveUsageAuth` | 为 `/usage` 及相关 Status 表面解析用量/计费凭证 | 提供商需要自定义用量/配额令牌解析,或使用不同的用量凭证 |
+| 40 | `fetchUsageSnapshot` | 在认证解析后获取并规范化特定于提供商的用量/配额快照 | 提供商需要特定于提供商的用量端点或负载解析器 |
+| 41 | `createEmbeddingProvider` | 为 Memory Wiki/搜索构建由提供商拥有的嵌入适配器 | Memory Wiki 嵌入行为应归属于提供商插件 |
+| 42 | `buildReplayPolicy` | 返回控制该提供商转录处理方式的重放策略 | 提供商需要自定义转录策略(例如去除思考块) |
+| 43 | `sanitizeReplayHistory` | 在通用转录清理之后重写重放历史 | 提供商需要超出共享压缩辅助工具能力范围的、特定于提供商的重放重写 |
+| 44 | `validateReplayTurns` | 在嵌入式运行器之前对重放轮次进行最终验证或重塑 | 提供商传输在通用清理之后需要更严格的轮次验证 |
+| 45 | `onModelSelected` | 在模型被选中后运行由提供商拥有的副作用 | 当模型变为活动状态时,提供商需要遥测或提供商拥有的状态 |
-`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查已匹配的
-provider 插件,然后继续尝试其他具备相应钩子能力的 provider 插件,
-直到有插件实际改写模型 id 或传输/配置。这样可以保持
-别名/兼容 provider shim 正常工作,而不要求调用方知道是哪个
-内置插件拥有该改写逻辑。如果没有任何 provider 钩子改写受支持的
-Google 家族配置项,内置的 Google 配置规范化器仍会应用
-那一层兼容性清理。
+`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查已匹配的提供商插件,然后继续尝试其他具备相应钩子能力的提供商插件,直到某个插件实际修改了模型 id 或传输/配置为止。这样可以让别名/兼容性提供商垫片继续工作,而不要求调用方知道到底是哪个内置插件拥有这项重写逻辑。如果没有任何提供商钩子重写受支持的 Google 家族配置项,内置的 Google 配置规范化器仍会应用这类兼容性清理。
-如果 provider 需要完全自定义的线协议或自定义请求执行器,
-那属于另一类扩展。这些钩子适用于仍运行在 OpenClaw
-常规推理循环上的 provider 行为。
+如果提供商需要完全自定义的线协议或自定义请求执行器,那属于另一类扩展。这些钩子适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。
-### provider 示例
+### 提供商示例
```ts
api.registerProvider({
@@ -300,44 +264,40 @@ api.registerProvider({
### 内置示例
-内置的 provider 插件会组合使用上述钩子,以适配各个供应商在目录、
-身份验证、思考、重放和用量方面的需求。权威的钩子集合与各插件一起
-存放在 `extensions/` 下;本页用于说明其形态,而不是镜像那份列表。
+内置提供商插件会组合使用上述钩子,以适配各供应商在目录、认证、思考、重放和用量方面的需求。权威的钩子集合以各插件在 `extensions/` 下的实现为准;本页旨在说明这些形态,而不是镜像列出完整清单。
-
- OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog` 以及
- `resolveDynamicModel` / `prepareDynamicModel`,以便它们能在
- OpenClaw 的静态目录之前暴露上游模型 id。
+
+ OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog`,再配合
+ `resolveDynamicModel` / `prepareDynamicModel`,以便在 OpenClaw 的静态目录之前先暴露上游模型 id。
-
- GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 会将
+
+ 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`)允许 providers 通过
- `buildReplayPolicy` 选择加入转录策略,而不是让每个插件
- 重新实现清理逻辑。
+ `anthropic-by-model`、`hybrid-anthropic-openai`)让提供商可以通过
+ `buildReplayPolicy` 选择加入转录策略,而不必由每个插件重复实现清理逻辑。
-
+
`byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、
`qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和
- `volcengine` 仅注册 `catalog`,并复用共享推理循环。
+ `volcengine` 只注册 `catalog`,并复用共享推理循环。
-
+
Beta 请求头、`/fast` / `serviceTier` 以及 `context1m` 位于
Anthropic 插件公开的 `api.ts` / `contract-api.ts` 接缝中
(`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、
- `resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不是位于
+ `resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不是放在
通用 SDK 中。
## 运行时辅助工具
-插件可以通过 `api.runtime` 访问部分 core 辅助工具。对于 TTS:
+插件可以通过 `api.runtime` 访问选定的核心辅助工具。以 TTS 为例:
```ts
const clip = await api.runtime.tts.textToSpeech({
@@ -358,14 +318,14 @@ const voices = await api.runtime.tts.listVoices({
说明:
-- `textToSpeech` 会返回用于文件/语音便笺表面的常规 core TTS 输出负载。
-- 使用 core `messages.tts` 配置和 provider 选择逻辑。
-- 返回 PCM 音频缓冲区 + 采样率。插件必须为 providers 进行重采样/编码。
-- `listVoices` 对每个 provider 来说都是可选的。可用于供应商自有的语音选择器或设置流程。
-- 语音列表可以包含更丰富的元数据,例如区域设置、性别和个性标签,以支持 provider 感知的选择器。
+- `textToSpeech` 会返回用于文件/语音消息表面的常规核心 TTS 输出负载。
+- 使用核心 `messages.tts` 配置和提供商选择逻辑。
+- 返回 PCM 音频缓冲区 + 采样率。插件必须自行针对提供商执行重采样/编码。
+- `listVoices` 是否可用取决于提供商。将其用于供应商自有的语音选择器或设置流程。
+- 语音列表可以包含更丰富的元数据,例如区域设置、性别和个性标签,以支持提供商感知的选择器。
- 目前 OpenAI 和 ElevenLabs 支持电话语音。Microsoft 不支持。
-插件也可以通过 `api.registerSpeechProvider(...)` 注册语音 providers。
+插件也可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。
```ts
api.registerSpeechProvider({
@@ -385,14 +345,12 @@ api.registerSpeechProvider({
说明:
-- 将 TTS 策略、回退和回复投递保留在 core 中。
-- 使用语音 providers 承载供应商自有的合成行为。
-- 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` provider id。
-- 推荐的所有权模型是面向公司的:随着 OpenClaw 增加这些
- 能力契约,一个供应商插件可以拥有文本、语音、图像以及未来的媒体 providers。
+- 将 TTS 策略、回退和回复投递保留在核心中。
+- 对于供应商自有的合成行为,请使用语音提供商。
+- 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` 提供商 id。
+- 推荐的归属模型是面向公司的:随着 OpenClaw 增加这些能力契约,一个供应商插件可以统一拥有文本、语音、图像和未来的媒体提供商。
-对于图像/音频/视频理解,插件会注册一个类型化的
-媒体理解 provider,而不是通用的键值包:
+对于图像/音频/视频理解,插件会注册一个类型化的媒体理解提供商,而不是通用的键值袋:
```ts
api.registerMediaUnderstandingProvider({
@@ -406,12 +364,11 @@ api.registerMediaUnderstandingProvider({
说明:
-- 将编排、回退、配置和渠道接线保留在 core 中。
-- 将供应商行为保留在 provider 插件中。
-- 增量扩展应保持类型化:新的可选方法、新的可选
- 结果字段、新的可选能力。
+- 将编排、回退、配置和渠道接线保留在核心中。
+- 将供应商行为保留在提供商插件中。
+- 增量扩展应保持类型化:新增可选方法、新增可选结果字段、新增可选能力。
- 视频生成已经遵循相同模式:
- - core 拥有能力契约和运行时辅助工具
+ - 核心拥有能力契约和运行时辅助工具
- 供应商插件注册 `api.registerVideoGenerationProvider(...)`
- 功能/渠道插件消费 `api.runtime.videoGeneration.*`
@@ -430,8 +387,7 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({
});
```
-对于音频转录,插件既可以使用媒体理解运行时,
-也可以使用旧版 STT 别名:
+对于音频转录,插件既可以使用媒体理解运行时,也可以使用较旧的 STT 别名:
```ts
const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
@@ -445,8 +401,8 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
说明:
- `api.runtime.mediaUnderstanding.*` 是图像/音频/视频理解的首选共享表面。
-- 使用 core 媒体理解音频配置(`tools.media.audio`)和 provider 回退顺序。
-- 当未生成转录输出时(例如输入被跳过/不受支持),返回 `{ text: undefined }`。
+- 使用核心媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。
+- 当未产生转录输出时返回 `{ text: undefined }`(例如输入被跳过/不受支持)。
- `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容性别名。
插件还可以通过 `api.runtime.subagent` 启动后台子智能体运行:
@@ -463,14 +419,13 @@ const result = await api.runtime.subagent.run({
说明:
-- `provider` 和 `model` 是按次运行的可选覆盖项,不是持久性的会话变更。
-- OpenClaw 只会为受信任调用方启用这些覆盖字段。
-- 对于插件自有的回退运行,运维者必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。
-- 使用 `plugins.entries..subagent.allowedModels` 可将受信任插件限制为特定的规范 `provider/model` 目标,或使用 `"*"` 以显式允许任意目标。
-- 不受信任插件的 subagent 运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。
+- `provider` 和 `model` 是每次运行可选的覆盖项,不是持久化的会话变更。
+- OpenClaw 仅对受信调用方接受这些覆盖字段。
+- 对于插件自有的回退运行,运维人员必须通过 `plugins.entries..subagent.allowModelOverride: true` 显式启用。
+- 使用 `plugins.entries..subagent.allowedModels` 将受信插件限制为特定的规范 `provider/model` 目标,或使用 `"*"` 显式允许任意目标。
+- 非受信插件的子智能体运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。
-对于 Web 搜索,插件可以使用共享运行时辅助工具,而不是
-深入到智能体工具接线中:
+对于 web 搜索,插件可以消费共享运行时辅助工具,而不必深入智能体工具接线:
```ts
const providers = api.runtime.webSearch.listProviders({
@@ -487,13 +442,13 @@ const result = await api.runtime.webSearch.search({
```
插件也可以通过
-`api.registerWebSearchProvider(...)` 注册 Web 搜索 providers。
+`api.registerWebSearchProvider(...)` 注册 web 搜索提供商。
说明:
-- 将 provider 选择、凭证解析和共享请求语义保留在 core 中。
-- 使用 Web 搜索 providers 承载供应商特定的搜索传输。
-- `api.runtime.webSearch.*` 是功能/渠道插件在需要搜索能力且不依赖智能体工具包装器时的首选共享表面。
+- 将提供商选择、凭证解析和共享请求语义保留在核心中。
+- 对于供应商特定的搜索传输,请使用 web 搜索提供商。
+- `api.runtime.webSearch.*` 是需要搜索行为但又不依赖智能体工具包装器的功能/渠道插件的首选共享表面。
### `api.runtime.imageGeneration`
@@ -508,8 +463,8 @@ const providers = api.runtime.imageGeneration.listProviders({
});
```
-- `generate(...)`:使用已配置的图像生成 provider 链生成图像。
-- `listProviders(...)`:列出可用的图像生成 providers 及其能力。
+- `generate(...)`:使用已配置的图像生成提供商链生成图像。
+- `listProviders(...)`:列出可用的图像生成提供商及其能力。
## Gateway 网关 HTTP 路由
@@ -531,151 +486,135 @@ api.registerHttpRoute({
路由字段:
- `path`:Gateway 网关 HTTP 服务器下的路由路径。
-- `auth`:必填。使用 `"gateway"` 要求常规 Gateway 网关身份验证,或使用 `"plugin"` 表示插件自管身份验证/Webhook 校验。
+- `auth`:必填。使用 `"gateway"` 表示需要常规 Gateway 网关认证,或使用 `"plugin"` 表示由插件管理认证/webhook 校验。
- `match`:可选。`"exact"`(默认)或 `"prefix"`。
-- `replaceExisting`:可选。允许同一插件替换其自身现有的路由注册。
+- `replaceExisting`:可选。允许同一插件替换它自己已有的路由注册。
- `handler`:当路由处理了请求时返回 `true`。
说明:
-- `api.registerHttpHandler(...)` 已被移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。
+- `api.registerHttpHandler(...)` 已移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`。
- 插件路由必须显式声明 `auth`。
-- 精确的 `path + match` 冲突会被拒绝,除非设置了 `replaceExisting: true`,并且一个插件不能替换另一个插件的路由。
-- 具有不同 `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` 请求头契约。
+- 除非设置了 `replaceExisting: true`,否则精确的 `path + match` 冲突会被拒绝,而且一个插件不能替换另一个插件的路由。
+- 使用不同 `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` 请求头契约。
## 插件 SDK 导入路径
-编写新插件时,请使用更窄的 SDK 子路径,而不是单体的 `openclaw/plugin-sdk` 根
-barrel。Core 子路径包括:
+在编写新插件时,请使用较窄的 SDK 子路径,而不是单体的 `openclaw/plugin-sdk` 根 barrel。核心子路径包括:
-| 子路径 | 用途 |
+| 子路径 | 用途 |
| ----------------------------------- | -------------------------------------------------- |
-| `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 |
-| `openclaw/plugin-sdk/channel-core` | 渠道入口/构建辅助工具 |
-| `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 |
-| `openclaw/plugin-sdk/config-schema` | 根 `openclaw.json` Zod 模式(`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` 契约,而不是分散混用在不相关的
-插件字段中。参见 [渠道插件](/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` 已弃用——它只是为旧插件提供的兼容性垫片。新代码应改为导入更窄的通用原语。
仓库内部入口点(按每个内置插件软件包根目录划分):
-- `index.js` —— 内置插件入口
-- `api.js` —— 辅助工具/类型 barrel
-- `runtime-api.js` —— 仅运行时 barrel
-- `setup-entry.js` —— 设置插件入口
+- `index.js` — 内置插件入口
+- `api.js` — 辅助工具/类型 barrel
+- `runtime-api.js` — 仅运行时 barrel
+- `setup-entry.js` — 设置插件入口
-外部插件应只导入 `openclaw/plugin-sdk/*` 子路径。绝不要从 core 或另一个插件中导入其他插件软件包的 `src/*`。
-由 facade 加载的入口点会优先使用当前活动的运行时配置快照;
-如果不存在,再回退到磁盘上已解析的配置文件。
+外部插件只能导入 `openclaw/plugin-sdk/*` 子路径。绝不要从核心或其他插件中导入另一个插件软件包的 `src/*`。
+由 facade 加载的入口点会优先使用当前活动的运行时配置快照;若不存在,则回退到磁盘上已解析的配置文件。
-诸如 `image-generation`、`media-understanding`
-和 `speech` 之类的能力专用子路径之所以存在,是因为内置插件目前就在使用它们。它们并不自动构成长期冻结的外部契约——依赖它们时,请查看相关的 SDK 参考页。
+诸如 `image-generation`、`media-understanding` 和 `speech` 这样的能力专用子路径之所以存在,是因为当前内置插件正在使用它们。它们并不自动意味着长期冻结的外部契约——在依赖它们时,请查阅相应的 SDK 参考页面。
## 消息工具模式
-对于 reaction、read 和 Polls 等非消息原语,插件应自行拥有渠道特定的 `describeMessageTool(...)` 模式
-贡献。共享发送呈现应使用通用的 `MessagePresentation` 契约,
-而不是 provider 原生的按钮、组件、分块或卡片字段。
-关于该契约、回退规则、provider 映射和插件作者检查清单,请参见 [Message Presentation](/zh-CN/plugins/message-presentation)。
+对于反应、已读和投票等非消息原语,插件应自行负责特定于渠道的 `describeMessageTool(...)` 模式贡献。
+共享发送展示应使用通用 `MessagePresentation` 契约,而不是供应商原生的按钮、组件、块或卡片字段。
+有关契约、回退规则、提供商映射和插件作者检查清单,请参阅
+[消息展示](/zh-CN/plugins/message-presentation)。
-具备发送能力的插件通过消息能力声明其可渲染内容:
+具备发送能力的插件通过消息能力声明它们可以渲染的内容:
-- `presentation` 用于语义化呈现块(`text`、`context`、`divider`、`buttons`、`select`)
-- `delivery-pin` 用于固定投递请求
+- `presentation` 用于语义化展示块(`text`、`context`、`divider`、`buttons`、`select`)
+- `delivery-pin` 用于置顶投递请求
-Core 会决定是原生渲染该呈现,还是将其降级为文本。
-不要从通用消息工具中暴露 provider 原生 UI 逃生通道。
-面向旧原生模式的已弃用 SDK 辅助工具仍会为现有
-第三方插件导出,但新插件不应使用它们。
+核心负责决定是原生渲染展示,还是将其降级为文本。
+不要从通用消息工具中暴露供应商原生 UI 逃生舱。
+旧版原生模式的已弃用 SDK 辅助工具仍会为现有第三方插件继续导出,但新插件不应使用它们。
## 渠道目标解析
-渠道插件应自行拥有渠道特定的目标语义。保持共享
-outbound host 通用,并通过消息适配器表面承载 provider 规则:
+渠道插件应负责特定于渠道的目标语义。保持共享出站主机通用,并使用消息适配器表面处理提供商规则:
-- `messaging.inferTargetChatType({ to })` 用于在目录查找前决定规范化目标
- 应被视为 `direct`、`group` 还是 `channel`。
-- `messaging.targetResolver.looksLikeId(raw, normalized)` 用于告知 core 某个
- 输入是否应跳过目录搜索,直接进入类似 id 的解析。
-- `messaging.targetResolver.resolveTarget(...)` 是当 core 在规范化之后或目录未命中之后,
- 需要最终由 provider 自行解析时的插件回退入口。
-- `messaging.resolveOutboundSessionRoute(...)` 则在目标解析完成后,
- 负责 provider 特定的会话路由构造。
+- `messaging.inferTargetChatType({ to })` 用于在目录查找前决定规范化目标应被视为 `direct`、`group` 还是 `channel`。
+- `messaging.targetResolver.looksLikeId(raw, normalized)` 用于告诉核心,某个输入是否应跳过目录搜索,直接进入类似 id 的解析。
+- `messaging.targetResolver.resolveTarget(...)` 是插件回退路径:当核心在规范化后或目录未命中后需要最终的提供商自有解析时使用。
+- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后负责构造特定于提供商的会话路由。
-推荐划分方式:
+推荐拆分方式:
-- 使用 `inferTargetChatType` 处理应在搜索 peers/groups 之前发生的类别判定。
-- 使用 `looksLikeId` 进行“将其视为显式/原生目标 id”的检查。
-- 使用 `resolveTarget` 处理 provider 特定的规范化回退,而不是进行广泛的目录搜索。
-- 将 chat id、thread id、JID、handle 和 room
- id 等 provider 原生 id 保留在 `target` 值或 provider 特定参数中,而不是放在通用 SDK
- 字段里。
+- 对于应在搜索联系人/群组之前发生的类别决策,使用 `inferTargetChatType`。
+- 对于“将此视为显式/原生目标 id”的检查,使用 `looksLikeId`。
+- 对于特定于提供商的规范化回退,使用 `resolveTarget`,而不是用于宽泛的目录搜索。
+- 将 chat id、thread id、JID、handle 和 room id 等提供商原生 id 放在 `target` 值或提供商特定参数中,而不是放入通用 SDK 字段。
## 基于配置的目录
-如果插件从配置派生目录条目,应将该逻辑保留在插件中,
-并复用 `openclaw/plugin-sdk/directory-runtime`
-中的共享辅助工具。
+如果插件从配置派生目录条目,应将该逻辑保留在插件中,并复用
+`openclaw/plugin-sdk/directory-runtime` 中的共享辅助工具。
-适用场景包括某个渠道需要基于配置的 peers/groups,例如:
+当某个渠道需要基于配置的联系人/群组时,请使用此方式,例如:
-- 基于 allowlist 的私信 peers
+- 由 allowlist 驱动的私信联系人
- 已配置的渠道/群组映射
-- 基于账户范围的静态目录回退
+- 按账户范围的静态目录回退
`directory-runtime` 中的共享辅助工具只处理通用操作:
- 查询过滤
-- 限制项应用
+- 限制应用
- 去重/规范化辅助工具
- 构建 `ChannelDirectoryEntry[]`
-渠道特定的账户检查和 id 规范化应保留在插件实现中。
+特定于渠道的账户检查和 id 规范化应保留在插件实现中。
-## provider 目录
+## 提供商目录
-Provider 插件可以通过
+提供商插件可以通过
`registerProvider({ catalog: { run(...) { ... } } })` 定义用于推理的模型目录。
-`catalog.run(...)` 返回的形态与 OpenClaw 写入
-`models.providers` 的内容相同:
+`catalog.run(...)` 返回与 OpenClaw 写入 `models.providers` 相同的形态:
-- `{ provider }` 表示一个 provider 条目
-- `{ providers }` 表示多个 provider 条目
+- `{ provider }` 表示一个提供商条目
+- `{ providers }` 表示多个提供商条目
-当插件拥有 provider 特定的模型 id、基础 URL 默认值或受身份验证保护的模型元数据时,应使用 `catalog`。
+当插件拥有特定于提供商的模型 id、base URL 默认值或受认证保护的模型元数据时,请使用 `catalog`。
-`catalog.order` 控制插件目录相对于 OpenClaw
-内置隐式 providers 的合并时机:
+`catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机:
-- `simple`:纯 API 密钥或环境变量驱动的 providers
-- `profile`:认证配置文件存在时出现的 providers
-- `paired`:合成多个相关 provider 条目的 providers
-- `late`:最后一轮,在其他隐式 providers 之后
+- `simple`:普通 API 密钥或环境变量驱动的提供商
+- `profile`:当存在认证配置文件时出现的提供商
+- `paired`:合成多个相关提供商条目的提供商
+- `late`:最后一轮,在其他隐式提供商之后
-后出现的 provider 会在键冲突时胜出,因此插件可以有意用相同 provider id
-覆盖内置 provider 条目。
+后出现的提供商会在键冲突时胜出,因此插件可以有意使用相同的提供商 id 覆盖内置提供商条目。
兼容性:
@@ -684,30 +623,28 @@ Provider 插件可以通过
## 只读渠道检查
-如果你的插件注册了一个渠道,优先同时实现
-`plugin.config.inspectAccount(cfg, accountId)` 和 `resolveAccount(...)`。
+如果你的插件注册了一个渠道,建议在实现 `resolveAccount(...)` 的同时实现
+`plugin.config.inspectAccount(cfg, accountId)`。
原因:
-- `resolveAccount(...)` 是运行时路径。它可以假定凭证
- 已完全实体化,并在缺少必需 secret 时快速失败。
-- 只读命令路径,例如 `openclaw status`、`openclaw status --all`、
- `openclaw channels status`、`openclaw channels resolve`,以及 Doctor/配置
- 修复流程,不应仅为了描述配置就去实体化运行时凭证。
+- `resolveAccount(...)` 是运行时路径。它可以假设凭证已经被完全实体化,并在缺少必需密钥时快速失败。
+- `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"`(以及对应的来源字段)就足以支持 Status 风格命令。
+- 当凭证通过 SecretRef 配置但在当前命令路径中不可用时,使用 `configured_unavailable`。
-这样,只读命令就可以报告“已配置,但在当前命令路径中不可用”,而不是崩溃或错误地将账户报告为未配置。
+这样,只读命令就能报告“已配置,但在此命令路径中不可用”,而不会崩溃或错误地将账户报告为未配置。
## 软件包打包集
@@ -724,57 +661,51 @@ Provider 插件可以通过
```
每个条目都会成为一个插件。如果该打包集列出多个扩展,插件 id
-会变成 `name/`。
+会变为 `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` 构建的软件包。
可选项:`openclaw.setupEntry` 可以指向一个轻量级的仅设置模块。
-当 OpenClaw 需要为已禁用的渠道插件提供设置表面时,或者
-当某个渠道插件已启用但仍未配置时,它会加载 `setupEntry`
-而不是完整插件入口。这样当主插件入口还会接入工具、钩子或其他仅运行时代码时,就能让启动和设置更轻量。
+当 OpenClaw 需要为已禁用的渠道插件提供设置表面,或者某个渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整插件入口。
+当你的主插件入口还会接线工具、钩子或其他仅运行时代码时,这可以让启动和设置更轻量。
可选项:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen`
-可以让某个渠道插件在 Gateway 网关
-监听前启动阶段中也选择同样的 `setupEntry` 路径,即使该渠道已经配置完成。
+可以让某个渠道插件在 Gateway 网关预监听启动阶段也选择相同的 `setupEntry`
+路径,即使该渠道已经完成配置。
-只有当 `setupEntry` 完整覆盖了网关开始监听之前必须存在的启动表面时,才使用此选项。实际上,这意味着设置入口
-必须注册启动所依赖的每个渠道自有能力,例如:
+只有当 `setupEntry` 完整覆盖了 Gateway 网关开始监听前必须存在的启动表面时,才应使用此项。
+在实践中,这意味着设置入口必须注册启动所依赖的每一项渠道自有能力,例如:
- 渠道注册本身
-- 任何必须在网关开始监听前可用的 HTTP 路由
+- 任何必须在 Gateway 网关开始监听前可用的 HTTP 路由
- 任何必须在同一时间窗口内存在的 Gateway 网关方法、工具或服务
-如果你的完整入口仍然拥有任何必需的启动能力,请不要启用
-此标志。保持插件使用默认行为,让 OpenClaw 在启动期间加载完整入口。
+如果你的完整入口仍然拥有任何必需的启动能力,请不要启用此标志。
+保持插件使用默认行为,并让 OpenClaw 在启动期间加载完整入口。
-内置渠道还可以发布仅设置阶段的契约表面辅助工具,供 core 在完整渠道运行时尚未加载前查询。当前的设置提升表面包括:
+内置渠道还可以发布仅设置的契约表面辅助工具,供核心在完整渠道运行时加载之前查询。当前的设置提升表面包括:
- `singleAccountKeysToMove`
- `namedAccountPromotionKeys`
- `resolveSingleAccountPromotionTarget(...)`
-当 core 需要在不加载完整插件入口的情况下,将旧版单账户渠道
-配置提升到 `channels..accounts.*` 时,会使用该表面。
-Matrix 是当前的内置示例:当已存在命名账户时,它只会将身份验证/引导键移动到
-一个已命名的提升账户中,并且可以保留一个已配置的非规范默认账户键,而不是总是创建
-`accounts.default`。
+当核心需要在不加载完整插件入口的情况下,将旧版单账户渠道配置提升到
+`channels..accounts.*` 时,就会使用这个表面。
+Matrix 是当前的内置示例:当命名账户已经存在时,它只会把认证/引导键移动到某个已命名的提升账户中;并且它可以保留已配置的非规范默认账户键,而不是总是创建 `accounts.default`。
-这些设置补丁适配器让内置契约表面发现保持懒加载。
-导入时保持轻量;提升表面只在首次使用时加载,
-而不会在模块导入时重新进入内置渠道启动流程。
+这些设置补丁适配器使内置契约表面发现保持惰性。导入时保持轻量;提升表面只会在首次使用时加载,而不是在模块导入时重新进入内置渠道启动流程。
-当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在
-插件特定的前缀下。Core 管理命名空间(`config.*`、
+当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在插件专用前缀下。
+核心管理命名空间(`config.*`、
`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为
-`operator.admin`,即使插件请求更窄的作用域也是如此。
+`operator.admin`,即使某个插件请求更窄的作用域也是如此。
示例:
@@ -793,7 +724,8 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会将身
### 渠道目录元数据
-渠道插件可以通过 `openclaw.channel` 声明设置/发现元数据,并通过 `openclaw.install` 声明安装提示。这样可以让 core 目录保持无数据。
+渠道插件可以通过 `openclaw.channel` 发布设置/发现元数据,并通过
+`openclaw.install` 发布安装提示。这样可以让核心目录保持无数据化。
示例:
@@ -805,10 +737,10 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会将身
"channel": {
"id": "nextcloud-talk",
"label": "Nextcloud Talk",
- "selectionLabel": "Nextcloud Talk(自托管)",
+ "selectionLabel": "Nextcloud Talk(self-hosted)",
"docsPath": "/channels/nextcloud-talk",
"docsLabel": "nextcloud-talk",
- "blurb": "通过 Nextcloud Talk webhook 机器人提供自托管聊天。",
+ "blurb": "通过 Nextcloud Talk webhook 机器人提供 self-hosted 聊天。",
"order": 65,
"aliases": ["nc-talk", "nc"]
},
@@ -821,66 +753,38 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会将身
}
```
-除最小示例外,有用的 `openclaw.channel` 字段还包括:
+除最小示例外,还有一些有用的 `openclaw.channel` 字段:
-- `detailLabel`:用于更丰富目录/状态表面的次级标签
+- `detailLabel`:用于更丰富目录/Status 表面的次级标签
- `docsLabel`:覆盖文档链接的链接文本
-- `preferOver`:该目录条目应优先于的低优先级插件/渠道 id
+- `preferOver`:此目录条目应优先于的较低优先级插件/渠道 id
- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面文案控制
-- `markdownCapable`:将该渠道标记为支持 Markdown,以便进行 outbound 格式决策
-- `exposure.configured`:设置为 `false` 时,在已配置渠道列表表面中隐藏该渠道
-- `exposure.setup`:设置为 `false` 时,在交互式设置/配置选择器中隐藏该渠道
-- `exposure.docs`:将该渠道标记为内部/私有,用于文档导航表面
+- `markdownCapable`:将该渠道标记为支持 Markdown,以供出站格式化决策使用
+- `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"` 键的旧别名。
-生成的渠道目录条目和 provider 安装目录条目会在原始 `openclaw.install` 块旁边暴露
-规范化后的安装来源事实。这些
-规范化事实可标识 npm 规范是否为精确版本或浮动选择器、
-是否存在预期完整性元数据,以及是否还提供本地
-来源路径。当目录/软件包标识已知时,规范化事实还会在
-解析得到的 npm 软件包名与该标识不一致时发出警告。
-如果 `defaultChoice` 无效、指向不可用来源,或存在 npm 完整性元数据
-却没有有效的 npm 来源,它们也会发出警告。使用方应将 `installSource`
-视为附加的可选字段,这样旧的手工构建条目和兼容 shim 就不必合成它。
-这使得新手引导和诊断可以解释来源层状态,而无需
-导入插件运行时。
+生成的渠道目录条目和提供商安装目录条目,会在原始 `openclaw.install` 块旁边暴露规范化后的安装源事实。这些规范化事实可标识 npm 规格是否为精确版本或浮动选择器、是否存在预期的完整性元数据,以及是否也存在本地源路径。当目录/软件包标识已知时,这些规范化事实会在解析出的 npm 软件包名称偏离该标识时给出警告。它们还会在 `defaultChoice` 无效、指向不可用源,或存在 npm 完整性元数据但没有有效 npm 源时给出警告。使用方应将 `installSource` 视为一个附加的可选字段,这样较旧的手工构建条目和兼容性垫片就不必合成它。这使新手引导和诊断能够在不导入插件运行时的情况下解释源平面状态。
-官方外部 npm 条目应优先使用精确的 `npmSpec` 加上
-`expectedIntegrity`。仅使用裸软件包名和 dist-tag 为兼容性仍然有效,
-但它们会暴露来源层警告,以便目录可以逐步转向固定版本、带完整性检查的安装,
-同时不破坏现有插件。
-当新手引导从本地目录路径安装时,它会记录一条托管插件
-安装账本条目,带有 `source: "path"`,并在可能时记录相对工作区的
-`sourcePath`。绝对的实际加载路径仍保留在
-`plugins.load.paths` 中;安装记录会避免将本地工作站路径重复写入长期配置。
-这样可以让本地开发安装对来源层诊断保持可见,同时不增加第二个原始文件系统路径暴露表面。
-旧版 `plugins.installs` 配置条目仍会作为
-兼容性回退继续读取,而状态管理的 `plugins/installs.json` 账本
-会成为安装来源的事实来源。
+官方外部 npm 条目应优先使用精确的 `npmSpec` 加 `expectedIntegrity`。为了兼容性,裸软件包名和 dist-tag 仍然可用,但它们会暴露源平面警告,以便目录能够逐步转向固定版本、带完整性校验的安装,而不会破坏现有插件。当新手引导从本地目录路径安装时,它会记录一条受管插件安装台账条目,使用 `source: "path"`,并在可能时记录相对于工作区的 `sourcePath`。绝对的操作加载路径仍保留在 `plugins.load.paths` 中;安装记录会避免将本地工作站路径重复写入长期配置。这使本地开发安装能被源平面诊断看到,同时又不会新增第二个原始文件系统路径暴露表面。旧版 `plugins.installs` 配置条目仍会作为兼容性回退被读取,而状态管理的 `plugins/installs.json` 台账将成为安装源的事实来源。`openclaw doctor --fix` 会将这些旧版配置条目迁移到受管台账中,并在不加载插件运行时模块的情况下刷新冷注册表索引。
## 上下文引擎插件
-上下文引擎插件负责会话上下文编排,包括摄取、组装
-和压缩。可通过你的插件使用
-`api.registerContextEngine(id, factory)` 注册它们,然后通过
-`plugins.slots.contextEngine` 选择活动引擎。
+上下文引擎插件负责会话上下文编排,包括摄取、组装和压缩。请在你的插件中通过 `api.registerContextEngine(id, factory)` 注册它们,然后使用 `plugins.slots.contextEngine` 选择活动引擎。
-当你的插件需要替换或扩展默认上下文
-管线,而不仅仅是添加 memory 搜索或钩子时,请使用此方式。
+当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加 Memory Wiki 搜索或钩子时,请使用此方式。
```ts
import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
@@ -908,8 +812,7 @@ export default function (api) {
}
```
-如果你的引擎**不**拥有压缩算法,请保持 `compact()`
-已实现,并显式委托它:
+如果你的引擎**不**拥有压缩算法,请保留 `compact()` 的实现,并显式委托出去:
```ts
import {
@@ -944,44 +847,41 @@ export default function (api) {
}
```
-## 添加新能力
+## 添加新的能力
-当插件需要当前 API 无法适配的行为时,不要通过私有方式绕过
-插件系统。应添加缺失的能力。
+当插件需要当前 API 无法容纳的行为时,不要通过私有直连绕过插件系统。应添加缺失的能力。
推荐顺序:
-1. 定义 core 契约
- 决定共享行为中哪些应由 core 拥有:策略、回退、配置合并、
- 生命周期、面向渠道的语义,以及运行时辅助工具形态。
-2. 添加类型化的插件注册/运行时表面
- 用最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和/或 `api.runtime`。
-3. 接入 core + 渠道/功能使用方
- 渠道和功能插件应通过 core 消费新能力,
+1. 定义核心契约
+ 决定哪些共享行为应由核心负责:策略、回退、配置合并、
+ 生命周期、面向渠道的语义和运行时辅助工具形态。
+2. 添加类型化的插件注册/运行时表面
+ 用最小但足够有用的类型化能力表面扩展 `OpenClawPluginApi` 和/或 `api.runtime`。
+3. 接线核心 + 渠道/功能使用方
+ 渠道和功能插件应通过核心消费这项新能力,
而不是直接导入某个供应商实现。
-4. 注册供应商实现
- 然后由供应商插件将其后端注册到该能力上。
-5. 添加契约覆盖
- 添加测试,以便随着时间推移,所有权和注册形态仍保持明确。
+4. 注册供应商实现
+ 然后由供应商插件针对该能力注册它们的后端。
+5. 添加契约覆盖
+ 添加测试,使归属和注册形态随着时间推移仍然保持明确。
-这正是 OpenClaw 能保持鲜明主张、同时又不被硬编码到某个
-provider 世界观中的方式。有关具体的文件检查清单和完整示例,请参见 [能力扩展手册](/zh-CN/plugins/architecture)。
+这正是 OpenClaw 在保持明确设计主张的同时,又不被硬编码到某一家提供商世界观中的方式。关于具体的文件清单和完整示例,请参阅 [能力扩展手册](/zh-CN/plugins/architecture)。
### 能力检查清单
-当你添加新能力时,实现通常应同时涉及以下表面:
+当你添加新的能力时,实现通常应同时涉及这些表面:
-- `src//types.ts` 中的 core 契约类型
-- `src//runtime.ts` 中的 core 运行器/运行时辅助工具
+- `src//types.ts` 中的核心契约类型
+- `src//runtime.ts` 中的核心运行器/运行时辅助工具
- `src/plugins/types.ts` 中的插件 API 注册表面
- `src/plugins/registry.ts` 中的插件注册表接线
-- 当功能/渠道插件需要消费该能力时,`src/plugins/runtime/*` 中的插件运行时暴露
+- 当功能/渠道插件需要消费它时,位于 `src/plugins/runtime/*` 中的插件运行时暴露
- `src/test-utils/plugin-registration.ts` 中的捕获/测试辅助工具
-- `src/plugins/contracts/registry.ts` 中的所有权/契约断言
-- `docs/` 中面向运维者/插件作者的文档
+- `src/plugins/contracts/registry.ts` 中的归属/契约断言
+- `docs/` 中面向运维/插件的文档
-如果其中某个表面缺失,通常说明该能力
-尚未完全集成。
+如果其中某个表面缺失,通常意味着这项能力还没有完全集成。
### 能力模板
@@ -1017,16 +917,16 @@ const clip = await api.runtime.videoGeneration.generate({
expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]);
```
-这样规则就很简单:
+这让规则保持简单:
-- core 拥有能力契约 + 编排
+- 核心拥有能力契约 + 编排
- 供应商插件拥有供应商实现
- 功能/渠道插件消费运行时辅助工具
-- 契约测试使所有权保持明确
+- 契约测试保持归属明确
## 相关内容
-- [插件架构](/zh-CN/plugins/architecture) —— 公开能力模型和形态
+- [插件架构](/zh-CN/plugins/architecture) — 公共能力模型和形态
- [插件 SDK 子路径](/zh-CN/plugins/sdk-subpaths)
- [插件 SDK 设置](/zh-CN/plugins/sdk-setup)
- [构建插件](/zh-CN/plugins/building-plugins)
diff --git a/docs/zh-CN/tools/plugin.md b/docs/zh-CN/tools/plugin.md
index 0ff492e3a..2591e41ac 100644
--- a/docs/zh-CN/tools/plugin.md
+++ b/docs/zh-CN/tools/plugin.md
@@ -1,26 +1,26 @@
---
read_when:
- 安装或配置插件
- - 了解插件发现与加载规则
+ - 了解插件发现和加载规则
- 使用与 Codex/Claude 兼容的插件包
sidebarTitle: Install and Configure
summary: 安装、配置和管理 OpenClaw 插件
title: 插件
x-i18n:
- generated_at: "2026-04-25T17:39:05Z"
+ generated_at: "2026-04-25T19:49:10Z"
model: gpt-5.4
provider: openai
- source_hash: 82e272b1b59006b1f40b4acc3f21a8bca8ecacc1a8b7fb577ad3d874b9a8e326
+ source_hash: bbc819fc29f0bf58fce83223e43e2ddba3f199c71c6536e900ac6032f181d770
source_path: tools/plugin.md
workflow: 15
---
-插件通过新增功能来扩展 OpenClaw:渠道、模型提供商、智能体 harness、工具、Skills、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索等。有些插件是 **核心** 插件(随 OpenClaw 一起提供),另一些则是 **外部** 插件(由社区发布到 npm)。
+插件通过新增能力来扩展 OpenClaw:渠道、模型提供商、智能体 harness、工具、Skills、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索等。有些插件是**核心**插件(随 OpenClaw 一起发布),另一些是**外部**插件(由社区发布到 npm)。
## 快速开始
-
+
```bash
openclaw plugins list
```
@@ -28,10 +28,10 @@ x-i18n:
```bash
- # 来自 npm
+ # 从 npm
openclaw plugins install @openclaw/voice-call
- # 来自本地目录或归档文件
+ # 从本地目录或归档文件
openclaw plugins install ./my-plugin
openclaw plugins install ./my-plugin.tgz
```
@@ -48,7 +48,7 @@ x-i18n:
-如果你更喜欢聊天原生控制,启用 `commands.plugins: true` 并使用:
+如果你更喜欢聊天原生控制方式,请启用 `commands.plugins: true`,然后使用:
```text
/plugin install clawhub:@openclaw/voice-call
@@ -56,16 +56,11 @@ x-i18n:
/plugin enable voice-call
```
-安装路径使用与 CLI 相同的解析器:本地路径/归档文件、显式 `clawhub:`,或裸包说明符(优先 ClawHub,其次回退到 npm)。
+安装路径使用与 CLI 相同的解析器:本地路径/归档文件、显式 `clawhub:`,或裸包说明符(优先 ClawHub,然后回退到 npm)。
-如果配置无效,安装通常会以失败关闭的方式结束,并提示你使用
-`openclaw doctor --fix`。唯一的恢复例外是一条受限的内置插件重装路径,适用于选择加入
-`openclaw.install.allowInvalidConfigRecovery` 的插件。
+如果配置无效,安装通常会以失败关闭的方式结束,并指引你运行 `openclaw doctor --fix`。唯一的恢复例外是一个范围很窄的内置插件重新安装路径,适用于选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件。
-打包后的 OpenClaw 安装不会急切安装每个内置插件的运行时依赖树。当某个 OpenClaw 自带的内置插件因插件配置、旧版渠道配置或默认启用的清单而处于活跃状态时,启动过程只会在导入它之前修复该插件声明的运行时依赖。显式禁用仍然优先:`plugins.entries..enabled: false`、
-`plugins.deny`、`plugins.enabled: false` 和 `channels..enabled: false`
-都会阻止对该插件/渠道自动执行内置运行时依赖修复。外部插件和自定义加载路径仍必须通过
-`openclaw plugins install` 安装。
+打包后的 OpenClaw 安装不会急切地安装每个内置插件的完整运行时依赖树。当某个 OpenClaw 自有的内置插件因插件配置、旧版渠道配置或默认启用的清单而处于激活状态时,启动流程只会在导入该插件之前修复它声明的运行时依赖。显式禁用仍然优先生效:`plugins.entries..enabled: false`、`plugins.deny`、`plugins.enabled: false` 和 `channels..enabled: false` 都会阻止该插件/渠道自动执行内置运行时依赖修复。外部插件和自定义加载路径仍必须通过 `openclaw plugins install` 安装。
## 插件类型
@@ -76,10 +71,9 @@ OpenClaw 可识别两种插件格式:
| **原生** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 包 |
| **Bundle** | 与 Codex/Claude/Cursor 兼容的布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` |
-两者都会显示在 `openclaw plugins list` 中。关于 bundle 的详细信息,请参见 [插件包](/zh-CN/plugins/bundles)。
+两者都会显示在 `openclaw plugins list` 中。有关 bundle 的详细信息,请参见 [Plugin Bundles](/zh-CN/plugins/bundles)。
-如果你正在编写原生插件,请从 [构建插件](/zh-CN/plugins/building-plugins)
-和 [插件 SDK 概览](/zh-CN/plugins/sdk-overview) 开始。
+如果你正在编写原生插件,请从 [构建插件](/zh-CN/plugins/building-plugins) 和 [插件 SDK 概览](/zh-CN/plugins/sdk-overview) 开始。
## 官方插件
@@ -94,33 +88,33 @@ OpenClaw 可识别两种插件格式:
| Zalo | `@openclaw/zalo` | [Zalo](/zh-CN/channels/zalo) |
| Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/zh-CN/plugins/zalouser) |
-### 核心(随 OpenClaw 一起提供)
+### 核心(随 OpenClaw 一起发布)
- `anthropic`, `byteplus`, `cloudflare-ai-gateway`, `github-copilot`, `google`,
- `huggingface`, `kilocode`, `kimi-coding`, `minimax`, `mistral`, `qwen`,
- `moonshot`, `nvidia`, `openai`, `opencode`, `opencode-go`, `openrouter`,
- `qianfan`, `synthetic`, `together`, `venice`,
- `vercel-ai-gateway`, `volcengine`, `xiaomi`, `zai`
+ `anthropic`、`byteplus`、`cloudflare-ai-gateway`、`github-copilot`、`google`、
+ `huggingface`、`kilocode`、`kimi-coding`、`minimax`、`mistral`、`qwen`、
+ `moonshot`、`nvidia`、`openai`、`opencode`、`opencode-go`、`openrouter`、
+ `qianfan`、`synthetic`、`together`、`venice`、
+ `vercel-ai-gateway`、`volcengine`、`xiaomi`、`zai`
-
- - `memory-core` — 内置的内存搜索(默认通过 `plugins.slots.memory` 启用)
- - `memory-lancedb` — 按需安装的长期记忆,带自动召回/捕获功能(设置 `plugins.slots.memory = "memory-lancedb"`)
+
+ - `memory-core` — 内置内存搜索(通过 `plugins.slots.memory` 默认使用)
+ - `memory-lancedb` — 按需安装的长期内存,带自动召回/捕获功能(设置 `plugins.slots.memory = "memory-lancedb"`)
- `elevenlabs`, `microsoft`
+ `elevenlabs`、`microsoft`
- `browser` — 用于浏览器工具、`openclaw browser` CLI、`browser.request` Gateway 网关方法、浏览器运行时以及默认浏览器控制服务的内置浏览器插件(默认启用;替换前请先禁用)
- - `copilot-proxy` — VS Code Copilot Proxy 桥接(默认禁用)
+ - `copilot-proxy` — VS Code Copilot Proxy 桥接器(默认禁用)
-在找第三方插件?请参见 [社区插件](/zh-CN/plugins/community)。
+在找第三方插件?请参见 [Community Plugins](/zh-CN/plugins/community)。
## 配置
@@ -144,23 +138,22 @@ OpenClaw 可识别两种插件格式:
| `allow` | 插件允许列表(可选) |
| `deny` | 插件拒绝列表(可选;拒绝优先) |
| `load.paths` | 额外的插件文件/目录 |
-| `slots` | 排他性插槽选择器(例如 `memory`、`contextEngine`) |
-| `entries.\` | 按插件划分的开关 + 配置 |
+| `slots` | 独占插槽选择器(例如 `memory`、`contextEngine`) |
+| `entries.\` | 每个插件的开关和配置 |
-配置更改 **需要重启网关**。如果 Gateway 网关在启用了配置监听和进程内重启的情况下运行(默认的 `openclaw gateway` 路径),那么在配置写入完成后,通常会自动稍后执行该重启。目前不支持对原生插件运行时代码或生命周期钩子的热重载;在期望更新后的 `register(api)` 代码、`api.on(...)` 钩子、工具、服务或提供商/运行时钩子生效之前,请重启为实时渠道提供服务的 Gateway 网关进程。
+配置更改**需要重启 Gateway 网关**。如果 Gateway 网关正在以启用配置监视和进程内重启的方式运行(默认的 `openclaw gateway` 路径),那么在配置写入完成后,通常会在片刻之后自动执行重启。原生插件运行时代码或生命周期钩子没有受支持的热重载路径;在期待更新后的 `register(api)` 代码、`api.on(...)` 钩子、工具、服务或提供商/运行时钩子生效之前,请重启提供实时渠道服务的 Gateway 网关进程。
-`openclaw plugins list` 是本地插件注册表/配置快照。那里显示为
-`enabled` 的插件表示持久化注册表和当前配置允许该插件参与运行。这并不能证明一个已经运行中的远程 Gateway 网关子进程已经重启并加载了相同的插件代码。在 VPS/容器部署中,如果存在包装进程,请把重启信号发给实际的 `openclaw gateway run` 进程,或针对正在运行的 Gateway 网关使用 `openclaw gateway restart`。
+`openclaw plugins list` 是本地插件注册表/配置快照。其中的 `enabled` 插件表示持久化注册表和当前配置允许该插件参与运行。但这并不能证明一个已经运行的远程 Gateway 网关子进程已经重启并加载了相同的插件代码。在 VPS/容器部署中,如果使用了包装进程,请向实际的 `openclaw gateway run` 进程发送重启信号,或对正在运行的 Gateway 网关使用 `openclaw gateway restart`。
- **已禁用**:插件存在,但启用规则将其关闭。配置会被保留。
- - **缺失**:配置引用了某个插件 id,但设备发现未找到它。
+ - **缺失**:配置引用了某个插件 id,但发现流程没有找到它。
- **无效**:插件存在,但其配置与声明的 schema 不匹配。
## 发现顺序和优先级
-OpenClaw 按以下顺序扫描插件(先匹配者生效):
+OpenClaw 按以下顺序扫描插件(先匹配者优先):
@@ -176,7 +169,7 @@ OpenClaw 按以下顺序扫描插件(先匹配者生效):
- 随 OpenClaw 一起提供。许多默认启用(模型提供商、语音)。
+ 随 OpenClaw 一起发布。许多默认启用(模型提供商、语音)。
其他则需要显式启用。
@@ -186,51 +179,50 @@ OpenClaw 按以下顺序扫描插件(先匹配者生效):
- `plugins.enabled: false` 会禁用所有插件
- `plugins.deny` 始终优先于 allow
- `plugins.entries.\.enabled: false` 会禁用该插件
-- 来源于工作区的插件 **默认禁用**(必须显式启用)
+- 来自工作区的插件**默认禁用**(必须显式启用)
- 内置插件遵循内建的默认启用集合,除非被覆盖
-- 排他性插槽可以强制启用为该插槽选定的插件
-- 某些选择加入的内置插件会在配置命名了某个插件拥有的表面时自动启用,例如提供商模型引用、渠道配置或 harness 运行时
-- OpenAI 系列的 Codex 路由保持独立的插件边界:
+- 独占插槽可以为该插槽强制启用所选插件
+- 一些选择加入的内置插件会在配置命名了某个插件自有的表面时自动启用,例如提供商模型引用、渠道配置或 harness 运行时
+- OpenAI 系列 Codex 路由保持独立的插件边界:
`openai-codex/*` 属于 OpenAI 插件,而内置的 Codex
app-server 插件则通过 `embeddedHarness.runtime: "codex"` 或旧版
`codex/*` 模型引用来选择
## 运行时钩子故障排除
-如果某个插件出现在 `plugins list` 中,但 `register(api)` 的副作用或钩子在实时聊天流量中没有运行,请先检查以下内容:
+如果某个插件出现在 `plugins list` 中,但 `register(api)` 的副作用或钩子没有在实时聊天流量中运行,请先检查以下内容:
-- 运行 `openclaw gateway status --deep --require-rpc`,确认当前活跃的
- Gateway 网关 URL、配置文件、配置路径和进程,正是你正在编辑的那些。
+- 运行 `openclaw gateway status --deep --require-rpc`,确认活动的
+ Gateway 网关 URL、profile、配置路径和进程就是你正在编辑的那些。
- 在插件安装/配置/代码更改后重启实时 Gateway 网关。在包装容器中,
- PID 1 可能只是一个监督进程;请重启或发送信号给子进程
- `openclaw gateway run`。
-- 使用 `openclaw plugins inspect --json` 确认钩子注册情况和诊断信息。非内置的会话钩子,如 `llm_input`、
- `llm_output` 和 `agent_end`,需要
+ PID 1 可能只是一个 supervisor;请重启或向子进程
+ `openclaw gateway run` 发送信号。
+- 使用 `openclaw plugins inspect --json` 确认钩子注册和
+ 诊断信息。像 `llm_input`、
+ `llm_output` 和 `agent_end` 这样的非内置会话钩子需要
`plugins.entries..hooks.allowConversationAccess=true`。
-- 对于模型切换,优先使用 `before_model_resolve`。它会在智能体轮次的模型解析之前运行;而 `llm_output` 仅在一次模型尝试产生助手输出后才运行。
-- 要证明生效中的会话模型,请使用 `openclaw sessions` 或
- Gateway 网关的会话/状态表面;在调试提供商负载时,请使用
- `--raw-stream --raw-stream-path ` 启动 Gateway 网关。
+- 对于模型切换,优先使用 `before_model_resolve`。它会在智能体轮次的模型解析之前运行;`llm_output` 只会在某次模型尝试产生助手输出之后运行。
+- 若要证明生效的会话模型,请使用 `openclaw sessions` 或 Gateway 网关的会话/Status 表面;在调试提供商负载时,请使用 `--raw-stream --raw-stream-path ` 启动 Gateway 网关。
-## 插件插槽(排他性类别)
+## 插件插槽(独占类别)
-某些类别是排他的(一次只能有一个处于活跃状态):
+有些类别是独占的(同一时间只能有一个处于活动状态):
```json5
{
plugins: {
slots: {
- memory: "memory-core", // 或 "none" 以禁用
+ memory: "memory-core", // 或使用 "none" 禁用
contextEngine: "legacy", // 或某个插件 id
},
},
}
```
-| 插槽 | 它控制的内容 | 默认值 |
+| 插槽 | 控制内容 | 默认值 |
| --------------- | --------------------- | ------------------- |
-| `memory` | 活跃的内存插件 | `memory-core` |
-| `contextEngine` | 活跃的上下文引擎 | `legacy`(内建) |
+| `memory` | 当前激活的内存插件 | `memory-core` |
+| `contextEngine` | 当前激活的上下文引擎 | `legacy`(内置) |
## CLI 参考
@@ -244,10 +236,11 @@ openclaw plugins inspect --json # 机器可读
openclaw plugins inspect --all # 全局表格
openclaw plugins info # inspect 别名
openclaw plugins doctor # 诊断
-openclaw plugins registry # 查看持久化注册表状态
+openclaw plugins registry # 检查持久化注册表状态
openclaw plugins registry --refresh # 重建持久化注册表
+openclaw doctor --fix # 修复注册表/账本迁移状态
-openclaw plugins install # 安装(优先 ClawHub,其次 npm)
+openclaw plugins install # 安装(优先 ClawHub,然后 npm)
openclaw plugins install clawhub: # 仅从 ClawHub 安装
openclaw plugins install --force # 覆盖现有安装
openclaw plugins install # 从本地路径安装
@@ -259,7 +252,7 @@ openclaw plugins install --dangerously-force-unsafe-install
openclaw plugins update # 更新单个插件
openclaw plugins update --dangerously-force-unsafe-install
openclaw plugins update --all # 更新全部
-openclaw plugins uninstall # 移除配置/安装记录
+openclaw plugins uninstall # 移除配置和安装账本记录
openclaw plugins uninstall --keep-files
openclaw plugins marketplace list
openclaw plugins marketplace list --json
@@ -268,39 +261,34 @@ openclaw plugins enable
openclaw plugins disable
```
-内置插件随 OpenClaw 一起提供。许多默认启用(例如内置模型提供商、内置语音提供商以及内置浏览器插件)。其他内置插件仍然需要使用 `openclaw plugins enable `。
+内置插件随 OpenClaw 一起发布。许多默认启用(例如内置模型提供商、内置语音提供商以及内置浏览器插件)。其他内置插件仍然需要执行 `openclaw plugins enable `。
-`--force` 会就地覆盖现有已安装的插件或 hook 包。对于已跟踪的 npm
-插件的常规升级,请使用 `openclaw plugins update `。
-它不支持与 `--link` 一起使用,因为后者会复用源路径,而不是复制到受管理的安装目标。
+`--force` 会原地覆盖已安装的插件或 hook 包。对于已跟踪 npm 插件的常规升级,请使用 `openclaw plugins update `。它不支持与 `--link` 一起使用,因为 `--link` 会复用源路径,而不是复制到受管理的安装目标。
-当 `plugins.allow` 已经设置时,`openclaw plugins install` 会在启用插件之前,将已安装插件的 id 添加到该允许列表中,因此重启后可立即加载。
+当 `plugins.allow` 已经设置时,`openclaw plugins install` 会先把已安装插件的 id 添加到该允许列表中,然后再启用它,这样重启后安装的插件就能立即被加载。
-OpenClaw 会维护一个持久化的本地插件注册表,将其作为插件清单、贡献归属和启动规划的冷读取模型。安装、更新、卸载、启用和禁用流程会在更改插件状态后刷新该注册表。如果注册表缺失、过期或无效,`openclaw plugins registry --refresh`
-会根据持久安装账本、配置策略以及清单/包元数据重建它,而不会加载插件运行时模块。
+OpenClaw 会维护一个持久化的本地插件注册表,作为插件清单、贡献归属和启动规划的冷读取模型。安装、更新、卸载、启用和禁用流程会在修改插件状态后刷新该注册表。如果注册表缺失、过期或无效,`openclaw plugins registry --refresh` 会在不加载插件运行时模块的前提下,根据持久安装账本、配置策略以及 manifest/package 元数据重建它。
+如果某台机器的配置中仍保留旧版 `plugins.installs` 记录,请运行 `openclaw doctor --fix`,把它们迁移到受管理的 `plugins/installs.json` 账本中,并移除配置里的副本。
-`openclaw plugins update ` 适用于已跟踪的安装。传入带有 dist-tag 或精确版本的 npm 包 spec 时,会将包名解析回已跟踪的插件记录,并为后续更新记录新的 spec。传入不带版本的包名时,会将一个精确固定版本的安装切回注册表的默认发布线。如果已安装的 npm 插件已经匹配解析后的版本和记录的构件标识,OpenClaw 会跳过更新,而不会下载、重新安装或重写配置。
+`openclaw plugins update ` 适用于已跟踪的安装。传入带 dist-tag 或精确版本的 npm 包 spec 时,会把包名解析回已跟踪的插件记录,并为后续更新记录新的 spec。传入不带版本的包名时,会把一个精确固定版本的安装移回注册表的默认发布线。如果已安装的 npm 插件已经匹配解析后的版本和记录的制品标识,OpenClaw 会跳过更新,不会下载、重新安装或重写配置。
`--pin` 仅适用于 npm。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 源元数据,而不是 npm spec。
-`--dangerously-force-unsafe-install` 是一个用于紧急破局的覆盖选项,用于处理内置危险代码扫描器的误报。它允许插件安装和插件更新在内置 `critical` 发现后继续执行,但仍不会绕过插件
-`before_install` 策略拦截或扫描失败拦截。
+`--dangerously-force-unsafe-install` 是一个“破玻璃”式覆盖选项,用于处理内置危险代码扫描器的误报。它允许插件安装和插件更新在内置 `critical` 发现后继续进行,但仍不会绕过插件 `before_install` 策略拦截或扫描失败拦截。
-这个 CLI 标志仅适用于插件安装/更新流程。由 Gateway 网关驱动的 Skills 依赖安装则使用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是独立的 ClawHub Skills 下载/安装流程。
+这个 CLI 标志仅适用于插件安装/更新流程。基于 Gateway 网关的 Skills 依赖安装则改用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是单独的 ClawHub Skills 下载/安装流程。
-兼容的 bundle 会参与相同的插件 list/inspect/enable/disable 流程。当前运行时支持包括 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` 和清单声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录。
+兼容的 bundle 会参与同一套插件 list/inspect/enable/disable 流程。当前运行时支持包括 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` 和 manifest 声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录。
`openclaw plugins inspect ` 还会报告检测到的 bundle 能力,以及由 bundle 支持的或不支持的 MCP 和 LSP 服务器条目。
-Marketplace 源可以是 `~/.claude/plugins/known_marketplaces.json`
-中的 Claude 已知 marketplace 名称、本地 marketplace 根目录或
-`marketplace.json` 路径、像 `owner/repo` 这样的 GitHub 简写、GitHub 仓库 URL,或 git URL。对于远程 marketplace,插件条目必须保留在克隆得到的 marketplace 仓库内部,并且只能使用相对路径源。
+Marketplace 源可以是来自 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知 marketplace 名称、本地 marketplace 根目录或 `marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL,或 git URL。对于远程 marketplace,插件条目必须保持在克隆得到的 marketplace 仓库内部,并且只能使用相对路径源。
完整详情请参见 [`openclaw plugins` CLI 参考](/zh-CN/cli/plugins)。
## 插件 API 概览
-原生插件会导出一个入口对象,并暴露 `register(api)`。较旧的插件仍可能使用 `activate(api)` 作为旧版别名,但新插件应使用 `register`。
+原生插件会导出一个入口对象,并暴露 `register(api)`。旧版插件仍可能使用 `activate(api)` 作为兼容别名,但新插件应使用 `register`。
```typescript
export default definePluginEntry({
@@ -320,19 +308,19 @@ export default definePluginEntry({
});
```
-OpenClaw 会加载入口对象,并在插件激活期间调用 `register(api)`。加载器仍会为旧插件回退到 `activate(api)`,但内置插件和新的外部插件应将 `register` 视为公开契约。
+OpenClaw 会加载这个入口对象,并在插件激活期间调用 `register(api)`。加载器仍会为旧插件回退到 `activate(api)`,但内置插件和新的外部插件都应将 `register` 视为公开契约。
-`api.registrationMode` 会告诉插件其入口为何被加载:
+`api.registrationMode` 会告诉插件,为什么正在加载它的入口:
| 模式 | 含义 |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `full` | 运行时激活。注册工具、钩子、服务、命令、路由以及其他实时副作用。 |
| `discovery` | 只读能力发现。注册提供商和元数据;可信插件入口代码可能会被加载,但应跳过实时副作用。 |
-| `setup-only` | 通过轻量级 setup 入口加载渠道设置元数据。 |
-| `setup-runtime` | 加载渠道设置,同时也需要运行时入口。 |
+| `setup-only` | 通过轻量级 setup 入口加载渠道 setup 元数据。 |
+| `setup-runtime` | 加载渠道 setup,同时还需要运行时入口。 |
| `cli-metadata` | 仅收集 CLI 命令元数据。 |
-那些会打开套接字、数据库、后台 worker 或长生命周期客户端的插件入口,应使用 `api.registrationMode === "full"` 来保护这些副作用。发现加载与激活加载会分别缓存,并且不会替换正在运行的 Gateway 网关注册表。发现过程不会激活,但也不是完全不导入:OpenClaw 可能会执行可信插件入口或渠道插件模块,以构建快照。请保持模块顶层轻量且无副作用,并将网络客户端、子进程、监听器、凭证读取和服务启动移到完整运行时路径之后。
+如果插件入口会打开 socket、数据库、后台 worker 或长生命周期客户端,应使用 `api.registrationMode === "full"` 来保护这些副作用。发现加载与激活加载会分别缓存,且不会替换正在运行的 Gateway 网关注册表。发现流程不会激活,但也不是完全不导入:OpenClaw 可能会执行可信的插件入口或渠道插件模块来构建快照。请保持模块顶层轻量且无副作用,并把网络客户端、子进程、监听器、凭证读取和服务启动移到完整运行时路径之后。
常见注册方法:
@@ -349,33 +337,31 @@ OpenClaw 会加载入口对象,并在插件激活期间调用 `register(api)`
| `registerImageGenerationProvider` | 图像生成 |
| `registerMusicGenerationProvider` | 音乐生成 |
| `registerVideoGenerationProvider` | 视频生成 |
-| `registerWebFetchProvider` | 网页抓取 / 爬取提供商 |
+| `registerWebFetchProvider` | 网页抓取 / 抓取提供商 |
| `registerWebSearchProvider` | 网页搜索 |
| `registerHttpRoute` | HTTP 端点 |
| `registerCommand` / `registerCli` | CLI 命令 |
| `registerContextEngine` | 上下文引擎 |
| `registerService` | 后台服务 |
-类型化生命周期钩子的钩子守卫行为:
+带类型生命周期钩子的钩子保护行为:
-- `before_tool_call`:`{ block: true }` 是终止性的;更低优先级的处理器会被跳过。
-- `before_tool_call`:`{ block: false }` 是空操作,不会清除更早的拦截。
-- `before_install`:`{ block: true }` 是终止性的;更低优先级的处理器会被跳过。
-- `before_install`:`{ block: false }` 是空操作,不会清除更早的拦截。
-- `message_sending`:`{ cancel: true }` 是终止性的;更低优先级的处理器会被跳过。
-- `message_sending`:`{ cancel: false }` 是空操作,不会清除更早的取消。
+- `before_tool_call`:`{ block: true }` 为终止结果;会跳过更低优先级的处理器。
+- `before_tool_call`:`{ block: false }` 是无操作,不会清除更早的拦截结果。
+- `before_install`:`{ block: true }` 为终止结果;会跳过更低优先级的处理器。
+- `before_install`:`{ block: false }` 是无操作,不会清除更早的拦截结果。
+- `message_sending`:`{ cancel: true }` 为终止结果;会跳过更低优先级的处理器。
+- `message_sending`:`{ cancel: false }` 是无操作,不会清除更早的取消结果。
-原生 Codex app-server 运行时会将桥接的 Codex 原生工具事件回送到这个钩子表面。插件可以通过 `before_tool_call` 拦截原生 Codex 工具,通过 `after_tool_call` 观察结果,并参与 Codex
-`PermissionRequest` 批准。该桥接目前还不会改写 Codex 原生工具参数。精确的 Codex 运行时支持边界位于
-[Codex harness v1 支持契约](/zh-CN/plugins/codex-harness#v1-support-contract)。
+原生 Codex app-server 运行时会把 bridge Codex 原生工具事件回传到这个钩子表面。插件可以通过 `before_tool_call` 拦截原生 Codex 工具,通过 `after_tool_call` 观察结果,并参与 Codex `PermissionRequest` 审批。这个 bridge 目前还不会重写 Codex 原生工具参数。精确的 Codex 运行时支持边界定义在 [Codex harness v1 支持契约](/zh-CN/plugins/codex-harness#v1-support-contract) 中。
-关于完整的类型化钩子行为,请参见 [SDK 概览](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。
+有关完整的类型化钩子行为,请参见 [SDK 概览](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。
## 相关内容
- [构建插件](/zh-CN/plugins/building-plugins) — 创建你自己的插件
-- [插件包](/zh-CN/plugins/bundles) — Codex/Claude/Cursor bundle 兼容性
-- [插件清单](/zh-CN/plugins/manifest) — 清单 schema
+- [Plugin Bundles](/zh-CN/plugins/bundles) — 与 Codex/Claude/Cursor bundle 的兼容性
+- [Plugin manifest](/zh-CN/plugins/manifest) — manifest schema
- [注册工具](/zh-CN/plugins/building-plugins#registering-agent-tools) — 在插件中添加智能体工具
- [插件内部机制](/zh-CN/plugins/architecture) — 能力模型和加载流水线
-- [社区插件](/zh-CN/plugins/community) — 第三方列表
+- [Community Plugins](/zh-CN/plugins/community) — 第三方列表