



























@@ -206,6 +206,21 @@ describe("qa mock openai server", () => {
206206expect(quietBody).toContain('"phase":"final_answer"');
207207expect(quietBody).toContain("QA_STREAMING_OK");
208208209+const partialResponse = await fetch(`${server.baseUrl}/v1/responses`, {
210+method: "POST",
211+headers: {
212+"content-type": "application/json",
213+},
214+body: JSON.stringify({
215+stream: true,
216+input: [makeUserInput("Partial streaming QA check: reply exactly `QA_PARTIAL_OK`.")],
217+}),
218+});
219+expect(partialResponse.status).toBe(200);
220+const partialBody = await partialResponse.text();
221+expect(partialBody).toContain('"type":"response.output_text.delta"');
222+expect(partialBody).toContain("QA_PARTIAL_OK");
223+209224const blockResponse = await fetch(`${server.baseUrl}/v1/responses`, {
210225method: "POST",
211226headers: {
@@ -228,6 +243,113 @@ describe("qa mock openai server", () => {
228243expect(blockBody).toContain("BLOCK_TWO_OK");
229244});
230245246+it("plans deterministic tool-progress reads from prompt paths", async () => {
247+const server = await startMockServer();
248+249+const response = await fetch(`${server.baseUrl}/v1/responses`, {
250+method: "POST",
251+headers: {
252+"content-type": "application/json",
253+},
254+body: JSON.stringify({
255+stream: true,
256+input: [
257+makeUserInput(
258+"Tool progress QA check: read `qa-progress-target.txt` before answering. After the read completes, reply exactly `TOOL_PROGRESS_OK`.",
259+),
260+],
261+}),
262+});
263+264+expect(response.status).toBe(200);
265+const body = await response.text();
266+expect(body).toContain('"name":"read"');
267+expect(body).toContain("qa-progress-target.txt");
268+});
269+270+it("requires deterministic tool-progress error prompts to observe a failed tool", async () => {
271+const server = await startMockServer();
272+const prompt =
273+"Tool progress error QA check: read `missing-tool-progress-target.txt` before answering. After the read fails, reply exactly `TOOL_PROGRESS_ERROR_OK`.";
274+275+const toolPlan = await fetch(`${server.baseUrl}/v1/responses`, {
276+method: "POST",
277+headers: {
278+"content-type": "application/json",
279+},
280+body: JSON.stringify({
281+stream: true,
282+input: [makeUserInput(prompt)],
283+}),
284+});
285+286+expect(toolPlan.status).toBe(200);
287+const toolPlanBody = await toolPlan.text();
288+expect(toolPlanBody).toContain('"name":"read"');
289+expect(toolPlanBody).toContain("missing-tool-progress-target.txt");
290+291+const successOutput = await expectResponsesJson<{
292+output: Array<{ content?: Array<{ text?: string }> }>;
293+}>(server, {
294+stream: false,
295+input: [
296+makeUserInput(prompt),
297+{
298+type: "function_call_output",
299+call_id: "call_mock_read_1",
300+output: JSON.stringify({ text: "unexpected success" }),
301+},
302+],
303+});
304+expect(successOutput.output[0]?.content?.[0]?.text).toBe("BUG-TOOL-DID-NOT-FAIL");
305+306+const errorOutput = await expectResponsesJson<{
307+output: Array<{ content?: Array<{ text?: string }> }>;
308+}>(server, {
309+stream: false,
310+input: [
311+makeUserInput(prompt),
312+{
313+type: "function_call_output",
314+call_id: "call_mock_read_1",
315+output: JSON.stringify({ error: "ENOENT: no such file or directory" }),
316+},
317+],
318+});
319+expect(errorOutput.output[0]?.content?.[0]?.text).toBe("TOOL_PROGRESS_ERROR_OK");
320+});
321+322+it("uses the latest user prompt path for tool-progress plans", async () => {
323+const server = await startMockServer();
324+325+const response = await fetch(`${server.baseUrl}/v1/responses`, {
326+method: "POST",
327+headers: {
328+"content-type": "application/json",
329+},
330+body: JSON.stringify({
331+stream: true,
332+input: [
333+makeUserInput(
334+"Tool progress QA check: read `older-progress-target.txt` before answering. After the read completes, reply exactly `OLD_PROGRESS_OK`.",
335+),
336+makeUserInput(
337+"Tool progress error QA check: read `latest-missing-progress-target.txt` before answering. After the read fails, reply exactly `LATEST_PROGRESS_OK`.",
338+),
339+makeUserInput(
340+"Continue with the QA scenario plan and report worked, failed, and blocked items.",
341+),
342+],
343+}),
344+});
345+346+expect(response.status).toBe(200);
347+const body = await response.text();
348+expect(body).toContain('"name":"read"');
349+expect(body).toContain("latest-missing-progress-target.txt");
350+expect(body).not.toContain("older-progress-target.txt");
351+});
352+231353it("prefers path-like refs over generic quoted keys in prompts", async () => {
232354const server = await startQaMockOpenAiServer({
233355host: "127.0.0.1",
@@ -1674,7 +1796,7 @@ describe("qa mock openai server", () => {
16741796content: [
16751797{
16761798type: "input_text",
1677-text: "@qa-sut:matrix-qa.test reply with only this exact marker: MATRIX_QA_CANARY_TEST",
1799+text: "@qa-sut.example.test reply with only this exact marker: QA_CANARY_TEST",
16781800},
16791801],
16801802},
@@ -1695,7 +1817,7 @@ describe("qa mock openai server", () => {
16951817expect(await response.json()).toMatchObject({
16961818output: [
16971819{
1698-content: [{ text: "MATRIX_QA_CANARY_TEST" }],
1820+content: [{ text: "QA_CANARY_TEST" }],
16991821},
17001822],
17011823});
@@ -1710,8 +1832,8 @@ describe("qa mock openai server", () => {
17101832await server.stop();
17111833});
171218341713-const matrixPrompt =
1714-"@qa-sut:matrix-qa.test Image generation check: generate a QA lighthouse image and summarize it in one short sentence.";
1835+const channelPrompt =
1836+"@qa-sut.example.test Image generation check: generate a QA lighthouse image and summarize it in one short sentence.";
17151837const genericPrompt =
17161838"Continue with the QA scenario plan and report worked, failed, and blocked items.";
17171839@@ -1722,7 +1844,7 @@ describe("qa mock openai server", () => {
17221844},
17231845body: JSON.stringify({
17241846stream: false,
1725-input: [makeUserInput(matrixPrompt), makeUserInput(genericPrompt)],
1847+input: [makeUserInput(channelPrompt), makeUserInput(genericPrompt)],
17261848}),
17271849});
17281850@@ -1745,7 +1867,7 @@ describe("qa mock openai server", () => {
17451867body: JSON.stringify({
17461868stream: false,
17471869input: [
1748-makeUserInput(matrixPrompt),
1870+makeUserInput(channelPrompt),
17491871makeUserInput(genericPrompt),
17501872{
17511873type: "function_call",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。