跳转至

编写 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 导入。

启用并加载它:

openclaw hooks info reset-greeting
openclaw hooks enable reset-greeting

在一个可路由回复的已配置聊天频道中的临时会话中发送 /new,例如给机器人的直接消息。预期在该会话中看到 Reset hook ran.,并在 Gateway 日志中看到 [reset-greeting] reset hook ran。/reset 会触发相同示例。常规命令授权仍然适用。

请使用普通的 OpenClaw 会话,而不是 ACP 绑定线程;绑定会话会将重置处理委托给其所属运行时。不要使用 Control UI/webchat 或 sessions.reset RPC 作为聊天回复检查:这些路径不会将此钩子的 event.messages 投递到 UI。日志标记仍可以显示重置事件已运行。有关确切边界,请参阅 回复投递。

完成后禁用该示例:

openclaw hooks disable reset-greeting

禁用会保留文件原样。若要改用工作区目录,请将这两个文件放入 <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