跳转至

Hook 事件类型与上下文

每个内部事件键、其触发与等待行为,以及每个生产者提供的上下文。属于 Hooks 指南的一部分。

事件类型

订阅以下某个精确键或仅家族名(command、session、agent、gateway、message)。家族订阅会接收该家族中的所有动作。除非希望新命令时它被调用两次,否则不要将同一个处理器同时订阅到 command 和 command:new。session:compact 既不是家族也不是通配符;请订阅两个精确的压缩键。

事件 触发与等待行为
command:new 经过授权的新会话命令处理,或会发出新命令钩子的 Gateway 会话操作;会被等待。
command:reset 经过授权的 reset 命令处理或 Gateway 会话重置;会被等待。
command:stop 中止请求之后的 stop 命令处理;会被等待,且不投递钩子回复。
session:auto-reset 由于每日/空闲策略替换现有会话;独立于后续轮次派发。
session:compact:before 压缩工作之前;会被等待。
session:compact:after 成功压缩之后;会被等待。
session:patch 已授权的 Gateway 补丁被应用,或受支持的模型选择路径持久化了变更;异步通知。
agent:bootstrap 上下文注入之前的工作区 bootstrap 解析;会被等待。
gateway:startup 在钩子加载以及 sidecar/通道启动工作之后调度;不会延迟初始 Gateway 绑定。
gateway:shutdown 关闭开始,位于通道/插件拆除之前;有界等待。
gateway:pre-restart 关闭具有有限的预期重启延迟;有界等待。
message:received 带有会话键的已接受入站派发;异步观察。
message:transcribed 代理前预处理具有非空音频转录文本和会话键;异步观察。
message:preprocessed 媒体/链接预处理完成或被跳过,并带有会话键;异步观察。
message:sent 投递所有者报告带有会话键的发送结果;异步观察。检查 context.success。

对 gateway:shutdown 和 gateway:pre-restart 钩子的初始等待是有界的,以便独立的拆除工作可以继续。超时不会取消处理器。在关闭共享状态之前,Gateway 会等待实际钩子完成;因此,一个永不结束的处理器可能会阻止进程内关闭完成。

并非每个传入的传输更新或尝试的低层发送都会产生内部消息事件。被抑制/重复的入站派发以及没有会话键的路径可能会省略它们。这些是观察点,而不是完整的传输审计,也不是阻止消息处理的方式。快速的原生命令路径可以跳过预处理事件。preprocessed 表示该阶段已通过,而不是每个附件或链接都被成功理解。同样,压缩可以在其 before 事件之后被跳过或失败,重试可以再次发出 before 事件。

未知订阅(例如 command:nwe)仍会被注册,但加载器会发出警告,并且 hooks info 会报告它们。核心不会发出它们。自定义键只有在自定义代码显式发出它时才会触发;在元数据中声明它并不会创建触发器。

command:stop 观察取消命令处理。它不是代理最终化的自然门控。对于该契约,请参阅 Plugin hooks 中的 before_agent_finalize。

事件上下文要点

以下字段描述生产者负载。标记为可选的值可能缺失;不要假设一个事件中的字段存在于另一个事件中。

command:new 和 command:reset: 在聊天命令路径上:agentId、sessionEntry、previousSessionEntry、commandSource、senderId、workspaceDir、storePath 和 cfg。条目和路由元数据取决于调用方。Gateway 重置使用 commandSource: "gateway:sessions.reset";Gateway 代理重置使用 gateway:agent,会话创建可以使用 webchat。Gateway 调用方会省略 senderId。会话创建只有在针对现有父级请求 emitCommandHooks 时才会发出新命令钩子。对于被替换的会话,优先使用 previousSessionEntry:聊天和 Gateway 路径在重置的不同点发出,因此它不是通用的重置前或重置成功回执。sessionFile 值可以是转录标识符,而不是可读文件路径;不要假设它是磁盘上的 JSONL。

command:stop: 可选的 sessionEntry、sessionId、commandSource 和 senderId。它不携带完整的新建/重置上下文。

session:auto-reset: cfg、agentId、workspaceDir、storePath、标识已结束的 sessionId 的 sessionEntry 以及可选的 sessionFile、reason(daily 或 idle),以及可选的 transcriptArchived、nextSessionId 和 nextSessionKey。

agent:bootstrap: workspaceDir、可变的 bootstrapFiles,以及可选的 cfg、sessionKey、sessionId、agentId。每个 bootstrap 记录具有 name、path、missing 和可选的 content。处理器可以替换或扩展该数组,但最终路径去重、会话/隐私过滤和上下文预算仍然适用。

session:patch: 操作后克隆的 sessionEntry、请求形状的 patch,以及 cfg。补丁包含目标/期望字段和已提交的设置,而不是计算出的已更改字段差异。即使提交的值已经存在,成功的 Gateway 补丁也可能发出。支持的模型选择路径也会发出,包括 /model、模型选择器,以及通过 session_status 进行的模型更改;只读状态查询不会发出。这不是针对每个会话存储写入的通知。

压缩: 两个阶段都包含 sessionId、missingSessionKey、messageCount 和可选的 tokenCount。Before 阶段还包含 messageCountOriginal 和可选的 tokenCountOriginal。After 阶段包含 compactedCount 以及可选的 summaryLength、tokensBefore、tokensAfter 和 firstKeptEntryId。不要将不可用的 token 数量推断为零。

gateway:startup: cfg、deps 和 workspaceDir。关闭与重启前: reason 和 restartExpectedMs(关闭时不预期重启时为 null)。关闭等待默认为 5 秒;重启前会额外增加一个独立的 10 秒预算。这些限制的是调用方的等待,而不是处理程序的工作:超时不会取消 Promise。通道尚未被拆除,但队列中的 agent 工作和消息投递都不保证在关闭前完成。类型化的 session_end 排空行为属于 插件钩子。

消息上下文

message:received 包含 from、content、channelId,以及可选的 timestamp、accountId、conversationId、messageId、media、originalMedia、mediaStagingPending 和 metadata。内容优先使用非空命令正文,然后是原始正文,然后是通用正文。它不会选择 BodyForAgent;回退正文由 surface 定义,而不是由 mapper 剥离所有增强。

接收到的 metadata 可以包含 to、provider、surface、threadId、senderId、senderName、senderUsername、senderE164、guildId、channelName 和 topicName。旧版附件别名是 mediaPath、mediaUrl、mediaType、mediaPaths、mediaUrls 和 mediaTypes;远程暂存元数据还可以包含 mediaRemoteHost、mediaStagingPending,以及对应的 originalMediaPath、originalMediaUrl、originalMediaType、originalMediaPaths、originalMediaUrls 和 originalMediaTypes。优先使用结构化媒体数组。

message:transcribed 和 message:preprocessed 包含 channelId、cfg,以及可选的 from、to、body、bodyForAgent、timestamp、conversationId、messageId、senderId、senderName、senderUsername、provider、surface 和结构化媒体字段。Transcribed 阶段添加必需的 transcript 文本;preprocessed 阶段添加可选的 transcript、isGroup 和 groupId。bodyForAgent 是为 agent 准备的增强正文。mediaPath 和 mediaType 仍然是已弃用的首个附件别名。这些上下文不保证提供 accountId 或接收事件的 metadata 对象。

每个结构化媒体事实可以包含 path、url、contentType、kind、transcribed、messageId 和 workspaceDir。事实保留源顺序。当 mediaStagingPending 为 true 时,media 会被扣留,originalMedia 描述原始附件;不要将远程路径视为本地文件。

message:sent 包含 to、content、success、channelId,以及可选的 error、accountId、conversationId、messageId、isGroup 和 groupId。success: false 报告在已发出结果的路径上的失败;事件缺失既不能证明成功,也不能证明失败。出站投递可以按每个逻辑负载报告一个结果,而不是按每个文本块报告,并且部分失败可以包含已发送部分的 message ID。持久出站队列结算可以延迟观察;它不会使钩子持久。不要盲目地在失败时重发:你可能会重复一个已投递的部分。发送结果不是接收者已读取消息的证明。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw