快速开始
插件 SDK 概览
插件 SDK 是插件和核心之间的类型化契约。本页是关于导入什么以及可以注册什么的参考。
导入约定
始终从特定子路径导入:
每个子路径都是一个小型、自包含的模块。这能保持启动快速,并防止循环依赖问题。对于特定渠道的入口/构建辅助工具,优先使用 openclaw/plugin-sdk/channel-core;将 openclaw/plugin-sdk/core 留给更宽泛的总括表面和共享辅助工具,例如 buildChannelConfigSchema。
对于渠道配置,请通过 openclaw.plugin.json#channelConfigs 发布渠道自有的 JSON Schema。plugin-sdk/channel-config-schema 子路径用于共享 schema 基元和通用构建器。OpenClaw 的内置插件使用 plugin-sdk/bundled-channel-config-schema 来保留内置渠道 schema。已弃用的兼容性导出仍保留在 plugin-sdk/channel-config-schema-legacy;这两个内置 schema 子路径都不是新插件应采用的模式。
子路径参考
插件 SDK 以一组按领域分组的窄子路径公开(插件入口、渠道、提供商、凭证、运行时、能力、记忆,以及保留的内置插件辅助工具)。完整目录(已分组并带链接)请参阅插件 SDK 子路径。
生成的 200+ 个子路径列表位于 scripts/lib/plugin-sdk-entrypoints.json。
注册 API
register(api) 回调会收到一个 OpenClawPluginApi 对象,包含这些方法:
能力注册
| 方法 | 注册内容 |
|---|---|
api.registerProvider(...) |
文本推理(LLM) |
api.registerAgentHarness(...) |
实验性低层级智能体执行器 |
api.registerCliBackend(...) |
本地 CLI 推理后端 |
api.registerChannel(...) |
消息渠道 |
api.registerSpeechProvider(...) |
文本转语音 / STT 合成 |
api.registerRealtimeTranscriptionProvider(...) |
流式实时转录 |
api.registerRealtimeVoiceProvider(...) |
双工实时语音会话 |
api.registerMediaUnderstandingProvider(...) |
图像/音频/视频分析 |
api.registerImageGenerationProvider(...) |
图像生成 |
api.registerMusicGenerationProvider(...) |
音乐生成 |
api.registerVideoGenerationProvider(...) |
视频生成 |
api.registerWebFetchProvider(...) |
Web 获取 / 抓取提供商 |
api.registerWebSearchProvider(...) |
Web 搜索 |
工具和命令
| 方法 | 注册内容 |
|---|---|
api.registerTool(tool, opts?) |
智能体工具(必需或 { optional: true }) |
api.registerCommand(def) |
自定义命令(绕过 LLM) |
当智能体需要一条由命令拥有的简短路由提示时,插件命令可以设置 agentPromptGuidance。请让该文本围绕命令本身;不要把提供商或插件特定策略添加到核心 prompt 构建器中。
基础设施
| 方法 | 注册内容 |
|---|---|
api.registerHook(events, handler, opts?) |
事件钩子 |
api.registerHttpRoute(params) |
Gateway 网关 HTTP 端点 |
api.registerGatewayMethod(name, handler) |
Gateway 网关 RPC 方法 |
api.registerGatewayDiscoveryService(service) |
本地 Gateway 网关发现公告器 |
api.registerCli(registrar, opts?) |
CLI 子命令 |
api.registerNodeCliFeature(registrar, opts?) |
openclaw nodes 下的 Node 功能 CLI |
api.registerService(service) |
后台服务 |
api.registerInteractiveHandler(registration) |
交互式处理程序 |
api.registerAgentToolResultMiddleware(...) |
运行时工具结果中间件 |
api.registerMemoryPromptSupplement(builder) |
追加式记忆相邻 prompt 区段 |
api.registerMemoryCorpusSupplement(adapter) |
追加式记忆搜索/读取语料 |
工作流插件的宿主钩子
宿主钩子是 SDK 接缝,适用于需要参与宿主生命周期,而不仅仅是添加提供商、渠道或工具的插件。它们是通用契约;Plan Mode 可以使用它们,审批工作流、工作区策略闸门、后台监控器、设置向导和 UI 配套插件也可以使用。
| 方法 | 它拥有的契约 |
|---|---|
api.registerSessionExtension(...) |
插件拥有的、JSON 兼容的会话状态,通过 Gateway 网关会话投射 |
api.enqueueNextTurnInjection(...) |
持久且仅一次的上下文,注入某个会话的下一次智能体轮次 |
api.registerTrustedToolPolicy(...) |
内置/受信任的前置插件工具策略,可阻止或重写工具参数 |
api.registerToolMetadata(...) |
工具目录展示元数据,不改变工具实现 |
api.registerCommand(...) |
有作用域的插件命令;命令结果可以设置 continueAgent: true;Discord 原生命令支持 descriptionLocalizations |
api.registerControlUiDescriptor(...) |
面向会话、工具、运行或设置表面的 Control UI 贡献描述符 |
api.registerRuntimeLifecycle(...) |
在重置/删除/重新加载路径中清理插件自有运行时资源的回调 |
api.registerAgentEventSubscription(...) |
用于工作流状态和监控器的净化事件订阅 |
api.setRunContext(...) / getRunContext(...) / clearRunContext(...) |
每次运行的插件临时状态,会在终止性运行生命周期时清除 |
api.registerSessionSchedulerJob(...) |
插件拥有的会话调度器作业记录,并带确定性清理 |
这些契约有意拆分权限:
- 外部插件可以拥有会话扩展、UI 描述符、命令、工具元数据、下一轮注入和普通钩子。
- 受信任的工具策略会在普通
before_tool_call钩子之前运行,并且仅限内置使用,因为它们参与宿主安全策略。 - 保留命令所有权仅限内置使用。外部插件应使用自己的命令名称或别名。
allowPromptInjection=false会禁用会修改 prompt 的钩子,包括agent_turn_prepare、before_prompt_build、heartbeat_prompt_contribution、来自旧版before_agent_start的 prompt 字段,以及enqueueNextTurnInjection。
非 Plan 消费者示例:
| 插件原型 | 使用的钩子 |
|---|---|
| 审批工作流 | 会话扩展、命令继续、下一轮注入、UI 描述符 |
| 预算/工作区策略闸门 | 受信任工具策略、工具元数据、会话投射 |
| 后台生命周期监控器 | 运行时生命周期清理、智能体事件订阅、会话调度器所有权/清理、Heartbeat prompt 贡献、UI 描述符 |
| 设置或新手引导向导 | 会话扩展、有作用域命令、Control UI 描述符 |
何时使用工具结果中间件
当内置插件需要在工具执行后、运行时将结果反馈给模型之前重写工具结果时,可以使用 api.registerAgentToolResultMiddleware(...)。这是用于 tokenjuice 等异步输出 reducer 的受信任、运行时中立接缝。
内置插件必须为每个目标运行时声明 contracts.agentToolResultMiddleware,
例如 ["pi", "codex"]。外部插件不能注册此中间件;对于不需要模型前工具结果时序的工作,请继续使用常规 OpenClaw 插件钩子。旧的仅限 Pi 的嵌入式扩展工厂注册路径已被移除。
Gateway 网关发现注册
api.registerGatewayDiscoveryService(...) 允许插件在 mDNS/Bonjour 等本地发现传输协议上通告活跃的 Gateway 网关。当启用本地发现时,OpenClaw 会在 Gateway 网关启动期间调用该服务,传入当前 Gateway 网关端口和非机密 TXT 提示数据,并在 Gateway 网关关闭期间调用返回的 stop 处理程序。
api.registerGatewayDiscoveryService({
id: "my-discovery",
async advertise(ctx) {
const handle = await startMyAdvertiser({
gatewayPort: ctx.gatewayPort,
tls: ctx.gatewayTlsEnabled,
displayName: ctx.machineDisplayName,
});
return { stop: () => handle.stop() };
},
});
Gateway 网关发现插件不得将通告的 TXT 值视为机密或身份验证。设备发现是路由提示;Gateway 网关身份验证和 TLS 固定仍然负责信任。
CLI 注册元数据
api.registerCli(registrar, opts?) 接受两类命令元数据:
commands:注册器拥有的显式命令名称descriptors:用于 CLI 帮助、路由和延迟插件 CLI 注册的解析时命令描述符parentPath:嵌套命令组的可选父命令路径,例如["nodes"]
对于配对节点功能,优先使用
api.registerNodeCliFeature(registrar, opts?)。它是
api.registerCli(..., { parentPath: ["nodes"] }) 的一个小包装,并使
openclaw nodes canvas 等命令成为显式的插件拥有节点功能。
如果你希望插件命令在常规根 CLI 路径中保持延迟加载,请提供覆盖该注册器暴露的每个顶级命令根的 descriptors。
api.registerCli(
async ({ program }) => {
const { registerMatrixCli } = await import("./src/cli.js");
registerMatrixCli({ program });
},
{
descriptors: [
{
name: "matrix",
description: "Manage Matrix accounts, verification, devices, and profile state",
hasSubcommands: true,
},
],
},
);
嵌套命令会以 program 接收已解析的父命令:
api.registerCli(
async ({ program }) => {
const { registerNodesCanvasCommands } = await import("./src/cli.js");
registerNodesCanvasCommands(program);
},
{
parentPath: ["nodes"],
descriptors: [
{
name: "canvas",
description: "Capture or render canvas content from a paired node",
hasSubcommands: true,
},
],
},
);
仅当你不需要延迟根 CLI 注册时,才单独使用 commands。该预先加载的兼容路径仍受支持,但它不会安装由描述符支持的占位符用于解析时延迟加载。
CLI 后端注册
api.registerCliBackend(...) 允许插件拥有本地 AI CLI 后端(例如 codex-cli)的默认配置。
- 后端
id会成为codex-cli/gpt-5等模型引用中的提供商前缀。 - 后端
config使用与agents.defaults.cliBackends.<id>相同的形状。 - 用户配置仍然优先。OpenClaw 会先将
agents.defaults.cliBackends.<id>合并到插件默认值之上,然后再运行 CLI。 - 当后端在合并后需要兼容性重写时,使用
normalizeConfig(例如规范化旧标志形状)。 - 对于属于 CLI 方言的请求作用域 argv 重写,请使用
resolveExecutionArgs,例如将 OpenClaw 思考级别映射到原生 effort 标志。
有关端到端创作指南,请参阅 CLI 后端插件。
独占槽位
| 方法 | 注册内容 |
|---|---|
api.registerContextEngine(id, factory) |
上下文引擎(同一时间一个处于活跃状态)。assemble() 回调会接收 availableTools 和 citationsMode,以便引擎可以定制提示添加内容。 |
api.registerMemoryCapability(capability) |
统一记忆能力 |
api.registerMemoryPromptSection(builder) |
记忆提示段构建器 |
api.registerMemoryFlushPlan(resolver) |
记忆 flush 计划解析器 |
api.registerMemoryRuntime(runtime) |
记忆运行时适配器 |
记忆嵌入适配器
| 方法 | 注册内容 |
|---|---|
api.registerMemoryEmbeddingProvider(adapter) |
活跃插件的记忆嵌入适配器 |
registerMemoryCapability是首选的独占记忆插件 API。registerMemoryCapability也可以暴露publicArtifacts.listArtifacts(...), 以便配套插件可以通过openclaw/plugin-sdk/memory-host-core使用导出的记忆产物,而不是访问特定记忆插件的私有布局。registerMemoryPromptSection、registerMemoryFlushPlan和registerMemoryRuntime是兼容旧版的独占记忆插件 API。MemoryFlushPlan.model可以将 flush 轮次固定到精确的provider/model引用,例如ollama/qwen3:8b,而不继承活跃的 fallback 链。registerMemoryEmbeddingProvider允许活跃记忆插件注册一个或多个嵌入适配器 ID(例如openai、gemini,或自定义的插件定义 ID)。agents.defaults.memorySearch.provider和agents.defaults.memorySearch.fallback等用户配置会基于这些已注册的适配器 ID 解析。
事件和生命周期
| 方法 | 作用 |
|---|---|
api.on(hookName, handler, opts?) |
类型化生命周期钩子 |
api.onConversationBindingResolved(handler) |
对话绑定回调 |
有关示例、常用钩子名称和守卫语义,请参阅插件钩子。
钩子决策语义
before_tool_call:返回{ block: true }是终止性的。一旦任何处理程序设置它,较低优先级的处理程序会被跳过。before_tool_call:返回{ block: false }会被视为没有决策(与省略block相同),而不是覆盖。before_install:返回{ block: true }是终止性的。一旦任何处理程序设置它,较低优先级的处理程序会被跳过。before_install:返回{ block: false }会被视为没有决策(与省略block相同),而不是覆盖。reply_dispatch:返回{ handled: true, ... }是终止性的。一旦任何处理程序声明已分发,较低优先级的处理程序和默认模型分发路径会被跳过。message_sending:返回{ cancel: true }是终止性的。一旦任何处理程序设置它,较低优先级的处理程序会被跳过。message_sending:返回{ cancel: false }会被视为没有决策(与省略cancel相同),而不是覆盖。message_received:当你需要入站线程/主题路由时,请使用类型化的threadId字段。将metadata保留给渠道特定的额外信息。message_sending:先使用类型化的replyToId/threadId路由字段,再回退到渠道特定的metadata。gateway_start:使用ctx.config、ctx.workspaceDir和ctx.getCron?.()获取 Gateway 网关拥有的启动状态,而不是依赖内部gateway:startup钩子。cron_changed:观察 Gateway 网关拥有的 cron 生命周期变化。在同步外部唤醒调度器时使用event.job?.state?.nextRunAtMs和ctx.getCron?.(),并让 OpenClaw 作为到期检查和执行的事实来源。
API 对象字段
| 字段 | 类型 | 描述 |
|---|---|---|
api.id |
string |
插件 ID |
api.name |
string |
显示名称 |
api.version |
string? |
插件版本(可选) |
api.description |
string? |
插件描述(可选) |
api.source |
string |
插件源路径 |
api.rootDir |
string? |
插件根目录(可选) |
api.config |
OpenClawConfig |
当前配置快照(可用时为活跃的内存中运行时快照) |
api.pluginConfig |
Record<string, unknown> |
来自 plugins.entries.<id>.config 的插件特定配置 |
api.runtime |
PluginRuntime |
运行时辅助工具 |
api.logger |
PluginLogger |
作用域日志记录器(debug、info、warn、error) |
api.registrationMode |
PluginRegistrationMode |
当前加载模式;"setup-runtime" 是轻量级的完整入口前启动/设置窗口 |
api.resolvePath(input) |
(string) => string |
解析相对于插件根目录的路径 |
内部模块约定
在你的插件中,使用本地 barrel 文件进行内部导入:
my-plugin/
api.ts # Public exports for external consumers
runtime-api.ts # Internal-only runtime exports
index.ts # Plugin entry point
setup-entry.ts # Lightweight setup-only entry (optional)
通过 facade 加载的内置插件公共表面(api.ts、runtime-api.ts、
index.ts、setup-entry.ts 以及类似的公共入口文件)在 OpenClaw 已经运行时优先使用活跃的运行时配置快照。如果尚不存在运行时快照,它们会回退到磁盘上解析出的配置文件。
打包的内置插件 facade 应通过 OpenClaw 的插件 facade 加载器加载;直接从 dist/extensions/... 导入会绕过打包安装用于插件拥有代码的清单和运行时 sidecar 检查。
提供商插件可以在辅助函数明确是提供商专用、且尚不属于通用 SDK 子路径时,暴露一个范围较窄的插件本地契约 barrel。内置示例:
- Anthropic:用于 Claude
beta-header 和
service_tier流式传输辅助函数的公开api.ts/contract-api.tsseam。 @openclaw/openai-provider:api.ts导出提供商构建器、 默认模型辅助函数和实时提供商构建器。@openclaw/openrouter-provider:api.ts导出提供商构建器 以及新手引导/配置辅助函数。