import { z } from "zod"; import { openai, SCRIPT_MODEL } from "@/lib/ai/openai"; import type { StructuredScript, TokenUsage } from "@/lib/ai/types"; export type RepurposeFormat = "blog" | "social_thread" | "newsletter"; const FORMAT_PROMPTS: Record = { blog: "Write an engaging, SEO-friendly blog post based on this episode. Include a compelling title and well-structured markdown body with headings and a short conclusion.", social_thread: "Write a punchy social thread (6–10 posts, numbered) summarizing the episode's best insights. Start with a strong hook. Put the whole thread in the markdown body.", newsletter: "Write a friendly email newsletter edition about this episode: a subject line as the title, a short intro, 3–4 key takeaways as bullets, and a call-to-action to listen. Markdown body.", }; const outputSchema = z.object({ title: z.string().min(1), body: z.string().min(1) }); export type RepurposedOutput = z.infer; function scriptToText(script: StructuredScript): string { return script.sections .map((s) => `## ${s.title}\n` + s.turns.map((t) => t.text).join("\n")) .join("\n\n"); } export async function repurposeScript( script: StructuredScript, format: RepurposeFormat ): Promise<{ content: RepurposedOutput; usage: TokenUsage }> { const transcript = scriptToText(script).slice(0, 9000); const res = await openai().chat.completions.create({ model: SCRIPT_MODEL, messages: [ { role: "system", content: "You are a content marketer who repurposes podcast episodes into other formats. Return STRICT JSON: { \"title\": string, \"body\": string } where body is markdown.", }, { role: "user", content: `${FORMAT_PROMPTS[format]}\n\nEpisode title: ${script.title}\n\nTranscript:\n${transcript}`, }, ], response_format: { type: "json_object" }, temperature: 0.7, }); const content = outputSchema.parse(JSON.parse(res.choices[0]?.message?.content ?? "{}")); return { content, usage: { inputTokens: res.usage?.prompt_tokens ?? 0, outputTokens: res.usage?.completion_tokens ?? 0, }, }; }