Skip to content

OpenClaw Plugin SDK 的导入和注册都通过 openclaw/plugin-sdk/<子路径> 进行,所有注册方法集中在 OpenClawPluginApi 对象上。本页列出全部可用方法及作用(能力注册、工具/命令、基础设施、独占槽位、内存嵌入适配器)、钩子的阻断/跳过语义(before_tool_call、reply_dispatch 等),以及推荐的文件组织结构(api.ts、runtime-api.ts)。上游英文原文是唯一事实来源,所有命令、路径、方法名保持原样。

OpenClaw Plugin SDK 子路径导入与注册API完整参考

Plugin SDK 是插件与 core 之间的类型化合约。本页是导入路径注册方法的完整参考。

本页面向在 OpenClaw 内部使用 openclaw/plugin-sdk/* 的插件作者。外部应用、脚本、仪表盘、CI 作业和 IDE 扩展需要使用 OpenClaw App SDK@openclaw/sdk 包。

需要操作指南?请从插件开发入门开始,渠道插件参考渠道插件开发,Provider 插件参考 Provider 插件开发,本地 AI CLI 后端参考 CLI 后端插件,工具或生命周期钩子参考插件钩子

导入约定

始终从特定子路径导入:

typescript
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";

每个子路径是一个小型、自包含的模块,可保持启动速度快、避免循环依赖。渠道特定的入口/构建 helper 优先用 openclaw/plugin-sdk/channel-coreopenclaw/plugin-sdk/core 保留给更宽泛的伞形接口和共享 helper(如 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 上。

警告:不要导入 Provider 或渠道品牌的便利接缝(如 openclaw/plugin-sdk/slack.../discord.../signal.../whatsapp)。内置插件通过自身的 api.ts / runtime-api.ts barrel 组合通用 SDK 子路径;core 消费者应使用插件本地的 barrel,或在真正跨渠道需求时添加窄通用的 SDK 合约。

一小部分内置插件 helper 接缝仍出现在生成的导出映射中,仅供内置插件维护,不推荐用于新的第三方插件。

openclaw/plugin-sdk/discordopenclaw/plugin-sdk/telegram-account 作为已废弃的兼容门面保留,请勿在新插件中复制这些导入路径。

子路径参考

Plugin SDK 按区域暴露为一组窄子路径(插件入口、渠道、Provider、认证、运行时、能力、内存和预留的内置插件 helper)。完整的分组列表及链接,请查看Plugin SDK 子路径

编译器入口清单位于 scripts/lib/plugin-sdk-entrypoints.json;包导出从公共子集中生成(减去 scripts/lib/plugin-sdk-private-local-only-subpaths.json 中列出的仓库本地测试/内部子路径)。运行 pnpm plugin-sdk:surface 审计公共导出数量。废弃的公共子路径(足够旧且未被内置扩展生产代码使用)跟踪在 scripts/lib/plugin-sdk-deprecated-public-subpaths.json;广泛的已废弃重导出 barrel 跟踪在 scripts/lib/plugin-sdk-deprecated-barrel-subpaths.json

注册 API

register(api) 回调接收 OpenClawPluginApi 对象,包含以下方法:

能力注册

方法注册内容
api.registerProvider(...)文本推理(LLM)
api.registerAgentHarness(...)实验性低层级 Agent 执行器
api.registerCliBackend(...)本地 CLI 推理后端
api.registerChannel(...)消息渠道
api.registerEmbeddingProvider(...)可复用的向量嵌入 Provider
api.registerSpeechProvider(...)文本转语音 / 语音转文字合成
api.registerRealtimeTranscriptionProvider(...)流式实时转录
api.registerRealtimeVoiceProvider(...)双工实时语音会话
api.registerMediaUnderstandingProvider(...)图像/音频/视频分析
api.registerImageGenerationProvider(...)图像生成
api.registerMusicGenerationProvider(...)音乐生成
api.registerVideoGenerationProvider(...)视频生成
api.registerWebFetchProvider(...)网页抓取/爬取 Provider
api.registerWebSearchProvider(...)网页搜索

使用 api.registerEmbeddingProvider(...) 注册的嵌入 Provider 必须在插件 manifest 的 contracts.embeddingProviders 中列出。这是用于可复用向量生成的通用嵌入接口。仅限内存的适配器仍使用 api.registerMemoryEmbeddingProvider(...)contracts.memoryEmbeddingProviders

工具和命令

简单工具插件(固定工具名)使用 defineToolPlugin。混合插件或完全动态工具注册使用 api.registerTool(...)

方法注册内容
api.registerTool(tool, opts?)Agent 工具(必选或 { optional: true }
api.registerCommand(def)自定义命令(绕过 LLM)

插件命令可设置 agentPromptGuidance,当 Agent 需要一个简短、命令所属的路由提示时。提示文本应仅关于命令本身,不要添加 Provider 或插件特定的策略到核心 prompt builder 中。

Guidance 条目可以是传统字符串(应用于所有 prompt 表面),或者结构化条目:

ts
agentPromptGuidance: [
  "全局命令提示。",
  { text: "仅在主 PI 提示中显示。", surfaces: ["pi_main"] },
];

结构化 surfaces 可包含 pi_maincodex_app_servercli_backendacp_backendsubagent。省略 surfaces 表示有意应用于所有表面。不要传递空 surfaces 数组,会被拒绝。

原生 Codex app-server 开发者指令比其他 prompt 表面更严格:只有显式限定到 codex_app_server 的 guidance 会提升到该高优先级通道。传统字符串 guidance 和非限定结构化 guidance 仍对其他非 Codex prompt 表面可用。

基础设施

方法注册内容
api.registerHook(events, handler, opts?)事件钩子
api.registerHttpRoute(params)网关 HTTP 端点
api.registerGatewayMethod(name, handler)网关 RPC 方法
api.registerGatewayDiscoveryService(service)本地网关发现广播器
api.registerCli(registrar, opts?)CLI 子命令
api.registerNodeCliFeature(registrar, opts?)openclaw nodes 下的节点功能 CLI
api.registerService(service)后台服务
api.registerInteractiveHandler(registration)交互式处理器
api.registerAgentToolResultMiddleware(...)运行时工具结果中间件
api.registerMemoryPromptSupplement(builder)附加的内存相邻 prompt 节
api.registerMemoryCorpusSupplement(adapter)附加的内存搜索/读取语料库

工作流插件的主机钩子

主机钩子是 SDK 用于需要参与主机生命周期而不仅仅是添加 Provider、渠道或工具的插件的接缝。它们是通用合约;Plan Mode 可以使用,审批工作流、工作区策略门控、后台监视器、设置向导和 UI 伴侣插件也可以使用。

方法所属合约
api.session.state.registerSessionExtension(...)插件拥有的、JSON 兼容的会话状态,通过 Gateway sessions 投射
api.session.workflow.enqueueNextTurnInjection(...)持久化 exactly-once 上下文,注入到下一 Agent 回合(一个会话)
api.registerTrustedToolPolicy(...)内置/信任的预插件工具策略,可阻止或重写工具参数
api.registerToolMetadata(...)工具目录显示元数据,不改变工具实现
api.registerCommand(...)限域插件命令;命令结果可设置 continueAgent: true;Discord 原生命令支持 descriptionLocalizations
api.session.controls.registerControlUiDescriptor(...)针对会话、工具、运行或设置表面的控制 UI 贡献描述符
api.lifecycle.registerRuntimeLifecycle(...)插件拥有的运行时资源的清理回调(重置/删除/重载路径)
api.agent.events.registerAgentEventSubscription(...)经过清理的事件订阅(用于工作流状态和监视器)
api.runContext.setRunContext(...) / getRunContext(...) / clearRunContext(...)每个运行的插件暂存状态,在运行终了生命周期清除
api.session.workflow.registerSessionSchedulerJob(...)插件拥有的调度器作业的清理元数据;不调度工作或创建任务记录
api.session.workflow.sendSessionAttachment(...)仅内置插件:主机中介的文件附件交付到活动直接出站会话路由
api.session.workflow.scheduleSessionTurn(...) / unscheduleSessionTurnsByTag(...)仅内置插件:基于 Cron 的调度的会话回合及标签清理

新插件代码使用分组命名空间:

  • api.session.state.registerSessionExtension(...)
  • api.session.workflow.enqueueNextTurnInjection(...)
  • api.session.workflow.registerSessionSchedulerJob(...)
  • api.session.workflow.sendSessionAttachment(...)
  • api.session.workflow.scheduleSessionTurn(...)
  • api.session.workflow.unscheduleSessionTurnsByTag(...)
  • api.session.controls.registerSessionAction(...)
  • api.session.controls.registerControlUiDescriptor(...)
  • api.agent.events.registerAgentEventSubscription(...)
  • api.agent.events.emitAgentEvent(...)
  • api.runContext.setRunContext(...) / getRunContext(...) / clearRunContext(...)
  • api.lifecycle.registerRuntimeLifecycle(...)

等价的扁平方法作为已废弃的兼容别名仍可用。不要在新插件代码中直接调用 api.registerSessionExtensionapi.enqueueNextTurnInjection 等。

scheduleSessionTurn(...) 是会话范围的便利方法,底层使用 Gateway Cron 调度器。Cron 负责计时,并在回合运行时创建后台任务记录;Plugin SDK 仅限定目标会话、插件拥有的命名和清理。在调度的回合内需要持久多步任务流状态时,使用 api.runtime.tasks.managedFlows

合约有意拆分权限:

  • 外部插件可以拥有会话扩展、UI 描述符、命令、工具元数据、下一回合注入和普通钩子。
  • 受信任的工具策略在普通 before_tool_call 钩子之前运行,仅限内置插件,因为它们参与主机安全策略。
  • 预留命令所有权仅限内置插件。外部插件应使用自己的命令名或别名。
  • allowPromptInjection=false 禁用 prompt 变异钩子,包括 agent_turn_preparebefore_prompt_buildheartbeat_prompt_contribution、来自旧版 before_agent_start 的 prompt 字段,以及 enqueueNextTurnInjection

非 Plan 消费者的示例:

插件原型使用的钩子
审批工作流会话扩展、命令延续、下一回合注入、UI 描述符
预算/工作区策略门控受信任工具策略、工具元数据、会话投影
后台生命周期监视器运行时生命周期清理、Agent 事件订阅、会话调度器拥有/清理、心跳 prompt 贡献、UI 描述符
设置或入职向导会话扩展、限域命令、控制 UI 描述符

预留 core 管理员命名空间(config.*exec.approvals.*wizard.*update.*)始终解析为 operator.admin,即使插件尝试分配更窄的网关方法作用域。插件拥有的方法应使用插件特定前缀。

何时使用工具结果中间件

内置插件可以使用 api.registerAgentToolResultMiddleware(...) 当需要在工具执行后、运行时将结果反馈回模型之前重写工具结果。这是用于异步输出归约器(例如 tokenjuice)的受信任运行时中立接缝。

内置插件必须为每个目标运行时声明 contracts.agentToolResultMiddleware,例如 ["pi", "codex"]。外部插件不能注册此中间件;对于不需要预模型工具结果定时的任务,使用普通的 OpenClaw 插件钩子。旧的 Pi 专用嵌入式扩展工厂注册路径已被移除。

网关发现注册

api.registerGatewayDiscoveryService(...) 让插件在本地发现传输(如 mDNS/Bonjour)上广播活动的 Gateway。OpenClaw 在 Gateway 启动时调用该服务(如果本地发现启用),传递当前 Gateway 端口和非秘密 TXT 提示数据,并在 Gateway 关闭时调用返回的 stop 处理器。

typescript
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 值视为秘密或认证。发现只是路由提示;网关认证和 TLS 固定仍负责信任。

CLI 注册元数据

api.registerCli(registrar, opts?) 接受两类命令元数据:

  • commands:注册器拥有的显式命令名
  • descriptors:解析时命令描述符(用于 CLI 帮助、路由和懒加载插件 CLI 注册)
  • parentPath:可选父命令路径(用于嵌套命令组,如 ["nodes"]

对于配对节点功能,优先使用 api.registerNodeCliFeature(registrar, opts?)。它是 api.registerCli(..., { parentPath: ["nodes"] }) 的包装器,使命令(如 openclaw nodes canvas)成为显式的插件拥有节点功能。

如果希望插件命令在正常根 CLI 路径中保持懒加载,提供覆盖该注册器暴露的每个顶级命令根的描述符。

typescript
api.registerCli(
  async ({ program }) => {
    const { registerMatrixCli } = await import("./src/cli.js");
    registerMatrixCli({ program });
  },
  {
    descriptors: [
      {
        name: "matrix",
        description: "管理 Matrix 账号、验证、设备和配置文件状态",
        hasSubcommands: true,
      },
    ],
  },
);

嵌套命令将已解析的父命令作为 program 接收:

typescript
api.registerCli(
  async ({ program }) => {
    const { registerNodesCanvasCommands } = await import("./src/cli.js");
    registerNodesCanvasCommands(program);
  },
  {
    parentPath: ["nodes"],
    descriptors: [
      {
        name: "canvas",
        description: "从配对的节点捕获或渲染画布内容",
        hasSubcommands: true,
      },
    ],
  },
);

仅当不需要懒加载根 CLI 注册时,才单独使用 commands。该急切兼容路径仍受支持,但不安装基于描述符的占位符以支持解析时懒加载。

CLI 后端注册

api.registerCliBackend(...) 让插件拥有本地 AI CLI 后端(如 claude-climy-cli)的默认配置。

  • 后端 id 成为模型引用中的 Provider 前缀,例如 my-cli/gpt-5
  • 后端 config 使用与 agents.defaults.cliBackends.&lt;id&gt; 相同的形状。
  • 用户配置优先。OpenClaw 在运行 CLI 前将 agents.defaults.cliBackends.&lt;id&gt; 合并到插件默认值之上。
  • 当后端需要在合并后进行兼容性重写(例如标准化旧 flag 形状)时,使用 normalizeConfig
  • 对于请求范围的 argv 重写(属于 CLI 方言,例如将 OpenClaw 思维级别映射到原生 effort flag),使用 resolveExecutionArgs

端到端编写指南请参阅 CLI 后端插件

独占槽位

方法注册内容
api.registerContextEngine(id, factory)上下文引擎(一次只能激活一个)。assemble() 回调接收 availableToolscitationsMode,以便引擎定制 prompt 添加内容。
api.registerMemoryCapability(capability)统一内存能力
api.registerMemoryPromptSection(builder)内存 prompt 节构建器
api.registerMemoryFlushPlan(resolver)内存刷写计划解析器
api.registerMemoryRuntime(runtime)内存运行时适配器

内存嵌入适配器

方法注册内容
api.registerMemoryEmbeddingProvider(adapter)激活的插件拥有的内存嵌入适配器
  • registerMemoryCapability 是优先的独占内存插件 API。
  • registerMemoryCapability 也可以暴露 publicArtifacts.listArtifacts(...),以便伴侣插件通过 openclaw/plugin-sdk/memory-host-core 消费导出的内存工件,而不是深入特定内存插件的私有布局。
  • registerMemoryPromptSectionregisterMemoryFlushPlanregisterMemoryRuntime 是向后兼容的旧版独占内存插件 API。
  • MemoryFlushPlan.model 可以将刷写回合固定到确切的 provider/model 引用(例如 ollama/qwen3:8b),而不继承活动的后备链。
  • registerMemoryEmbeddingProvider 允许激活的内存插件注册一个或多个嵌入适配器 id(例如 openaigemini 或自定义 id)。
  • 用户配置如 agents.defaults.memorySearch.provideragents.defaults.memorySearch.fallback 会解析到这些已注册的适配器 id。

事件与生命周期

方法作用
api.on(hookName, handler, opts?)类型化生命周期钩子
api.onConversationBindingResolved(handler)会话绑定回调

详见插件钩子的示例、常见钩子名和守卫语义。

钩子决策语义

  • before_tool_call:返回 { block: true } 是终止决策,后续低优先级处理器被跳过;{ block: false } 视为无决策(等同于省略 block),不覆盖。
  • before_install:返回 { block: true } 终止,{ block: false } 无决策。
  • reply_dispatch:返回 { handled: true, ... } 终止,后续处理器和默认模型调度路径被跳过。
  • message_sending:返回 { cancel: true } 终止,{ cancel: false } 无决策。
  • message_received:需要入站线程/主题路由时使用类型化 threadId 字段。渠道特定的额外信息放在 metadata 中。
  • message_sending:优先使用类型化 replyToId / threadId 路由字段,再回退到渠道特定的 metadata
  • gateway_start:使用 ctx.configctx.workspaceDirctx.getCron?.() 获取网关拥有的启动状态,不要依赖内部 gateway:startup 钩子。
  • cron_changed:观察网关拥有的 cron 生命周期变化。同步外部唤醒调度器时使用 event.job?.state?.nextRunAtMsctx.getCron?.(),并将 OpenClaw 作为到期检查和执行的事实来源。

API 对象字段

字段类型说明
api.idstring插件 id
api.namestring显示名称
api.versionstring?插件版本(可选)
api.descriptionstring?插件描述(可选)
api.sourcestring插件源路径
api.rootDirstring?插件根目录(可选)
api.configOpenClawConfig当前配置快照(有可用运行时内存快照时使用活动内存快照)
api.pluginConfigRecord<string, unknown>插件特定配置(来自 plugins.entries.&lt;id&gt;.config
api.runtimePluginRuntime运行时辅助工具
api.loggerPluginLogger作用域日志器(debuginfowarnerror
api.registrationModePluginRegistrationMode当前加载模式;"setup-runtime" 是轻量级预完整入口的启动/设置窗口
api.resolvePath(input)(string) => string解析相对于插件根的路径

插件内部模块约定

在插件内部使用本地 barrel 文件管理内部导入:

my-plugin/
  api.ts            # 外部消费者的公开导出
  runtime-api.ts    # 仅内部使用的运行时导出
  index.ts          # 插件入口点
  setup-entry.ts    # 轻量设置专用入口(可选)

警告:永远不要在生产代码中通过 openclaw/plugin-sdk/&lt;your-plugin&gt; 导入自己的插件。内部导入通过 ./api.ts./runtime-api.ts 路由。SDK 路径仅是对外合约。

门面加载的内置插件公共表面(api.tsruntime-api.tsindex.tssetup-entry.ts 等)在 OpenClaw 已运行时优先使用活动运行时配置快照。如果尚无运行时快照,回退到磁盘上已解析的配置文件。打包的内置插件门面应通过 OpenClaw 的插件门面加载器加载;从 dist/extensions/... 直接导入会绕过打包安装用于插件拥有代码的 manifest 和运行时 sidecar 检查。

Provider 插件可以在需要助手时暴露窄的插件本地合约 barrel(当 helper 是 Provider 特定且尚未属于通用 SDK 子路径时)。内置示例:

  • Anthropic:公共 api.ts / contract-api.ts 接缝,用于 Claude beta-header 和 service_tier 流 helper。
  • @openclaw/openai-providerapi.ts 导出 Provider 构建器、默认模型 helper 和实时 Provider 构建器。
  • @openclaw/openrouter-providerapi.ts 导出 Provider 构建器以及入职/配置 helper。

扩展生产代码也应避免 openclaw/plugin-sdk/&lt;other-plugin&gt; 导入。如果 helper 确实需要共享,请将其提升到中立的 SDK 子路径,例如 openclaw/plugin-sdk/speech.../provider-model-shared 或其他能力导向的表面,而不是将两个插件耦合在一起。

相关文档

常见问题

如何选择正确的导入子路径?

渠道插件首选 openclaw/plugin-sdk/channel-core;Provider 插件使用 openclaw/plugin-sdk/provider-entry 和相关的子路径(如 plugin-sdk/provider-authplugin-sdk/provider-http)。通用工具插件使用 openclaw/plugin-sdk/plugin-entry。完整的子路径分组列表见 Plugin SDK 子路径

registerTool 和 registerCommand 有什么区别?

registerTool 注册一个可由 LLM 调用的 Agent 工具(可选或必需);registerCommand 注册一个绕过 LLM 的自定义命令,可用于实现 /slash 命令等。命令可以设置 agentPromptGuidance 来影响 Agent 行为。

为什么不能在插件内通过 openclaw/plugin-sdk/<自己> 导入?

SDK 路径是对外合约,供 core 或其他插件使用。插件内部导入应通过本地的 ./api.ts./runtime-api.ts,以保持封装并避免循环依赖。内置插件门面加载时优先使用运行时配置快照,直接导入会绕过这些检查。