feat(agent): Pi subagents via agent.spawn / agent.await

- agent_run gains depth / spawn_reason (0029); agent_run_event types
  subagent_spawned / subagent_event / subagent_completed
- agent.spawn (propose, medium, replay never): allowlist ⊆ parent, mode not
  above parent, budget carved from parent's remainder, idempotent per run+input;
  settings.pi.subagents {enabled, maxConcurrent, maxDepth} (subagentsEnabled kept as alias)
- child runs claim a concurrency slot under an advisory lock (waitForFact while
  queued); agent.await polls business tables without calling the model
- parent abort cascades to all descendants; parent runtime budget counts
  descendant usage; child events mirrored into the parent stream by parent seq
- authorize caps every child call by all ancestors' allowlists/kinds
- session page shows parent link, inherited info and the subagent tree
- e2e E11; runbook section on subagents

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 02:49:37 +08:00
1 parent daa85a8bb4
commit 459991421e
27 files changed
+1720 -32

No files matched your search

+8 -1
View File
@@ -156,7 +156,14 @@ export function useAgentRun(id: string | undefined) {
params: { afterSeq: NO_EVENTS, limit: 1 },
signal,
});
return { run: d.run, messages: d.messages, report: d.report };
return {
run: d.run,
messages: d.messages,
report: d.report,
parent: d.parent ?? null,
children: d.children ?? [],
...(d.familyUsage ? { familyUsage: d.familyUsage } : {}),
};
},
refetchInterval: (q) => (isRunActive(q.state.data?.run.status) ? 3 * TTL_SECOND : false),
});