import assert from "node:assert/strict"; import test from "node:test"; import { mkdtemp, rm, writeFile } from "node:fs/promises"; import { join } from "node:path"; import { tmpdir } from "node:os"; import { observeGeneratedReferences, observeOriginalVisual, ORIGINAL_OBSERVER_INSTRUCTION } from "./reference-first-visual-observer.mjs"; const product = { category: "鞋", form: "自然直立", colors: ["黑色"], material_and_light_cues: ["哑光鞋面"], identity_cues: ["白色鞋底", "黑色鞋带"], natural_support_and_use: ["地面穿着"] }; test("original observer makes one descriptive Qwen call and reuses by source hash", async () => { const directory = await mkdtemp(join(tmpdir(), "fmode-observer-")); try { const source = join(directory, "source.png"); const output = join(directory, "observation.json"); await writeFile(source, "image"); let calls = 0; const options = { runId: "run-20260804210000-aabbcc", source, outputFile: output, config: { provider: "qwen", model: "qwen3-vl-plus", apiKey: "x" }, uploadImage: async () => ({ public_url: "https://image.test/source.png" }), requestJson: async ({ instruction }) => { calls += 1; assert.match(instruction, /不是创意策划器/); return { value: { product }, usage: { total_tokens: 10 } }; } }; assert.equal((await observeOriginalVisual(options)).model_calls, 1); assert.equal((await observeOriginalVisual(options)).model_calls, 0); assert.equal(calls, 1); assert.match(ORIGINAL_OBSERVER_INSTRUCTION, /禁止选择页面模板/); } finally { await rm(directory, { recursive: true, force: true }); } }); test("reference observer observes both assets in one model call", async () => { let calls = 0; const result = await observeGeneratedReferences({ runId: "run-20260804210000-aabbcc", sources: ["https://image.test/three.png", "https://image.test/board.png"], config: { provider: "qwen", model: "qwen3-vl-plus", apiKey: "x" }, requestJson: async ({ imageUrls }) => { calls += 1; assert.equal(imageUrls.length, 2); return { value: { assets: [{ product }, { product, actual_composition_and_scenes: ["四场景"] }] } }; } }); assert.equal(result.model_calls, 1); assert.equal(calls, 1); assert.equal(result.observation.assets[1].asset_role, "setting_board_visual"); });