storytellurx/scripts/product-demo/generate-images.ts

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`);
}