此页面面向在 OpenClaw 内部使用
openclaw/plugin-sdk/* 的插件作者。对于希望通过 Gateway 运行代理的外部应用、脚本、仪表板、CI 作业和 IDE 扩展,请改用 面向外部应用的 Gateway 集成。导入约定
始终从特定子路径导入: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。该内置 Schema 子路径不应作为新插件的开发模式。
子路径参考
插件 SDK 以按领域分组的一组窄子路径形式暴露(插件 入口、渠道、提供方、认证、运行时、能力、内存,以及保留的 捆绑插件辅助函数)。完整目录——按组整理并带链接——请参见 插件 SDK 子路径。 编译器入口点清单位于scripts/lib/plugin-sdk-entrypoints.json;类型化公共导出不包括
scripts/lib/plugin-sdk-private-local-only-subpaths.json 中列出的内部子路径。该列表中的生产入口仍为单独发布的官方插件保留仅 JavaScript 的宿主运行时导出,而仅用于测试的入口则仍不导出。运行
pnpm plugin-sdk:surface 可审计公共导出数量。对于已存在足够长时间且未被捆绑扩展生产代码使用的已弃用公共子路径,
其记录位于 scripts/lib/plugin-sdk-deprecated-public-subpaths.json;范围较广的已弃用重新导出桶记录于
scripts/lib/plugin-sdk-deprecated-barrel-subpaths.json
注册 API
register(api) 回调会接收一个 OpenClawPluginApi 对象,其中包含这些
方法:
为会话提供外部团队聊天界面的插件可以注册由
openclaw/plugin-sdk/session-discussion 导出的、进程范围内唯一的提供程序。其
info({ sessionKey }) 方法会报告讨论不可用、已准备好打开或已经打开;open({ sessionKey })
会创建或解析该讨论,并返回其嵌入 URL 和外部 URL。注册另一个提供程序会替换当前提供程序。
能力注册
Worker provider 还必须在
contracts.workerProviders 中声明其 id。
Core 会在 provision(profile, operationId) 之前持久化 durable intent。Provider 会在外部分配之前验证设置,并针对永久性的 profile 拒绝抛出 WorkerProviderError。当 operation id 重复时,provision 必须采用同一个 lease。其 provisioning 合理地可能超过 Core 五分钟默认值的 provider,可以从 resolveProvisionTimeoutMs(profile) 返回一个正的毫秒预算;获取、provider 所拥有的设置和清理都必须包含在该时限内。
Core 会将经过验证的 profile 设置与 lease 一同持久化,并将该快照提供给 destroy({ leaseId, profile }),后者必须具备幂等性;还会将其提供给 inspect({ leaseId, profile }),后者返回 active、destroyed 或 unknown。这样,provider 就能在 Gateway 重启或命名 profile 被移除后路由生命周期调用。SSH endpoint 使用 SecretRef 作为 keyRef,绝不能内联密钥材料,并且包含来自可信 provisioning 输出的 hostKey,其格式必须严格为 algorithm base64,不能包含 hostname 或 comment。Core 会固定 hostKey,绝不信任首次连接中的密钥。Provider 还可以返回最多 10 个有序且唯一的 fallbackPorts(范围为 1 到 65535 的整数端口,不包括主 port);Core 会验证并持久化这些所播报的候选端口,用于幂等探测、内容寻址传输、由回执/锁保护的 artifact 安装、收敛式 managed-worktree 镜像以及隧道重连。含义不明确且未受保护的有状态命令会安全失败,不会在候选端口之间重放。当 SSH 账户还拥有不相关的进程时,lease 可以设置 sharedHost: true;这样,Core 在 workspace reconciliation 期间就不会冻结整个主机的进程。省略该字段或设置为 false 表示使用专用 worker 主机。活动 inspection 会重复这一事实,使 Core 能够为在该字段存在之前持久化的 lease 协调 provider 所拥有的隔离;隧道启动会等待首次权威 inspection。生成动态 keyRef 的 provider 可以实现 resolveSshIdentity({ leaseId, profile, keyRef });如果存在该方法,则该 resolver 具有权威性;没有该方法的 provider 则使用所配置的通用 secret resolver。
WorkerLease.desktop 是可选的,其形式为 { protocol: "rfb"; port: number; passwordFilePath?: string; apps?: WorkerDesktopApp[] };如果存在,passwordFilePath 必须是绝对路径。Provider 会从 provision 报告这一 warm-time capability;它不能补充到已存活的 lease 上。Gateway 会在需要时通过 provider 的 SSH endpoint 读取密码文件,绝不持久化密码。WorkerDesktopApp 是一个封闭联合类型:{ id: "browser"; executablePath: string; cdpPort: number } 或 { id: "terminal"; executablePath: string }。App id 必须唯一,可执行文件路径必须是绝对路径,browser CDP 端口必须是 1 到 65535 之间的整数,并且列表最多接受八个条目。Core 会拒绝未知的 id 和字段。
具有可续期租约的 provider 还可以实现 renew(leaseId)。
inspect 在发生暂时性或不确定的失败时必须抛出异常;只有在权威确认资源不存在时才返回 unknown。在已持久化销毁请求之后,Core 会将活动的本地记录标记为孤立,或将资源不存在视为拆除完成。
通过 api.registerEmbeddingProvider(...) 注册的嵌入 provider 还必须在插件清单中的 contracts.embeddingProviders 里列出。这是用于可复用向量生成的通用嵌入接口。Memory search 可以消费这个通用 provider 接口。较旧的 api.registerMemoryEmbeddingProvider(...) 和 contracts.memoryEmbeddingProviders 接口现已弃用,作为兼容性保留,供现有的 memory 专用 provider 迁移。
仍然暴露运行时 batchEmbed(...) 的 memory 专用 provider,除非其运行时明确设置 sourceWideBatchEmbed: true,否则仍遵循现有的按文件批处理契约。该显式启用项允许 memory host 将来自多个脏 memory 文件和已启用来源的 chunk 一次性提交到单个 batchEmbed(...) 调用中,直到达到 host 的批处理限制为止。上传 JSONL 请求文件的批处理适配器,必须同时按上传大小上限和请求数量上限拆分 provider 作业。Provider 必须按 batch.chunks 的顺序,为每个输入 chunk 返回一个 embedding;如果 provider 期望按文件本地批处理,或无法在更大的 source-wide 作业中保持输入顺序,则不要省略该标志。
工具和命令
对于固定工具名称的简单工具插件,请使用defineToolPlugin。
对于混合插件或完全动态的工具注册,请直接使用 api.registerTool(...)。
当代理需要一个简短的、由命令拥有的路由提示时,插件命令可以设置
agentPromptGuidance。该文本应仅与命令本身相关;不要将提供方或插件特定策略加入核心提示构建器中。
指导条目可以是传统字符串,适用于每个提示界面,或者是
结构化条目:
surfaces 可以包括 openclaw_main、codex_app_server、
cli_backend、acp_backend 或 subagent。pi_main 仍然是
openclaw_main 的弃用别名。若有意对所有界面生效,请省略 surfaces。
不要传入空的 surfaces 数组;它会被拒绝,这样就不会因为意外的作用域丢失而变成全局提示文本。
原生 Codex app-server 开发者指令比其他提示界面更严格:只有明确作用域为 codex_app_server 的指导才会被提升到那个更高优先级的通道。传统字符串指导和未指定作用域的结构化指导仍然可用于非 Codex 提示界面,以保持兼容性。
节点主机命令在已连接的节点主机上运行,而不是在 Gateway
进程内部运行。如果存在 agentTool,节点会在成功连接 Gateway 后发布描述符;Gateway 仅在该节点已连接期间,且仅当描述符的
command 位于节点已批准的命令范围内时,才会将其公开给代理运行。将 agentTool.defaultPlatforms 设置为将非危险命令加入默认节点命令允许列表;否则需要显式设置
gateway.nodes.commands.allow 或节点调用策略。agentTool.name
必须符合提供方安全要求:以字母开头,只能使用字母、数字、下划线或连字符,且长度不得超过 64 个字符。基于 MCP 的节点工具可以设置 agentTool.mcp 元数据,以便目录和工具搜索界面显示远程 MCP 服务器/工具的身份信息,但执行仍会通过所公布的节点命令进行。
基础设施
确认后的 Webhook 工作
在处理完成前确认请求的 Webhook 路由,必须将这部分脱离请求的工作转移到其自身受跟踪的准入根上:runDetachedWebhookWork(...)。该辅助函数会立即保留一个独立的根,然后在下一个微任务中启动回调,以便请求处理器能够先写入确认响应。返回的 promise 会采用回调结果;调用方仍负责处理拒绝。这样可以确保确认后的队列工作得到接受,并使重启或暂停时的排空操作等待这部分工作。返回前等待所有处理完成的处理器不需要使用此辅助函数。
按请求方作用域划分的 MCP 连接
在mcp.servers、原生插件的 mcpServers 清单字段或捆绑包清单中,保持 MCP 服务器的身份(名称、工具过滤器)静态不变。也可以选择注册连接解析器,以便每个受信任的消息请求方获得自己的传输:
- 解析器上下文只携带受信任的宿主身份(
requesterSenderId、 可选的agentAccountId/messageChannel)。未来受信任字段(例如 cron/子代理用户上下文)可以以追加方式加入。 - 一个插件只能拥有一个服务器名称:来自另一个插件、针对相同
serverName的重复registerMcpServerConnectionResolver会被以错误诊断拒绝 (首次注册者获胜),因此连接所有权永远不依赖插件加载顺序。 - 工具名称由完整声明的服务器集合派生,因此部分解析绝不会在不同请求方或轮次之间改变安全的服务器名称。Core 不会验证不同请求方端点是否提供完全相同的工具 schema;解析器必须让每个请求方指向同一个逻辑服务,否则工具 schema(以及提示缓存稳定性)会按请求方发生分歧。
- 在没有受信任的
requesterSenderId的运行中(cron、子代理、心跳、公共网关),永远不会实例化按请求方作用域划分的服务器。不存在共享的回退连接。 resolve对每个服务器的执行上限为 10 秒;超时或抛错会在本次运行中省略该服务器,而不会使静态 MCP 失败。- 已解析的连接对每个请求方最多每 5 分钟重新校验一次:轮换会用新凭据重建传输,而
null结果会撤销它(即使在会话中途,缓存的运行时也会被释放)。因此,已撤销或已轮换的凭据最多可能继续使用 5 分钟。 - 已解析的
headers绝不会被记录或持久化;core 只保留一个短暂的、仅进程内的键控摘要(进程本地 HMAC)来检测凭据轮换,并将已解析的 header/URL 凭据值注册到日志/调试捕获脱敏注册表中。 - 按请求方作用域划分的服务器不会生成 MCP App 视图:视图的生命周期会超出经过请求方认证的运行,而且网关视图边界没有请求方身份,因此这些服务器的 app 预览会保持 fail-closed。工具结果不受影响。
- 没有解析器的静态服务器会保留现有的会话作用域生命周期。
- Harness 传递规则: 按请求方作用域划分的服务器绝不会进入 harness 原生 MCP 客户端配置(Codex 线程
mcp_servers、CLI-c mcp_servers=…,或任何其他会话共享的 MCP 投影)。harness 会将它们作为运行作用域工具传递:- 嵌入式运行器:会话 MCP 运行时 + bundle 工具(静态 + 作用域)。
- Codex 应用服务器:通过
materializeRequesterScopedMcpToolsForHarnessRun提供动态工具(仅作用域;静态服务器仍留在 Codex 的原生 MCP 客户端中)。
- 作用域工具的规范在该会话中首次成功解析后保持会话稳定,因此共享线程 harness(Codex)不会因为发送方变化而切换线程。在任何请求方解析之前,不会公布作用域规范。
- 共享线程 harness 上的未认证请求方仍会看到已公布的作用域工具;调用其中任意一个都会针对该请求方返回一个干净的未连接工具错误。OpenClaw 永远不会回退到其他请求方的凭据。
agentId、agentSessionKey 和 sandboxed 上下文。记忆语料补充的 search 和 get 调用会接收可选的 agentId 和 sandboxed 上下文。拥有代理所有存储的插件应当在每次调用时解析该存储,而不是在注册期间捕获某个全局路径。如果在多代理操作中需要 agent id 但未提供,应当直接失败并关闭,而不是选择任意一个代理。
当提示词文本依赖异步插件状态时,请使用 registerMemoryPromptPreparation(...)。该回调会在每个完整的代理提示词之前运行一次,并接收与同步记忆提示词构建器相同的工具、代理、会话和沙箱上下文。在加载持久化状态前,验证当前存储所有者实例,然后只返回本次运行所需的行。OpenClaw 会冻结这些行,并将不可变结果交给同步提示词组装流程。将持久化、原子替换和所有者移除时的删除操作保留在所属插件内部;不要从提示词构建器中轮询或读取文件。
Telegram 交互处理器可以返回 { submitText },以便在处理器成功后通过 Telegram 的正常入站代理路径路由文本。当入站策略跳过文本或处理失败时,OpenClaw 会保留回调按钮,以便用户在阻塞条件发生变化后重试。此结果字段仅适用于 Telegram;其他渠道保留各自的交互结果契约。
工作流插件的宿主钩子
宿主钩子是面向需要参与宿主 生命周期的插件的 SDK 接口,而不仅仅是添加提供方、渠道或工具。它们是 通用契约;Plan Mode 可以使用它们,审批工作流、 工作区策略门禁、后台监视器、安装向导以及 UI 伴随插件也都可以使用。surface: "tab" 描述符会向 Control UI 添加一个侧边栏标签页。活动
插件的标签页描述符会在 gateway
hello(controlUiTabs)中向 dashboard 客户端通告,因此该标签页仅在插件启用时出现。
捆绑插件可以为其标签页提供一流的 dashboard 视图;其他
插件可以将 path 设置为一个插件 HTTP 路由(参见
api.registerHttpRoute(...)),由 dashboard 在沙箱化框架中渲染。
icon 是 dashboard 图标名称提示,group 选择侧边栏分区
(control 或 agent),order 用于在插件标签页之间排序,而 requiredScopes
会将缺少这些操作员作用域的连接隐藏该标签页:
对于受 Gateway 保护的外部标签页,请将描述符的 path 注册在同一插件的
auth: "gateway" HTTP 路由下。完成经过身份验证的引导后,浏览器会获得一个
短期有效、HttpOnly 的授权令牌,其作用域限定为该插件和路由根路径,因此
沙箱化框架可以加载,而无需将 Gateway bearer 令牌复制到其 URL
或 JavaScript 中。经过身份验证的父页面会在外部标签页处于活动状态时,以及
导航或浏览器恢复后挂载标签页之前续期该授权令牌。
它还会在挂载前从同一个不透明沙箱中探测该授权令牌,因此会阻止 Cookie 的浏览器隐私模式
会以安全失败方式显示不可用面板。
框架授权令牌只接受 GET 和 HEAD,并始终携带
operator.read;requiredScopes 控制标签页可见性,但绝不会扩大 Cookie 授权范围。
变更操作仍需通过明确的、经过 Gateway 身份验证的父页面或 bearer 界面执行。
外部标签页要求使用 HTTPS/Tailscale Serve,或浏览器信任的回环源;
在局域网主机上使用普通 HTTP 时,会显示安全上下文错误,而不是挂载一个
无法完成身份验证的面板。
完全阻止第三方 Cookie 也会使受 Gateway 保护的标签页不可用。
与所有原生插件界面一样,框架仍处于已安装插件的信任边界内;OpenClaw 不会将已安装插件
视为彼此隔离的浏览器安全主体。
Cookie 授权遵循浏览器的主机名边界,而不是端口边界。
不要在 Gateway 主机名下托管彼此不受信任的服务,即使它们使用不同的端口。
由插件管理身份验证的标签页保持其直接 iframe 行为,不会请求或要求此 Gateway 授权令牌。
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.registerSessionExtension、api.enqueueNextTurnInjection、
api.registerControlUiDescriptor、api.registerRuntimeLifecycle、
api.registerAgentEventSubscription、api.emitAgentEvent、
api.setRunContext、api.getRunContext、api.clearRunContext、
api.registerSessionSchedulerJob、api.registerSessionAction、
api.sendSessionAttachment、api.scheduleSessionTurn 或
api.unscheduleSessionTurnsByTag。
scheduleSessionTurn(...) 是在 Gateway
Cron 调度器之上的会话作用域便捷封装。Cron 负责时序,并在回合运行时创建后台任务记录;Plugin SDK 仅约束目标会话、插件拥有的
命名和清理。当工作本身需要持久化的多步骤 Task Flow 状态时,请在计划中的
回合内使用 api.runtime.tasks.managedFlows。
这些契约刻意分离了权限:
- 外部插件可以拥有会话扩展、UI 描述符、命令、工具元数据、 下一回合注入以及普通钩子。
- 受信任的工具策略会在普通的
before_tool_call钩子之前运行,并且受宿主信任。 捆绑策略首先运行;已安装插件的策略需要显式启用,并且其本地 ID 必须位于contracts.trustedToolPolicies中,随后按插件加载顺序运行。策略 ID 的作用域限定为注册该策略的插件。 - 保留命令的所有权仅限捆绑插件。外部插件应使用自己的命令名称或别名。
allowPromptInjection=false会禁用修改提示词的钩子,包括agent_turn_prepare、before_prompt_build、heartbeat_prompt_contribution和enqueueNextTurnInjection。
保留的核心管理命名空间(
config.*、exec.approvals.*、wizard.*、
update.*)始终保持 operator.admin,即使插件尝试分配更窄的
Gateway 方法作用域。优先为插件拥有的方法使用插件特定前缀。何时使用 tool-result 中间件
何时使用 tool-result 中间件
捆绑插件以及显式启用、且清单契约匹配的已安装插件,在需要于执行后、运行时将结果回传给模型之前重写工具结果时,可以使用
api.registerAgentToolResultMiddleware(...)。这是用于 tokenjuice 等异步输出归约器的受信任、与运行时无关的接缝。插件必须针对每个目标运行时声明 contracts.agentToolResultMiddleware,例如 ["openclaw", "codex"]。没有该契约或未显式启用的已安装插件不能注册此中间件;对于不需要在模型前进行工具结果时序控制的工作,请保留使用普通 OpenClaw 插件钩子。旧的仅嵌入式运行器扩展工厂注册路径已被移除。Gateway 发现注册
api.registerGatewayDiscoveryService(...) 允许插件通过本地发现传输(例如 mDNS/Bonjour)公告活动中的
Gateway。OpenClaw 会在启用本地发现时于 Gateway 启动期间调用该
服务,传入当前 Gateway 端口和非机密的 TXT 提示数据,并在 Gateway 关闭期间调用返回的
stop 处理器。
CLI 注册元数据
api.registerCli(registrar, opts?) 接受两类命令元数据:
commands:由 registrar 拥有的显式命令名称descriptors:用于 CLI 帮助、路由和惰性插件 CLI 注册的解析时命令描述符parentPath:用于嵌套命令组的可选父命令路径,例如["nodes"]
api.registerNodeCliFeature(registrar, opts?)。它是
api.registerCli(..., { parentPath: ["nodes"] }) 的一个小包装,并使诸如
openclaw nodes canvas 这样的命令成为明确的插件拥有节点功能。
如果你希望插件命令在常规根 CLI 路径中保持惰性加载,
请提供覆盖该 registrar 暴露的每个顶层命令根的 descriptors。
machineOutput({ argv, stdoutIsTTY }),用于在不完全依赖字面量
--json 标志的情况下,表明命令将 stdout 保留给 JSON、JSONL 或其他机器可读格式。
OpenClaw 会在激活插件之前评估此解析器,以便将启动诊断路由到 stderr。该解析器必须是
同步、纯函数且依赖轻量的:只能检查提供的原始 argv 和 stdout TTY 状态。当轻量级 CLI
元数据和完整注册都需要使用该解析器时,应复用同一个解析器,以确保发现和执行不会产生
分歧。当解析器需要命令路径令牌时,请使用
openclaw/plugin-sdk/cli-argv 中的 getRootOptionAwareCommandPath;它接受位于命令根
之前或之后的受支持根选项。machineOutput 属于根元数据;嵌套描述符不能使用它,因为
其所属根在它们可见之前就必须已经处于活动状态。
嵌套命令会将解析后的父命令作为 program 接收:
commands。
该急切兼容路径仍受支持,但它不会为解析时惰性加载安装基于
描述符的占位符。
CLI 后端注册
api.registerCliBackend(...) 允许插件拥有本地
AI CLI 后端(例如 claude-cli 或 my-cli)的默认配置。
- 后端的
id会成为模型引用(如my-cli/gpt-5)中的提供商前缀。 - 后端的
config是权威的命令适配器:argv、环境、解析器、会话、图像和可靠性行为都由插件代码负责。 - 用户通过模型引用或模型范围的
agentRuntime.id选择后端;openclaw.json不会重写适配器。 - 当注册的静态字段需要运行时感知的规范化处理时,使用
normalizeConfig。 - 对于属于 CLI 方言的、按请求范围进行的 argv 重写(例如将 OpenClaw 思考级别映射为原生 effort 标志),使用
resolveExecutionArgs。该钩子会接收ctx.executionMode;对于临时的/btw调用,使用"side-question"添加后端原生的隔离标志。如果这些标志能够可靠地为一个原本始终启用原生工具的 CLI 禁用原生工具,则同时声明sideQuestionToolMode: "disabled"。 - 对于由后端负责的启动环境或临时身份验证/配置桥接,使用
prepareExecution。其ctx.contextTokenBudget是本次运行所选的有效 token 限制,因此支持原生压缩的后端可以自行对齐其阈值,而无需在提供商专用的核心分支中处理。它还会接收核心准备好的ctx.env,以便后端暂存过程扩展捆绑的 MCP 设置。 - 能够在特定运行中禁用所有原生工具的后端可以声明
nativeToolMode: "selectable"。受限调用会传入精确的ctx.toolAvailability.native列表以及规范化的ctx.toolAvailability.openClaw名称。声明toolAvailabilityEnforcement: "execution-args",并在最终的新建/恢复 argv 中执行该约定;或者声明"prepare-execution",在暂存策略中执行该约定,并返回toolAvailabilityEnforced: true。对于 crontoolsAllow等运行时限制,OpenClaw 会禁用原生工具;当声明的执行路径不完整时,则采取故障安全拒绝策略。
独占槽位
要参与持久化的已接纳回合,上下文引擎必须在
info.transcriptSemantics 下声明
currentTurnFence: "before-current-turn-entry-v1" 和
turnAdvancementIdempotency: "atomic-idempotent-v1",然后将 commitTurn(...) 实现为一个以 advancementKey 为键的原子幂等写入。OpenClaw 仅提供包含边界的已接受回合,从已接纳的用户条目开始,直到其终止条目为止;使用 readSessionTranscriptVisibleMessageDelta(...) 游标 API 引导或重建更早的历史记录。如果没有完整的契约,OpenClaw 会在整个逻辑回合及其重试过程中使用旧版上下文路径,保持配置的引擎不变,并在下一个逻辑回合再次尝试该引擎。
已弃用的内存嵌入适配器
registerMemoryCapability是唯一的内存插件 API。registerMemoryCapability还可以通过publicArtifacts.listArtifacts(...)暴露由主机管理的导出内容。枚举这些已声明导出内容的配套插件仍应使用保留的openclaw/plugin-sdk/memory-host-core外观中的listActiveMemoryPublicArtifacts(...),直到出现专用的公共消费者 API;它们不得 访问另一个插件的私有布局。- 能够返回会话转录命中的内存运行时应实现
runtime.authorizeSearchHits(...)。主机会在原始搜索命中到达调用方可见的界面之前调用此钩子,并提供请求代理、会话密钥和沙箱状态。仅返回请求方可以查看的命中。如果缺少此钩子,OpenClaw 将通过隐藏会话来源的命中来采取默认拒绝策略,同时保留普通内存命中。将转录身份和可见性策略保留在所属的内存插件中;调用方不得根据路径推断授权,也不得重复实现插件特定的规则。 MemoryFlushPlan.model可以将刷新轮次固定到精确的provider/model引用,例如ollama/qwen3:8b,而不会继承当前的回退链。registerMemoryEmbeddingProvider已弃用。新的嵌入提供程序应使用api.registerEmbeddingProvider(...)和contracts.embeddingProviders。- 现有的内存专用提供程序在迁移期间仍可继续工作,但对于非内置插件,插件检查会将其报告为兼容性债务。
事件和生命周期
示例、常见钩子名称和守卫
语义请参见 插件钩子。
钩子决策语义
before_install 是插件运行时生命周期钩子,而不是 operator 安装
策略面。当允许/阻止决策必须覆盖 CLI 和由 Gateway 支持的安装或更新路径时,请使用 security.installPolicy。
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: 在回退到通道特定的metadata之前,请先使用带类型的replyToId/threadId路由字段。gateway_start: 请使用ctx.config、ctx.workspaceDir和ctx.getCron?.()来获取 Gateway 拥有的启动状态,而不是依赖内部的gateway:startup钩子。此时 Cron 可能仍在加载中。cron_reconciled: 在启动或调度器重新加载后,重建完整的外部 cron 投影。它包含reason和有效的enabled状态,包括enabled: false,而ctx.getCron?.()返回的是精确对齐后的调度器。将ctx.abortSignal传入持久化投影工作;当该调度器快照被替换或 Gateway 关闭时,它会中止。cron_changed: 观察 Gateway 拥有的 cron 生命周期变化。scheduled和removed事件是提交后的对账提示,而不是有序的增量日志。scheduled 事件的event.nextRunAtMs在任务没有下次唤醒时会缺失;removed 事件仍然携带已删除任务的快照。
cron_changed 事件进行去抖或合并,
然后从 cron_reconciled 最后捕获的调度器中重新读取完整的持久视图。不要从 cron_changed 上下文中采用调度器:来自较旧调度器的分离提示可能会与后续重新加载重叠。
将 cron_reconciled 作为在 Gateway 启动或调度器替换时加载的持久状态的完整快照触发器。它不会在仅插件热重载时重新播放。观察处理器并行运行,且即发即忘的分发可能重叠,因此消费者不能依赖事件完成顺序。请将 OpenClaw 作为到期检查和执行的事实来源。
关于具有持久替换、重试/退避以及干净关闭的单飞适配器,请参见 安全的外部 cron 投影。
API 对象字段
内部模块约定
在你的插件中,内部导入请使用本地 barrel 文件:api.ts、runtime-api.ts、
index.ts、setup-entry.ts 以及类似的公共入口文件),当 OpenClaw 已经运行时,
优先使用当前运行时配置快照。如果还没有运行时快照,则回退到磁盘上已解析的配置文件。
打包后的插件外观应通过 OpenClaw 的插件外观加载器加载;直接从 dist/extensions/... 导入会绕过清单和运行时 sidecar 检查,而这些检查会在插件自身代码的打包安装中使用。
提供方插件可以暴露一个较窄、仅限插件本地的契约 barrel,当某个 helper 明确只适用于该提供方,并且尚未成为通用 SDK 子路径的一部分时。
打包示例:
- Anthropic:
api.ts/contract-api.ts接口用于 Claude, 适用于 beta-header 和service_tier流式处理 helper。 @openclaw/openai-provider:api.ts导出 provider 构建器、 默认模型 helper,以及实时 provider 构建器。@openclaw/openrouter-provider:api.ts导出 provider 构建器 以及引导/配置 helper。
相关内容
入口点
definePluginEntry 和 defineChannelPluginEntry 选项。运行时助手
api.runtime 命名空间完整参考。设置和配置
打包、清单和配置模式。
测试
测试工具和 lint 规则。
SDK 迁移
从已弃用的表面迁移。
插件内部
深入的架构和能力模型。