From af77477a2ad0f5c8d1df0e3cedbea227d5fa05b6 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Sun, 2 Aug 2026 17:24:35 +0800 Subject: [PATCH] fix(qa): generated-image evidence waits despite successful delivery (#117799) * fix(qa): observe generated images from outbound media * fix(qa): preserve generated image producer evidence --- .../src/suite-runtime-agent-media.test.ts | 6 +-- .../qa-lab/src/suite-runtime-agent-media.ts | 43 +++++++++++-------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/extensions/qa-lab/src/suite-runtime-agent-media.test.ts b/extensions/qa-lab/src/suite-runtime-agent-media.test.ts index 9de2c05ed87c..4b67f27c9b50 100644 --- a/extensions/qa-lab/src/suite-runtime-agent-media.test.ts +++ b/extensions/qa-lab/src/suite-runtime-agent-media.test.ts @@ -105,7 +105,7 @@ describe("qa suite runtime agent media helpers", () => { "ignores %s generated media paths returned by matching mock requests", async (artifactState) => { const tempRoot = await makeTempDir("qa-generated-image-invalid-request-"); - const mediaDir = path.join(tempRoot, "state", "media", "tool-image-generation"); + const mediaDir = path.join(tempRoot, "state", "media", "outbound"); await fs.mkdir(mediaDir, { recursive: true }); const freshMediaPath = path.join(mediaDir, "fresh-generated.png"); await fs.writeFile(freshMediaPath, "fresh png", "utf8"); @@ -140,9 +140,9 @@ describe("qa suite runtime agent media helpers", () => { }, ); - it("falls back to generated image files under the gateway temp root", async () => { + it("falls back to generated image files in the canonical outbound media store", async () => { const tempRoot = await makeTempDir("qa-generated-image-"); - const mediaDir = path.join(tempRoot, "state", "media", "tool-image-generation"); + const mediaDir = path.join(tempRoot, "state", "media", "outbound"); await fs.mkdir(mediaDir, { recursive: true }); const mediaPath = path.join(mediaDir, "generated.png"); await fs.writeFile(mediaPath, "png", "utf8"); diff --git a/extensions/qa-lab/src/suite-runtime-agent-media.ts b/extensions/qa-lab/src/suite-runtime-agent-media.ts index 437992348d4f..038a8943c981 100644 --- a/extensions/qa-lab/src/suite-runtime-agent-media.ts +++ b/extensions/qa-lab/src/suite-runtime-agent-media.ts @@ -112,26 +112,31 @@ async function resolveGeneratedImagePath(params: { } } - const mediaDir = path.join( - params.env.gateway.tempRoot, - "state", - "media", - "tool-image-generation", - ); - const entries = await fs.readdir(mediaDir).catch(() => []); - const candidates = await Promise.all( - entries.map(async (entry) => { - const fullPath = path.join(mediaDir, entry); - const stat = await fs.stat(fullPath).catch(() => null); - if (!stat?.isFile() || stat.size === 0) { - return null; - } - return { - fullPath, - mtimeMs: stat.mtimeMs, - }; - }), + // Generated media may deliver directly from tool storage or be staged outbound; + // either fresh owner artifact proves this run without depending on one delivery path. + const mediaDirs = ["outbound", "tool-image-generation"].map((subdir) => + path.join(params.env.gateway.tempRoot, "state", "media", subdir), ); + const candidates = ( + await Promise.all( + mediaDirs.map(async (mediaDir) => { + const entries = await fs.readdir(mediaDir).catch(() => []); + return Promise.all( + entries.map(async (entry) => { + const fullPath = path.join(mediaDir, entry); + const stat = await fs.stat(fullPath).catch(() => null); + if (!stat?.isFile() || stat.size === 0) { + return null; + } + return { + fullPath, + mtimeMs: stat.mtimeMs, + }; + }), + ); + }), + ) + ).flat(); const match = candidates .filter((entry): entry is NonNullable => Boolean(entry)) .filter((entry) => entry.mtimeMs >= params.startedAtMs - 1_000)