Initial commit: PodcastYes — AI podcast platform
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
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<RepurposeFormat, string> = {
|
||||
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<typeof outputSchema>;
|
||||
|
||||
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,
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user