import { z } from "zod"; import { guarded, body } from "@/lib/api"; import { openaiSpeak } from "@/lib/ai/openai"; import { recordUsage } from "@/lib/usage"; export const maxDuration = 120; export const POST = guarded(async (req) => { const b = await body(req, z.object({ text: z.string().min(1).max(4000), voice: z.string().max(20).optional(), model: z.string().optional(), instructions: z.string().max(500).optional() })); const model = b.model ?? "gpt-4o-mini-tts"; const t0 = Date.now(); const mp3 = await openaiSpeak(b.text, b.voice ?? "alloy", model, b.instructions); // verified prices: gpt-4o-mini-tts text in $0.60/M (~4 chars/token), audio out $12/M (≈ $0.015/min); tts-1 $15 per 1M chars const cost = model.startsWith("tts-1") ? b.text.length * (model === "tts-1-hd" ? 30 : 15) / 1e6 : (b.text.length / 4) * 0.6 / 1e6 + (b.text.length / 900) * 0.015; await recordUsage({ provider: "openai", modelId: model, kind: "tts", usage: { input: Math.round(b.text.length / 4), output: 0 }, costEstimated: cost, latencyMs: Date.now() - t0 }); return new Response(new Uint8Array(mp3), { headers: { "content-type": "audio/mpeg", "cache-control": "private, max-age=600" } }); });