四、树的查询与遍历
4.1 核心遍历算法 — BFS
forEachDescendantRun(runs, rootSessionKey, visitor):pending = [root] // BFS 队列visited = Set([root]) // 防循环for each requester in pending:for each run where run.requesterSessionKey === requester:visitor(runId, run) // 访问该运行记录if run.childSessionKey not in visited:visited.add(childKey)pending.push(childKey) // 将子会话入队
4.2 查询函数清单
forEachDescendantRun() | BFS 遍历所有后代 run |
countActiveDescendantRunsFromRuns() | 统计未结束(`!endedAt`)的后代数 |
countPendingDescendantRunsFromRuns() | 统计未完成清理(`!endedAt \|\| !cleanupCompletedAt`)的后代数 |
countPendingDescendantRunsExcludingRunFromRuns() | 排除指定 run 后统计(防自锁) |
listDescendantRunsForRequesterFromRuns() | 收集所有后代 run 记录列表 |
listRunsForRequesterFromRuns() | 列出直接子 run(支持时间窗口过滤) |
listRunsForControllerFromRuns() | 按 controller 列出受控 run |
countActiveRunsForSessionFromRuns() | 统计活跃 run(含等待后代的) |
findRunIdsByChildSessionKeyFromRuns() | 按子会话 key 查 runId |
resolveRequesterForChildSessionFromRuns() | 查子会话的父会话信息 |
五、生命周期管理
5.1 Run状态机
CREATED↓REGISTERED↓STARTED↓RUNNING → ENDED↓CLEANUP_STARTED↓┌─ DEFER_DESCENDANTS(后代未完成,等待)│ ↓│ WAKE_ON_SETTLE(后代完成后唤醒)└───────── ↓ANNOUNCE_PENDING↓┌─ ANNOUNCE_RETRYING(指数退避 1s→2s→4s→8s)└───────── ↓CLEANUP_COMPLETED↓DELETED 或 KEPT(取决于 cleanup 策略)
5.2 结束原因枚举
subagent-complete | |
subagent-error | |
subagent-killed | 被父会话主动杀死 |
session-reset | 会话被重置 |
session-delete | 会话被删除 |
5.3 等待子代完成
设置 ‘wakeOnDescendantSettle = true’ 进入 ’defer-descendants‘ 状态,每 1 秒重新检查 后代全部 settle 后,唤醒父 run 继续 announce 流程 硬超时 30 分钟后放弃等待
resolveDeferredCleanupDecision():如果 expectsCompletionMessage && activeDescendantRuns > 0:→ defer-descendants(延迟 1s 后重试)如果超过硬超时(30min):→ give-up如果重试次数 >= 3 或超过普通超时(5min):→ give-up否则:→ retry(指数退避)
5.4级联杀死(Cascade Kill)
定义在‘src/agents/subagent-control.ts’,当杀死父会话时递归杀死所有后代。
cascadeKillChildren(parentChildSessionKey):childRuns = listSubagentRunsForController(parent)for each run in childRuns:if not visited(run.childSessionKey):visited.add(childSessionKey)killSubagentRun(run) // 中止 PI 运行 + 清空队列 + 标记终止cascadeKillChildren(childSessionKey) // 递归杀死孙代
每次 kill 操作会:
`abortEmbeddedPiRun()` — 中止嵌入的 PI 运行 `clearSessionQueues()` — 清空消息队列 更新 session store:`abortedLastRun = true` `markSubagentRunTerminated()` — 标记 run 为 killed 触发 `subagent_ended` 钩子
5.5 Steer(转向控制)
标记旧 run 为 `steer-restart`(抑制 announce) 中止旧嵌入会话 + 清空队列 等待 `agent.wait()` settle 发送新指令启动新 run 替换旧 run 记录为新 run 记录 速率限制:同一目标最少间隔 2 秒
5.6 生命周期错误宽限期
15 秒内如果收到 start/end 成功事件 → 取消错误 15 秒后仍无成功信号 → 最终确认为 error 并触发清理
5.7 进程重启恢复
restoreSubagentRunsOnce():1. 从磁盘恢复 run 记录2. 清理孤儿 run(session store 中已不存在的)3. 恢复待完成的清理/announce 流程4. 启动 sweeper 定时器(每 60s 扫描可归档的 run)
夜雨聆风