37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
import { openai, ART_MODEL } from "../openai";
|
|
import type { ArtProvider } from "../types";
|
|
|
|
export class OpenAIArtProvider implements ArtProvider {
|
|
readonly model = ART_MODEL;
|
|
|
|
async generateCover(
|
|
prompt: string,
|
|
opts?: { size?: "1024x1024" }
|
|
): Promise<{ data: Buffer; revisedPrompt?: string }> {
|
|
const res = await openai().images.generate({
|
|
model: this.model,
|
|
prompt,
|
|
n: 1,
|
|
size: opts?.size ?? "1024x1024",
|
|
response_format: "b64_json",
|
|
});
|
|
const item = res.data?.[0];
|
|
if (!item?.b64_json) throw new Error("DALL·E returned no image data");
|
|
return {
|
|
data: Buffer.from(item.b64_json, "base64"),
|
|
revisedPrompt: item.revised_prompt,
|
|
};
|
|
}
|
|
}
|
|
|
|
/** Build a cover-art prompt for an episode topic. */
|
|
export function buildCoverPrompt(topic: string, tone: string, title?: string): string {
|
|
return [
|
|
`Podcast cover art for an episode titled "${title ?? topic}".`,
|
|
`Topic: ${topic}. Mood/tone: ${tone}.`,
|
|
"Modern, bold, eye-catching square album-cover style.",
|
|
"Strong focal subject, clean composition, vibrant but tasteful colors.",
|
|
"No text, no words, no letters, no logos.",
|
|
].join(" ");
|
|
}
|