Initial commit: PodcastYes — AI podcast platform

This commit is contained in:
Leon Serfaty
2026-06-07 03:58:32 -04:00
commit 155507f21a
151 changed files with 19826 additions and 0 deletions
+53
View File
@@ -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 (610 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, 34 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,
},
};
}