feat(pi): capture subagent activity events
This commit is contained in:
@@ -26,6 +26,55 @@ function events(): RunnerEvents {
|
||||
};
|
||||
}
|
||||
|
||||
test("child RPC process forwards structured activity before collecting the final result", async (t) => {
|
||||
const running: unknown[] = [];
|
||||
const completed: Array<{ result: string; stopReason?: string }> = [];
|
||||
const fakeChild = new EventEmitter() as EventEmitter & {
|
||||
stdout: FakeStream;
|
||||
stderr: FakeStream;
|
||||
stdin: FakeStream;
|
||||
killed: boolean;
|
||||
pid?: number;
|
||||
kill(signal?: NodeJS.Signals): boolean;
|
||||
};
|
||||
fakeChild.stdout = new FakeStream();
|
||||
fakeChild.stderr = new FakeStream();
|
||||
fakeChild.stdin = new FakeStream();
|
||||
fakeChild.killed = false;
|
||||
fakeChild.kill = () => {
|
||||
fakeChild.killed = true;
|
||||
return true;
|
||||
};
|
||||
t.mock.method(fakeChild.stdin, "write", (chunk, callback?: (error?: Error | null) => void) => {
|
||||
const request = JSON.parse(String(chunk)) as { id: string; type: string };
|
||||
callback?.();
|
||||
if (request.type === "get_last_assistant_text") {
|
||||
queueMicrotask(() => {
|
||||
fakeChild.stdout.emit("data", `${JSON.stringify({ id: request.id, type: "response", success: true, data: { text: "final answer" } })}\n`);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
});
|
||||
t.mock.method(childProcess, "spawn", () => fakeChild as unknown as childProcess.ChildProcessWithoutNullStreams);
|
||||
|
||||
const { SubprocessRpcRunner } = await import("./runner.ts");
|
||||
const runner = new SubprocessRpcRunner();
|
||||
await runner.start("child-1", { prompt: "work", label: "Review migration" }, "/tmp", {
|
||||
...events(),
|
||||
running: (event) => running.push(event),
|
||||
completed: (result, stopReason) => completed.push({ result, stopReason }),
|
||||
});
|
||||
|
||||
const firstActivity = { type: "message_start", role: "assistant", message: { id: "msg-1" } };
|
||||
const secondActivity = { type: "tool_execution_start", tool: "read", input: { path: "runner.ts" } };
|
||||
const settledActivity = { type: "agent_settled" };
|
||||
fakeChild.stdout.emit("data", `${JSON.stringify(firstActivity)}\n${JSON.stringify(secondActivity)}\n${JSON.stringify(settledActivity)}\n`);
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
|
||||
assert.deepEqual(running, [firstActivity, secondActivity, settledActivity]);
|
||||
assert.deepEqual(completed, [{ result: "final answer", stopReason: "agent_settled" }]);
|
||||
});
|
||||
|
||||
test("child RPC process disables discovery while explicitly loading subagents extension", async (t) => {
|
||||
const calls: Array<{ command: string; args: string[] }> = [];
|
||||
const fakeChild = new EventEmitter() as EventEmitter & {
|
||||
|
||||
Reference in New Issue
Block a user