会话与停止 Hook
区分正常停止、异常停止、子智能体完成和显式会话删除。
This page has not been translated into English yet. The original Chinese version is shown below.
生命周期 Hook 用于初始化、交接和观察终止。不是所有事件都可阻止流程,也不是所有客户端都发出相同的异常事件。
会话开始与结束
SessionStart 的 source 是 startup、resume、clear 或 compact,另有 model 和可选 agent_type,可通过 additionalContext 提供会话背景。
SessionEnd 按 reason 匹配,包括 clear、logout、prompt_input_exit、bypass_permissions_disabled、other,用于退出清理。普通 Hook 输入还提供 session_id、transcript_path、cwd、hook_event_name、timestamp;子智能体事件可有 agent_id,属于模型轮次时可有 prompt_id。
输入契约允许未来增加可选字段。外部消费者应忽略未知字段;严格解码器需在升级前确认新字段不会让验证路径意外失败。
Stop 阻止结束
Stop 在一轮正常结束前运行,包含 last_assistant_message、stop_hook_active、后台任务和 cron 列表,以及可选上下文用量字段。context_usage 可以超过 1;input_tokens 的具体统计可能因提供商而含输出 token,不能当作统一账单。
{
"decision": "block",
"reason": "The requested verification result is still missing."
}这种返回要求模型继续。continue: false 则是停止执行,不要把 continue 与“阻止停止”反向理解。
连续阻止按 prompt 计数,跨工具往返继续累计。stopHookBlockingCap 默认 8,单次运行可用 QWEN_CODE_STOP_HOOK_BLOCK_CAP 覆盖。允许停止、用户 steer/新输入、重试、Goal 新轮或异常结束会重置计数与 stop_hook_active。
stop_hook_active 在因上次阻止而继续的轮次为 true,即使中途调用工具也不重置。非交互文本模式把消息与上限警告写 stderr,JSON 输出不改。
子智能体事件
SubagentStart 按 agent_type 匹配,可追加初始上下文。SubagentStop 包含 agent_id、agent_type、agent_transcript_path、最后消息、后台任务、cron 与 stop_hook_active,也可以通过 block 和 reason 要求继续。
Agent frontmatter 中的 Stop 不会自动变成 SubagentStop。前者不能代替子智能体完成事件,作用域见配置。
StopFailure 的客户端差异
| 原因 | TUI | 无头 -p | ACP |
|---|---|---|---|
| API 错误结束 | 触发 | 不触发 | 触发 |
| 循环检测结束 | 触发 | 触发 | 不触发 |
它替代 Stop,但不等待执行完成,输出和退出码均忽略。matcher 使用 error,分类依次检查 rate_limit、authentication_failed、billing_error、invalid_request、server_error、max_output_tokens,最后 unknown;循环为 loop_detected。可带 error_details,TUI 的 last_assistant_message 当前可能就是格式化错误文本。
Command 接收后即使 Qwen 退出也允许独立完成,stdout/stderr 不连接到 Qwen 输出。它适合日志,不适合补救后要求原轮继续。
SessionDelete 发生在删除之后
输入 deleted_session_id 指明被删会话,普通 session_id/cwd 属于执行删除的运行时。ACP 删除运行时自身无转录,transcript_path 为空。
目前仅交互 /delete 与 ACP 显式 deleteSession 发出,daemon REST 批量删除和内部清理不发出。输出、故障都不能撤销删除,command 接收后可在 Qwen 退出后独立完成。不能用它代替删除前审批。