diff --git a/tests/runner-e2e/chat-flow.ts b/tests/runner-e2e/chat-flow.ts index 0fda3d862cc..a2d06e00a82 100644 --- a/tests/runner-e2e/chat-flow.ts +++ b/tests/runner-e2e/chat-flow.ts @@ -307,6 +307,7 @@ export async function runChatFlow(input: ChatFlowInput) { const draftMarker = chatMarker("DRAFT", nonce); const caseId = execution.task.id; const stopCase = ["stop-new-resume", "stop-startup-new-resume"].includes(caseId); + const interruptionCase = ["followup-while-running", "revise-while-running"].includes(caseId); let issue: ChatIssue; let runs: ChatRun[] = []; const settings = await api.get>( @@ -384,7 +385,7 @@ export async function runChatFlow(input: ChatFlowInput) { if (caseId === "enable-disable-resume") { await runChatSettingsLifecycle({ input, marker, issue: () => issue!, idle, allRuns, comments }); - } else if (["followup-while-running", "revise-while-running"].includes(caseId)) { + } else if (interruptionCase) { await runChatInterruption({ input, marker, issue: () => issue!, idle, allRuns, comments, refreshIssue: async () => { issue = await api.get(chatPath); input.observe(issue, await allRuns()); } }); } else if ( @@ -918,10 +919,12 @@ export async function runChatFlow(input: ChatFlowInput) { projects, }); } - await idle(execution.task.expectedRunCount); - expect(runs.filter((run) => !isResetRun(run))).toHaveLength( - execution.task.expectedRunCount, - ); + await idle(interruptionCase ? 1 : execution.task.expectedRunCount); + // The interruption oracle already proves delivery and bounds one steered + // run or two sequential runs. Other stories keep their exact run counts. + if (!interruptionCase) expect(runs.filter((run) => !isResetRun(run))).toHaveLength( + execution.task.expectedRunCount, + ); for (const run of runs.filter((run) => !isResetRun(run))) { expect(run.runtimeMode).toBe(execution.profile.expectedRuntimeMode); expect(run.status).toBe( diff --git a/tests/runner-e2e/chat-stories.ts b/tests/runner-e2e/chat-stories.ts index ec652a94d8f..ccfa30ce105 100644 --- a/tests/runner-e2e/chat-stories.ts +++ b/tests/runner-e2e/chat-stories.ts @@ -95,6 +95,14 @@ export async function runChatInterruption(context: Context & { refreshIssue(): P } finally { // Always release a provider that is still waiting, including failed UI runs. await writeFile(gate, reference, "utf8"); + const chatPath = `/api/companies/${input.fixtures.company.id}/chats/${input.fixtures.agent.id}`; + const current = await input.api.get(chatPath).catch(() => null); + await input.evidence("chat-interruption-state.json", { + issue: current, + runs: await allRuns().catch(error => ({ readError: String(error) })), + comments: current ? await input.api.get(`/api/issues/${current.id}/comments?order=asc`).catch(error => ({ readError: String(error) })) : [], + plan: current && revise ? await input.api.get(`/api/issues/${current.id}/documents/plan`).catch(error => ({ readError: String(error) })) : null, + }); } }