Hooks
Hooks 是当 Gateway(网关) 内部发生某些事情时运行的小脚本。可以从目录中发现它们,并使用 Gateway(网关)openclaw hooksGateway(网关) 进行检查。只有在您启用了 hooks 或配置了至少一个 hook 条目、hook 包、旧版处理程序或额外的 hook 目录后,Gateway(网关) 才会加载内部 hooks。
OpenClaw 中有两种钩子:
- Internal hooks (本页):当 agent 事件触发时在 Gateway(网关) 内部运行,例如 Gateway(网关)
/new、/reset、/stop或生命周期事件。 - Webhooks:外部 HTTP 端点,允许其他系统在 OpenClaw 中触发工作。请参阅 Webhooks。
Hooks 也可以捆绑在插件内部。openclaw hooks list 显示了独立的 hooks 和由插件管理的 hooks。
# List available hooksopenclaw hooks list
# Enable a hookopenclaw hooks enable session-memory
# Check hook statusopenclaw hooks check
# Get detailed informationopenclaw hooks info session-memory| 事件 | 触发时机 |
|---|---|
command:new | /new command issued |
command:reset | /reset command issued |
command:stop | /stop command issued |
command | 任何命令事件(通用监听器) |
session:compact:before | 在压缩总结历史记录之前 |
session:compact:after | 压缩完成后 |
session:patch | 当会话属性被修改时 |
agent:bootstrap | 在注入工作区引导文件之前 |
gateway:startup | 渠道启动且钩子加载后 |
gateway:shutdown | 当网关关闭开始时 |
gateway:pre-restart | 在预期的网关重启之前 |
message:received | 来自任何渠道的入站消息 |
message:transcribed | 音频转录完成后 |
message:preprocessed | 媒体和链接预处理完成或跳过后 |
message:sent | 出站消息已投递 |
每个钩子都是一个包含两个文件的目录:
my-hook/├── HOOK.md # Metadata + documentation└── handler.ts # Handler implementationHOOK.md 格式
Section titled “HOOK.md 格式”---name: my-hookdescription: "Short description of what this hook does"metadata: { "openclaw": { "emoji": "🔗", "events": ["command:new"], "requires": { "bins": ["node"] } } }---
# My Hook
Detailed documentation goes here.Metadata fields (metadata.openclaw):
| 字段 | 描述 |
|---|---|
emoji | CLI 的显示表情符号 |
events | 要监听的事件数组 |
export | 要使用的命名导出(默认为 "default") |
os | 所需的平台(例如 ["darwin", "linux"]) |
requires | 必需 bins、anyBins、env 或 config 路径 |
always | 绕过资格检查(布尔值) |
install | 安装方法 |
处理程序实现
Section titled “处理程序实现”const handler = async (event) => { if (event.type !== "command" || event.action !== "new") { return; }
console.log(`[my-hook] New command triggered`); // Your logic here
// Optionally send message to user event.messages.push("Hook executed!");};
export default handler;每个事件包含:type、action、sessionKey、timestamp、messages(推送以发送给用户)和 context(特定于事件的数据)。Agent 和工具插件 Hook 上下文还可以包含 trace,这是一个只读的符合 W3C 标准的诊断跟踪上下文,插件可以将其传递到结构化日志中以进行 OTEL 关联。
事件上下文要点
Section titled “事件上下文要点”命令事件 (command:new、command:reset):context.sessionEntry、context.previousSessionEntry、context.commandSource、context.workspaceDir、context.cfg。
消息事件 (message:received):context.from、context.content、context.channelId、context.metadata(提供商特定数据,包括 senderId、senderName、guildId)。对于类似命令的消息,context.content 优先使用非空的命令正文,然后回退到原始入站正文和通用正文;它不包含仅限 Agent 的增强内容,例如线程历史或链接摘要。
消息事件 (message:sent):context.to、context.content、context.success、context.channelId。
消息事件 (message:transcribed):context.transcript、context.from、context.channelId、context.mediaPath。
消息事件 (message:preprocessed):context.bodyForAgent(最终增强正文)、context.from、context.channelId。
Bootstrap events (agent:bootstrap): context.bootstrapFiles (mutable array), context.agentId。
Session patch events (session:patch): context.sessionEntry, context.patch (only changed fields), context.cfg。只有特权客户端才能触发补丁事件。
Compaction events: session:compact:before 包含 messageCount, tokenCount。session:compact:after 添加了 compactedCount, summaryLength, tokensBefore, tokensAfter。
command:stop 观察用户发出的 /stop;它是取消/命令生命周期,而不是代理最终确定的关卡。需要检查自然最终答案并请求代理再进行一轮传递的插件,应该改用类型化的插件钩子 before_agent_finalize。请参阅 Plugin hooks。
Gateway(网关) lifecycle events: Gateway(网关)gateway:shutdown 包含 reason 和 restartExpectedMs 并在 Gateway 关闭开始时触发。gateway:pre-restart 包含相同的上下文,但仅在关闭是预期重启的一部分且提供了有限的 restartExpectedMs 值时才触发。在关闭期间,每个生命周期钩子的等待都是尽力而为且有界的,因此如果处理程序停止,关闭仍会继续。gateway:shutdown 的默认等待时间为 5 秒,gateway:pre-restart 为 10 秒。
使用 gateway:pre-restart 在频道仍可用时发送简短的重启通知:
import { execFile } from "node:child_process";import { promisify } from "node:util";
const execFileAsync = promisify(execFile);
export default async function handler(event) { if (event.type !== "gateway" || event.action !== "pre-restart") { return; }
const restartInSeconds = Math.ceil(event.context.restartExpectedMs / 1000); await execFileAsync("openclaw", ["system", "event", "--mode", "now", "--text", `Gateway restarting in ~${restartInSeconds}s (${event.context.reason}). Checkpoint now.`]);}在 gateway:shutdown(或 gateway:pre-restart)事件与关闭序列的其余部分之间,Gateway(网关) 还会为进程停止时仍处于活动状态的每个会话触发一个类型化的 session_end 插件钩子。对于普通的 SIGTERM/SIGINT 停止,该事件的 reason 为 shutdown;而当关闭是作为预期重启的一部分被调度时,则为 restart。此排空操作是有界的,因此缓慢的 session_end 处理程序无法阻止进程退出,并且已通过 replace / reset / delete / compaction 完成最终确定的会话将被跳过,以避免重复触发。
钩子从以下目录中发现,按覆盖优先级递增的顺序排列:
- 内置钩子 (Bundled hooks):随 OpenClaw 一起提供
- 插件钩子 (Plugin hooks):捆绑在已安装插件内部的钩子
- 托管钩子 (Managed hooks):
~/.openclaw/hooks/(用户安装的,在工作区之间共享)。来自hooks.internal.load.extraDirs的额外目录共享此优先级。 - 工作区钩子 (Workspace hooks):
<workspace>/hooks/(每个代理一个,默认禁用,直到明确启用)
工作区钩子可以添加新的钩子名称,但不能覆盖具有相同名称的内置、托管或插件提供的钩子。
Gateway(网关) 在启动时会跳过内部钩子发现,直到配置了内部钩子。使用 Gateway(网关)openclaw hooks enable <name> 启用内置或托管钩子,安装钩子包,或设置 hooks.internal.enabled=trueGateway(网关) 以选择加入。当您启用一个命名钩子时,Gateway(网关) 仅加载该钩子的处理程序;hooks.internal.enabled=true、额外的钩子目录和旧版处理程序则选择加入广泛发现。
钩子包 (Hook packs)
Section titled “钩子包 (Hook packs)”钩子包是通过 package.json 中的 openclaw.hooks 导出钩子的 npm 包。安装方法如下:
openclaw plugins install <path-or-spec>Npm 规范仅限于注册表(包名称 + 可选的确切版本或 dist-tag)。拒绝 Git/URL/文件规范和 semver 范围。
| 钩子 | 事件 | 作用 |
|---|---|---|
| 会话-memory | command:new, command:reset | 将会话上下文保存到 <workspace>/memory/ |
| bootstrap-extra-files | agent:bootstrap | 根据 glob 模式注入额外的引导文件 |
| command-logger | command | 将所有命令记录到 ~/.openclaw/logs/commands.log |
| compaction-notifier | session:compact:before, session:compact:after | 当会话压缩开始/结束时发送可见的聊天通知 |
| boot-md | gateway:startup | 当网关启动时运行 BOOT.md |
启用任何捆绑的 Hook:
openclaw hooks enable <hook-name>会话-memory 详细信息
Section titled “会话-memory 详细信息”提取最后 15 条用户/助手消息,并使用主机本地日期保存到 <workspace>/memory/YYYY-MM-DD-HHMM.md。内存捕获在后台运行,因此 /new 和 /reset 确认不会因读取转录或可选的 slug 生成而延迟。设置 hooks.internal.entries.session-memory.llmSlug: true 以使用配置的模型生成描述性文件名 slug。需要配置 workspace.dir。
bootstrap-extra-files 配置
Section titled “bootstrap-extra-files 配置”{ "hooks": { "internal": { "entries": { "bootstrap-extra-files": { "enabled": true, "paths": ["packages/*/AGENTS.md", "packages/*/TOOLS.md"] } } } }}路径相对于工作区解析。仅加载已识别的引导基名 (AGENTS.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, HEARTBEAT.md, BOOTSTRAP.md, MEMORY.md)。
command-logger 详细信息
Section titled “command-logger 详细信息”将每个斜杠命令记录到 ~/.openclaw/logs/commands.log。
compaction-notifier 详细信息
Section titled “compaction-notifier 详细信息”当 OpenClaw 开始和结束压缩会话记录时,向当前对话发送简短的状态消息。这使聊天界面上的长轮次不再令人困惑,因为用户可以看到助手正在总结上下文,并将在压缩后继续。
boot-md 详细信息
Section titled “boot-md 详细信息”当网关启动时,从活动工作区运行 BOOT.md。
插件 Hooks
Section titled “插件 Hooks”插件可以通过 Plugin SDK 注册类型化钩子以实现更深度的集成:
拦截工具调用、修改提示词、控制消息流等。
当您需要 before_tool_call、before_agent_reply、
before_install 或其他进程内生命周期钩子时,请使用插件钩子。
有关完整的插件钩子参考,请参阅 Plugin hooks。
{ "hooks": { "internal": { "enabled": true, "entries": { "session-memory": { "enabled": true }, "command-logger": { "enabled": false } } } }}每个钩子的环境变量:
{ "hooks": { "internal": { "entries": { "my-hook": { "enabled": true, "env": { "MY_CUSTOM_VAR": "value" } } } } }}额外的钩子目录:
{ "hooks": { "internal": { "load": { "extraDirs": ["/path/to/more/hooks"] } } }}CLI 参考
Section titled “CLI 参考”# List all hooks (add --eligible, --verbose, or --json)openclaw hooks list
# Show detailed info about a hookopenclaw hooks info <hook-name>
# Show eligibility summaryopenclaw hooks check
# Enable/disableopenclaw hooks enable <hook-name>openclaw hooks disable <hook-name>- 保持处理程序的快速性。 钩子在命令处理期间运行。使用
void processInBackground(event)即发即弃(fire-and-forget)繁重的工作。 - 优雅地处理错误。 将有风险的操作包装在 try/catch 中;不要抛出错误,以便其他处理程序能够运行。
- 尽早过滤事件。 如果事件类型/动作不相关,则立即返回。
- 使用特定的事件键。 优先使用
"events": ["command:new"]而非"events": ["command"]以减少开销。
# Verify directory structurels -la ~/.openclaw/hooks/my-hook/# Should show: HOOK.md, handler.ts
# List all discovered hooksopenclaw hooks list钩子不符合条件
Section titled “钩子不符合条件”openclaw hooks info my-hook检查是否缺少二进制文件 (PATH)、环境变量、配置值或操作系统兼容性问题。
- 验证钩子是否已启用:
openclaw hooks list - 重启您的网关进程以便重新加载钩子。
- 检查网关日志:
./scripts/clawlog.sh | grep hook
- CLI 参考:hooks
- Webhooks
- Plugin hooks — 进程内插件生命周期钩子
- 配置