(options: IterateOptions)
| 21 | * Iterate on an existing design using session state. |
| 22 | */ |
| 23 | export async function iterate(options: IterateOptions): Promise<void> { |
| 24 | const apiKey = requireApiKey(); |
| 25 | const session = readSession(options.session); |
| 26 | |
| 27 | console.error(`Iterating on session ${session.id}...`); |
| 28 | console.error(` Previous iterations: ${session.feedbackHistory.length}`); |
| 29 | console.error(` Feedback: "${options.feedback}"`); |
| 30 | |
| 31 | const startTime = Date.now(); |
| 32 | |
| 33 | // Try multi-turn with previous_response_id first |
| 34 | let success = false; |
| 35 | let responseId = ""; |
| 36 | |
| 37 | try { |
| 38 | const result = await callWithThreading(apiKey, session.lastResponseId, options.feedback); |
| 39 | responseId = result.responseId; |
| 40 | |
| 41 | fs.mkdirSync(path.dirname(options.output), { recursive: true }); |
| 42 | fs.writeFileSync(options.output, Buffer.from(result.imageData, "base64")); |
| 43 | success = true; |
| 44 | } catch (err: any) { |
| 45 | console.error(` Threading failed: ${err.message}`); |
| 46 | console.error(" Falling back to re-generation with accumulated feedback..."); |
| 47 | |
| 48 | // Fallback: re-generate with original brief + all feedback |
| 49 | const accumulatedPrompt = buildAccumulatedPrompt( |
| 50 | session.originalBrief, |
| 51 | [...session.feedbackHistory, options.feedback] |
| 52 | ); |
| 53 | |
| 54 | const result = await callFresh(apiKey, accumulatedPrompt); |
| 55 | responseId = result.responseId; |
| 56 | |
| 57 | fs.mkdirSync(path.dirname(options.output), { recursive: true }); |
| 58 | fs.writeFileSync(options.output, Buffer.from(result.imageData, "base64")); |
| 59 | success = true; |
| 60 | } |
| 61 | |
| 62 | if (success) { |
| 63 | const elapsed = ((Date.now() - startTime) / 1000).toFixed(1); |
| 64 | const size = fs.statSync(options.output).size; |
| 65 | console.error(`Generated (${elapsed}s, ${(size / 1024).toFixed(0)}KB) → ${options.output}`); |
| 66 | |
| 67 | // Update session |
| 68 | updateSession(session, responseId, options.feedback, options.output); |
| 69 | |
| 70 | console.log(JSON.stringify({ |
| 71 | outputPath: options.output, |
| 72 | sessionFile: options.session, |
| 73 | responseId, |
| 74 | iteration: session.feedbackHistory.length + 1, |
| 75 | }, null, 2)); |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | async function callWithThreading( |
| 80 | apiKey: string, |
no test coverage detected