关于公共能力模型、插件形态以及所有权/执行 契约,请参阅 插件架构。本页是内部机制的 参考:加载流水线、注册表、运行时钩子、 Gateway 网关 HTTP 路由、导入路径和 schema 表。Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
加载流水线
启动时,OpenClaw 大致会执行以下操作:- 发现候选插件根目录
- 读取原生或兼容的 bundle 清单和 package 元数据
- 拒绝不安全的候选项
- 规范化插件配置(
plugins.enabled、allow、deny、entries、slots、load.paths) - 决定每个候选项是否启用
- 加载已启用的原生模块:已构建的内置模块使用原生加载器; 第三方本地源码 TypeScript 使用应急 Jiti 回退
- 调用原生
register(api)钩子,并将注册项收集到插件注册表 - 将注册表暴露给命令/运行时界面
activate 是 register 的旧版别名,加载器会解析存在的那个(def.register ?? def.activate),并在同一位置调用它。所有内置插件都使用 register;新插件请优先使用 register。清单优先行为
清单是控制面的事实来源。OpenClaw 使用它来:- 识别插件
- 发现声明的渠道/Skills/配置 schema 或 bundle 能力
- 验证
plugins.entries.<id>.config - 增强 Control UI 标签/占位符
- 显示安装/catalog 元数据
- 在不加载插件运行时的情况下保留低成本的激活和设置描述符
activation 和 setup 块保留在控制面。
它们是用于激活规划和设置发现的仅元数据描述符;
它们不会替代运行时注册、register(...) 或 setupEntry。
首批实时激活消费者现在会使用清单命令、渠道和提供商提示,
在更宽泛的注册表物化之前缩小插件加载范围:
- CLI 加载会缩小到拥有所请求主命令的插件
- 渠道设置/插件解析会缩小到拥有所请求 渠道 id 的插件
- 显式提供商设置/运行时解析会缩小到拥有所请求 提供商 id 的插件
- Gateway 网关启动规划会使用
activation.onStartup来处理显式启动 导入和启动选择退出;没有启动元数据的插件只会 通过更窄的激活触发器加载
all 范围,仍会从配置、启动规划、已配置的
渠道、slot 和自动启用规则派生出
显式的有效插件 id 集。如果派生出的集合为空,OpenClaw
会加载一个空的运行时注册表,而不是扩大到每个可发现的
插件。
激活规划器同时为现有调用方暴露仅 ids API,并为
新诊断暴露 plan API。计划条目会报告插件被选中的原因,
将显式 activation.* 规划器提示与清单所有权
回退分开,例如 providers、channels、commandAliases、setup.providers、
contracts.tools 和钩子。该原因拆分是兼容性边界:
现有插件元数据会继续工作,而新代码可以检测宽泛提示
或回退行为,而不改变运行时加载语义。
设置发现现在会优先使用描述符拥有的 id,例如 setup.providers 和
setup.cliBackends,在回退到
仍需要设置时运行时钩子的插件的 setup-api 之前缩小候选插件范围。提供商
设置列表使用清单 providerAuthChoices、由描述符派生的设置
选项和安装 catalog 元数据,而无需加载提供商运行时。显式
setup.requiresRuntime: false 是仅描述符的截断点;省略的
requiresRuntime 会保留旧版 setup-api 回退以兼容。如果多个
已发现插件声明了同一个规范化设置提供商或 CLI
后端 id,设置查找会拒绝这个有歧义的所有者,而不是依赖
发现顺序。当设置运行时确实执行时,注册表诊断会报告
setup.providers / setup.cliBackends 与 setup-api 注册的提供商或 CLI
后端之间的漂移,但不会阻止旧版插件。
插件缓存边界
OpenClaw 不会在按挂钟时间划分的窗口后面缓存插件发现结果或直接清单注册表 数据。安装、清单编辑和加载路径变更 必须在下一次显式元数据读取或快照重建时可见。 清单文件解析器可以保留一个有界的文件签名缓存,该缓存以已打开的 清单路径、inode、大小和时间戳为键;该缓存只用于避免 重新解析未变更的字节,且不得缓存发现、注册表、所有者或 策略答案。 安全的元数据快速路径是显式对象所有权,而不是隐藏缓存。 Gateway 网关启动热路径应通过调用链传递当前的PluginMetadataSnapshot、
派生出的 PluginLookUpTable,或显式清单注册表。
配置验证、启动自动启用、插件引导和提供商
选择可以复用这些对象,前提是它们代表当前配置和
插件清单。设置查找仍会按需重建清单元数据,
除非具体设置路径接收到显式清单注册表;应将其保持为冷路径回退,
而不是添加隐藏查找缓存。输入
变化时,重建并替换快照,而不是修改它或保留
历史副本。
活动插件注册表上的视图和内置渠道引导帮助程序
应从当前注册表/根目录重新计算。短生命周期 map 可以
在一次调用内用于去重工作或防止重入;它们不得变成进程
元数据缓存。
对于插件加载,持久缓存层是运行时加载。当代码或已安装构件确实被加载时,它可以复用
加载器状态,例如:
PluginLoaderCacheState和兼容的活动运行时注册表- jiti/module 缓存和公共界面加载器缓存,用于避免反复导入 同一个运行时界面
- 已安装插件构件的文件系统缓存
- 用于路径规范化或重复项解析的短生命周期每调用 map
- 发现结果
- 直接清单注册表
- 从已安装插件索引重建的清单注册表
- 提供商所有者查找、模型抑制、提供商策略或公共构件 元数据
- 任何其他由清单派生的答案,其中已变更的清单、已安装索引 或加载路径应在下一次元数据读取时可见
注册表模型
已加载的插件不会直接修改随机核心全局变量。它们会注册到一个 中心插件注册表中。 注册表跟踪:- 插件记录(身份、来源、origin、Status、诊断)
- 工具
- 旧版钩子和类型化钩子
- 渠道
- 提供商
- Gateway 网关 RPC 处理器
- HTTP 路由
- CLI 注册器
- 后台服务
- 插件拥有的命令
- 插件模块 -> 注册表注册
- 核心运行时 -> 注册表消费
会话绑定回调
绑定会话的插件可以在 approval 完成解析时做出反应。 使用api.onConversationBindingResolved(...) 在绑定
请求获批或被拒后接收回调:
status:"approved"或"denied"decision:"allow-once"、"allow-always"或"deny"binding:已获批请求的已解析绑定request:原始请求摘要、detach 提示、发送者 id 和 会话元数据
提供商运行时钩子
提供商插件有三层:- 用于低成本预运行时查找的清单元数据:
setup.providers[].envVars、已弃用的兼容性providerAuthEnvVars、providerAuthAliases、providerAuthChoices和channelEnvVars。 - 配置时钩子:
catalog(旧版discovery)以及applyConfigDefaults。 - 运行时钩子:40 多个可选钩子,涵盖凭证、模型解析、 流包装、思考等级、重放策略和用量端点。请参阅 钩子顺序和用法 下的完整列表。
setup.providers[].envVars。
在弃用窗口期间,兼容性适配器仍会读取已弃用的 providerAuthEnvVars,
使用它的非内置插件会收到清单诊断。一个提供商 id 应复用另一个提供商 id 的环境变量、
auth profiles、配置支持的凭证和 API key 新手引导选项时,
请使用清单 providerAuthAliases。当新手引导/凭证选择 CLI 界面应在不
加载提供商运行时的情况下了解提供商的选择 id、分组标签和简单的单标志凭证接线时,
请使用清单 providerAuthChoices。将提供商运行时
envVars 保留给面向操作员的提示,例如新手引导标签或 OAuth
client-id/client-secret 设置变量。
当渠道具有由环境变量驱动的凭证或设置,且通用 shell 环境回退、配置/Status 检查或设置提示应在不加载
渠道运行时的情况下看到这些信息时,请使用清单 channelEnvVars。
钩子顺序和用法
对于模型/提供商插件,OpenClaw 会按以下大致顺序调用钩子。 “When to use” 列是快速决策指南。 仅用于兼容性的提供商字段,例如ProviderPlugin.capabilities 和 suppressBuiltInModel,OpenClaw 已不再调用,
因此有意未在此列出。
| # | 钩子 | 作用 | 何时使用 |
|---|---|---|---|
| 1 | catalog | 在生成 models.json 期间,将提供商配置发布到 models.providers | 提供商拥有目录或 base URL 默认值 |
| 2 | applyConfigDefaults | 在配置物化期间应用提供商拥有的全局配置默认值 | 默认值取决于认证模式、环境变量或提供商模型系列语义 |
| — | (内置模型查找) | OpenClaw 会先尝试常规注册表/目录路径 | (不是插件钩子) |
| 3 | normalizeModelId | 在查找之前规范化旧版或预览模型 ID 别名 | 提供商在规范模型解析之前负责别名清理 |
| 4 | normalizeTransport | 在通用模型组装之前规范化提供商系列的 api / baseUrl | 提供商负责同一传输协议系列中自定义提供商 ID 的传输协议清理 |
| 5 | normalizeConfig | 在运行时/提供商解析之前规范化 models.providers.<id> | 提供商需要与插件同属的配置清理;内置 Google 系列辅助工具也会为受支持的 Google 配置项提供兜底 |
| 6 | applyNativeStreamingUsageCompat | 对配置提供商应用原生流式用量兼容性重写 | 提供商需要由端点驱动的原生流式用量元数据修复 |
| 7 | resolveConfigApiKey | 在加载运行时认证之前,为配置提供商解析环境变量标记认证 | 提供商拥有自己的环境变量标记 API key 解析;amazon-bedrock 此处也有内置 AWS 环境变量标记解析器 |
| 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 | normalizeToolSchemas | 在嵌入式运行器看到工具 schema 之前规范化它们 | 提供商需要传输协议系列的 schema 清理 |
| 16 | inspectToolSchemas | 在规范化后暴露提供商拥有的 schema 诊断 | 提供商希望发出关键字警告,而不把提供商特定规则教给核心 |
| 17 | resolveReasoningOutputMode | 选择原生或带标签的推理输出契约 | 提供商需要带标签的推理/最终输出,而不是原生字段 |
| 18 | prepareExtraParams | 在通用流式选项包装器之前进行请求参数规范化 | 提供商需要默认请求参数或按提供商清理参数 |
| 19 | createStreamFn | 用自定义传输协议完全替换常规流式路径 | 提供商需要自定义线路协议,而不只是包装器 |
| 20 | wrapStreamFn | 在应用通用包装器之后的流式包装器 | 提供商需要请求标头/正文/模型兼容性包装器,但不需要自定义传输协议 |
| 21 | resolveTransportTurnState | 附加原生的逐轮传输协议标头或元数据 | 提供商希望通用传输协议发送提供商原生的轮次身份 |
| 22 | resolveWebSocketSessionPolicy | 附加原生 WebSocket 标头或会话冷却策略 | 提供商希望通用 WS 传输协议调整会话标头或兜底策略 |
| 23 | formatApiKey | 认证配置文件格式化器:已存储配置文件会变成运行时 apiKey 字符串 | 提供商存储额外认证元数据,并需要自定义运行时令牌形态 |
| 24 | refreshOAuth | 针对自定义刷新端点或刷新失败策略的 OAuth 刷新覆盖 | 提供商不适配共享的 pi-ai 刷新器 |
| 25 | buildAuthDoctorHint | OAuth 刷新失败时附加的修复提示 | 提供商需要在刷新失败后提供由提供商拥有的认证修复指引 |
| 26 | matchesContextOverflowError | 提供商拥有的上下文窗口溢出匹配器 | 提供商有通用启发式会漏掉的原始溢出错误 |
| 27 | classifyFailoverReason | 提供商拥有的故障转移原因分类 | 提供商可以将原始 API/传输协议错误映射为速率限制/过载等 |
| 28 | isCacheTtlEligible | 代理/回传提供商的提示缓存策略 | 提供商需要特定于代理的缓存 TTL 门控 |
| 29 | buildMissingAuthMessage | 替换通用的缺失认证恢复消息 | 提供商需要特定于提供商的缺失认证恢复提示 |
| 30 | augmentModelCatalog | 设备发现后追加的合成/最终目录行 | 提供商需要在 models list 和选择器中加入合成的前向兼容行 |
| 31 | resolveThinkingProfile | 模型特定的 /think 级别集合、显示标签和默认值 | 提供商为选定模型暴露自定义思考层级或二元标签 |
| 32 | isBinaryThinking | 开/关推理切换兼容性钩子 | 提供商仅暴露二元思考开关 |
| 33 | supportsXHighThinking | xhigh 推理支持兼容性钩子 | 提供商只希望在一部分模型上启用 xhigh |
| 34 | resolveDefaultThinkingLevel | 默认 /think 级别兼容性钩子 | 提供商拥有某个模型系列的默认 /think 策略 |
| 35 | isModernModelRef | 用于实时配置文件过滤和冒烟选择的现代模型匹配器 | 提供商拥有实时/冒烟首选模型匹配 |
| 36 | prepareRuntimeAuth | 在推理前,将已配置凭据交换为实际运行时令牌/密钥 | 提供商需要令牌交换或短期请求凭据 |
| 37 | resolveUsageAuth | 为 /usage 和相关状态界面解析使用量/计费凭证 | 提供商需要自定义的使用量/配额令牌解析,或不同的使用量凭证 |
| 38 | fetchUsageSnapshot | 在凭证解析完成后,获取并规范化提供商特定的使用量/配额快照 | 提供商需要提供商特定的使用量端点或载荷解析器 |
| 39 | createEmbeddingProvider | 为记忆/搜索构建提供商自有的嵌入适配器 | 记忆嵌入行为属于提供商插件 |
| 40 | buildReplayPolicy | 返回一个重放策略,用于控制提供商的对话记录处理 | 提供商需要自定义对话记录策略(例如移除思考块) |
| 41 | sanitizeReplayHistory | 在通用对话记录清理后重写重放历史 | 提供商需要共享压缩助手之外的提供商特定重放重写 |
| 42 | validateReplayTurns | 在嵌入式运行器之前执行最终的重放轮次验证或重塑 | 提供商传输协议需要在通用清理后进行更严格的轮次验证 |
| 43 | onModelSelected | 运行提供商自有的选择后副作用 | 当模型变为活跃时,提供商需要遥测或提供商自有状态 |
normalizeModelId、normalizeTransport 和 normalizeConfig 会先检查匹配的提供商插件,然后继续遍历其他支持钩子的提供商插件,直到其中一个确实改变了模型 ID 或传输协议/配置。这样可以让别名/兼容性提供商垫片正常工作,而不要求调用方知道哪个内置插件负责改写。如果没有提供商钩子改写受支持的 Google 系列配置项,内置的 Google 配置规范化器仍会应用该兼容性清理。
如果提供商需要完全自定义的通信协议或自定义请求执行器,那属于另一类扩展。这些钩子用于仍在 OpenClaw 正常推理循环上运行的提供商行为。
提供商示例
内置示例
内置提供商插件会组合上面的钩子,以适配每个厂商的目录、认证、思考、重放和用量需求。权威的钩子集合随每个插件位于extensions/ 下;本页展示的是形态,而不是镜像完整列表。
Pass-through catalog providers
Pass-through catalog providers
OpenRouter、Kilocode、Z.AI、xAI 会注册
catalog 以及
resolveDynamicModel / prepareDynamicModel,因此它们可以在 OpenClaw 静态目录之前展示上游模型 ID。OAuth and usage endpoint providers
OAuth and usage endpoint providers
GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 会将
prepareRuntimeAuth 或 formatApiKey 与 resolveUsageAuth +
fetchUsageSnapshot 配对,用于接管令牌交换和 /usage 集成。Replay and transcript cleanup families
Replay and transcript cleanup families
共享的命名系列(
google-gemini、passthrough-gemini、
anthropic-by-model、hybrid-anthropic-openai)让提供商通过 buildReplayPolicy 选择加入转录策略,而不需要每个插件重新实现清理。Catalog-only providers
Catalog-only providers
byteplus、cloudflare-ai-gateway、huggingface、kimi-coding、nvidia、
qianfan、synthetic、together、venice、vercel-ai-gateway 和
volcengine 只注册 catalog,并使用共享推理循环。Anthropic-specific stream helpers
Anthropic-specific stream helpers
Beta 标头、
/fast / serviceTier 和 context1m 位于
Anthropic 插件的公共 api.ts / contract-api.ts 接缝中
(wrapAnthropicProviderStream、resolveAnthropicBetas、
resolveAnthropicFastMode、resolveAnthropicServiceTier),而不是位于通用 SDK 中。运行时辅助函数
插件可以通过api.runtime 访问选定的核心辅助函数。对于 TTS:
textToSpeech返回用于文件/语音备注表面的常规核心 TTS 输出载荷。- 使用核心
messages.tts配置和提供商选择。 - 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商重新采样/编码。
listVoices对每个提供商都是可选的。将其用于厂商自有的语音选择器或设置流程。- 语音列表可以包含更丰富的元数据,例如语言区域、性别和人格标签,以支持感知提供商的选择器。
- OpenAI 和 ElevenLabs 目前支持电话音频。Microsoft 不支持。
api.registerSpeechProvider(...) 注册语音提供商。
- 将 TTS 策略、回退和回复投递保留在核心中。
- 将语音提供商用于厂商自有的合成行为。
- 旧版 Microsoft
edge输入会规范化为microsoft提供商 ID。 - 首选的所有权模型以公司为导向:随着 OpenClaw 增加这些能力契约,一个厂商插件可以拥有文本、语音、图像以及未来的媒体提供商。
- 将编排、回退、配置和渠道接线保留在核心中。
- 将厂商行为保留在提供商插件中。
- 增量扩展应保持类型化:新的可选方法、新的可选结果字段、新的可选能力。
- 视频生成已经遵循相同模式:
- 核心拥有能力契约和运行时辅助函数
- 厂商插件注册
api.registerVideoGenerationProvider(...) - 功能/渠道插件使用
api.runtime.videoGeneration.*
api.runtime.mediaUnderstanding.*是图像/音频/视频理解的首选共享表面。- 使用核心媒体理解音频配置(
tools.media.audio)和提供商回退顺序。 - 当未产生转写输出时(例如输入被跳过/不受支持),返回
{ text: undefined }。 api.runtime.stt.transcribeAudioFile(...)仍保留为兼容性别名。
api.runtime.subagent 启动后台子智能体运行:
provider和model是每次运行的可选覆盖项,不是持久会话变更。- OpenClaw 只会为受信任调用方采用这些覆盖字段。
- 对于插件拥有的回退运行,操作员必须使用
plugins.entries.<id>.subagent.allowModelOverride: true选择加入。 - 使用
plugins.entries.<id>.subagent.allowedModels将受信任插件限制为特定规范provider/model目标,或使用"*"明确允许任意目标。 - 不受信任的插件子智能体运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。
- 插件创建的子智能体会话会带有创建插件 ID 的标签。回退
api.runtime.subagent.deleteSession(...)只能删除这些自有会话;任意会话删除仍需要管理员范围的 Gateway 网关请求。
api.registerWebSearchProvider(...) 注册 Web 搜索提供商。
说明:
- 将提供商选择、凭证解析和共享请求语义保留在核心中。
- 将 Web 搜索提供商用于厂商特定的搜索传输。
api.runtime.webSearch.*是需要搜索行为但不依赖智能体工具包装器的功能/渠道插件的首选共享表面。
api.runtime.imageGeneration
generate(...):使用配置的图像生成提供商链生成图像。listProviders(...):列出可用的图像生成提供商及其能力。
Gateway 网关 HTTP 路由
插件可以通过api.registerHttpRoute(...) 暴露 HTTP 端点。
path:Gateway 网关 HTTP 服务器下的路由路径。auth:必填。使用"gateway"要求常规 Gateway 网关认证,或使用"plugin"进行插件管理的认证/webhook 验证。match:可选。"exact"(默认)或"prefix"。replaceExisting:可选。允许同一插件替换其已有的路由注册。handler:当路由已处理请求时返回true。
api.registerHttpHandler(...)已移除,并会导致插件加载错误。请改用api.registerHttpRoute(...)。- 插件路由必须显式声明
auth。 - 除非设置
replaceExisting: true,否则会拒绝精确的path + match冲突,并且一个插件不能替换另一个插件的路由。 - 会拒绝
auth级别不同的重叠路由。仅在同一认证级别上保留exact/prefix回退链。 auth: "plugin"路由不会自动获得 operator 运行时作用域。它们用于插件管理的 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
- 共享密钥 bearer 认证(
- 实用规则:不要假定经过 gateway 认证的插件路由是隐式管理员界面。如果你的路由需要仅限管理员的行为,请要求带身份的认证模式,并记录显式的
x-openclaw-scopes标头约定。
插件 SDK 导入路径
编写新插件时,请使用更窄的 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 schema(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 约定上,而不是混用无关的插件字段。参见 渠道插件。
运行时和配置辅助工具位于匹配的聚焦 *-runtime 子路径下(approval-runtime、agent-runtime、lazy-runtime、directory-runtime、text-runtime、runtime-store、system-event-runtime、heartbeat-runtime、channel-activity-runtime 等)。优先使用 config-types、plugin-config-runtime、runtime-config-snapshot 和 config-mutation,而不是宽泛的 config-runtime 兼容 barrel。
openclaw/plugin-sdk/channel-runtime、openclaw/plugin-sdk/config-runtime 和 openclaw/plugin-sdk/infra-runtime 是面向旧插件的已弃用兼容 shim。新代码应改为导入更窄的通用原语。index.js— 内置插件入口api.js— 辅助工具/类型 barrelruntime-api.js— 仅运行时 barrelsetup-entry.js— 设置插件入口
openclaw/plugin-sdk/* 子路径。绝不要从核心或另一个插件导入另一个插件包的 src/*。由 facade 加载的入口点会优先使用当前运行时配置快照(如果存在),然后回退到磁盘上解析后的配置文件。
存在 image-generation、media-understanding 和 speech 等能力特定子路径,是因为内置插件现在使用它们。它们不会自动成为长期冻结的外部约定;依赖它们时请查看相关 SDK 参考页面。
消息工具 schema
插件应拥有特定渠道的describeMessageTool(...) schema 贡献,用于 reaction、read 和 poll 等非消息原语。共享发送展示应使用通用 MessagePresentation 约定,而不是提供商原生的按钮、组件、block 或卡片字段。请参阅 消息展示,了解约定、回退规则、提供商映射和插件作者检查清单。
具备发送能力的插件通过消息能力声明它们可以渲染的内容:
presentation用于语义展示块(text、context、divider、buttons、select)delivery-pin用于置顶投递请求
渠道目标解析
渠道插件应拥有特定渠道的目标语义。保持共享出站宿主通用,并使用消息适配器界面处理提供商规则:messaging.inferTargetChatType({ to })会在目录查找前决定规范化目标应视为direct、group还是channel。messaging.targetResolver.looksLikeId(raw, normalized)会告诉核心输入是否应跳过目录搜索,直接进入类似 id 的解析。messaging.targetResolver.resolveTarget(...)是当核心在规范化后或目录未命中后需要最终由提供商拥有的解析时使用的插件回退。messaging.resolveOutboundSessionRoute(...)在目标解析完成后拥有特定提供商的会话路由构造。
- 使用
inferTargetChatType处理应在搜索 peers/groups 前发生的类别决策。 - 使用
looksLikeId进行“将其视为显式/原生目标 id”的检查。 - 使用
resolveTarget作为特定提供商的规范化回退,而不是用于宽泛的目录搜索。 - 将聊天 id、thread id、JID、handle 和 room id 等提供商原生 id 保留在
target值或提供商特定参数中,而不是通用 SDK 字段中。
配置支持的目录
从配置派生目录条目的插件应将该逻辑保留在插件中,并复用来自openclaw/plugin-sdk/directory-runtime 的共享辅助工具。
当渠道需要配置支持的 peers/groups 时使用它,例如:
- 由 allowlist 驱动的私信 peer
- 已配置的渠道/群组映射
- 账号作用域的静态目录回退
directory-runtime 中的共享辅助工具只处理通用操作:
- 查询过滤
- limit 应用
- 去重/规范化辅助工具
- 构建
ChannelDirectoryEntry[]
提供商目录
提供商插件可以用registerProvider({ catalog: { run(...) { ... } } }) 定义用于推理的模型目录。
catalog.run(...) 返回与 OpenClaw 写入 models.providers 相同的形状:
{ provider }表示一个提供商条目{ providers }表示多个提供商条目
catalog。
catalog.order 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机:
simple:普通 API key 或由环境变量驱动的提供商profile:存在认证配置文件时出现的提供商paired:合成多个相关提供商条目的提供商late:最后一轮,在其他隐式提供商之后
discovery仍可作为旧版别名使用- 如果同时注册了
catalog和discovery,OpenClaw 会使用catalog
只读渠道检查
如果你的插件注册了渠道,建议在resolveAccount(...) 旁实现 plugin.config.inspectAccount(cfg, accountId)。
原因:
resolveAccount(...)是运行时路径。它可以假定凭据已完全实例化,并且在缺少必需 secret 时可以快速失败。openclaw status、openclaw status --all、openclaw channels status、openclaw channels resolve等只读命令路径,以及 Doctor/配置修复流程,不应仅为描述配置而需要实例化运行时凭据。
inspectAccount(...) 行为:
- 仅返回描述性的账号状态。
- 保留
enabled和configured。 - 在相关时包含凭据来源/状态字段,例如:
tokenSource、tokenStatusbotTokenSource、botTokenStatusappTokenSource、appTokenStatussigningSecretSource、signingSecretStatus
- 你无需为了报告只读可用性而返回原始 token 值。返回
tokenStatus: "available"(以及匹配的 source 字段)就足以支持 status 风格的命令。 - 当凭据通过 SecretRef 配置但在当前命令路径中不可用时,使用
configured_unavailable。
包集合
插件目录可以包含带有openclaw.extensions 的 package.json:
name/<fileBase>。
如果你的插件导入 npm 依赖,请将它们安装到该目录中,以便 node_modules 可用(npm install / pnpm install)。
安全护栏:每个 openclaw.extensions 条目在符号链接解析后都必须留在插件目录内。逃出包目录的条目会被拒绝。
安全说明:openclaw plugins install 会使用项目本地的 npm install --omit=dev --ignore-scripts 安装插件依赖(没有生命周期脚本,运行时没有 dev 依赖),并忽略继承的全局 npm 安装设置。请保持插件依赖树为“纯 JS/TS”,并避免需要 postinstall 构建的包。
可选:openclaw.setupEntry 可以指向一个轻量的仅设置模块。当 OpenClaw 需要为已禁用的渠道插件提供设置界面,或当渠道插件已启用但仍未配置时,它会加载 setupEntry,而不是完整插件入口。当你的主插件入口还会接入工具、钩子或其他仅运行时代码时,这可以让启动和设置更轻量。
可选:openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen 可以让渠道插件在 Gateway 网关监听前的启动阶段选择使用相同的 setupEntry 路径,即使该渠道已经配置完成。
仅当 setupEntry 完全覆盖 Gateway 网关开始监听前必须存在的启动界面时,才使用此项。实践中,这意味着设置入口必须注册启动所依赖的每一项渠道自有能力,例如:
- 渠道注册本身
- Gateway 网关开始监听前必须可用的任何 HTTP 路由
- 同一窗口期间必须存在的任何 Gateway 网关方法、工具或服务
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
channels.<id>.accounts.*,且不加载完整插件入口时,会使用该表面。Matrix 是当前内置示例:当命名账号已存在时,它只会把认证/引导键移动到一个命名提升账号中,并且可以保留已配置的非规范默认账号键,而不是总是创建 accounts.default。
这些设置补丁适配器会让内置契约表面发现保持惰性。导入时间保持轻量;提升表面只会在首次使用时加载,而不是在模块导入时重新进入内置渠道启动流程。
当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们放在插件专属前缀下。核心管理命名空间(config.*、exec.approvals.*、wizard.*、update.*)仍然保留,并且始终解析为 operator.admin,即使某个插件请求更窄的作用域也是如此。
示例:
渠道目录元数据
渠道插件可以通过openclaw.channel 声明设置/设备发现元数据,并通过 openclaw.install 声明安装提示。这会让核心目录不携带数据。
示例:
openclaw.channel 字段包括:
detailLabel:用于更丰富的目录/Status 表面的次级标签docsLabel:覆盖文档链接的链接文本preferOver:此目录条目应优先于的低优先级插件/渠道 IDselectionDocsPrefix、selectionDocsOmitLabel、selectionExtras:选择表面的文案控制markdownCapable:将渠道标记为支持 markdown,用于出站格式化决策exposure.configured:设置为false时,从已配置渠道列表表面隐藏该渠道exposure.setup:设置为false时,从交互式设置/配置选择器隐藏该渠道exposure.docs:将渠道标记为文档导航表面中的内部/私有渠道showConfigured/showInSetup:为兼容性仍然接受的旧版别名;优先使用exposurequickstartAllowFrom:选择让渠道加入标准快速开始allowFrom流程forceAccountBinding:即使只有一个账号存在,也要求显式账号绑定preferSessionLookupForAnnounceTarget:解析公告目标时优先使用会话查找
~/.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.install 块旁暴露规范化的安装来源事实。规范化事实会标识 npm 规格是精确版本还是浮动选择器、预期完整性元数据是否存在,以及本地源路径是否也可用。当目录/包身份已知时,如果解析出的 npm 包名偏离该身份,规范化事实会给出警告。它们也会在 defaultChoice 无效或指向不可用来源时,以及 npm 完整性元数据存在但没有有效 npm 来源时给出警告。消费者应将 installSource 视为一个附加的可选字段,这样手写条目和目录兼容层就不必合成它。这让新手引导和诊断可以解释来源平面状态,而无需导入插件运行时。
官方外部 npm 条目应优先使用精确的 npmSpec 加 expectedIntegrity。裸包名和 dist-tag 为兼容性仍然可用,但它们会显示来源平面警告,以便目录可以在不破坏现有插件的情况下转向固定版本、带完整性校验的安装。当新手引导从本地目录路径安装时,它会记录一个托管插件索引条目,其中 source: "path",并在可行时记录相对于工作区的 sourcePath。绝对的运行加载路径保留在 plugins.load.paths 中;安装记录会避免把本地工作站路径重复写入长期配置。这让本地开发安装对来源平面诊断保持可见,同时不会增加第二个原始文件系统路径披露表面。持久化的 plugins/installs.json 插件索引是安装来源事实源,并且可以在不加载插件运行时模块的情况下刷新。即使插件清单缺失或无效,其 installRecords 映射也会持久保留;其 plugins 数组是可重建的清单视图。
上下文引擎插件
上下文引擎插件拥有会话上下文编排,用于摄取、组装和压缩。从你的插件中使用api.registerContextEngine(id, factory) 注册它们,然后用 plugins.slots.contextEngine 选择活动引擎。
当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加记忆搜索或钩子时,请使用此能力。
ctx 会暴露可选的 config、agentDir 和 workspaceDir 值,用于构造时初始化。
如果你的引擎不拥有压缩算法,请保持 compact() 已实现,并显式委托它:
添加新能力
当某个插件需要的行为不适合当前 API 时,不要通过私有越界访问绕过插件系统。添加缺失的能力。 推荐顺序:- 定义核心契约 决定核心应拥有哪些共享行为:策略、回退、配置合并、生命周期、面向渠道的语义,以及运行时辅助工具形态。
- 添加类型化插件注册/运行时表面
用最小的实用类型化能力表面扩展
OpenClawPluginApi和/或api.runtime。 - 连接核心 + 渠道/功能消费者 渠道和功能插件应通过核心消费新能力,而不是直接导入供应商实现。
- 注册供应商实现 然后供应商插件将它们的后端注册到该能力。
- 添加契约覆盖 添加测试,确保所有权和注册形态随时间保持显式。
能力清单
添加新能力时,实现通常应一起触及这些表面:src/<capability>/types.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/contracts/registry.ts中的所有权/契约断言docs/中的操作员/插件文档
能力模板
最小模式:- 核心拥有能力契约 + 编排
- 供应商插件拥有供应商实现
- 功能/渠道插件消费运行时辅助工具
- 契约测试让所有权保持显式
相关内容
- 插件架构 — 公共能力模型和形态
- 插件 SDK 子路径
- 插件 SDK 设置
- 构建插件