钩子
钩子用于在会话内注册生命周期回调。管理入口是 registerHook()、hookCount() 和
unregisterHook()。
事件
Node.js 与 Python 的注册辅助方法接受以下 25 个名称
(sdk/node/src/hook_bridge.rs),其他字符串会被拒绝:
Rust Core 还把 permission_request、pre_compact 和 post_compact 暴露为生命
周期点。Go SDK 会把 Hook.EventType 直接交给 Core 的钩子类型解析,因此 Go 也可以
注册这三个名称。Node.js 与 Python 的解析器会拒绝它们;策略需要直接拦截权限请求或
上下文压缩时,应使用 Rust 或 Go 宿主。
感知、memory、规划、推理、限流、确认、成功和意图事件服务于专用 harness。任何宿主都 可以注册它们,但只有发出该事件的运行时路径才会触发。只有受保护的运行时路径确实消费某个事件的决策时,才能把它当作策略边界。
注册示例
处理函数可返回 { action: 'continue' }、{ action: 'skip' }、
{ action: 'block', reason }、{ action: 'retry', reason, delayMs },也可返回空值表示
继续。把钩子用作生产关卡前,应验证产品实际依赖的事件路径。
生命周期治理
真正具有门控语义的事件是 pre_tool_use、permission_request、pre_compact、
pre_prompt、pre_planning 和 pre_run_control。这些事件的处理函数失败或超时时会失败即阻断(fail closed);其他事件
属于观察或建议点,处理基础设施失败时继续运行。
pre_tool_use 可以在工具进入确认或产生副作用前替换参数:
Core 接受 updatedInput、updated_input、args 或 modified 中的直接参数对象,也
接受 Codex 风格的 hookSpecificOutput 包装。改写后的对象会再次通过工具 JSON Schema
校验;非法参数会在任何工具副作用发生前被拒绝。
pre_prompt 可以返回 modified.prompt,以及可选的
modified.additionalContext(或 additional_context)。最终 prompt 会包含有边界的
钩子上下文块,并真正替换发送给模型的用户消息。permission_request 可以返回
decision: 'allow' 或 decision: 'deny';pre_compact 可以阻止压缩。
session_start 与 session_end 为宿主清理和审计提供配对的生命周期观察。
pre_run_control 会在 typed steer 或 interrupt 请求进入活动 Run 收件箱前执行
门控;post_run_control 观察持久的 accepted、applied、settled 或 rejected 回执。
使用相同 Request ID 与载荷重试时,会复用已经记录的准入结果,不会再次触发门控决策;
同一 ID 的冲突载荷会被拒绝。控制后的 Hook 仅用于观察,不能改写已经产生的回执。
拒绝反馈
无法在不改变请求、参数或策略上下文的情况下成功时,返回 block。临时条件应返回
retry,并提供原因和建议延迟:
Python 回调使用 delay_ms;Go 回调返回
&code.HookResponse{Action: "retry", Reason: "...", DelayMS: 1000}。当前调用会被拒绝,
而不是自动重新调度。模型会收到原因和明确的重试指引,直接 SDK 调用者则收到结构化
工具错误:
block 使用同一错误类型,但 retryable 为 false、retry_after_ms 为 null。
需要保留完整重试说明的 Rust 调用者可使用 HookEngine::fire_outcome(),它返回带重试
原因的 HookOutcome;HookEngine::fire() 返回更简单的 HookResult,其中
Retry(u64) 只保留延迟时间。
传播
委派与自动子智能体扇出都经过 task 工具。子运行会继承父 session 的钩子引擎(除非
其自身配置提供了钩子引擎),因此父钩子能观察子运行的工具调用。产品依赖钩子跨委派
运行传播时,应覆盖对应的产品集成路径。