import { describe, expect, it } from "vitest"; import { GeminiFlashAdapter } from "../../apps/worker/src/ai-adapter-gemini-flash.js"; import { GeminiProAdapter } from "../../apps/worker/src/ai-adapter-gemini-pro.js"; import { GptImageAdapter } from "../../apps/worker/src/ai-adapter-gpt-image.js"; import { gptImageRequestSizeForRatio, normalizeImageOutputToRatio, productDimensionsForRatio, } from "../../apps/worker/src/image-output-normalizer.mjs"; const onePixelPng = Buffer.from( "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=", "base64", ); describe("TDD-WP7-EXT-001 exact image output normalization", () => { it("uses only GPT Image 2 request sizes allowed by the upstream API", () => { expect(["3:4", "1:1", "4:3", "9:16"].map((ratio) => gptImageRequestSizeForRatio(ratio))).toEqual([ "1056x1408", "1088x1088", "1408x1056", "1008x1792", ]); for (const ratio of ["3:4", "1:1", "4:3", "9:16"] as const) { const [width, height] = gptImageRequestSizeForRatio(ratio).split("x").map(Number); expect(width % 16).toBe(0); expect(height % 16).toBe(0); } }); it("normalizes provider output to the frozen product dimensions", async () => { const output = await normalizeImageOutputToRatio({ bytes: onePixelPng, mimeType: "image/png", ratio: "1:1" }); expect(output).toMatchObject({ mimeType: "image/png", normalized: true, pixelHeight: 1080, pixelWidth: 1080, upstreamPixelHeight: 1, upstreamPixelWidth: 1, }); expect(output.bytes.subarray(0, 8).toString("hex")).toBe("89504e470d0a1a0a"); expect(productDimensionsForRatio("9:16")).toEqual({ pixelHeight: 1920, pixelWidth: 1080 }); }); it("is used by all three production adapter boundaries", async () => { const encoded = onePixelPng.toString("base64"); const adapters = [ new GeminiFlashAdapter({ transport: { async start() { return { candidates: [{ inline_data: { data: encoded, mime_type: "image/png" }, pixelHeight: 1, pixelWidth: 1 }] }; }, async poll() { return {}; }, } }), new GeminiProAdapter({ transport: { async start() { return { operation: { done: true, response: { candidates: [{ inline_data: { data: encoded, mime_type: "image/png" }, pixelHeight: 1, pixelWidth: 1 }] } } }; }, async poll() { return {}; }, } }), new GptImageAdapter({ transport: { async start() { return { data: [{ b64_json: encoded, pixelHeight: 1, pixelWidth: 1 }] }; }, async poll() { return {}; }, } }), ]; for (const adapter of adapters) { const result = await adapter.start({ configSnapshot: {}, generationId: `normalization-${adapter.modelId}`, modelId: adapter.modelId, prompt: "sanitized fixture", ratio: "1:1", referenceAssetIds: [], }); expect(result).toMatchObject({ status: "completed", outputs: [{ mimeType: "image/png", pixelHeight: 1080, pixelWidth: 1080 }] }); } }); });