chore(i18n): refresh zh-CN translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-24 16:02:57 +00:00
parent fc95f16c53
commit d4178444d1
2 changed files with 497 additions and 444 deletions

View File

@ -1,64 +1,68 @@
---
read_when:
- 实现提供商运行时钩子、渠道生命周期或软件包包
- 实现提供商运行时钩子、渠道生命周期或软件包包集
- 调试插件加载顺序或注册表状态
- 添加新的插件能力或上下文引擎插件
summary: 插件架构内部机制:加载线、注册表、运行时钩子、HTTP 路由和参考表
summary: 插件架构内部机制:加载流水线、注册表、运行时钩子、HTTP 路由和参考表
title: 插件架构内部机制
x-i18n:
generated_at: "2026-04-24T07:36:34Z"
generated_at: "2026-04-24T16:00:08Z"
model: gpt-5.4
provider: openai
source_hash: 9370788c5f986e9205b1108ae633e829edec8890e442a49f80d84bb0098bb393
source_hash: 10120a0e05be6bb414339e83ed846001cfe31b491bd8ce9a4bcf340d4b8186d5
source_path: plugins/architecture-internals.md
workflow: 15
---
对于公共能力模型、插件形状以及所有权/执行契约,请参阅 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考:加载管线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。
关于公开的能力模型、插件形态以及所有权/执行契约,请参阅 [Plugin architecture](/zh-CN/plugins/architecture)。本页是内部机制的参考文档:加载流水线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。
## 加载线
## 加载流水线
启动时OpenClaw 大致会这样做
在启动时OpenClaw 大致会执行以下步骤
1. 发现候选插件根目录
2. 读取原生或兼容 bundle 清单以及 package 元数据
2. 读取原生或兼容打包的清单和包元数据
3. 拒绝不安全的候选项
4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`
5. 为每个候选项决定是否启用
6. 加载已启用的原生模块:已构建的内置模块使用原生加载器;未构建的原生插件使用 `jiti`
7. 调用原生 `register(api)` 钩子,并将注册内容收集到插件注册表中
7. 调用原生 `register(api)` 钩子,并将注册结果收集到插件注册表中
8. 将注册表暴露给命令/运行时表面
<Note>
`activate``register` 的旧别名——加载器会解析两者中存在的那个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`;新插件优先使用 `register`
`activate``register` 的旧别名——加载器会解析现有的任意一个(`def.register ?? def.activate`),并在同一时机调用。所有内置插件都使用 `register`对于新插件优先使用 `register`
</Note>
安全门禁发生在**运行时执行之前**。当入口逃逸出插件根目录、路径对所有人可写,或对于非内置插件来说路径所有权看起来可疑时,候选项会被阻止。
安全门控发生在运行时执行**之前**。当入口逃逸出插件根目录、路径对所有用户可写,或者对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。
### 清单优先行为
### Manifest-first 行为
清单是控制平面的事实来源。OpenClaw 使用它来:
清单是控制平面的事实来源。OpenClaw 用它来:
- 标识插件
- 发现已声明的渠道/Skills/配置模式或 bundle 能力
- 发现已声明的渠道/Skills/配置模式或打包能力
- 验证 `plugins.entries.<id>.config`
- 增强 Control UI 标签/占位符
- 显示安装/目录元数据
- 在不加载插件运行时的情况下保留轻量激活和设置描述符
- 在不加载插件运行时的情况下保留轻量激活和设置描述符
对于原生插件,运行时模块是数据平面部分。它会注册实际行为,例如钩子、工具、命令或提供商流程。
可选的清单 `activation``setup` 块仍然保留在控制平面。它们只是用于激活规划和设置发现的纯元数据描述符;它们不会替代运行时注册、`register(...)` 或 `setupEntry`。第一批实时激活消费者现在会使用清单中的命令、渠道和提供商提示,在更广泛的注册表具体化之前缩小插件加载范围:
可选的清单 `activation``setup` 区块仍然留在控制平面中。
它们只是用于激活规划和设置发现的元数据描述符;
它们不会替代运行时注册、`register(...)` 或 `setupEntry`
目前首批实时激活消费者会使用清单中的命令、渠道和提供商提示,
在更广泛的注册表具体化之前先缩小插件加载范围:
- CLI 加载会缩小到拥有所请求主命令的插件
- 渠道设置/插件解析会缩小到拥有所请求渠道 id 的插件
- 显式提供商设置/运行时解析会缩小到拥有所请求提供商 id 的插件
激活规划器同时为现有调用方暴露仅 ids 的 API以及为新诊断提供计划 API。计划条目会报告插件为何被选中将显式 `activation.*` 规划器提示与清单所有权回退原因分开,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和钩子。这种原因拆分就是兼容性边界:现有插件元数据仍可继续工作,而新代码可以检测宽泛提示或回退行为,而无需改变运行时加载语义。
激活规划器既为现有调用方暴露仅含 id 的 API也为新的诊断暴露 plan API。Plan 条目会报告某个插件为何被选中,将显式的 `activation.*` 规划器提示与清单所有权回退原因分开,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和钩子。这种原因拆分就是兼容性边界:现有插件元数据仍可继续工作,而新代码可以检测宽泛提示或回退行为,而无需改变运行时加载语义。
设置发现现在优先使用描述符拥有的 id例如 `setup.providers``setup.cliBackends`以便在回退到 `setup-api` 之前先缩小候选插件范围;后者只用于那些仍需要设置时运行时钩子的插件。如果多个已发现的插件声明了相同的规范化设置提供商或 CLI 后端 id则设置查找会拒绝这个有歧义的所有者,而不是依赖发现顺序。
设置发现现在优先使用描述符拥有的 id例如 `setup.providers``setup.cliBackends`,在回退到 `setup-api` 之前先缩小候选插件范围,以兼容仍需要设置阶段运行时钩子的插件。如果多个已发现插件声明了同一个规范化后的设置提供商或 CLI 后端 id设置查找将拒绝这个有歧义的所有者,而不是依赖发现顺序。
### 加载器缓存的内容
### 加载器会缓存什么
OpenClaw 会保留短生命周期的进程内缓存,用于:
@ -66,40 +70,42 @@ 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` 调整缓存窗口。
## 注册表模型
已加载的插件不会直接修改随意的核心全局状态。它们会注册到一个中央插件注册表中。
已加载的插件不会直接修改任意核心全局状态。它们会注册到一个中央插件注册表中。
注册表会跟踪:
- 插件记录(身份、来源、源头、状态、诊断
- 插件记录(标识、来源、起源、状态、诊断信息
- 工具
- 旧版钩子和类型化钩子
- 渠道
- 提供商
- gateway RPC 处理器
- Gateway 网关 RPC 处理器
- HTTP 路由
- CLI 注册器
- 后台服务
- 插件拥有的命令
然后,核心功能会从该注册表中读取,而不是直接与插件模块交互。这样可保持单向加载:
随后,核心功能会从这个注册表读取内容,而不是直接与插件模块交互。这样可保持单向加载:
- 插件模块 -> 注册表注册
- 核心运行时 -> 注册表消费
这种分离对可维护性很重要。意味着大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块编写特殊分支”。
这种分离对可维护性很重要。意味着大多数核心表面只需要一个集成点:“读取注册表”,而不是“为每个插件模块编写特殊分支”。
## 会话绑定回调
绑定会话的插件可以在批结果确定后作出响应。
绑定会话的插件可以在批结果确定后作出响应。
使用 `api.onConversationBindingResolved(...)` 可在绑定请求被批准或拒绝后接收回调:
@ -109,12 +115,12 @@ export default {
register(api) {
api.onConversationBindingResolved(async (event) => {
if (event.status === "approved") {
// 这个插件 + 会话现在已存在一个绑定。
// 现在已存在此插件 + 会话的绑定。
console.log(event.binding?.conversationId);
return;
}
// 请求被拒绝;清任何本地待处理状态。
// 请求被拒绝;清任何本地待处理状态。
console.log(event.request.conversation.conversationId);
});
},
@ -126,81 +132,81 @@ export default {
- `status``"approved"` 或 `"denied"`
- `decision``"allow-once"`、`"allow-always"` 或 `"deny"`
- `binding`:已批准请求的解析后绑定
- `request`:原始请求摘要、detach 提示、发送者 id 和会话元数据
- `request`:原始请求摘要、分离提示、发送者 id 和会话元数据
此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在核心批处理完成后运行。
此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在核心批处理完成后运行。
## 提供商运行时钩子
提供商插件有三层:
- 用于轻量级运行前查找的**清单元数据**`providerAuthEnvVars`、`providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`
- **配置时钩子**`catalog`(旧 `discovery`)以及 `applyConfigDefaults`
- **运行时钩子**40 多个可选钩子,覆盖鉴权、模型解析、流包装、思考级别、重放策略和用量端点。完整列表请参阅 [钩子顺序和用法](#hook-order-and-usage)。
- **清单元数据**,用于低成本的运行时前查找`providerAuthEnvVars`、`providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`
- **配置时钩子**`catalog`(旧 `discovery`)以及 `applyConfigDefaults`
- **运行时钩子**40 多个可选钩子,涵盖认证、模型解析、流包装、思考级别、重放策略和用量端点。完整列表请参见 [钩子顺序和用法](#hook-order-and-usage)。
OpenClaw 仍然负责通用的智能体循环、故障转移、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,无需实现整套自定义推理传输。
OpenClaw 仍然负责通用智能体循环、故障切换、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,因此无需实现整套自定义推理传输。
当提供商具有基于环境变量的凭证,并且你希望通用鉴权/状态/模型选择器路径在不加载插件运行时的情况下就能看到它们时,请使用清单 `providerAuthEnvVars`。当某个提供商 id 应复用另一个提供商 id 的环境变量、auth profiles、配置驱动鉴权以及 API key 新手引导选项时,请使用清单 `providerAuthAliases`。当新手引导/鉴权选择 CLI 表面需要在不加载提供商运行时的情况下知道提供商的 choice id、分组标签和简单单 flag 鉴权接线时,请使用清单 `providerAuthChoices`。将提供商运行时 `envVars` 保留用于面向运维者的提示,例如新手引导标签或 OAuth client-id/client-secret 设置变量。
当提供商具有基于环境变量的凭证,并且通用认证/状态/模型选择器路径需要在不加载插件运行时的情况下感知它们时,请使用清单 `providerAuthEnvVars`。当某个提供商 id 需要复用另一个提供商 id 的环境变量、认证配置文件、基于配置的认证以及 API 密钥新手引导选项时,请使用清单 `providerAuthAliases`。当新手引导/认证选择 CLI 表面需要在不加载提供商运行时的情况下了解该提供商的 choice id、分组标签和简单的单标志认证接线时请使用清单 `providerAuthChoices`。请保留提供商运行时 `envVars`,用于面向运维人员的提示,例如新手引导标签或 OAuth client-id/client-secret 设置变量。
当某个渠道具有由环境变量驱动的鉴权或设置,并且你希望通用 shell 环境变量回退、配置/状态检查或设置提示在不加载渠道运行时的情况下看到它时,请使用清单 `channelEnvVars`
当某个渠道具有由环境变量驱动的认证或设置,并且通用 shell 环境变量回退、配置/状态检查或设置提示需要在不加载渠道运行时的情况下感知它们时,请使用清单 `channelEnvVars`
### 钩子顺序和用法
对于模型/提供商插件OpenClaw 会大致按这个顺序调用钩子。
对于模型/提供商插件OpenClaw 会按以下大致顺序调用钩子。
“何时使用”这一列是快速决策指南。
| # | 钩子 | 作用 | 何时使用 |
| --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers`| 提供商拥有目录或 base URL 默认值 |
| 2 | `applyConfigDefaults` | 在配置具体化期间应用提供商拥有的全局配置默认值 | 默认值依赖于鉴权模式、环境变量或提供商模型家族语义 |
| -- | _(内置模型查找)_ | OpenClaw 会先尝试常规注册表/目录路径 | _(不是插件钩子)_ |
| 3 | `normalizeModelId` | 在查找前规范化旧版或预览 model-id 别名 | 提供商负责在规范模型解析前清理别名 |
| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商家族的 `api` / `baseUrl` | 提供商负责清理同一传输家族中自定义提供商 id 的传输配置 |
| 5 | `normalizeConfig` | 在运行时/提供商解析前规范化 `models.providers.<id>` | 提供商需要将配置清理逻辑保留在插件中;内置的 Google 家族辅助逻辑也会为受支持的 Google 配置条目提供兜底 |
| 6 | `applyNativeStreamingUsageCompat` | 将原生流式用量兼容性重写应用到配置提供商 | 提供商需要基于端点驱动的原生流式用量元数据修复 |
| 7 | `resolveConfigApiKey` | 在加载运行时鉴权之前,为配置提供商解析 env-marker 鉴权 | 提供商具有提供商自有的 env-marker API key 解析逻辑;`amazon-bedrock` 在这里也有一个内置的 AWS env-marker 解析器 |
| 8 | `resolveSyntheticAuth` | 暴露本地/自托管或配置驱动的鉴权,而不持久化明文 | 提供商可以使用合成/本地凭证标记运行 |
| 9 | `resolveExternalAuthProfiles` | 叠加提供商自有的外部 auth profiles默认 `persistence` 对于 CLI/应用自有凭证为 `runtime-only` | 提供商可复用外部鉴权凭证,而不持久化复制的刷新令牌;请在清单中声明 `contracts.externalAuthProviders` |
| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成 profile 占位符优先级降低到 env/配置驱动鉴权之后 | 提供商会存储不应优先生效的合成占位 profile |
| 11 | `resolveDynamicModel` | 为尚未进入本地注册表的提供商自有模型 id 提供同步回退 | 提供商接受任意上游模型 id |
| 12 | `prepareDynamicModel` | 先进行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 |
| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用已解析模型前进行最终重写 | 提供商需要进行传输重写,但仍使用核心传输 |
| 14 | `contributeResolvedModelCompat` | 为另一种兼容传输背后的供应商模型贡献兼容性标志 | 提供商可以在代理传输上识别自己的模型,而无需接管该提供商 |
| 15 | `capabilities` | 由共享核心逻辑使用的提供商自有转录/工具元数据 | 提供商需要处理转录/提供商家族特有行为 |
| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式之前对其进行规范化 | 提供商需要进行传输家族级的模式清理 |
| 17 | `inspectToolSchemas` | 在规范化之后暴露提供商自有的模式诊断 | 提供商希望给出关键字警告,而不需要让核心学习提供商特定规则 |
| 18 | `resolveReasoningOutputMode` | 选择原生还是带标签的 reasoning-output 契约 | 提供商需要使用带标签的推理/最终输出,而不是原生字段 |
| 19 | `prepareExtraParams` | 在通用流选项包装器之前进行请求参数规范化 | 提供商需要默认请求参数或按提供商进行参数清理 |
| 20 | `createStreamFn` | 使用自定义传输完全替换常规流路径 | 提供商需要自定义线协议,而不只是包装器 |
| 21 | `wrapStreamFn` | 在应用通用包装器之后再包裹流函数 | 提供商需要请求头/请求体/模型兼容性包装器,但不需要自定义传输 |
| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次身份信息 |
| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 头或会话冷却策略 | 提供商希望通用 WS 传输调整会话头或回退策略 |
| 24 | `formatApiKey` | auth profile 格式化器:将已存储 profile 转为运行时 `apiKey` 字符串 | 提供商会存储额外鉴权元数据,并需要自定义运行时令牌形状 |
| 25 | `refreshOAuth` | 针对自定义刷新端点或刷新失败策略的 OAuth 刷新覆盖 | 提供商不适配共享的 `pi-ai` 刷新器 |
| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加的修复提示 | 提供商在刷新失败后需要提供商自有的鉴权修复指导 |
| 27 | `matchesContextOverflowError` | 提供商自有的上下文窗口溢出匹配器 | 提供商存在通用启发式规则会漏掉的原始溢出错误 |
| 28 | `classifyFailoverReason` | 提供商自有的故障转移原因分类 | 提供商可以将原始 API/传输错误映射为速率限制、过载等 |
| 29 | `isCacheTtlEligible` | 面向代理/回传提供商的 prompt-cache 策略 | 提供商需要代理特定的缓存 TTL 门控 |
| 30 | `buildMissingAuthMessage` | 替换通用缺失鉴权恢复消息 | 提供商需要提供商特定的缺失鉴权恢复提示 |
| 31 | `suppressBuiltInModel` | 过时上游模型抑制,并可选提供面向用户的错误提示 | 提供商需要隐藏过时的上游行,或用供应商提示替换它们 |
| 32 | `augmentModelCatalog` | 在发现之后追加合成/最终目录行 | 提供商需要在 `models list` 和选择器中提供合成的前向兼容行 |
| 33 | `resolveThinkingProfile` | 针对特定模型的 `/think` 级别集合、显示标签和默认值 | 提供商为选定模型暴露自定义思考层级或二元标签 |
| 34 | `isBinaryThinking` | 开/关推理切换兼容性钩子 | 提供商只暴露二元的思考开/关 |
| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | 提供商希望在部分模型上启用 `xhigh` |
| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级别兼容性钩子 | 提供商拥有某个模型家族的默认 `/think` 策略 |
| 37 | `isModernModelRef` | 用于实时 profile 过滤和冒烟选择的 modern-model 匹配器 | 提供商拥有实时/冒烟优选模型匹配逻辑 |
| 38 | `prepareRuntimeAuth` | 在推理前将已配置凭证交换为实际运行时令牌/key | 提供商需要令牌交换或短生命周期请求凭证 |
| 39 | `resolveUsageAuth` | 为 `/usage` 和相关状态表面解析用量/计费凭证 | 提供商需要自定义用量/配额令牌解析,或使用不同的用量凭证 |
| 40 | `fetchUsageSnapshot` | 在鉴权解析后获取并规范化提供商特定的用量/配额快照 | 提供商需要提供商特定的用量端点或负载解析器 |
| 41 | `createEmbeddingProvider` | 为 memory/search 构建提供商自有的 embedding 适配器 | Memory embedding 行为应归属于提供商插件 |
| 42 | `buildReplayPolicy` | 返回一个重放策略,用于控制该提供商的转录处理 | 提供商需要自定义转录策略(例如去除 thinking block |
| 43 | `sanitizeReplayHistory` | 在通用转录清理后重写重放历史 | 提供商需要超出共享压缩辅助工具之外的提供商特定重放重写 |
| 44 | `validateReplayTurns` | 在嵌入式运行器之前对重放轮次进行最终校验或重塑 | 提供商传输在通用清理之后需要更严格的轮次校验 |
| 45 | `onModelSelected` | 在模型被选中后运行提供商自有的副作用 | 当模型变为活动状态时,提供商需要遥测或提供商自有状态 |
| # | 钩子 | 作用 | 何时使用 |
| --- | --------------------------------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers` | 提供商拥有目录或基础 URL 默认值 |
| 2 | `applyConfigDefaults` | 在配置具体化期间,应用由提供商拥有的全局配置默认值 | 默认值依赖于认证模式、环境变量或提供商模型家族语义 |
| -- | _(内置模型查找)_ | OpenClaw 会先尝试正常的注册表/目录路径 | _(不是插件钩子)_ |
| 3 | `normalizeModelId` | 在查找前规范化旧版或预览版 model-id 别名 | 提供商拥有在规范模型解析之前进行别名清理的逻辑 |
| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商家族的 `api` / `baseUrl` | 提供商拥有同一传输家族中自定义提供商 id 的传输清理逻辑 |
| 5 | `normalizeConfig` | 在运行时/提供商解析之前,规范化 `models.providers.<id>` | 提供商需要应与插件放在一起的配置清理;内置的 Google 家族辅助逻辑也会为受支持的 Google 配置项提供兜底 |
| 6 | `applyNativeStreamingUsageCompat` | 将原生流式用量兼容性重写应用到配置提供商 | 提供商需要基于端点的原生流式用量元数据修复 |
| 7 | `resolveConfigApiKey` | 在加载运行时认证之前,为配置提供商解析 env-marker 认证 | 提供商拥有由其控制的 env-marker API 密钥解析;`amazon-bedrock` 在这里也有内置的 AWS env-marker 解析器 |
| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露本地/自托管或基于配置的认证 | 提供商可以使用合成/本地凭证标记运行 |
| 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` | 用于实时配置文件筛选和冒烟选择的现代模型匹配器 | 提供商拥有实时/冒烟首选模型匹配逻辑 |
| 38 | `prepareRuntimeAuth` | 在推理之前,将已配置的凭证交换为实际运行时令牌/密钥 | 提供商需要令牌交换或短生命周期请求凭证 |
| 39 | `resolveUsageAuth` | 为 `/usage` 及相关状态表面解析用量/计费凭证 | 提供商需要自定义用量/配额令牌解析,或使用不同的用量凭证 |
| 40 | `fetchUsageSnapshot` | 在认证解析完成后,获取并规范化提供商特定的用量/配额快照 | 提供商需要提供商特定的用量端点或负载解析器 |
| 41 | `createEmbeddingProvider` | 为 Memory/search 构建由提供商拥有的嵌入适配器 | Memory 嵌入行为应归属于提供商插件 |
| 42 | `buildReplayPolicy` | 返回一个重放策略,用于控制该提供商的转录处理 | 提供商需要自定义转录策略(例如剥离思考块) |
| 43 | `sanitizeReplayHistory` | 在通用转录清理之后重写重放历史 | 提供商需要超出共享压缩辅助函数范围的提供商特定重放重写 |
| 44 | `validateReplayTurns` | 在嵌入式运行器之前,对重放轮次进行最终校验或重塑 | 提供商传输在通用净化之后需要更严格的轮次校验 |
| 45 | `onModelSelected` | 运行由提供商拥有的模型选定后副作用 | 当模型变为活动状态时,提供商需要遥测或提供商自有状态 |
`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查匹配到的提供商插件,然后依次回退到其他具备钩子能力的提供商插件,直到有一个实际修改了模型 id 或传输/配置。这样可以让别名/兼容性提供商 shim 正常工作,而不要求调用方知道哪个内置插件拥有这项重写逻辑。如果没有任何提供商钩子重写受支持的 Google 家族配置条目,内置的 Google 配置规范化器仍会应用该兼容性清理。
`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查已匹配的提供商插件,然后继续尝试其他具备钩子能力的提供商插件,直到某个插件实际更改了模型 id 或传输/配置。这样可以让别名/兼容性提供商 shim 正常工作,而无需调用方知道哪个内置插件拥有该重写逻辑。如果没有任何提供商钩子重写受支持的 Google 家族配置项,内置的 Google 配置规范化器仍会应用这类兼容性清理。
如果提供商需要完全自定义的线协议或自定义请求执行器,那就是另一类扩展。这些钩子适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。
如果提供商需要完全自定义的线协议或自定义请求执行器,那就是另一类扩展。这些钩子适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。
### 提供商示例
@ -258,29 +264,41 @@ api.registerProvider({
### 内置示例
内置提供商插件会组合使用上述钩子,以适配各供应商的目录、鉴权、思考、重放和用量需求。权威的钩子集合与各插件一起存放在 `extensions/` 下;本页展示的是形状,而不是镜像整份列表。
内置提供商插件会组合使用上述钩子,以适配各个供应商在目录、认证、思考、重放和用量方面的需求。权威的钩子集合与各插件一起存放在 `extensions/` 下;本页用于说明这些形态,而不是镜像完整列表。
<AccordionGroup>
<Accordion title="直通目录提供商">
OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog` 以及 `resolveDynamicModel` / `prepareDynamicModel`,以便它们能在 OpenClaw 的静态目录之前暴露上游模型 id。
<Accordion title="透传目录提供商">
OpenRouter、Kilocode、Z.AI、xAI 会注册 `catalog` 以及
`resolveDynamicModel` / `prepareDynamicModel`,这样它们就能在
OpenClaw 的静态目录之前暴露上游模型 id。
</Accordion>
<Accordion title="OAuth 和用量端点提供商">
GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 会将 `prepareRuntimeAuth``formatApiKey``resolveUsageAuth` + `fetchUsageSnapshot` 配对使用,以接管令牌交换和 `/usage` 集成。
GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 会将
`prepareRuntimeAuth``formatApiKey``resolveUsageAuth` +
`fetchUsageSnapshot` 配合使用,以接管令牌交换和 `/usage` 集成。
</Accordion>
<Accordion title="重放与转录清理家族">
共享的命名家族(`google-gemini`、`passthrough-gemini`、`anthropic-by-model`、`hybrid-anthropic-openai`)让提供商可以通过 `buildReplayPolicy` 选择加入转录策略,而不必让每个插件重复实现清理逻辑。
<Accordion title="重放和转录清理家族">
共享命名家族(`google-gemini`、`passthrough-gemini`、
`anthropic-by-model`、`hybrid-anthropic-openai`)使提供商可以通过
`buildReplayPolicy` 选择转录策略,而不需要每个插件都重新实现清理逻辑。
</Accordion>
<Accordion title="仅目录提供商">
`byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、`qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和 `volcengine` 只注册 `catalog`,并复用共享推理循环。
`byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、
`qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和
`volcengine` 仅注册 `catalog`,并沿用共享推理循环。
</Accordion>
<Accordion title="Anthropic 专用流辅助工具">
Beta 标头、`/fast` / `serviceTier``context1m` 位于 Anthropic 插件的公共 `api.ts` / `contract-api.ts` 接缝中(`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不在通用 SDK 中。
<Accordion title="Anthropic 特定的流辅助函数">
Beta 头、`/fast` / `serviceTier` 以及 `context1m` 位于
Anthropic 插件的公开 `api.ts` / `contract-api.ts` 接缝中
`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、
`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`
而不在通用 SDK 中。
</Accordion>
</AccordionGroup>
## 运行时辅助工具
## 运行时辅助函数
插件可以通过 `api.runtime` 访问精选的核心辅助工具。对于 TTS
插件可以通过 `api.runtime` 访问部分核心辅助函数。对于 TTS
```ts
const clip = await api.runtime.tts.textToSpeech({
@ -301,12 +319,12 @@ const voices = await api.runtime.tts.listVoices({
说明:
- `textToSpeech` 会返回普通核心 TTS 输出负载,用于文件/语音便笺表面
- 使用核心 `messages.tts` 配置和提供商选择逻辑
- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商重采样/编码。
- `listVoices` 对每个提供商来说是可选的。可将其用于供应商自有的语音选择器或设置流程。
- 语音列表可包含更丰富的元数据,例如区域设置、性别和个性标签,供具备提供商感知能力的选择器使用
- 目前支持 telephony 的是 OpenAI 和 ElevenLabs。Microsoft 不支持。
- `textToSpeech` 返回用于文件/语音便笺表面的常规核心 TTS 输出负载
- 使用核心 `messages.tts` 配置和提供商选择。
- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商进行重采样/编码。
- `listVoices` 对每个提供商来说都是可选的。可将其用于由供应商控制的语音选择器或设置流程。
- 语音列表可包含更丰富的元数据,例如区域设置、性别和个性标签,以支持具备提供商感知能力的选择器
- 目前 OpenAI 和 ElevenLabs 支持电话语音。Microsoft 不支持。
插件也可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。
@ -328,10 +346,10 @@ api.registerSpeechProvider({
说明:
- 将 TTS 策略、回退和回复投递保留在核心中。
- 使用语音提供商承载供应商自有的合成行为。
- 保持 TTS 策略、回退和回复投递逻辑位于核心中。
- 语音提供商用于由供应商控制的语音合成行为。
- 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` 提供商 id。
- 首选的所有权模型是面向公司的:随着 OpenClaw 增加这些能力契约,一个供应商插件可以统一拥有文本、语音、图像未来的媒体提供商。
- 推荐的所有权模型是面向公司的:随着 OpenClaw 增加这些能力契约,一个供应商插件可以统一拥有文本、语音、图像以及未来的媒体提供商。
对于图像/音频/视频理解,插件会注册一个类型化的媒体理解提供商,而不是通用的键值包:
@ -347,15 +365,15 @@ api.registerMediaUnderstandingProvider({
说明:
- 将编排、回退、配置和渠道接线保留在核心中。
- 保持编排、回退、配置和渠道接线逻辑位于核心中。
- 将供应商行为保留在提供商插件中。
- 增量扩展应保持类型化:新的可选方法、新的可选结果字段、新的可选能力。
- 视频生成已经遵循相同模式:
- 核心拥有能力契约和运行时辅助工具
- 核心拥有能力契约和运行时辅助函数
- 供应商插件注册 `api.registerVideoGenerationProvider(...)`
- 功能/渠道插件消费 `api.runtime.videoGeneration.*`
对于媒体理解运行时辅助工具,插件可以调用:
对于媒体理解运行时辅助函数,插件可以调用:
```ts
const image = await api.runtime.mediaUnderstanding.describeImageFile({
@ -370,13 +388,13 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({
});
```
对于音频转录,插件可以使用媒体理解运行时,也可以使用旧版 STT 别名:
对于音频转录,插件可以使用媒体理解运行时,也可以使用旧版 STT 别名:
```ts
const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
filePath: "/tmp/inbound-audio.ogg",
cfg: api.config,
// 当 MIME 无法可靠推断时可选:
// 当无法可靠推断 MIME 时可选:
mime: "audio/ogg",
});
```
@ -385,10 +403,10 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
- `api.runtime.mediaUnderstanding.*` 是图像/音频/视频理解的首选共享表面。
- 使用核心媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。
- 当未产生任何转录输出时,返回 `{ text: undefined }`(例如输入被跳过/不受支持)
- 当没有生成转录输出时(例如输入被跳过/不受支持),返回 `{ text: undefined }`
- `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容性别名。
插件可以通过 `api.runtime.subagent` 启动后台子智能体运行:
插件可以通过 `api.runtime.subagent` 启动后台子智能体运行:
```ts
const result = await api.runtime.subagent.run({
@ -402,13 +420,13 @@ const result = await api.runtime.subagent.run({
说明:
- `provider``model`每次运行的可选覆盖项,不是持久化的会话变更。
- OpenClaw 只会为受信任调用方接受这些覆盖字段。
- 对于插件自有的回退运行,运维者必须通过 `plugins.entries.<id>.subagent.allowModelOverride: true` 显式启用。
- 使用 `plugins.entries.<id>.subagent.allowedModels` 可将受信任插件限制为特定的规范 `provider/model` 目标,或使用 `"*"` 显式允许任意目标。
- 不受信任的插件子智能体运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。
- `provider``model`单次运行级别的可选覆盖项,不是持久化的会话变更。
- OpenClaw 只会对受信任调用方尊重这些覆盖字段。
- 对于插件拥有的回退运行,运维人员必须通过 `plugins.entries.<id>.subagent.allowModelOverride: true` 明确启用。
- 使用 `plugins.entries.<id>.subagent.allowedModels` 可将受信任插件限制为特定的规范 `provider/model` 目标,或设置为 `"*"`显式允许任意目标。
- 不受信任的插件子智能体运行仍然可用,但覆盖请求会被拒绝,而不是静默回退。
对于 Web 搜索,插件可以消费共享运行时辅助工具,而不必深入智能体工具接线
对于 Web 搜索,插件可以消费共享运行时辅助函数,而不是深入到智能体工具接线中
```ts
const providers = api.runtime.webSearch.listProviders({
@ -424,13 +442,14 @@ const result = await api.runtime.webSearch.search({
});
```
插件也可以通过 `api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。
插件也可以通过
`api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。
说明:
- 将提供商选择、凭证解析和共享请求语义保留在核心中。
- 使用 Web 搜索提供商承载供应商特定的搜索传输。
- `api.runtime.webSearch.*` 是功能/渠道插件需要搜索行为但又不依赖智能体工具包装器时的首选共享表面。
- 保持提供商选择、凭证解析和共享请求语义位于核心中。
- Web 搜索提供商用于供应商特定的搜索传输。
- `api.runtime.webSearch.*` 是功能/渠道插件需要搜索行为但又不依赖智能体工具包装器时的首选共享表面。
### `api.runtime.imageGeneration`
@ -468,151 +487,170 @@ 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(...)`
- 插件路由必须显式声明 `auth`
- 除非设置 `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`头契约。
- 精确的 `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` 请求头契约。
## 插件 SDK 导入路径
在编写新插件时,应使用更窄的 SDK 子路径,而不是体式的 `openclaw/plugin-sdk` 根 barrel。核心子路径包括
在编写新插件时,应使用更窄的 SDK 子路径,而不是体式的 `openclaw/plugin-sdk` 根 barrel。核心子路径
| 子路径 | 用途 |
| 子路径 | 用途 |
| ----------------------------------- | -------------------------------------------------- |
| `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 |
| `openclaw/plugin-sdk/channel-core` | 渠道入口/构建辅助工具 |
| `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 |
| `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`、`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-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)。
运行时和配置辅助工具位于对应的 `*-runtime` 子路径下(`approval-runtime`、`config-runtime`、`infra-runtime`、`agent-runtime`、`lazy-runtime`、`directory-runtime`、`text-runtime`、`runtime-store` 等)。
运行时和配置辅助函数位于对应的 `*-runtime` 子路径下
`approval-runtime`、`config-runtime`、`infra-runtime`、`agent-runtime`、
`lazy-runtime`、`directory-runtime`、`text-runtime`、`runtime-store` 等)。
<Info>
`openclaw/plugin-sdk/channel-runtime` 已弃用——它只是为旧插件提供的兼容性 shim。新代码应改为导入更窄的通用原语。
`openclaw/plugin-sdk/channel-runtime` 已弃用——它只是为旧插件提供的兼容性 shim。
新代码应改为导入更窄的通用原语。
</Info>
仓库内部入口点(每个内置插件 package 根目录
仓库内部入口点(按每个内置插件包根目录划分
- `index.js` —— 内置插件入口
- `api.js` —— 辅助工具/类型 barrel
- `api.js` —— 辅助函数/类型 barrel
- `runtime-api.js` —— 仅运行时 barrel
- `setup-entry.js` —— 设置插件入口
外部插件应只导入 `openclaw/plugin-sdk/*` 子路径。绝不要从核心或其他插件中导入另一个插件 package 的 `src/*`。由 facade 加载的入口点在可用时会优先使用当前活动的运行时配置快照,然后才回退到磁盘上解析出的配置文件。
外部插件只能导入 `openclaw/plugin-sdk/*` 子路径。绝不要从核心或另一个插件中导入其他插件包的 `src/*`
通过 facade 加载的入口点在存在活动运行时配置快照时会优先使用它,否则回退到磁盘上已解析的配置文件。
诸如 `image-generation`、`media-understanding` 和 `speech`样的能力专用子路径之所以存在,是因为内置插件目前正在使用它们。它们并不自动属于长期冻结的外部契约——在依赖它们时,请查阅相关的 SDK 参考页面
诸如 `image-generation`、`media-understanding` 和 `speech`类能力专用子路径之所以存在,是因为内置插件当前在使用它们。它们并不自动等同于长期冻结的外部契约——在依赖它们时,请查看相应的 SDK 参考页
## 消息工具模式
对于诸如 reactions、reads 和 polls 这类非消息原语,插件应拥有渠道特定的 `describeMessageTool(...)` 模式贡献。共享发送展示应使用通用 `MessagePresentation` 契约而不是提供商原生的按钮、组件、block 或卡片字段。有关该契约、回退规则、提供商映射和插件作者检查清单,请参阅 [Message Presentation](/zh-CN/plugins/message-presentation)。
对于反应、已读和投票等非消息原语,插件应自行拥有渠道特定的 `describeMessageTool(...)` 模式扩展。
共享发送展示应使用通用 `MessagePresentation` 契约,而不是提供商原生的按钮、组件、区块或卡片字段。
契约、回退规则、提供商映射和插件作者检查清单,请参见 [Message Presentation](/zh-CN/plugins/message-presentation)。
具备发送能力的插件会通过消息能力声明其可渲染内容:
具备发送能力的插件会通过消息能力声明它们可以渲染的内容:
- `presentation`:用于语义化展示 block`text`、`context`、`divider`、`buttons`、`select`
- `delivery-pin`:用于置顶投递请求
- `presentation`:用于语义展示区块`text`、`context`、`divider`、`buttons`、`select`
- `delivery-pin`:用于固定投递请求
核心会决定是原生渲染该展示,还是将其降级为文本。不要从通用消息工具中暴露提供商原生 UI 逃逸口。为旧版原生模式提供的已弃用 SDK 辅助工具仍会继续导出,以兼容现有第三方插件,但新插件不应使用它们。
核心会决定是原生渲染该展示,还是将其降级为文本。
不要从通用消息工具暴露提供商原生 UI 逃生口。
为旧版原生模式保留的已弃用 SDK 辅助函数仍会导出,以兼容现有第三方插件,但新插件不应使用它们。
## 渠道目标解析
渠道插件应拥有渠道特定的目标语义。保持共享出站主机通用,并使用消息适配器表面承载提供商规则:
渠道插件应自行拥有渠道特定的目标语义。保持共享出站宿主的通用性,并使用消息适配器表面处理提供商规则:
- `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)` 用于告诉核心某个输入是否应跳过目录搜索,直接进入类似 id 的解析。
- `messaging.targetResolver.resolveTarget(...)`核心在规范化后或目录未命中后需要最终由提供商控制的解析时使用的插件回退逻辑
- `messaging.resolveOutboundSessionRoute(...)` 用于在目标解析完成后拥有提供商特定的会话路由构造逻辑
推荐拆分方式:
- 对于应在搜索 peers/groups 之前发生的分类决策,使用 `inferTargetChatType`
- 对于“将其视为显式/原生目标 id”的判断,使用 `looksLikeId`
- 对于应在搜索 peers/groups 之前完成的类别判断,使用 `inferTargetChatType`
- 对于“将其视为显式/原生目标 id”的检查,使用 `looksLikeId`
- 对于提供商特定的规范化回退,使用 `resolveTarget`,而不是用于广泛的目录搜索。
- 将提供商原生 id例如 chat ids、thread ids、JIDs、handles 和 room ids保留在 `target` 值或提供商特定参数中,而不是放在通用 SDK 字段里。
- 将 chat id、thread id、JID、handle 和 room id 这类提供商原生 id 保存在 `target` 值或提供商特定参数中,而不要放在通用 SDK 字段里。
## 配置驱动的目录
## 基于配置的目录
如果插件从配置中派生目录条目,应将该逻辑保留在插件中,并复用 `openclaw/plugin-sdk/directory-runtime` 中的共享辅助工具。
如果插件从配置派生目录条目,应将该逻辑保留在插件内部,并复用
`openclaw/plugin-sdk/directory-runtime` 中的共享辅助函数。
当渠道需要配置驱动的 peers/groups 时,请使用这种方式,例如:
某个渠道需要基于配置的 peers/groups 时,请使用这种方式,例如:
- 基于 allowlist 的私信 peers
- 已配置的渠道/群组映射
- 按账号作用域划分的静态目录回退
- 按账划分的静态目录回退
`directory-runtime` 中的共享辅助工具只处理通用操作:
`directory-runtime` 中的共享辅助函数只处理通用操作:
- 查询过滤
- limit 应用
- 去重/规范化辅助工具
- 限制应用
- 去重/规范化辅助函数
- 构建 `ChannelDirectoryEntry[]`
渠道特定的账检查和 id 规范化应保留在插件实现中。
渠道特定的账检查和 id 规范化应保留在插件实现中。
## 提供商目录
提供商插件可以使用 `registerProvider({ catalog: { run(...) { ... } } })` 为推理定义模型目录。
提供商插件可以通过
`registerProvider({ catalog: { run(...) { ... } } })` 为推理定义模型目录。
`catalog.run(...)` 返回的形状与 OpenClaw 写入 `models.providers` 的形状相同:
`catalog.run(...)` 返回与 OpenClaw 写入
`models.providers` 相同的形状:
- `{ provider }`个提供商条目
- `{ provider }`个提供商条目
- `{ providers }`:多个提供商条目
当插件拥有提供商特定的模型 id、base URL 默认值或受鉴权控制的模型元数据时,请使用 `catalog`
当插件拥有提供商特定的模型 id、基础 URL 默认值或受认证控制的模型元数据时,请使用 `catalog`
`catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机:
- `simple`:普通 API key 或环境变量驱动的提供商
- `profile`存在 auth profiles 时出现的提供商
- `simple`:普通 API 密钥或由环境变量驱动的提供商
- `profile`在存在认证配置文件时出现的提供商
- `paired`:会合成多个相关提供商条目的提供商
- `late`:最后一轮,在其他隐式提供商之后
面的提供商会在键冲突时胜出,因此插件可以有意使用相同的提供商 id 覆盖内置提供商条目。
出现的提供商会在键冲突时获胜,因此插件可以有意用相同的提供商 id 覆盖内置提供商条目。
兼容性:
- `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/配置修复流程这样的只读命令路径,不应仅为了描述配置就去具体化运行时凭证。
- `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"`(以及相应的来源字段)就足以支持 status 风格的命令。
- 当凭证通过 SecretRef 配置但在当前命令路径中不可用时,使用 `configured_unavailable`
- 你无需为了报告只读可用性而返回原始令牌值。返回 `tokenStatus: "available"`(以及对应的来源字段)就足以支持状态类命令。
- 当凭证通过 SecretRef 配置但在当前命令路径中不可用时,使用 `configured_unavailable`
这样一来,只读命令就可以报告“已配置,但在此命令路径中不可用”,而不是崩溃或错误地将该账号报告为未配置。
这样只读命令就能报告“已配置,但在当前命令路径中不可用”,而不是崩溃或错误地将账户报告为未配置。
## 软件包包
## 软件包包集
插件目录可以包含带有 `openclaw.extensions``package.json`
插件目录可以包含一个带有 `openclaw.extensions``package.json`
```json
{
@ -624,37 +662,53 @@ api.registerHttpRoute({
}
```
每个条目都会变成一个插件。如果该包合集列出了多个扩展,则插件 id 会变成 `name/<fileBase>`
每个条目都会变成一个插件。如果该包集列出了多个扩展,则插件 id
会变成 `name/<fileBase>`
如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便 `node_modules` 可用(`npm install` / `pnpm install`)。
如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便
`node_modules` 可用(`npm install` / `pnpm install`)。
安全护栏:每个 `openclaw.extensions` 条目在符号链接解析后都必须仍位于插件目录内。任何逃逸出 package 目录的条目都会被拒绝。
安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须保留在插件目录内。逃逸出包目录的条目会被拒绝。
安全说明:`openclaw plugins install` 会使用 `npm install --omit=dev --ignore-scripts` 安装插件依赖(无生命周期脚本、运行时无开发依赖)。请保持插件依赖树为“纯 JS/TS”并避免使用需要 `postinstall` 构建的包。
安全说明:`openclaw plugins install` 会使用
`npm install --omit=dev --ignore-scripts` 安装插件依赖
(无生命周期脚本,运行时无开发依赖)。请保持插件依赖树为“纯 JS/TS”并避免需要 `postinstall` 构建的包。
可选:`openclaw.setupEntry` 可以指向一个轻量级、仅用于设置的模块。当 OpenClaw 需要为一个已禁用的渠道插件提供设置表面,或者某个渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整插件入口。这样在你的主插件入口还会接入工具、钩子或其他仅运行时代码时,可以让启动和设置更轻量。
可选:`openclaw.setupEntry` 可以指向一个仅用于设置的轻量模块。
当 OpenClaw 需要为已禁用的渠道插件提供设置表面,或者
当渠道插件已启用但尚未配置时,它会加载 `setupEntry`
而不是完整的插件入口。这样在你的主插件入口还需要接线工具、钩子或其他仅运行时代码时,可以让启动和设置更加轻量。
可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` 可以让渠道插件在 Gateway 网关的 pre-listen 启动阶段也走同样的 `setupEntry` 路径,即使该渠道已经配置完成。
可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen`
可以让渠道插件在 Gateway 网关的 pre-listen 启动阶段也走同一个 `setupEntry` 路径,
即使该渠道已经配置完成。
仅当 `setupEntry` 完全覆盖了 Gateway 网关开始监听之前必须存在的启动表面时,才应使用它。实际中,这意味着设置入口必须注册启动所依赖的每一项渠道自有能力,例如:
仅当 `setupEntry` 完整覆盖了 Gateway 网关开始监听之前必须存在的启动表面时,才使用此项。
在实践中,这意味着设置入口必须注册启动所依赖的每一项由渠道拥有的能力,例如:
- 渠道注册本身
- 任何必须在 Gateway 网关开始监听前可用的 HTTP 路由
- 任何在同一时间窗口内必须存在的 gateway 方法、工具或服务
- 在 Gateway 网关开始监听必须可用的任何 HTTP 路由
- 在同一窗口期间必须存在的任何 Gateway 网关方法、工具或服务
如果你的完整入口仍拥有任何必需的启动能力,就不要启用这个标志。保持插件的默认行为,让 OpenClaw 在启动期间加载完整入口。
如果你的完整入口仍然拥有任何必需的启动能力,就不要启用这个标志。
请保持插件采用默认行为,让 OpenClaw 在启动期间加载完整入口。
内置渠道也可以发布仅用于设置的契约表面辅助工具,供核心在完整渠道运行时加载之前查询。当前的设置提升表面包括:
内置渠道也可以发布仅设置阶段使用的契约表面辅助函数,供核心在完整渠道运行时加载之前查询。当前的设置提升表面包括:
- `singleAccountKeysToMove`
- `namedAccountPromotionKeys`
- `resolveSingleAccountPromotionTarget(...)`
当核心需要将旧版单账号渠道配置提升到 `channels.<id>.accounts.*`但又不加载完整插件入口时就会使用这组表面。Matrix 是当前的内置示例:当已存在命名账号时,它只会将 auth/bootstrap 键迁移到某个已命名的提升账号中,并且它可以保留已配置的非规范默认账号键,而不是总是创建 `accounts.default`
当核心需要在不加载完整插件入口的情况下,将旧版单账户渠道配置提升到
`channels.<id>.accounts.*` 时,会使用这个表面。
Matrix 是当前的内置示例:当已存在命名账户时,它只会把认证/bootstrap 键移动到某个已命名的提升账户中,并且可以保留一个已配置的、非规范默认账户键,而不是总是创建
`accounts.default`
这些设置补丁适配器让内置契约表面发现保持惰性。导入时开销仍然很轻;提升表面只会在首次使用时加载,而不会在模块导入时重新进入内置渠道启动流程。
这些设置补丁适配器让内置契约表面发现保持懒加载。
导入时保持轻量;提升表面仅在首次使用时加载,而不是在模块导入时重新进入内置渠道启动流程。
当这些启动表面包含 gateway RPC 方法时,请将它们保留在插件专用前缀下。核心管理命名空间(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)仍然是保留的,并且始终会解析为 `operator.admin`,即使某个插件请求更窄的作用域也是如此。
当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在插件特定前缀下。核心管理命名空间(`config.*`、
`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为 `operator.admin`,即使某个插件请求了更窄的作用域也是如此。
示例:
@ -673,7 +727,7 @@ api.registerHttpRoute({
### 渠道目录元数据
渠道插件可以通过 `openclaw.channel`传设置/发现元数据,并通过 `openclaw.install` 宣传安装提示。这样可以让核心目录保持无数据。
渠道插件可以通过 `openclaw.channel`告设置/发现元数据,并通过 `openclaw.install` 宣告安装提示。这样可以保持核心目录不携带数据。
示例:
@ -688,7 +742,7 @@ api.registerHttpRoute({
"selectionLabel": "Nextcloud Talk自托管",
"docsPath": "/channels/nextcloud-talk",
"docsLabel": "nextcloud-talk",
"blurb": "通过 Nextcloud Talk webhook 机器人实现自托管聊天。",
"blurb": "通过 Nextcloud Talk webhook 机器人实现自托管聊天。",
"order": 65,
"aliases": ["nc-talk", "nc"]
},
@ -701,38 +755,41 @@ api.registerHttpRoute({
}
```
除最小示例外,有用的 `openclaw.channel` 字段还包括
除最小示例外,还有一些有用的 `openclaw.channel` 字段:
- `detailLabel`:用于更丰富目录/状态表面的次级标签
- `docsLabel`:覆盖文档链接的链接文本
- `preferOver`:此目录条目应优先于的低优先级插件/渠道 id
- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面文案控制
- `markdownCapable`:将该渠道标记为支持 markdown用于出站格式决策
- `exposure.configured`设为 `false` 时,在已配置渠道列表表面中隐藏该渠道
- `exposure.setup`设为 `false` 时,在交互式设置/配置选择器中隐藏该渠道
- `exposure.docs`:将该渠道标记为文档导航表面中的内部/私有渠道
- `showConfigured` / `showInSetup`为兼容性仍接受的旧别名;优先使用 `exposure`
- `quickstartAllowFrom`让该渠道选择加入标准快速开始 `allowFrom` 流程
- `forceAccountBinding`:即使仅存在一个账号,也要求显式账号绑定
- `preferSessionLookupForAnnounceTarget`:在解析 announce 目标时优先使用会话查找
- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面文案控制
- `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"` 键的旧别名。
生成的渠道目录条目和提供商安装目录条目会在原始 `openclaw.install` 块旁暴露规范化后的安装源事实。这些规范化事实会标识 npm 规范是精确版本还是浮动选择器、是否存在预期的完整性元数据,以及本地源路径是否也可用。消费者应将 `installSource` 视为一个增量式可选字段,这样较旧的手工构建条目和兼容性 shim 就不必合成它。这让新手引导和诊断可以在不导入插件运行时的情况下解释源平面状态。
生成的渠道目录条目和提供商安装目录条目会在原始 `openclaw.install` 区块旁暴露规范化后的安装来源事实。这些规范化事实可标识 npm 规格是精确版本还是浮动选择器、是否存在预期的完整性元数据,以及是否同时提供本地源路径。它们还会在 `defaultChoice` 无效或指向不可用来源时发出警告。消费者应将 `installSource` 视为一个附加的可选字段,这样较旧的手工构建条目和兼容性 shim 就不必合成它。这使得新手引导和诊断能够在不导入插件运行时的情况下解释来源平面状态。
官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 `expectedIntegrity`裸包名和 dist-tag 仍可出于兼容性继续使用,但它们会暴露源平面警告,以便目录逐步转向固定版本并进行完整性校验的安装,而不会破坏现有插件。当新手引导从本地目录路径安装时,它会记录一条 `plugins.installs` 条目,其中 `source: "path"`,并尽可能使用相对于工作区的 `sourcePath`。绝对的实际加载路径仍保留在 `plugins.load.paths` 中;安装记录会避免将本地工作站路径重复写入长期配置。这让本地开发安装对于源平面诊断可见,同时不会增加第二个原始文件系统路径暴露表面。
官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 `expectedIntegrity`仅包名和 dist-tag 仍可出于兼容性继续使用,但它们会暴露来源平面警告,以便目录逐步迁移到固定版本、带完整性校验的安装方式,同时不破坏现有插件。当新手引导从本地目录路径安装时,它会尽可能记录一条带有 `source: "path"` 和工作区相对 `sourcePath``plugins.installs` 条目。绝对的实际加载路径仍保留在 `plugins.load.paths` 中;安装记录会避免将本地工作站路径重复写入长期配置。这样可以让本地开发安装对来源平面诊断可见,而不会增加第二个原始文件系统路径暴露表面。
## 上下文引擎插件
上下文引擎插件负责会话上下文编排,包括摄取、组装和压缩。通过 `api.registerContextEngine(id, factory)` 从你的插件中注册它们,然后通过 `plugins.slots.contextEngine` 选择活动引擎。
上下文引擎插件拥有会话上下文编排,用于摄取、组装和压缩。可通过
`api.registerContextEngine(id, factory)` 从你的插件中注册它们,然后使用
`plugins.slots.contextEngine` 选择活动引擎。
当你的插件需要替换或扩展默认上下文管线,而不只是添加内存搜索或钩子时,请使用此方式。
当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加内存搜索或钩子时,请使用此方式。
```ts
import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
@ -760,7 +817,8 @@ export default function (api) {
}
```
如果你的引擎**不**拥有压缩算法,请保持 `compact()` 已实现,并显式委托:
如果你的引擎**不**拥有压缩算法,请保持 `compact()`
已实现,并显式委托它:
```ts
import {
@ -797,51 +855,54 @@ export default function (api) {
## 添加新的能力
当插件需要当前 API 无法适配的行为时,不要通过私有深入访问来绕过插件系统。应添加缺失的能力。
当插件需要当前 API 无法适配的行为时,不要通过私有直连绕过插件系统。请添加缺失的能力。
推荐顺序:
1. 定义核心契约
决定哪些共享行为应由核心拥有:策略、回退、配置合并、生命周期、面向渠道的语义,以及运行时辅助工具形状。
2. 添加类型化的插件注册/运行时表面
用最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和/或 `api.runtime`
3. 接入核心 + 渠道/功能消费者
渠道和功能插件应通过核心消费新能力,而不是直接导入某个供应商实现。
4. 注册供应商实现
1. 定义核心契约
确定哪些共享行为应由核心拥有:策略、回退、配置合并、
生命周期、面向渠道的语义,以及运行时辅助函数形态。
2. 添加类型化的插件注册/运行时表面
以最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和/或 `api.runtime`
3. 连接核心 + 渠道/功能消费者
渠道和功能插件应通过核心消费该新能力,
而不是直接导入某个供应商实现。
4. 注册供应商实现
然后由供应商插件将其后端注册到该能力上。
5. 添加契约覆盖
添加测试,以便随着时间推移,所有权和注册形状仍然保持明确。
5. 添加契约覆盖
添加测试,以便所有权和注册形态在长期演进中保持明确。
正是 OpenClaw 能够保持明确立场,同时又不会硬编码到某一家提供商世界观中的方式。有关具体文件检查清单和完整示例,请参阅 [能力扩展手册](/zh-CN/plugins/architecture)。
就是 OpenClaw 保持鲜明主张、又不被硬编码到某一家提供商世界观中的方式。有关具体文件清单和完整示例,请参见 [能力扩展手册](/zh-CN/plugins/architecture)。
### 能力检查清单
### 能力清单
当你添加新的能力时,实现通常应同时涉及这些表面:
当你添加一个新能力时,通常应同时修改以下表面:
- `src/<capability>/types.ts` 中的核心契约类型
- `src/<capability>/runtime.ts` 中的核心运行器/运行时辅助工具
- `src/<capability>/runtime.ts` 中的核心运行器/运行时辅助函数
- `src/plugins/types.ts` 中的插件 API 注册表面
- `src/plugins/registry.ts` 中的插件注册表接线
- 当功能/渠道插件需要消费它时,`src/plugins/runtime/*` 中的插件运行时暴露
- `src/test-utils/plugin-registration.ts` 中的捕获/测试辅助工具
- 当功能/渠道
插件需要消费它时,位于 `src/plugins/runtime/*` 的插件运行时暴露层
- `src/test-utils/plugin-registration.ts` 中的捕获/测试辅助函数
- `src/plugins/contracts/registry.ts` 中的所有权/契约断言
- `docs/` 中面向运维/插件的文档
- `docs/` 中面向运维人员/插件的文档
如果其中某个表面缺失,通常说明这个能力尚未完全集成。
如果上述某个表面缺失,通常说明这个能力尚未完全集成。
### 能力模板
最小模式:
```ts
// 核心契约
// core contract
export type VideoGenerationProviderPlugin = {
id: string;
label: string;
generateVideo: (req: VideoGenerationRequest) => Promise<VideoGenerationResult>;
};
// 插件 API
// plugin API
api.registerVideoGenerationProvider({
id: "openai",
label: "OpenAI",
@ -850,7 +911,7 @@ api.registerVideoGenerationProvider({
},
});
// 功能/渠道插件的共享运行时辅助工具
// shared runtime helper for feature/channel plugins
const clip = await api.runtime.videoGeneration.generate({
prompt: "Show the robot walking through the lab.",
cfg,
@ -863,16 +924,16 @@ const clip = await api.runtime.videoGeneration.generate({
expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]);
```
这样可以让规则保持简单:
这样规则保持简单:
- 核心拥有能力契约 + 编排
- 供应商插件拥有供应商实现
- 功能/渠道插件消费运行时辅助工具
- 契约测试让所有权保持明确
- 功能/渠道插件消费运行时辅助函数
- 契约测试保持所有权明确
## 相关内容
- [插件架构](/zh-CN/plugins/architecture) —— 公共能力模型和形状
- [插件 SDK 子路径](/zh-CN/plugins/sdk-subpaths)
- [插件 SDK 设置](/zh-CN/plugins/sdk-setup)
- [构建插件](/zh-CN/plugins/building-plugins)
- [Plugin architecture](/zh-CN/plugins/architecture) —— 公开的能力模型和形态
- [Plugin SDK subpaths](/zh-CN/plugins/sdk-subpaths)
- [Plugin SDK setup](/zh-CN/plugins/sdk-setup)
- [Building plugins](/zh-CN/plugins/building-plugins)

View File

@ -1,21 +1,21 @@
---
read_when:
- 你正在构建一个 OpenClaw 插件
- 你需要发布一个插件配置模式,或调试插件验证错误
summary: 插件清单 + JSON 模式要求(严格配置验证)
- 你需要提供插件配置 schema,或调试插件验证错误
summary: 插件清单 + JSON schema 要求(严格配置验证)
title: 插件清单
x-i18n:
generated_at: "2026-04-24T06:33:29Z"
generated_at: "2026-04-24T16:00:08Z"
model: gpt-5.4
provider: openai
source_hash: e680a978c4f0bc8fec099462a6e08585f39dfd72e0c159ecfe5162586e7d7258
source_hash: 3ad8f4d82624420f97f38ba5f7b1de12dbf88d4cc4fb37a52ae31cbb838ebabf
source_path: plugins/manifest.md
workflow: 15
---
此页面仅适用于**原生 OpenClaw 插件清单**。
关于兼容的 bundle 布局,请参阅 [Plugin bundles](/zh-CN/plugins/bundles)。
关于兼容的 bundle 布局,请参阅 [插件 bundles](/zh-CN/plugins/bundles)。
兼容的 bundle 格式使用不同的清单文件:
@ -23,31 +23,30 @@ x-i18n:
- Claude bundle`.claude-plugin/plugin.json`,或不带清单的默认 Claude 组件布局
- Cursor bundle`.cursor-plugin/plugin.json`
OpenClaw 也会自动检测这些 bundle 布局,但不会根据这里描述的 `openclaw.plugin.json` 模式对其进行验证。
OpenClaw 也会自动检测这些 bundle 布局,但不会根据此处所述的 `openclaw.plugin.json` schema 对它们进行验证。
对于兼容 bundleOpenClaw 当前会在布局符合 OpenClaw 运行时预期时,读取 bundle 元数据以及已声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值,以及受支持的 hook pack
对于兼容 bundle当前当布局符合 OpenClaw 运行时预期时OpenClaw 会读取 bundle 元数据、声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值,以及受支持的 hook
每个原生 OpenClaw 插件**必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用此清单在**不执行插件代码的情况下**验证配置。缺失或无效的清单会被视为插件错误,并阻止配置验证。
每个原生 OpenClaw 插件**必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用此清单在**不执行插件代码**的情况下验证配置。缺失或无效的清单会被视为插件错误,并阻止配置验证。
查看完整的插件系统指南:[Plugins](/zh-CN/tools/plugin)。
关于原生能力模型和当前的外部兼容性指引,请参阅:
[Capability model](/zh-CN/plugins/architecture#public-capability-model)。
请参阅完整的插件系统指南:[插件](/zh-CN/tools/plugin)。
关于原生能力模型和当前外部兼容性指引,请参阅:[能力模型](/zh-CN/plugins/architecture#public-capability-model)。
## 此文件的作用
`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。以下所有内容都必须足够轻量,以便在不启动插件运行时的情况下进行检查。
`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。下面的所有内容都必须足够轻量,能够在不启动插件运行时的情况下进行检查。
**用于:**
**将它用于:**
- 插件标识、配置验证,以及配置 UI 提示
- 凭证、onboarding 和设置元数据(别名、自动启用、provider 环境变量、凭证选择)
- 凭证、onboarding 和设置元数据(别名、自动启用、提供商环境变量、凭证选择)
- 控制平面界面的激活提示
- 简写模型家族归属
- 简写模型家族归属
- 静态能力归属快照(`contracts`
- 共享 `openclaw qa` 主机检查的 QA 运行器元数据
- 合并到目录和验证界面的渠道专用配置元数据
- 共享 `openclaw qa` 主机检查的 QA 运行器元数据
- 合并到目录和验证界面的渠道专用配置元数据
**不要用于:**注册运行时行为、声明代码入口点,或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。
**不要将它用于:** 注册运行时行为、声明代码入口点,或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。
## 最小示例
@ -96,19 +95,19 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会根据这里描述的
"provider": "openrouter",
"method": "api-key",
"choiceId": "openrouter-api-key",
"choiceLabel": "OpenRouter API key",
"choiceLabel": "OpenRouter API 密钥",
"groupId": "openrouter",
"groupLabel": "OpenRouter",
"optionKey": "openrouterApiKey",
"cliFlag": "--openrouter-api-key",
"cliOption": "--openrouter-api-key <key>",
"cliDescription": "OpenRouter API key",
"cliDescription": "OpenRouter API 密钥",
"onboardingScopes": ["text-inference"]
}
],
"uiHints": {
"apiKey": {
"label": "API key",
"label": "API 密钥",
"placeholder": "sk-or-v1-...",
"sensitive": true
}
@ -129,64 +128,64 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会根据这里描述的
| 字段 | 必填 | 类型 | 含义 |
| ------------------------------------ | -------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | 是 | `string` | 规范插件 id。这是 `plugins.entries.<id>` 中使用的 id。 |
| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 |
| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略它,或设置为任何非 `true` 的值,都会使该插件默认保持禁用。 |
| `legacyPluginIds` | 否 | `string[]` | 会规范化为此规范插件 id 的旧版 id。 |
| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当凭证、配置或模型引用提到这些 provider id 时,应自动启用此插件。 |
| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明一个由 `plugins.slots.*` 使用的排他性插件类型。 |
| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于发现和配置验证。 |
| `providers` | 否 | `string[]` | 由此插件拥有的 provider id。 |
| `providerDiscoveryEntry` | 否 | `string` | 轻量级 provider 发现模块路径,相对于插件根目录,用于可在不激活完整插件运行时的情况下加载的、限定于清单作用域的 provider 目录元数据。 |
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型家族元数据,用于在运行时之前自动加载插件。 |
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的 endpoint host/baseUrl 元数据,用于核心在 provider 运行时加载前对 provider 路由进行分类。 |
| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 id。用于基于显式配置引用在启动时自动激活。 |
| `syntheticAuthRefs` | 否 | `string[]` | provider 或 CLI 后端引用;在运行时加载前的冷启动模型发现期间,应探测其由插件拥有的 synthetic auth hook。 |
| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API key 值,用于表示非机密的本地、OAuth 或环境凭证状态。 |
| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称;在运行时加载前,这些命令应生成具备插件感知能力的配置和 CLI 诊断信息。 |
| `providerAuthEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级 provider 凭证环境变量元数据。 |
| `providerAuthAliases` | 否 | `Record<string, string>` | 应复用另一个 provider id 进行凭证查找的 provider id例如共享基础 provider API key 和凭证配置文件的 coding provider。 |
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级渠道环境变量元数据。将其用于由环境变量驱动的渠道设置,或用于通用启动/配置辅助工具应看到的凭证界面。 |
| `providerAuthChoices` | 否 | `object[]` | 用于 onboarding 选择器、首选 provider 解析和简单 CLI flag 绑定的轻量级凭证选择元数据。 |
| `activation` | 否 | `object` | 用于 provider、命令、渠道、路由和由能力触发的加载的轻量级激活规划器元数据。仅限元数据;实际行为仍由插件运行时负责。 |
| `setup` | 否 | `object` | 供发现和设置界面在不加载插件运行时的情况下检查的轻量级设置 / onboarding 描述符。 |
| `qaRunners` | 否 | `object[]` | 共享 `openclaw qa` 主机在插件运行时加载前使用的轻量级 QA 运行器描述符。 |
| `contracts` | 否 | `object` | 面向外部凭证 hook、语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、网页抓取、网页搜索和工具归属的静态内置能力快照。 |
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | 为 `contracts.mediaUnderstandingProviders` 中声明的 provider id 提供的轻量级媒体理解默认值。 |
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到发现和验证界面中。 |
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
| `name` | 否 | `string` | 人类可读的插件名称。 |
| `description` | 否 | `string` | 显示在插件界面中的简短摘要。 |
| `version` | 否 | `string` | 信息性插件版本。 |
| `uiHints` | 否 | `Record<string, object>` | 配置字段的 UI 标签、占位符和敏感性提示。 |
| `id` | 是 | `string` | 规范插件 id。这是 `plugins.entries.<id>` 中使用的 id。 |
| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 |
| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略此字段,或将其设置为任何非 `true` 的值,可使插件默认保持禁用。 |
| `legacyPluginIds` | 否 | `string[]` | 会规范化为此规范插件 id 的旧版 id。 |
| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当凭证、配置或模型引用提到这些提供商 id 时,应自动启用此插件。 |
| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明 `plugins.slots.*` 使用的排他性插件类型。 |
| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于设备发现和配置验证。 |
| `providers` | 否 | `string[]` | 由此插件拥有的提供商 id。 |
| `providerDiscoveryEntry` | 否 | `string` | 轻量级提供商发现模块路径,相对于插件根目录,用于可在不激活完整插件运行时的情况下加载的、受清单作用域约束的提供商目录元数据。 |
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型家族元数据,用于在运行时之前自动加载插件。 |
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的端点 host/baseUrl 元数据,用于核心在提供商运行时加载前必须分类的提供商路由。 |
| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 id。用于根据显式配置引用进行启动时自动激活。 |
| `syntheticAuthRefs` | 否 | `string[]` | 在运行时加载前进行冷启动模型发现期间,应探测其插件自有 synthetic auth hook 的提供商或 CLI 后端引用。 |
| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API 密钥值,表示非密钥的本地、OAuth 或环境凭证状态。 |
| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称,应在运行时加载前生成具备插件感知能力的配置和 CLI 诊断信息。 |
| `providerAuthEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级提供商凭证环境变量元数据。 |
| `providerAuthAliases` | 否 | `Record<string, string>` | 应复用另一个提供商 id 进行凭证查找的提供商 id例如共享基础提供商 API 密钥和凭证配置文件的 coding 提供商。 |
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级渠道环境变量元数据。将其用于由环境变量驱动的渠道设置或凭证界面,以便通用启动/配置辅助逻辑能够识别。 |
| `providerAuthChoices` | 否 | `object[]` | 用于 onboarding 选择器、首选提供商解析和简单 CLI 标志接线的轻量级凭证选择元数据。 |
| `activation` | 否 | `object` | 用于提供商、命令、渠道、路由及能力触发加载的轻量级激活规划器元数据。仅为元数据;实际行为仍由插件运行时负责。 |
| `setup` | 否 | `object` | 轻量级设置 / onboarding 描述符,设备发现和设置界面在不加载插件运行时的情况下检查。 |
| `qaRunners` | 否 | `object[]` | 共享 `openclaw qa` 主机在插件运行时加载前使用的轻量级 QA 运行器描述符。 |
| `contracts` | 否 | `object` | 外部凭证 hook、语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、web-fetch、网页搜索及工具归属的静态内置能力快照。 |
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | 为 `contracts.mediaUnderstandingProviders` 中声明的提供商 id 提供的轻量级媒体理解默认值。 |
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到设备发现和验证界面中。 |
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
| `name` | 否 | `string` | 便于人阅读的插件名称。 |
| `description` | 否 | `string` | 在插件界面中显示的简短摘要。 |
| `version` | 否 | `string` | 说明性插件版本。 |
| `uiHints` | 否 | `Record<string, object>` | 配置字段的 UI 标签、占位符和敏感性提示。 |
## `providerAuthChoices` 参考
每个 `providerAuthChoices` 条目描述一个 onboarding 或凭证选择。
OpenClaw 会在 provider 运行时加载前读取这些内容
OpenClaw 会在提供商运行时加载前读取它
| 字段 | 必填 | 类型 | 含义 |
| --------------------- | -------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `provider` | 是 | `string` | 此选择所属的 provider id。 |
| `method` | 是 | `string` | 要分发到的凭证方法 id。 |
| `choiceId` | 是 | `string` | onboarding 和 CLI 流程使用的稳定凭证选择 id。 |
| `choiceLabel` | 否 | `string` | 面向用户的标签。如果省略OpenClaw 会回退到 `choiceId`。 |
| `choiceHint` | 否 | `string` | 选择器中的简短帮助文本。 |
| `assistantPriority` | 否 | `number` | 在由 assistant 驱动的交互式选择器中,值越小排序越靠前。 |
| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在 assistant 选择器中隐藏此选择,但仍允许手动通过 CLI 选择。 |
| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选择的旧版 choice id。 |
| `groupId` | 否 | `string` | 用于对相关选择分组的可选分组 id。 |
| `groupLabel` | 否 | `string` | 该分组面向用户标签。 |
| `groupHint` | 否 | `string` | 该分组的简短帮助文本。 |
| `optionKey` | 否 | `string` | 用于简单单 flag 凭证流程的内部选项键。 |
| `cliFlag` | 否 | `string` | CLI flag 名称,例如 `--openrouter-api-key`。 |
| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key <key>`。 |
| `cliDescription` | 否 | `string` | CLI 帮助中使用的描述。 |
| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选择应出现在哪些 onboarding 界面中。如果省略,默认值为 `["text-inference"]`。 |
| `provider` | 是 | `string` | 此选择所属的提供商 id。 |
| `method` | 是 | `string` | 要分发到的凭证方法 id。 |
| `choiceId` | 是 | `string` | onboarding 和 CLI 流程使用的稳定凭证选择 id。 |
| `choiceLabel` | 否 | `string` | 面向用户的标签。若省略OpenClaw 会回退到 `choiceId`。 |
| `choiceHint` | 否 | `string` | 选择器中的简短辅助文本。 |
| `assistantPriority` | 否 | `number` | 在由智能体驱动的交互式选择器中,值越小越靠前。 |
| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在智能体选择器中隐藏此选项,同时仍允许通过手动 CLI 选择。 |
| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到此替代选项的旧版 choice id。 |
| `groupId` | 否 | `string` | 用于对相关选项分组的可选组 id。 |
| `groupLabel` | 否 | `string` | 该分组面向用户标签。 |
| `groupHint` | 否 | `string` | 该分组的简短辅助文本。 |
| `optionKey` | 否 | `string` | 用于简单单标志凭证流程的内部选项键。 |
| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 |
| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key <key>`。 |
| `cliDescription` | 否 | `string` | CLI 帮助中使用的说明。 |
| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选项应出现在哪些 onboarding 界面中。若省略,默认值为 `["text-inference"]`。 |
## `commandAliases` 参考
当插件拥有某个运行时命令名,而用户可能会误将其放入 `plugins.allow`,或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用这些元数据提供诊断,而无需导入插件运行时代码
当插件拥有一个运行时命令名称,而用户可能会误将其放入 `plugins.allow`,或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用这些元数据在不导入插件运行时代码的情况下提供诊断
```json
{
@ -202,19 +201,19 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
| 字段 | 必填 | 类型 | 含义 |
| ------------ | -------- | ----------------- | ----------------------------------------------------------------------- |
| `name` | 是 | `string` | 属于此插件的命令名称。 |
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 |
| `cliCommand` | 否 | `string` | 若存在,用于建议 CLI 操作的相关根 CLI 命令。 |
| `name` | 是 | `string` | 属于此插件的命令名称。 |
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 |
| `cliCommand` | 否 | `string` | 若存在,用于 CLI 操作时建议的相关根 CLI 命令。 |
## `activation` 参考
当插件可以以低成本声明哪些控制平面事件应将其纳入激活 / 加载计划时,请使用 `activation`
此块是规划器元数据,不是生命周期 API。它不会注册运行时行为不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段在回退到现有清单归属元数据(如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks之前缩小候选插件范围。
此块是规划器元数据,不是生命周期 API。它不会注册运行时行为不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段在回退到现有清单归属元数据(`providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks之前缩小候选插件范围。
优先使用已能描述归属关系的最窄元数据。当这些字段能够表达关系时,请使用 `providers`、`channels`、`commandAliases`、设置描述符或 `contracts`。仅在这些归属字段无法表示额外的规划器提示时,才使用 `activation`
优先使用已能描述归属关系的最窄元数据。当 `providers`、`channels`、`commandAliases`、设置描述符或 `contracts` 这些字段已能表达该关系时,应使用它们。对于无法通过这些归属字段表示的额外规划器提示,再使用 `activation`
此块仅包含元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时 / 插件入口点。当前使用方会在更广泛的插件加载之前,将其作缩小范围的提示,因此缺少激活元数据通常只会带来性能成本;在旧版清单归属回退仍存在时,它不应影响正确性。
此块仅元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时 / 插件入口点。当前使用方会在更广泛的插件加载之前,将其作缩小范围的提示,因此缺少激活元数据通常只会带来性能损失;在旧版清单归属回退机制仍存在时,它不应改变正确性。
```json
{
@ -230,27 +229,26 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
| 字段 | 必填 | 类型 | 含义 |
| ---------------- | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `onProviders` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的 provider id。 |
| `onCommands` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的命令 id。 |
| `onChannels` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的渠道 id。 |
| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的路由类型。 |
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 控制平面激活规划中使用的宽泛能力提示。若可能,优先使用更窄的字段。 |
| `onProviders` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的提供商 id。 |
| `onCommands` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的命令 id。 |
| `onChannels` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的渠道 id。 |
| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的路由类型。 |
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 控制平面激活规划中使用的宽泛能力提示。尽可能优先使用更窄的字段。 |
当前在线使用方:
- 由命令触发的 CLI 规划会回退到旧版
`commandAliases[].cliCommand``commandAliases[].name`
- 由渠道触发的设置 / 渠道规划在缺少显式渠道激活元数据时,会回退到旧版 `channels[]`
- 由渠道触发的设置 / 渠道规划在缺少显式渠道激活元数据时,会回退到旧版 `channels[]`
归属
- 由 provider 触发的设置 / 运行时规划在缺少显式 provider
激活元数据时,会回退到旧版
- 由提供商触发的设置 / 运行时规划,在缺少显式提供商激活元数据时,会回退到旧版
`providers[]` 和顶层 `cliBackends[]` 归属
规划器诊断可以区分显式激活提示和清单归属回退。例如,`activation-command-hint` 表示匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改为使用 `commandAliases` 归属。这些原因标签用于主诊断和测试;插件作者应继续声明最能描述归属关系的元数据。
规划器诊断可以区分显式激活提示和清单归属回退。例如,`activation-command-hint` 表示匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改为使用 `commandAliases` 归属。这些原因标签用于宿主诊断和测试;插件作者应继续声明最能描述归属关系的元数据。
## `qaRunners` 参考
当插件在共享 `openclaw qa` 根命令下提供一个或多个传输运行器时,请使用 `qaRunners`。保持这些元数据轻量且静态;实际的 CLI 注册仍由插件运行时通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 接口负责
当插件在共享 `openclaw qa` 根命令下提供一个或多个传输运行器时,请使用 `qaRunners`。保持这些元数据轻量且静态;插件运行时通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 界面负责实际的 CLI 注册
```json
{
@ -265,8 +263,8 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
| 字段 | 必填 | 类型 | 含义 |
| ------------- | -------- | -------- | ------------------------------------------------------------------ |
| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 下的子命令,例如 `matrix`。 |
| `description` | 否 | `string` | 当共享主需要一个 stub 命令时使用的回退帮助文本。 |
| `commandName` | 是 | `string` | 挂载在 `openclaw qa` 下的子命令,例如 `matrix`。 |
| `description` | 否 | `string` | 当共享宿主需要一个 stub 命令时使用的回退帮助文本。 |
## `setup` 参考
@ -289,28 +287,28 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
}
```
顶层 `cliBackends` 依然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是用于控制平面 / 设置流程的、仅元数据的设置专用描述符界面。
顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是控制平面 / 设置流程所使用的、应保持为纯元数据的设置专用描述符界面。
如果存在,`setup.providers` 和 `setup.cliBackends` 是设置发现时优先使用的描述符优先查找界面。如果该描述符只能缩小候选插件范围,而设置仍需要更丰富的设置时运行时 hook请将 `requiresRuntime` 设为 `true`,并保留 `setup-api` 作为回退执行路径。
存在 `setup.providers``setup.cliBackends` 时,它们是设置发现的首选“描述符优先”查找界面。如果该描述符只能缩小候选插件范围,而设置流程仍需要更丰富的设置时运行时 hooks,请将 `requiresRuntime` 设为 `true`,并保留 `setup-api` 作为回退执行路径。
由于设置查找可能执行由插件拥有的 `setup-api` 代码,规范化`setup.providers[].id``setup.cliBackends[]`在所有已发现插件之间必须保持唯一。归属不明确时会以封闭失败处理,而不是按发现顺序选出一个获胜者
由于设置查找可能执行由插件拥有的 `setup-api` 代码,经过规范化的 `setup.providers[].id``setup.cliBackends[]`必须在所有已发现插件中保持唯一。若归属关系存在歧义,系统会以失败关闭的方式处理,而不是按发现顺序挑选一个赢家
### `setup.providers` 参考
| 字段 | 必填 | 类型 | 含义 |
| ------------- | -------- | ---------- | ------------------------------------------------------------------------------------ |
| `id` | 是 | `string` | 在设置或 onboarding 期间暴露的 provider id。保持规范化 id 在全局范围内唯一。 |
| `authMethods` | 否 | `string[]` | 此 provider 在不加载完整运行时的情况下支持的设置 / 凭证方法 id。 |
| `envVars` | 否 | `string[]` | 通用设置 / 状态界面可在插件运行时加载前检查的环境变量。 |
| `id` | 是 | `string` | 在设置或 onboarding 期间暴露的提供商 id。保持规范化后的 id 在全局唯一。 |
| `authMethods` | 否 | `string[]` | 此提供商在不加载完整运行时的情况下支持的设置 / 凭证方法 id。 |
| `envVars` | 否 | `string[]` | 通用设置 / 状态界面可在插件运行时加载前检查的环境变量。 |
### `setup` 字段
| 字段 | 必填 | 类型 | 含义 |
| ------------------ | -------- | ---------- | --------------------------------------------------------------------------------------------------- |
| `providers` | 否 | `object[]` | 在设置和 onboarding 期间暴露的 provider 设置描述符。 |
| `cliBackends` | 否 | `string[]` | 用于描述符优先设置查找的设置时后端 id。保持规范化 id 在全局范围内唯一。 |
| `configMigrations` | 否 | `string[]` | 由此插件设置界面拥有的配置迁移 id。 |
| `requiresRuntime` | 否 | `boolean` | 描述符查找后,设置是否仍需要执行 `setup-api`。 |
| `providers` | 否 | `object[]` | 在设置和 onboarding 期间暴露的提供商设置描述符。 |
| `cliBackends` | 否 | `string[]` | 用于描述符优先设置查找的设置时后端 id。保持规范化后的 id 在全局唯一。 |
| `configMigrations` | 否 | `string[]` | 由此插件设置界面拥有的配置迁移 id。 |
| `requiresRuntime` | 否 | `boolean` | 描述符查找后,设置流程是否仍需要执行 `setup-api`。 |
## `uiHints` 参考
@ -333,16 +331,16 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
| 字段 | 类型 | 含义 |
| ------------- | ---------- | --------------------------------------- |
| `label` | `string` | 面向用户的字段标签。 |
| `help` | `string` | 简短帮助文本。 |
| `tags` | `string[]` | 可选的 UI 标签。 |
| `advanced` | `boolean` | 将该字段标记为高级字段。 |
| `sensitive` | `boolean` | 将该字段标记为机密或敏感字段。 |
| `placeholder` | `string` | 表单输入的占位文本。 |
| `label` | `string` | 面向用户的字段标签。 |
| `help` | `string` | 简短辅助文本。 |
| `tags` | `string[]` | 可选的 UI 标签。 |
| `advanced` | `boolean` | 将字段标记为高级项。 |
| `sensitive` | `boolean` | 将字段标记为密钥或敏感项。 |
| `placeholder` | `string` | 表单输入的占位文本。 |
## `contracts` 参考
在 OpenClaw 可以在不导入插件运行时的情况下读取静态能力归属元数据时,才使用 `contracts`
当用于 OpenClaw 可在不导入插件运行时的情况下读取的静态能力归属元数据时,才使用 `contracts`
```json
{
@ -367,26 +365,26 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
| 字段 | 类型 | 含义 |
| -------------------------------- | ---------- | ----------------------------------------------------------------- |
| `embeddedExtensionFactories` | `string[]` | 内置插件可为其注册工厂的嵌入式运行时 id。 |
| `externalAuthProviders` | `string[]` | 此插件拥有其外部凭证配置文件 hook 的 provider id。 |
| `speechProviders` | `string[]` | 由此插件拥有的语音 provider id。 |
| `realtimeTranscriptionProviders` | `string[]` | 由此插件拥有的实时转录 provider id。 |
| `realtimeVoiceProviders` | `string[]` | 由此插件拥有的实时语音 provider id。 |
| `memoryEmbeddingProviders` | `string[]` | 由此插件拥有的 Memory 嵌入 provider id。 |
| `mediaUnderstandingProviders` | `string[]` | 由此插件拥有的媒体理解 provider id。 |
| `imageGenerationProviders` | `string[]` | 由此插件拥有的图像生成 provider id。 |
| `videoGenerationProviders` | `string[]` | 由此插件拥有的视频生成 provider id。 |
| `webFetchProviders` | `string[]` | 由此插件拥有的网页抓取 provider id。 |
| `webSearchProviders` | `string[]` | 由此插件拥有的网页搜索 provider id。 |
| `tools` | `string[]` | 此插件拥有、用于内置契约检查的智能体工具名称。 |
| `embeddedExtensionFactories` | `string[]` | 内置插件可为其注册工厂的嵌入式运行时 id。 |
| `externalAuthProviders` | `string[]` | 此插件拥有其外部凭证配置文件 hook 的提供商 id。 |
| `speechProviders` | `string[]` | 此插件拥有的语音提供商 id。 |
| `realtimeTranscriptionProviders` | `string[]` | 此插件拥有的实时转录提供商 id。 |
| `realtimeVoiceProviders` | `string[]` | 此插件拥有的实时语音提供商 id。 |
| `memoryEmbeddingProviders` | `string[]` | 此插件拥有的 Memory 嵌入提供商 id。 |
| `mediaUnderstandingProviders` | `string[]` | 此插件拥有的媒体理解提供商 id。 |
| `imageGenerationProviders` | `string[]` | 此插件拥有的图像生成提供商 id。 |
| `videoGenerationProviders` | `string[]` | 此插件拥有的视频生成提供商 id。 |
| `webFetchProviders` | `string[]` | 此插件拥有的 web-fetch 提供商 id。 |
| `webSearchProviders` | `string[]` | 此插件拥有的网页搜索提供商 id。 |
| `tools` | `string[]` | 此插件拥有的智能体工具名称,用于内置契约检查。 |
实现`resolveExternalAuthProfiles` 的 provider 插件应声明 `contracts.externalAuthProviders`。未声明的插件仍会通过已弃用的兼容性回退路径运行,但该回退路径更慢,并将在迁移窗口结束后移除。
实现 `resolveExternalAuthProfiles` 的提供商插件应声明 `contracts.externalAuthProviders`。未声明该项的插件仍会通过已弃用的兼容性回退路径运行,但该回退路径更慢,并将在迁移窗口结束后移除。
内置的 Memory 嵌入 provider 应为其公开的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括诸如 `local` 之类的内置适配器。独立 CLI 路径使用此清单契约,在完整 Gateway 网关运行时注册 provider 之前,仅加载拥有该能力的插件。
内置的 Memory 嵌入提供商应为其暴露的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括诸如 `local` 之类的内建适配器。独立 CLI 路径使用此清单契约,仅在完整 Gateway 网关运行时注册提供商之前加载归属插件。
## `mediaUnderstandingProviderMetadata` 参考
当媒体理解 provider 具有默认模型、自动凭证回退优先级,或通用核心辅助工具在运行时加载前所需的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`键也必须在 `contracts.mediaUnderstandingProviders` 中声明。
当媒体理解提供商具有默认模型、自动凭证回退优先级,或通用核心辅助逻辑在运行时加载前所需的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`。键也必须在 `contracts.mediaUnderstandingProviders` 中声明。
```json
{
@ -409,18 +407,18 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
}
```
每个 provider 条目可包含:
每个提供商条目可包含:
| 字段 | 类型 | 含义 |
| ---------------------- | ----------------------------------- | ---------------------------------------------------------------------------- |
| `capabilities` | `("image" \| "audio" \| "video")[]` | 该 provider 暴露的媒体能力。 |
| `defaultModels` | `Record<string, string>` | 当配置未指定模型时使用的能力到模型默认映射。 |
| `autoPriority` | `Record<string, number>` | 用于基于凭证自动 provider 回退时,数字越小排序越靠前。 |
| `nativeDocumentInputs` | `"pdf"[]` | provider 支持的原生文档输入。 |
| `capabilities` | `("image" \| "audio" \| "video")[]` | 此提供商暴露的媒体能力。 |
| `defaultModels` | `Record<string, string>` | 当配置未指定模型时使用的能力到模型默认映射。 |
| `autoPriority` | `Record<string, number>` | 用于基于凭证自动回退提供商的排序优先级,数字越小越靠前。 |
| `nativeDocumentInputs` | `"pdf"[]` | 提供商支持的原生文档输入。 |
## `channelConfigs` 参考
当渠道插件在运行时加载前需要低成本的配置元数据时,请使用 `channelConfigs`
当渠道插件在运行时加载前需要轻量级配置元数据时,请使用 `channelConfigs`
```json
{
@ -451,15 +449,15 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
| 字段 | 类型 | 含义 |
| ------------- | ------------------------ | ----------------------------------------------------------------------------------------- |
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 |
| `uiHints` | `Record<string, object>` | 该渠道配置部分可选 UI 标签 / 占位符 / 敏感性提示。 |
| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查界面的渠道标签。 |
| `description` | `string` | 用于检查和目录界面的简短渠道描述。 |
| `preferOver` | `string[]` | 在选择界面中,此渠道应优先于的旧版或较低优先级插件 id。 |
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 |
| `uiHints` | `Record<string, object>` | 该渠道配置部分可选 UI 标签 / 占位符 / 敏感性提示。 |
| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查界面的渠道标签。 |
| `description` | `string` | 用于检查和目录界面的简短渠道描述。 |
| `preferOver` | `string[]` | 在选择界面中,此渠道应优先于的旧版或较低优先级插件 id。 |
## `modelSupport` 参考
当 OpenClaw 应在插件运行时加载前,根据 `gpt-5.5``claude-sonnet-4.6` 这样的简写模型 id 推断你的 provider 插件时,请使用 `modelSupport`
当 OpenClaw 应在插件运行时加载前,根据 `gpt-5.5``claude-sonnet-4.6` 之类的简写模型 id 推断你的提供商插件时,请使用 `modelSupport`
```json
{
@ -470,77 +468,71 @@ OpenClaw 会在 provider 运行时加载前读取这些内容。
}
```
OpenClaw 应用以下优先级
OpenClaw 按以下优先级处理
- 显式`provider/model` 引用使用拥有该模型的 `providers` 清单元数据
- 显式 `provider/model` 引用使用归属 `providers` 清单元数据
- `modelPatterns` 优先于 `modelPrefixes`
- 如果一个非内置插件和一个内置插件都匹配,则非内置插件
- 剩余的歧义会被忽略,直到用户或配置指定 provider
- 如果一个非内置插件和一个内置插件都匹配,则非内置插件胜
- 剩余歧义会被忽略,直到用户或配置指定提供商
字段:
| 字段 | 类型 | 含义 |
| --------------- | ---------- | ------------------------------------------------------------------------------- |
| `modelPrefixes` | `string[]` | 针对简写模型 id 使用 `startsWith` 匹配的前缀。 |
| `modelPatterns` | `string[]` | 在移除 profile 后缀后,对简写模型 id 进行匹配的正则表达式源码。 |
| `modelPrefixes` | `string[]` | 使用 `startsWith` 对简写模型 id 进行匹配的前缀。 |
| `modelPatterns` | `string[]` | 在移除 profile 后缀后,对简写模型 id 进行匹配的正则表达式源码。 |
旧版顶层能力键已弃用。使用 `openclaw doctor --fix`
`speechProviders`、`realtimeTranscriptionProviders`、
`realtimeVoiceProviders`、`mediaUnderstandingProviders`、
`imageGenerationProviders`、`videoGenerationProviders`、
`webFetchProviders``webSearchProviders` 移动到 `contracts` 下;常规清单加载不再将这些顶层字段视为能力归属。
旧版顶层能力键已弃用。请使用 `openclaw doctor --fix``speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;常规清单加载不再将这些顶层字段视为能力归属。
## 清单与 `package.json` 的区别
## 清单与 package.json 的区别
这两个文件承担不同的职责:
| 文件 | 用途 |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.plugin.json` | 发现、配置验证、凭证选择元数据,以及在插件代码运行前必须存在的 UI 提示 |
| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 块 |
| `openclaw.plugin.json` | 设备发现、配置验证、凭证选择元数据,以及必须在插件代码运行前存在的 UI 提示 |
| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 块 |
如果你不确定某条元数据应该放在哪里,请使用以下规则:
如果你不确定某项元数据应放在哪里,请使用以下规则:
- 如果 OpenClaw 必须在加载插件代码前知道它,就放到 `openclaw.plugin.json`
- 如果它与打包、入口文件或 npm 安装行为有关,就放到 `package.json`
- 如果 OpenClaw 必须在加载插件代码之前知道它,请将其放在 `openclaw.plugin.json`
- 如果它与打包、入口文件或 npm 安装行为有关,请将其放在 `package.json`
### 影响发现的 `package.json` 字段
### 影响设备发现的 `package.json` 字段
某些运行时前插件元数据被有意放在 `package.json`
`openclaw` 块中,而不是 `openclaw.plugin.json` 中。
某些运行时前的插件元数据有意存放在 `package.json``openclaw` 块下,而不是 `openclaw.plugin.json` 中。
重要示例:
| 字段 | 含义 |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `openclaw.extensions` | 声明原生插件入口点。必须保持在插件包目录内。 |
| `openclaw.runtimeExtensions` | 为已安装包声明已构建的 JavaScript 运行时入口点。必须保持在插件包目录内。 |
| `openclaw.setupEntry` | 轻量级、仅用于设置的入口点,供 onboarding、延迟渠道启动以及只读的渠道状态 / SecretRef 发现期间使用。必须保持在插件包目录内。 |
| `openclaw.runtimeSetupEntry` | 为已安装包声明已构建的 JavaScript 设置入口点。必须保持在插件包目录内。 |
| `openclaw.channel` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择文案。 |
| `openclaw.channel.configuredState` | 轻量级的已配置状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经存在仅基于环境变量的设置?”。 |
| `openclaw.channel.persistedAuthState` | 轻量级持久化凭证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已经有任何账户登录?”。 |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 内置和外部发布插件的安装 / 更新提示。 |
| `openclaw.install.defaultChoice` | 当存在多个安装来源时,首选的安装路径。 |
| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 主机版本,使用类似 `>=2026.3.22` 的 semver 下限。 |
| `openclaw.install.expectedIntegrity` | 预期的 npm 分发完整性字符串,例如 `sha512-...`;安装和更新流程会据此校验拉取的制品。 |
| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个范围很窄的内置插件重新安装恢复路径。 |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许在启动期间先加载仅设置用途的渠道界面,再加载完整渠道插件。 |
| `openclaw.extensions` | 声明原生插件入口点。必须保留在插件包目录内。 |
| `openclaw.runtimeExtensions` | 为已安装包声明构建后的 JavaScript 运行时入口点。必须保留在插件包目录内。 |
| `openclaw.setupEntry` | 仅用于设置的轻量级入口点,用于 onboarding、延迟渠道启动以及只读的渠道状态 / SecretRef 发现。必须保留在插件包目录内。 |
| `openclaw.runtimeSetupEntry` | 为已安装包声明构建后的 JavaScript 设置入口点。必须保留在插件包目录内。 |
| `openclaw.channel` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择文案。 |
| `openclaw.channel.configuredState` | 轻量级 configured-state 检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已存在仅通过环境变量完成的设置?”。 |
| `openclaw.channel.persistedAuthState` | 轻量级持久化凭证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已有任何已登录状态?”。 |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 内置插件和外部发布插件的安装 / 更新提示。 |
| `openclaw.install.defaultChoice` | 当有多个安装来源可用时的首选安装路径。 |
| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 宿主版本,使用如 `>=2026.3.22` 这样的 semver 下限。 |
| `openclaw.install.expectedIntegrity` | 预期的 npm dist 完整性字符串,例如 `sha512-...`;安装和更新流程会据此校验获取到的工件。 |
| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个范围很窄的内置插件重新安装恢复路径。 |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许在启动期间先加载仅用于设置的渠道界面,再加载完整渠道插件。 |
清单元数据决定了在运行时加载前onboarding 中会显示哪些 provider / channel / setup 选择。`package.json#openclaw.install` 则告诉 onboarding当用户选中这些选项之一时,应如何获取或启用该插件。不要将安装提示移到 `openclaw.plugin.json` 中。
清单元数据决定了在运行时加载前onboarding 中会出现哪些提供商 / 渠道 / 设置选项。`package.json#openclaw.install` 则告诉 onboarding当用户选择其中某个选项时,应如何获取或启用该插件。不要将安装提示移到 `openclaw.plugin.json` 中。
`openclaw.install.minHostVersion` 会在安装和清单注册表加载期间强制执行。无效值会被拒绝;较新的但有效的值会让旧主机跳过该插件。
`openclaw.install.minHostVersion` 会在安装期间和清单注册表加载期间强制执行。无效值会被拒绝;值若有效但要求更高版本,则会在旧宿主上跳过该插件。
精确的 npm 版本固定已存在于 `npmSpec` 中,例如
`"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录条目应将精确 spec 与 `expectedIntegrity` 配对使用,以便当拉取到的 npm 制品不再匹配已固定版本时,更新流程会以封闭失败方式处理。出于兼容性考虑,交互式 onboarding 仍会提供受信任的注册表 npm spec包括裸包名和 dist-tag。目录诊断可以区分精确、浮动、已固定完整性和缺少完整性的来源。当存在 `expectedIntegrity` 时,安装 / 更新流程会强制执行它;若省略,则会记录注册表解析结果,但不带完整性固定。
精确 npm 版本固定已存在于 `npmSpec` 中,例如 `"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录条目应将精确 spec 与 `expectedIntegrity` 配对使用,这样如果获取到的 npm 工件不再匹配所固定的发布版本,更新流程就会以失败关闭的方式处理。为了兼容性,交互式 onboarding 仍会提供受信任注册表的 npm spec包括裸包名和 dist-tag。目录诊断可以区分精确来源、浮动来源、带完整性固定的来源、缺少完整性固定的来源以及无效的默认选项来源。存在 `expectedIntegrity` 时,安装 / 更新流程会强制执行它;省略时,会记录注册表解析结果,但不附带完整性固定。
当状态、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`该设置入口点应暴露渠道元数据以及适用于设置场景的配置、状态和密钥适配器;请将网络客户端、Gateway 网关监听器和传输运行时保留在主扩展入口点中。
当状态、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`设置入口点应暴露渠道元数据,以及可安全用于设置的配置、状态和密钥适配器;网络客户端、Gateway 网关监听器和传输运行时保留在主扩展入口点中。
运行时入口点字段不会覆盖源入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让一个越界的 `openclaw.extensions` 路径变得可加载。
运行时入口点字段不会覆盖针对入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让一个越界的 `openclaw.extensions` 路径变得可加载。
`openclaw.install.allowInvalidConfigRecovery`适用范围被有意限制得很窄。它并不会让任意损坏的配置都变得可安装。当前它只允许安装流程从特定的旧版内置插件升级失败中恢复,例如缺失的内置插件路径,或同一内置插件对应的陈旧 `channels.<id>` 条目。无关的配置错误仍会阻止安装,并将运维人员引导到 `openclaw doctor --fix`
`openclaw.install.allowInvalidConfigRecovery`范围是有意收窄的。它不会让任意损坏的配置都可安装。当前它只允许安装流程从某些特定的陈旧内置插件升级失败中恢复,例如缺失的内置插件路径,或该同一内置插件下陈旧的 `channels.<id>` 条目。无关的配置错误仍会阻止安装,并将操作人员引导至 `openclaw doctor --fix`
`openclaw.channel.persistedAuthState` 是一个微型检查器模块的包元数据:
`openclaw.channel.persistedAuthState` 是一个用于极小检查器模块的包元数据:
```json
{
@ -556,9 +548,9 @@ OpenClaw 应用以下优先级:
}
```
当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前执行一个低成本的“是 / 否”凭证探测时,请使用它。目标导出应是一个只读取持久化状态的小函数;不要通过完整渠道运行时 barrel 转发它。
当设置、Doctor 或 configured-state 流程需要在完整渠道插件加载前进行低成本的“是 / 否”凭证探测时,请使用它。目标导出应是一个只读取持久化状态的小函数;不要通过完整渠道运行时 barrel 转发它。
`openclaw.channel.configuredState`低成本的、仅基于环境变量的已配置检查也采用相同结构:
`openclaw.channel.configuredState`于低成本的仅环境变量 configured 检查采用相同结构:
```json
{
@ -574,11 +566,11 @@ OpenClaw 应用以下优先级:
}
```
某个渠道可以仅通过环境变量或其他很小的非运行时输入来判断已配置状态时,请使用它。如果该检查需要完整配置解析或真实的渠道运行时,请将该逻辑保留在插件的 `config.hasConfiguredState` hook 中。
一个渠道可以通过环境变量或其他极小的非运行时输入来回答 configured-state 时,请使用它。如果检查需要完整配置解析或真实渠道运行时,请将该逻辑保留在插件 `config.hasConfiguredState` hook 中。
## 发现优先级(重复插件 id
## 设备发现优先级(重复插件 id
OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区、配置中显式选定路径)。如果两个发现结果共享相同的 `id`,则只保留**优先级最高**的清单;较低优先级的重复项会被丢弃,而不是与其并列加载。
OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区、显式配置选定路径)。如果两个发现结果共享相同的 `id`,则只保留**优先级最高**的清单;优先级较低的重复项会被丢弃,而不会与之并行加载。
优先级从高到低如下:
@ -587,50 +579,50 @@ OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区
3. **全局安装** —— 安装到全局 OpenClaw 插件根目录中的插件
4. **工作区** —— 相对于当前工作区发现的插件
影响如下
影响:
- 放在工作区中的某个内置插件分叉版或旧副本,不会覆盖内置构建
- 若要真正用本地插件覆盖某个内置插件,请通过 `plugins.entries.<id>` 固定它,使其依靠优先级获胜,而不是依赖工作区发现。
- 被丢弃的重复项会被记录日志,以便 Doctor 和启动诊断指向被舍弃的副本。
- 放在工作区中的某个内置插件分叉版本或陈旧副本,不会遮蔽内置构建版本
- 若要真正用本地插件覆盖内置插件,请通过 `plugins.entries.<id>` 固定它,使其凭借优先级获胜,而不是依赖工作区发现。
- 被丢弃的重复项会被记录日志,以便 Doctor 和启动诊断可指出被舍弃的副本。
## JSON Schema 要求
- **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置。
- 可以使用空 schema例如 `{ "type": "object", "additionalProperties": false }`)。
- 可以接受空 schema例如 `{ "type": "object", "additionalProperties": false }`)。
- Schema 会在配置读写时验证,而不是在运行时验证。
## 验证行为
- 未知的 `channels.*`是**错误**,除非该 channel id 已由某个插件清单声明。
- 未知的 `channels.*`会被视为**错误**,除非该渠道 id 已由某个插件清单声明。
- `plugins.entries.<id>`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*`
必须引用**可发现的**插件 id。未知 id 属于**错误**。
必须引用**可发现的**插件 id。未知 id 会被视为**错误**。
- 如果某个插件已安装,但其清单或 schema 损坏或缺失则验证会失败Doctor 会报告该插件错误。
- 如果插件配置存在,但插件处于**禁用**状态,则配置会被保留,并在 Doctor + 日志中显示**警告**。
- 如果插件配置存在但该插件**已禁用**,则配置会被保留,并且 Doctor + 日志中会显示**警告**。
完整的 `plugins.*` schema 请参阅[配置参考](/zh-CN/gateway/configuration)。
## 注意事项
## 说明
- 清单对于**原生 OpenClaw 插件**是**必需的**,包括本地文件系统加载。运行时仍会单独加载插件模块;清单仅用于发现 + 验证。
- 原生清单使用 JSON5 解析,因此注释、尾随逗号和未加引号的键都可接受,只要最终值仍是一个对象
- 清单加载器只会读取文档中说明的清单字段。避免使用自定义顶层键。
- 当插件不需要它们时,`channels`、`providers`、`cliBackends` 和 `skills` 都可以省略
- `providerDiscoveryEntry` 必须保持轻量,不应导入范围很广的运行时代码;它适用于静态 provider 目录元数据或窄范围的发现描述符,不适用于请求时执行
- 对于**原生 OpenClaw 插件**,包括本地文件系统加载,清单都是**必需的**。运行时仍会单独加载插件模块;清单仅用于设备发现 + 验证。
- 原生清单使用 JSON5 解析,因此只要最终值仍是一个对象,就接受注释、尾随逗号和未加引号的键名
- 清单加载器只会读取已记录的清单字段。避免使用自定义顶层键。
- 当插件不需要时,可以省略 `channels`、`providers`、`cliBackends` 和 `skills`
- `providerDiscoveryEntry` 必须保持轻量,不应导入宽泛的运行时代码;应将其用于静态提供商目录元数据或窄范围发现描述符,而不是请求时执行逻辑
- 排他性插件类型通过 `plugins.slots.*` 选择:`kind: "memory"` 通过 `plugins.slots.memory``kind: "context-engine"` 通过 `plugins.slots.contextEngine`(默认 `legacy`)。
- 环境变量元数据(`providerAuthEnvVars`、`channelEnvVars`)仅具声明性。状态、审计、cron 投递验证以及其他只读界面,在将某个环境变量视为已配置之前,仍会应用插件信任和有效激活策略。
- 关于需要 provider 代码的运行时向导元数据,请参阅 [Provider runtime hooks](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。
- 环境变量元数据(`providerAuthEnvVars`、`channelEnvVars`)仅是声明式元数据。状态、审计、cron 投递验证及其他只读界面在将环境变量视为已配置之前,仍会应用插件信任和有效激活策略。
- 关于需要提供商代码的运行时向导元数据,请参阅[提供商运行时 hooks](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。
- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器 allowlist 要求(例如 pnpm `allow-build-scripts` + `pnpm rebuild <package>`)。
## 相关内容
<CardGroup cols={3}>
<Card title="构建插件" href="/zh-CN/plugins/building-plugins" icon="rocket">
插件快速开始
插件入门指南
</Card>
<Card title="插件架构" href="/zh-CN/plugins/architecture" icon="diagram-project">
内部架构能力模型。
内部架构能力模型。
</Card>
<Card title="SDK 概览" href="/zh-CN/plugins/sdk-overview" icon="book">
插件 SDK 参考子路径导入。
<Card title="插件 SDK 概览" href="/zh-CN/plugins/sdk-overview" icon="book">
插件 SDK 参考子路径导入。
</Card>
</CardGroup>