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:
1 parent
daa85a8bb4
commit
459991421e
27 files changed
+1720
-32
No files matched your search
@@ -0,0 +1,50 @@
|
||||
import type { Kysely } from "kysely";
|
||||
import { execDdl, oneOf } from "../src/migration-helpers.ts";
|
||||
|
||||
// W7-B Pi 子代理(agent.spawn):agent_run 已有 parent_run_id(0010),这里补派生深度与派生理由;
|
||||
// agent_run_event 增加 subagent_spawned / subagent_event / subagent_completed(子会话事件镜像进父会话事件流)。
|
||||
|
||||
const OLD_TYPES = [
|
||||
"run_started",
|
||||
"text_delta",
|
||||
"thinking_delta",
|
||||
"tool_call_start",
|
||||
"tool_call_end",
|
||||
"tool_call_rejected",
|
||||
"compaction",
|
||||
"run_completed",
|
||||
"run_failed",
|
||||
];
|
||||
const NEW_TYPES = [...OLD_TYPES, "subagent_spawned", "subagent_event", "subagent_completed"];
|
||||
|
||||
const swap = (values: readonly string[]) => `
|
||||
alter table agent_run_event drop constraint agent_run_event_type_check;
|
||||
alter table agent_run_event add constraint agent_run_event_type_check ${oneOf("type", values)};
|
||||
`;
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: 迁移不依赖应用表类型
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await execDdl(
|
||||
db,
|
||||
`
|
||||
alter table agent_run add column depth integer not null default 0 check (depth >= 0);
|
||||
alter table agent_run add column spawn_reason text;
|
||||
create index agent_run_parent_idx on agent_run (parent_run_id, created_at) where parent_run_id is not null;
|
||||
${swap(NEW_TYPES)}
|
||||
`,
|
||||
);
|
||||
}
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: 同上
|
||||
export async function down(db: Kysely<any>): Promise<void> {
|
||||
await execDdl(
|
||||
db,
|
||||
`
|
||||
delete from agent_run_event where type in ('subagent_spawned', 'subagent_event', 'subagent_completed');
|
||||
${swap(OLD_TYPES)}
|
||||
drop index if exists agent_run_parent_idx;
|
||||
alter table agent_run drop column spawn_reason;
|
||||
alter table agent_run drop column depth;
|
||||
`,
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user