fix(tests): iteration 4

This commit is contained in:
Mohamed Boudra
2026-03-13 13:44:25 +07:00
parent 8e67f5a707
commit f74031b50d
2 changed files with 55 additions and 210 deletions
@@ -1387,11 +1387,46 @@ describe("AgentManager", () => {
cwd: workdir,
});
const runningStateEvents: string[] = [];
let resolveAutonomousTurnStarted!: () => void;
const autonomousTurnStarted = new Promise<void>((resolve) => {
resolveAutonomousTurnStarted = resolve;
});
let resolveSecondRunningState!: () => void;
const secondRunningState = new Promise<void>((resolve) => {
resolveSecondRunningState = resolve;
});
manager.subscribe(
(event) => {
if (event.type === "agent_state" && event.agent.id === snapshot.id) {
if (event.agent.lifecycle !== "running") {
return;
}
runningStateEvents.push(event.agent.lifecycle);
if (runningStateEvents.length >= 2) {
resolveSecondRunningState();
}
return;
}
if (
event.type === "agent_stream" &&
event.agentId === snapshot.id &&
event.event.type === "turn_started"
) {
resolveAutonomousTurnStarted();
}
},
{ agentId: snapshot.id, replayState: true }
);
const foreground = manager.streamAgent(snapshot.id, "foreground run");
const consumeForeground = (async () => {
for await (const _event of foreground) {
// Drain foreground stream.
const foregroundResults = (async () => {
const events: AgentStreamEvent[] = [];
for await (const event of foreground) {
events.push(event);
}
return events;
})();
await manager.waitForAgentRunStart(snapshot.id);
@@ -1405,16 +1440,32 @@ describe("AgentManager", () => {
liveEvents.push({ type: "turn_completed", provider: "codex" });
releaseForeground.resolve();
await consumeForeground;
const foregroundEvents = await foregroundResults;
const replaying = manager.getAgent(snapshot.id);
expect(replaying?.lifecycle).toBe("running");
expect(
foregroundEvents.some((event) => event.type === "turn_completed")
).toBe(true);
expect(
foregroundEvents.some(
(event) =>
event.type === "timeline" &&
event.item.type === "assistant_message" &&
event.item.text.includes("AUTONOMOUS_DURING_FOREGROUND")
)
).toBe(false);
await autonomousTurnStarted;
await secondRunningState;
const settled = await manager.waitForAgentEvent(snapshot.id);
expect(settled.status).toBe("idle");
expect(manager.getTimeline(snapshot.id)).toContainEqual({
type: "assistant_message",
text: "AUTONOMOUS_DURING_FOREGROUND",
});
expect(runningStateEvents).toHaveLength(2);
});
test("restarts live event pump after iterator failure", async () => {
@@ -1322,210 +1322,4 @@ describe("ClaudeAgentSession redesign invariants", () => {
await session.close();
});
test("surfaces autonomous running transitions during true overlap before foreground terminal result", async () => {
sdkMocks.query.mockImplementation(({ prompt }: { prompt: AsyncIterable<unknown> }) => {
const readPromptUuid = createPromptUuidReader(prompt);
let step = 0;
return createBaseQueryMock(
vi.fn(async () => {
if (step === 0) {
step += 1;
return {
done: false,
value: {
type: "system",
subtype: "init",
session_id: "redesign-manager-overlap-session",
permissionMode: "default",
model: "opus",
},
};
}
if (step === 1) {
step += 1;
return {
done: false,
value: {
type: "user",
message: { role: "user", content: "foreground prompt replay" },
parent_tool_use_id: null,
uuid: (await readPromptUuid()) ?? "missing-prompt-uuid",
session_id: "redesign-manager-overlap-session",
},
};
}
if (step === 2) {
step += 1;
return {
done: false,
value: {
type: "assistant",
task_id: "fg-1",
message: { content: "FOREGROUND_BEFORE_OVERLAP" },
},
};
}
if (step === 3) {
step += 1;
return {
done: false,
value: {
type: "stream_event",
task_id: "bg-1",
event: {
type: "message_start",
message: { id: "bg-msg-1", role: "assistant", model: "opus" },
},
},
};
}
if (step === 4) {
step += 1;
return {
done: false,
value: {
type: "stream_event",
task_id: "bg-1",
event: {
type: "content_block_delta",
message_id: "bg-msg-1",
delta: { type: "text_delta", text: "AUTONOMOUS_OVERLAP_DONE" },
},
},
};
}
if (step === 5) {
step += 1;
return {
done: false,
value: {
type: "stream_event",
task_id: "bg-1",
event: {
type: "message_stop",
message_id: "bg-msg-1",
},
},
};
}
if (step === 6) {
step += 1;
return {
done: false,
value: {
type: "result",
subtype: "success",
task_id: "bg-1",
usage: buildUsage(),
total_cost_usd: 0,
},
};
}
if (step === 7) {
step += 1;
return {
done: false,
value: {
type: "assistant",
message: { content: "FOREGROUND_DONE" },
},
};
}
if (step === 8) {
step += 1;
return {
done: false,
value: {
type: "result",
subtype: "success",
usage: buildUsage(),
total_cost_usd: 0,
},
};
}
return { done: true, value: undefined };
})
);
});
const logger = createTestLogger();
const claudeClient = new ClaudeAgentClient({ logger });
vi.spyOn(claudeClient, "isAvailable").mockResolvedValue(true);
const manager = new AgentManager({
clients: {
claude: claudeClient,
},
logger,
});
const agent = await manager.createAgent({
provider: "claude",
cwd: process.cwd(),
});
const runningStateEvents: string[] = [];
const turnStartedEvents: AgentStreamEvent[] = [];
const unsubscribe = manager.subscribe(
(event) => {
if (event.type === "agent_state" && event.agent.id === agent.id) {
if (event.agent.lifecycle === "running") {
runningStateEvents.push(event.agent.lifecycle);
}
return;
}
if (
event.type === "agent_stream" &&
event.agentId === agent.id &&
event.event.type === "turn_started"
) {
turnStartedEvents.push(event.event);
}
},
{ agentId: agent.id, replayState: true }
);
const foregroundEvents = await collectUntilTerminal(
manager.streamAgent(agent.id, "foreground prompt")
);
expect(
foregroundEvents.some((event) => event.type === "turn_completed")
).toBe(true);
expect(
foregroundEvents.some(
(event) =>
event.type === "timeline" &&
event.item.type === "assistant_message" &&
event.item.text.includes("AUTONOMOUS_OVERLAP_DONE")
)
).toBe(false);
await waitForCondition(() => turnStartedEvents.length >= 1, 5_000);
await waitForCondition(() => runningStateEvents.length >= 2, 5_000);
const timeline = manager.getTimeline(agent.id);
expect(
timeline.some(
(item) =>
item.type === "assistant_message" &&
item.text.includes("FOREGROUND_BEFORE_OVERLAP")
)
).toBe(true);
expect(
timeline.some(
(item) =>
item.type === "assistant_message" &&
item.text.includes("FOREGROUND_DONE")
)
).toBe(true);
expect(
timeline.some(
(item) =>
item.type === "assistant_message" &&
item.text.includes("AUTONOMOUS_OVERLAP_DONE")
)
).toBe(true);
unsubscribe();
await manager.closeAgent(agent.id);
});
});