Skip to content

Commit 6236f37

Browse files
author
Miriad
committed
feat: add topic-level API with config-driven instructions and deterministic seeds
- generateInfographicsForTopic() reads instructions from contentConfig - Deterministic seeds from topic+index for brand consistency - DEFAULT_INSTRUCTIONS with blueprint-style prompts from spec - Appends topic context to each instruction prompt
1 parent e50201f commit 6236f37

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

‎lib/services/gemini-infographics.ts‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,86 @@ export function buildInfographicPrompt(
198198
`No watermarks. High information density. Developer audience.`
199199
);
200200
}
201+
202+
// ---------------------------------------------------------------------------
203+
// Default instructions (blueprint style from spec)
204+
// ---------------------------------------------------------------------------
205+
206+
/** Default infographic instructions if Sanity contentConfig is not set up */
207+
const DEFAULT_INSTRUCTIONS: string[] = [
208+
'Create a technical architecture sketch using white "hand-drawn" ink lines on a deep navy blue background (#003366). Use rough-sketched server and database icons with visible "marker" strokes, handwritten labels in a casual font, and a subtle grid pattern. Style: blueprint meets whiteboard doodle.',
209+
'Create a comparison chart on a vibrant blue background (#004080) with hand-inked white headers and uneven, sketchy borders. Use white cross-hatching and doodle-style checkmarks to highlight feature differences. Include hand-drawn arrows and annotations. Style: technical chalkboard.',
210+
'Create a step-by-step workflow "blueprint" on a dark blue canvas (#003366). Use hand-drawn white arrows connecting rough-sketched boxes, simple "stick-figure" style worker avatars, and handwritten-style labels with a slight chalk texture. Add a subtle grid background. Style: engineering whiteboard.',
211+
'Create a hand-sketched timeline using a jagged white line on a royal blue background. Represent milestones with simple, iconic white doodles that look like they were quickly sketched during a brainstorming session. Use handwritten dates and labels. Style: notebook sketch on blue paper.',
212+
'Create a pros and cons summary with a "lo-fi" aesthetic. Use hand-drawn white thumbs-up/down icons and rough-sketched containers on a deep blue background (#003366). Add hand-drawn underlines and circled keywords. Style: high-contrast ink-on-blueprint with cyan accent highlights.',
213+
];
214+
215+
// ---------------------------------------------------------------------------
216+
// High-level API: generate all infographics for a topic
217+
// ---------------------------------------------------------------------------
218+
219+
/**
220+
* Generate a deterministic seed from a topic + instruction index.
221+
* Ensures the same topic always produces the same seed per instruction,
222+
* enabling brand-consistent regeneration.
223+
*/
224+
function generateSeed(topic: string, index: number): number {
225+
let hash = 0;
226+
const str = `${topic}-infographic-${index}`;
227+
for (let i = 0; i < str.length; i++) {
228+
const char = str.charCodeAt(i);
229+
hash = ((hash << 5) - hash) + char;
230+
hash = hash & hash;
231+
}
232+
return Math.abs(hash) % 2147483647;
233+
}
234+
235+
/**
236+
* Generate all infographics for a research topic using instructions
237+
* from Sanity contentConfig.
238+
*
239+
* This is the main entry point for the check-research cron route.
240+
* Reads infographic instructions from contentConfig.infographicInstructions,
241+
* appends topic context to each, and generates images with deterministic
242+
* seeds for brand consistency.
243+
*
244+
* @param topic - The research topic (e.g. "React Server Components")
245+
* @param briefing - Optional research briefing text for additional context
246+
* @returns InfographicBatchResult with generated images and any errors
247+
*/
248+
export async function generateInfographicsForTopic(
249+
topic: string,
250+
briefing?: string,
251+
): Promise<InfographicBatchResult> {
252+
const instructions = await getConfigValue(
253+
"content_config", "infographicInstructions", DEFAULT_INSTRUCTIONS
254+
);
255+
256+
const model = await getConfigValue(
257+
"pipeline_config", "infographicModel", "imagen-4-fast"
258+
);
259+
260+
const contextSuffix = briefing
261+
? `\n\nTopic: ${topic}\nContext: ${briefing.slice(0, 500)}`
262+
: `\n\nTopic: ${topic}`;
263+
264+
const requests: InfographicRequest[] = instructions.map(
265+
(instruction, index) => ({
266+
prompt: `${instruction}${contextSuffix}`,
267+
seed: generateSeed(topic, index),
268+
aspectRatio: "16:9" as const,
269+
})
270+
);
271+
272+
console.log(
273+
`[infographics] Generating ${requests.length} infographics for "${topic}" with ${model}`
274+
);
275+
276+
const result = await generateInfographicBatch(requests, { model });
277+
278+
console.log(
279+
`[infographics] Complete: ${result.results.length} generated, ${result.errors.length} failed`
280+
);
281+
282+
return result;
283+
}

0 commit comments

Comments
 (0)