本页内容

本页内容

构建插件

挂钩参考

注册规则、执行合同、每个处理程序的预算以及完整的类型化挂钩目录。 插件挂钩 指南的一部分。

注册执行

保持 register(api) 同步并在那里注册处理程序。除了两个同步持久性挂钩之外,处理程序本身可以是异步的。

处理程序默认优先级为 0;优先级较高的优先级优先,注册顺序打破了平局。执行取决于钩子类型:

类型 执行合同
调整 顺序;结果根据下面的钩子合同进行合并。返回重写通常不会更改传递给后续处理程序的事件。
宣称 顺序;第一个 { handled: true } 获胜并跳过剩余的处理程序。
闸门 顺序;一个块会停止剩余的处理程序。
观察 处理程序同时运行;返回值被忽略。发射器可以等待完成或调度即发即弃。
同步modify/gate 同步,按优先顺序;每个处理程序都会看到最新的消息。承诺被忽略并带有警告。
评价 技能评估器同时运行并产生单独的归因结果。

优先级不会对观察副作用进行序列化。即发即弃事件可以与后续事件重叠,并且回调不是持久的事件队列。显式返回修改,而不是依赖就地突变。

api.on(name, handler, opts?) 接受:

选项 作用
matcher 由 before_tool_call 或 after_tool_call 处理的标准 OpenClaw 工具 ID 的非空列表,例如 exec、apply_patch 或 spawn_agent。省略匹配所有工具。空列表、通配符、空白和特定于提供商的别名无效。
priority 排序;数值越高越先运行。
registrationId 插件内一次注册的稳定身份。技能评估者将其用作evaluatorId;否则使用插件 ID。
timeoutMs 每个处理程序异步等待预算。过期应用下面的钩子失败策略;它不会取消处理程序或其副作用。忽略使用跑步者的默认值(如果有)。
eligibleTriggers 仅适用于 before_agent_reply,将宿主分发限制为 cron、heartbeat 或 user 中的一个或多个触发器。
eligibleDispatchKinds 仅适用于 reply_dispatch,将主机调度限制为 agent、acp 或两者。省略处理所有调度类型。
requiresToolAuthority 仅适用于 before_prompt_build,在主机完成当前回合的工具表面并提供临时 ctx.toolAuthority 后运行处理程序。使用它进行必须遵循工具策略的上下文检索。

触发器资格由宿主在调用处理器之前强制执行。因此,使用 eligibleTriggers: ["heartbeat", "cron"] 注册的钩子对于用户轮次处于非活动状态,包括恢复的用户轮次。省略、为空、格式错误或部分包含未知值的列表仍不受限制,因此钩子会在这些轮次中运行。其他钩子类型不接受此选项。

运维人员可以在不修改插件代码的情况下设置钩子预算:

json
{  "plugins": {    "entries": {      "my-plugin": {        "hooks": {          "timeoutMs": 30000,          "timeouts": {            "before_prompt_build": 90000,            "agent_end": 60000          }        }      }    }  }}

hooks.timeouts.<hookName> 会覆盖 hooks.timeoutMs,后者会覆盖插件编写的 api.on(..., { timeoutMs }) 值。两个操作员配置字段接受最多 600000 毫秒的正整数。对于已知的慢钩子,更喜欢按钩子覆盖,这样一个插件就不会在任何地方都获得更长的预算。

超时处理程序 Promise 会继续运行,因为挂钩回调不会收到超时拥有的取消信号。 before_tool_call 可以接收所属工具调用的 ctx.abortSignal,但钩子超时到期不会中止它。当插件工作仍在进行时,钩子调度可以释放其网关许可。拥有长时间运行工作的插件必须提供自己的取消和关闭生命周期。

在结果变得不合格后,提示构建处理程序可以使用 ctx.hookInvocation.assertActive() 拒绝副作用。请参阅 Handler 生命周期。

标准运行程序应用这些默认值 per handler:

钩子 默认超时 抛出错误或超时时
before_agent_run, before_tool_call, before_install 15秒 阻止运行、工具调用或安装
before_agent_finalize, before_prompt_build, message_sending, reply_payload_sending, resolve_exec_env 15秒 记录并跳过失败的处理程序;保留其他成功结果
agent_end, before_compaction, after_compaction, skill_changed 30 秒 记录并继续
channel_pairing_requested 2秒 记录并继续
gateway_stop 5秒 记录并继续关闭
其他异步钩子,包括声明钩子 除非配置,否则没有跑步者超时 记录并继续
tool_result_persist, before_message_write 无异步超时 记录同步错误;失败的结果将被忽略

发射器可以施加更严格的整体生命周期预算,例如下面的关闭 session_end 排水。超时仅限制异步等待;它不能中断同步JavaScript。对于策略要求,请使用一个阻止错误操作的门,而不是假设观察或交付挂钩将拒绝失败的操作。

对于声明挂钩,继续意味着尝试下一个处理程序。如果无人认领,则由呼叫者决定如何处理;绑定对话失败的 inbound_claim 可以生成绑定通知而不是普通代理回复。

使用 createReplyDispatcher 的通道插件同样可以通过 beforeDeliverOptions: { timeoutMs } 声明更大的正向每阶段预算,或者在通过 dispatcher.appendBeforeDeliver(handler, { timeoutMs }) 追加工作时指定。若没有所有者声明的预算,这些回调会使用相同的 15 秒默认值,这样一个卡住的回调就不会占用序列化交付通道。

钩子目录

钩子按其延伸的表面进行分组。种类参见上述执行合同;修改钩子不是观察钩子。

Agent 回合

钩子 类型 用途
before_model_resolve 调整 在加载会话消息之前覆盖提供程序、模型或运行的后备链
agent_turn_prepare 调整 检查耗尽的插件转注入并在提示钩子之前添加上下文
before_prompt_build 调整 添加提示上下文,缩小当前回合提交的工具范围,或执行授权的策略后充实
before_agent_run 闸门 在模型提交之前检查提示和会话消息;节点在工作本地上下文组装之前打开门网关输入
before_agent_reply 宣称 使用合成回复或静默来提前结束模型回合
before_agent_finalize 调整 检查自然生成的最终答案,并请求模型再次处理
agent_end 观察 观察最终消息、成功状态和运行时长
heartbeat_prompt_contribution 调整 为后台监控和生命周期插件添加仅用于心跳的上下文

对话观察

钩子 类型 用途
model_call_started / model_call_ended 观察 净化的 provider/model 调用元数据:计时、结果、有界请求 ID 哈希值。无提示或响应内容。
llm_input 观察 提供方输入:系统提示词、提示词、历史记录
llm_output 观察 提供方输出、用量,以及可用时解析得到的 contextTokenBudget

工具

钩子 类型 用途
before_tool_call 修改/门 重写工具参数、阻止执行或要求批准
after_tool_call 观察 观察工具结果、错误和持续时间
resolve_exec_env 调整 为 exec 提供插件拥有的环境变量
tool_result_persist 同步修改 在转录持久化之前重写 toolResult 消息
before_message_write 同步修改/门控 在转录持久化之前重写或阻止消息

消息与传递

钩子 类型 用途
inbound_claim 宣称 为拥有该消息会话绑定的插件认领入站消息
channel_pairing_requested 观察 观察新创建的 DM 配对请求
message_received 观察 观察入站内容、发送者、线程和元数据
message_sending 修改/门 重写出站内容或取消传递
reply_payload_sending 修改/门 在传递前修改或取消规范化的回复负载
message_sent 观察 观察出站传递的成功或失败
before_dispatch 宣称 在正常模型调度之前处理入站消息
reply_dispatch 宣称 自己的回复生成和发送,而不是默认的模型路径

inbound_claim 不是全局预路由广播。 OpenClaw 仅针对拥有消息的核心管理对话绑定的插件调用它。要在模型输入之前抑制普通代理转动而不保留转录中的原始提示,请在受支持的运行器上使用 before_agent_run。要通过合成回复或静音来短路代理回合,请使用 before_agent_reply。

对于心跳轮换,当主机知道底层系统事件队列时,before_agent_reply 会收到 ctx.heartbeatEventQueueSessionKey。这可能与隔离心跳运行的 ctx.sessionKey 不同。使用提供的键进行事件查找;不要通过删除 :heartbeat 后缀来派生基本会话,因为配置的会话可以命名为 heartbeat。对于较旧的主机,该字段是可选的。没有它,插件只能检查 ctx.sessionKey;他们无法推断隔离运行的基本队列。该字段标识现有队列并且不授予额外的访问权限。

会话与压缩

钩子 类型 用途
session_start / session_end 观察 跟踪会话生命周期边界
before_compaction / after_compaction 观察 观察压实边界;没有重写或否决结果
before_reset 观察 观察会话重置事件(/reset、程序化重置)

即使没有历史记录更改,成功的引擎拥有的内置本机压缩尝试也会发出 after_compaction,并带有 compactedCount: 0。本机跳过包括仅心跳记录和自动保留策略无操作。完成意味着尝试完成;它不保证历史重写。失败或中止的尝试不会发出该完成挂钩。

session_end.reason 是 new、reset、idle、daily、compaction、deleted、shutdown、restart 之一,或unknown。 session_start 无原因字段;它可以包括 resumedFrom。 Shutdown/restart 事件来自活动会话的网关终结器,因此插件可以在进程退出之前关闭会话状态。

在当前主机上,session_end 上下文包括 endedTranscript。当 OpenClaw 具有不可变的结束会话源时,具有会话访问权限的插件会接收 { available: true, readTail }。看涨期权必须提供正值 maxMessages 和 maxBytes; OpenClaw 强制执行主机上限并返回 { messages, totalMessages, truncated }。当允许的处理程序处于活动状态时,读取器仍然有效。处理程序解决、其配置的挂钩超时、所属插件实例强制退出或 shutdown/restart 耗尽截止时间后,保留或仍待处理的读取会被拒绝。

当不存在安全源时,值为{ available: false, reason }。当前的原因包括缺少对话权限、没有稳定截止的生命周期、已删除的隐身状态、不可用的存档以及不受支持的源。这是一个明确的非结果,而不是一个空的成绩单。根据此合同编译的插件仍应将缺失的字段视为较旧的主机。

session_end 本身仍然是元数据挂钩,无需对话访问即可注册。对于非捆绑插件,plugins.entries.<id>.hooks.allowConversationAccess=true 仅授予有界的结束转录阅读器。捆绑插件遵循相同的有效策略,可以通过 allowConversationAccess: false 拒绝。权限更改适用于成功发布的插件运行时替换所承认的处理程序。已经运行的处理程序保留其生成的授权,同时其有界调用仍然被允许;处理程序结算、挂钩超时、强制实例退役或关闭耗尽到期都会结束租约。前一个版本和后续版本可能会重叠。

关闭和重新启动在所有活动会话和插件处理程序中共享一个 2 秒总计 session_end 消耗预算;预算不是每个处理程序的。快速返回或保持最终确定有界和持久性崩溃一致。如果预算到期,OpenClaw 会记录 shutdown session-end drain timed out 并继续关闭,因此可以中断未完成的插件工作。

对于 sessions.create 与 parentSessionKey 和 emitCommandHooks: true 的调用,不同的子级始终接收 session_start。调用者声明父级是否也接收终端 session_end 和 succeedsParent:true 表示后继,false 表示并行子级。省略保留了遗留的父级翻转行为。在这两种情况下,command:new 和 before_reset 挂钩仍然描述请求的 /new 操作。

子代理

  • subagent_spawned / subagent_ended - 观察子代理的启动和完成。
  • subagent_progress - 观察便携式 started / ended 后台子运行的进度;包括 runId、childSessionKey、可选请求者路由以及 ended 上的结果。
  • subagent_delivery_target - 当没有核心会话绑定可以投影路线时,修改兼容性挂钩以完成交付。第一个返回的 origin 获胜。
  • subagent_spawned 在 OpenClaw 已在启动前解析出子会话原生模型时,会包含 resolvedModel 和 resolvedProvider。
  • subagent_ended 包含 targetSessionKey(标识 - 与 subagent_spawned.childSessionKey 匹配)、targetKind("subagent" 或 "acp")、reason、可选的 outcome("ok"、"error"、"timeout"、"killed"、"reset" 或 "deleted")、可选的 error、runId、endedAt、accountId 和 sendFarewell。它不包含 agentId 或 childSessionKey;请使用 targetSessionKey 与匹配的 subagent_spawned 事件进行关联。

生命周期

钩子 类型 用途
gateway_start / gateway_stop 观察 与 Gateway 一同启动或停止插件拥有的服务
cron_reconciled 观察 在启动或重新加载后与完整的 Gateway cron 状态进行协调
cron_changed 观察 观察 Gateway 拥有的 cron 生命周期变化(添加、更新、移除、启动、完成、计划)
before_install 修改/门 从已加载的插件运行时检查暂存的技能或插件安装材料
skill_changed 观察 观察已提交的实时技能创建、更新和移除事件

技能生命周期

skill_changed 在实时技能创建、更新或删除提交后触发,并包括带有内容和树哈希的可选 before/after 工件,以及可用的声明版本和源版本。

频道配对请求

当未配对的 DM 发送者创建待处理的配对请求后,插件需要通知操作员或写入审核记录时,请使用 channel_pairing_requested。该钩子在创建请求时调度;配对回复的通道传递不会因缓慢或失败的挂钩处理程序而延迟。

typescript
api.on("channel_pairing_requested", async (event) => {  await notifyOperator({    text: `New ${event.channel} pairing request from ${event.senderId}: ${event.code}`,  });});

该钩子仅用于观察。它不会批准、拒绝、抑制或重写配对回复。有效负载包含通道、可选的 accountId、按通道范围的 senderId、配对 code 以及通道元数据。请将配对代码视为实时一次性批准凭证,并仅将其交付给受信任的操作员接收端。请将 metadata 视为不受信任的、由发送者提供的身份文本。该钩子不包含传入消息正文或媒体。

本页有帮助吗?