编写 hooks
钩子文件布局、处理程序契约、回复投递以及 HOOK.md 元数据字段。属于 Hooks 指南的一部分。
编写钩子¶
本示例会响应重置命令并写入固定的日志标记。它不会读取消息内容、调用模型或联系外部服务。
钩子结构¶
在 Gateway 主机上,使用一个新的受管钩子目录。以下命令假设使用默认状态目录,并且 reset-greeting 尚不存在;请选择其他名称,而不是覆盖现有钩子。
mkdir -p ~/.openclaw/hooks/reset-greeting
cat > ~/.openclaw/hooks/reset-greeting/HOOK.md <<'HOOK'
---
name: reset-greeting
description: "Confirm that a reset hook ran"
metadata:
{ "openclaw": { "events": ["command:new", "command:reset"] } }
---
# Reset greeting
Send a short confirmation after an authorized reset command.
HOOK
cat > ~/.openclaw/hooks/reset-greeting/handler.js <<'HANDLER'
export default function handler(event) {
if (event.type !== "command" || !["new", "reset"].includes(event.action)) {
return;
}
console.log("[reset-greeting] reset hook ran");
event.messages.push("Reset hook ran.");
}
HANDLER
钩子需要 HOOK.md 和一个处理程序文件。发现机制会按顺序检查 handler.ts、handler.js、index.ts,然后是 index.js,并使用找到的第一个文件。本示例使用 JavaScript,因此不需要 TypeScript 类型或 SDK 导入。
启用并加载它:
在一个可路由回复的已配置聊天频道中的临时会话中发送 /new,例如给机器人的直接消息。预期在该会话中看到 Reset hook ran.,并在 Gateway 日志中看到 [reset-greeting] reset hook ran。/reset 会触发相同示例。常规命令授权仍然适用。
请使用普通的 OpenClaw 会话,而不是 ACP 绑定线程;绑定会话会将重置处理委托给其所属运行时。不要使用 Control UI/webchat 或 sessions.reset RPC 作为聊天回复检查:这些路径不会将此钩子的 event.messages 投递到 UI。日志标记仍可以显示重置事件已运行。有关确切边界,请参阅 回复投递。
完成后禁用该示例:
禁用会保留文件原样。若要改用工作区目录,请将这两个文件放入 <workspace>/hooks/reset-greeting/,然后显式启用该钩子。工作区放置位置不是代理沙箱,也不保证 Gateway 会加载该工作区的钩子。
处理程序实现¶
处理程序导出一个返回 void 或 Promise<void> 的函数。除非 metadata.openclaw.export 指定了另一个导出,否则加载器使用默认导出。返回值不会阻塞、取消或重写该操作。
每个事件都具有以下字段:
| 字段 | 含义 |
|---|---|
type |
类别:command、session、agent、gateway 或 message |
action |
类别内的操作,例如 new 或 compact:before |
sessionKey |
会话关联键;Gateway 事件改用 Gateway 键 |
timestamp |
创建事件对象时的 JavaScript Date |
context |
在 事件上下文要点 中描述的事件特定数据 |
messages |
初始为空字符串数组;只有某些生产者会将其作为回复消费 |
将 context 视为观察数据,而不是实时状态编辑 API。字段因生产者而异,并且并非每个事件都有 cfg。特别是,patch 事件携带克隆的快照。明确的可变例外是 agent:bootstrap 的 context.bootstrapFiles。
回复投递¶
向 event.messages 推送并不是通用的发送消息 API:
| 生产者 | event.messages 的处理方式 |
|---|---|
针对 /new 和 /reset 的聊天命令处理 |
等待处理程序,用空行连接字符串,并尝试向原始频道/接收方发送回复,同时保留账户和线程上下文 |
发出 command:new 或 command:reset 的 Gateway 会话重置/创建 RPC |
处理程序会运行,但消息不会作为聊天回复路由 |
session:compact:before 和 session:compact:after |
如果存在,转发到调用方的压缩通知回调;该回调负责投递 |
| 所有其他核心事件 | 作为回复被忽略,包括 /stop、自动重置、消息事件、bootstrap、patch 和 Gateway 生命周期事件 |
缺少接收方、不支持的路由、发送策略或投递失败都可能阻止回复。请在处理程序的 promise 结算之前追加消息;稍后推送的分离任务可能会错过生产者的投递步骤。若要控制常规代理回复或发送取消,请使用相应的 类型化插件钩子。
HOOK.md 格式¶
HOOK.md 使用 YAML 前置元数据,后接人类可读的 Markdown:
---
name: my-hook
description: "Short description of what this hook does"
homepage: https://example.com/my-hook
metadata:
{ "openclaw": { "emoji": "🔗", "events": ["command:new"], "requires": { "bins": ["node"] } } }
---
# My Hook
Explain the side effects, configuration, and verification steps here.
name 默认取目录名;请使用唯一且稳定的名称。
description 会显示在报告中。以下字段属于
metadata.openclaw:
| 字段 | 约定 |
|---|---|
events |
事件键数组。至少需要一个才能注册处理器。 |
export |
函数导出名称;默认为 default。 |
hookKey |
配置项键;默认为钩子名称。发现冲突时仍使用钩子名称。 |
emoji |
显示表情符号。 |
homepage |
文档 URL;覆盖顶层 homepage、website 或 url。 |
os |
允许的 Node 平台名称,例如 darwin、linux 或 win32。 |
requires.bins |
每个指定的可执行文件都必须位于 PATH 中。 |
requires.anyBins |
至少一个指定的可执行文件必须位于 PATH 中。 |
requires.env |
每个指定的变量都需要非空进程值或按钩子的 env 值。 |
requires.config |
每个点分隔的配置路径都必须为真值。 |
always |
绕过二进制、环境和配置要求;但不绕过操作系统或启用策略。 |
install |
信息性安装描述符:kind 为 bundled、npm 或 git;可选 id、label、package、repository 和 bins。此元数据不会安装依赖,也不会使 Git 规范被 CLI 接受。 |
请使用 hooks.internal.entries.<hookKey>.enabled 控制启用状态,而不是在
HOOK.md 中使用顶层 enabled 标志。对于历史要求元数据,
workspace.dir、browser.enabled 和 browser.evaluateEnabled 在缺失时默认为 true。
workspace.dir 不是需要添加到配置中的新设置。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw