(options: EvolveOptions)
| 21 | * asking it to produce a new version incorporating the brief's changes. |
| 22 | */ |
| 23 | export async function evolve(options: EvolveOptions): Promise<void> { |
| 24 | const apiKey = requireApiKey(); |
| 25 | const screenshotData = fs.readFileSync(options.screenshot).toString("base64"); |
| 26 | |
| 27 | console.error(`Evolving ${options.screenshot} with: "${options.brief}"`); |
| 28 | const startTime = Date.now(); |
| 29 | |
| 30 | // Use the Responses API with both a text prompt referencing the screenshot |
| 31 | // and the image_generation tool to produce the evolved version. |
| 32 | // Since we can't send reference images directly to image_generation, |
| 33 | // we describe the current state in detail first via vision, then generate. |
| 34 | |
| 35 | // Step 1: Analyze current screenshot |
| 36 | const analysis = await analyzeScreenshot(apiKey, screenshotData); |
| 37 | console.error(` Analyzed current design: ${analysis.slice(0, 100)}...`); |
| 38 | |
| 39 | // Step 2: Generate evolved version using analysis + brief |
| 40 | const evolvedPrompt = [ |
| 41 | "Generate a pixel-perfect UI mockup that is an improved version of an existing design.", |
| 42 | "", |
| 43 | "CURRENT DESIGN (what exists now):", |
| 44 | analysis, |
| 45 | "", |
| 46 | "REQUESTED CHANGES:", |
| 47 | options.brief, |
| 48 | "", |
| 49 | "Generate a new mockup that keeps the existing layout structure but applies the requested changes.", |
| 50 | "The result should look like a real production UI. All text must be readable.", |
| 51 | "1536x1024 pixels.", |
| 52 | ].join("\n"); |
| 53 | |
| 54 | const controller = new AbortController(); |
| 55 | const timeout = setTimeout(() => controller.abort(), 240_000); |
| 56 | |
| 57 | try { |
| 58 | const response = await fetch("https://api.openai.com/v1/responses", { |
| 59 | method: "POST", |
| 60 | headers: { |
| 61 | "Authorization": `Bearer ${apiKey}`, |
| 62 | "Content-Type": "application/json", |
| 63 | }, |
| 64 | body: JSON.stringify({ |
| 65 | model: "gpt-4o", |
| 66 | input: evolvedPrompt, |
| 67 | tools: [{ type: "image_generation", model: "gpt-image-2", size: "1536x1024", quality: "high" }], |
| 68 | }), |
| 69 | signal: controller.signal, |
| 70 | }); |
| 71 | |
| 72 | if (!response.ok) { |
| 73 | const error = await response.text(); |
| 74 | if (response.status === 403 && error.includes("organization must be verified")) { |
| 75 | throw new Error( |
| 76 | "OpenAI organization verification required.\n" |
| 77 | + "Go to https://platform.openai.com/settings/organization to verify.\n" |
| 78 | + "After verification, wait up to 15 minutes for access to propagate.", |
| 79 | ); |
| 80 | } |
no test coverage detected