import type { CanvasGenerateImageResult } from "./generate-image"; import { layoutReplaceQualityFailure, type LayoutReplaceQuality } from "./layout-replace-quality"; // A semantic rejection may generate one corrected candidate. Network/unknown // generation failures and unavailable verification never replay a paid request. export async function runValidatedLayoutReplacement(params: { generate: (attempt: number, feedback: string) => Promise; normalize: (result: CanvasGenerateImageResult) => Promise; verify: (result: CanvasGenerateImageResult) => Promise; persist: (result: CanvasGenerateImageResult) => Promise; }) { let feedback = ""; for (let attempt = 0; attempt < 2; attempt++) { const generated = await params.generate(attempt, feedback); if (!generated.images[0]?.originalUrl) throw new Error("排版替换未返回结果图片"); const normalized = await params.normalize(generated); const check = await params.verify(normalized); if (check.passed) { const result = { ...normalized, validation: { kind: "layout-replace", status: "passed", attempts: attempt + 1, confidence: check.confidence, } }; await params.persist(result); return result; } feedback = layoutReplaceQualityFailure(check); console.warn("[Canvas Layout Replace] candidate rejected", { attempt: attempt + 1, reasons: feedback }); } throw new Error(`替换结果未通过质量检查,未作为合格结果返回:${feedback}`); }