From ce3d1d22bed1c918cf702248dfc489cc475a824b Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Thu, 13 Aug 2026 10:41:42 +0800 Subject: [PATCH] fix(qa): preserve Code Mode reads in model-switch mock (#122935) --- .../mock-openai/mock-openai-events.ts | 11 +---- .../src/providers/mock-openai/server.test.ts | 43 +++++++++++++++++++ .../src/providers/mock-openai/server.ts | 3 +- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/extensions/qa-lab/src/providers/mock-openai/mock-openai-events.ts b/extensions/qa-lab/src/providers/mock-openai/mock-openai-events.ts index e8d7c86441dc..9a344b5463ce 100644 --- a/extensions/qa-lab/src/providers/mock-openai/mock-openai-events.ts +++ b/extensions/qa-lab/src/providers/mock-openai/mock-openai-events.ts @@ -1,11 +1,7 @@ // QA Lab mock provider output event builders. import type { StreamEvent } from "./mock-openai-contracts.js"; -import { - readTargetFromPrompt, - buildMockFunctionCall, - buildToolCallEventsWithArgs, -} from "./mock-openai-tooling.js"; +import { buildMockFunctionCall } from "./mock-openai-tooling.js"; export function buildFailedResponseEvents(): StreamEvent[] { const responseId = `resp_qa_failed_${Date.now()}`; @@ -55,11 +51,6 @@ export function buildPartialFailureEvents(partialText: string): StreamEvent[] { ]; } -export function buildToolCallEvents(prompt: string): StreamEvent[] { - const targetPath = readTargetFromPrompt(prompt); - return buildToolCallEventsWithArgs("read", { path: targetPath }); -} - export function buildReleaseAuditJson() { return `${JSON.stringify( { diff --git a/extensions/qa-lab/src/providers/mock-openai/server.test.ts b/extensions/qa-lab/src/providers/mock-openai/server.test.ts index 52885416a27a..0a2348afdba3 100644 --- a/extensions/qa-lab/src/providers/mock-openai/server.test.ts +++ b/extensions/qa-lab/src/providers/mock-openai/server.test.ts @@ -6396,6 +6396,49 @@ Update and merge these partial structured summaries.`, expect(await response.text()).toContain('"name":"read"'); }); + it("routes the initial model-switch read through Anthropic guest Code Mode", async () => { + const server = await startMockServer(); + const body = (await expectAnthropicMessagesJson(server, { + tools: [ + { + name: "exec", + input_schema: { + type: "object", + properties: { code: { type: "string" } }, + required: ["code"], + }, + }, + { + name: "wait", + input_schema: { + type: "object", + properties: { runId: { type: "string" } }, + required: ["runId"], + }, + }, + ], + messages: [ + makeAnthropicUserText( + "Read repo/qa/scenarios/index.yaml and summarize the QA scenario pack mission in one clause before any model switch.", + ), + ], + })) as { + stop_reason: string; + content: Array>; + }; + + expect(body.stop_reason).toBe("tool_use"); + expect(body.content.find((block) => block.type === "tool_use")?.name).toBe("exec"); + + const debug = requireRecord( + await getJson(server, "/debug/last-request"), + "model switch Code Mode debug request", + ); + expect(debug.plannedToolName).toBe("read"); + expect(debug.plannedWireToolName).toBe("exec"); + expect(debug.plannedToolArgs).toEqual({ path: "repo/qa/scenarios/index.yaml" }); + }); + it("returns continuity language after the model-switch reread completes", async () => { const server = await startMockServer(); diff --git a/extensions/qa-lab/src/providers/mock-openai/server.ts b/extensions/qa-lab/src/providers/mock-openai/server.ts index 8feac7a08144..e15d924e83a9 100644 --- a/extensions/qa-lab/src/providers/mock-openai/server.ts +++ b/extensions/qa-lab/src/providers/mock-openai/server.ts @@ -134,7 +134,6 @@ import { isHeartbeatPrompt, } from "./mock-openai-directives.js"; import { - buildToolCallEvents, buildReleaseAuditJson, buildReleaseHandoffMarkdown, extractPlannedToolName, @@ -2363,7 +2362,7 @@ async function buildResponsesPayload( }); } if (!hasCompletedToolOutput && /\b(read|inspect|repo|docs|scenario|kickoff)\b/i.test(prompt)) { - return buildToolCallEvents(prompt); + return buildToolCallEventsWithArgs("read", { path: readTargetFromPrompt(prompt) }); } if (/visible skill marker/i.test(prompt) && !hasCompletedToolOutput) { return buildAssistantEvents("VISIBLE-SKILL-OK");