52 lines
2.2 KiB
TypeScript
52 lines
2.2 KiB
TypeScript
import { demoScenes } from "./scenes.ts";
|
|
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
import { z } from "zod";
|
|
|
|
const resultSchema = z.object({
|
|
name: z.literal("generation:result"),
|
|
value: z.object({ model: z.string(), images: z.array(z.object({ url: z.string() })).min(1) }),
|
|
});
|
|
function imageResult(body: string) {
|
|
for (const line of body.split("\n")) {
|
|
if (!line.startsWith("data: ")) continue;
|
|
const result = resultSchema.safeParse(JSON.parse(line.slice(6)));
|
|
if (result.success) return result.data.value;
|
|
}
|
|
return null;
|
|
}
|
|
for (const { id, prompt: scene } of demoScenes) {
|
|
const dir = `reports/image-reveal-demo/${id}`;
|
|
await mkdir(dir, { recursive: true });
|
|
let result = imageResult(await readFile(`${dir}/image.sse`, "utf8").catch(() => ""));
|
|
if (process.env["REGENERATE"]?.split(",").includes(id)) result = null;
|
|
if (!result) {
|
|
const data = {
|
|
messageId: `product-demo-${id}`,
|
|
gatewayId: "nanogpt",
|
|
prompt: `${scene}. Atmospheric concept art, vaporous and dreamy, painterly illustration, soft bloom. Empty landscape and inanimate objects only.`,
|
|
negativePrompt: "photographs, people, typography, watermark",
|
|
};
|
|
await writeFile(
|
|
`${dir}/image-request.json`,
|
|
JSON.stringify({ model: "rev-animated", steps: 3, cfgScale: 1, ...data }, null, 2),
|
|
);
|
|
for (let attempt = 0; attempt < 3 && !result; attempt++) {
|
|
const response = await fetch("http://127.0.0.1:3000/api/ai/image", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({ data, forwardedProps: data }),
|
|
signal: AbortSignal.timeout(120000),
|
|
});
|
|
const body = await response.text();
|
|
await writeFile(`${dir}/image.sse`, body);
|
|
result = imageResult(body);
|
|
console.log(
|
|
`${id}: attempt ${attempt + 1}, ${result ? "Rev Animated image received" : `provider response ${response.status}, no image`}`,
|
|
);
|
|
if (!result) await new Promise((resolve) => setTimeout(resolve, 2500));
|
|
}
|
|
}
|
|
if (!result) throw new Error(`No image generated for ${id}`);
|
|
await writeFile(`${dir}/provider-image.json`, JSON.stringify(result));
|
|
console.log(`${id}: image ready`);
|
|
}
|