Files
2026-06-07 03:58:32 -04:00

53 lines
1.4 KiB
TypeScript

import { prisma } from "@/lib/db";
import type { TokenUsage } from "./types";
// Rough 2026 unit prices (USD). Tune in one place; admin cost dashboards read AiCostLog.
const PRICE = {
gptInputPer1k: 0.0025,
gptOutputPer1k: 0.01,
elevenPer1kChars: 0.3,
dallePerImage: 0.04,
};
export function scriptCostUsd(usage: TokenUsage): number {
return round4(
(usage.inputTokens / 1000) * PRICE.gptInputPer1k +
(usage.outputTokens / 1000) * PRICE.gptOutputPer1k
);
}
export function audioCostUsd(characters: number): number {
return round4((characters / 1000) * PRICE.elevenPer1kChars);
}
export function artCostUsd(images: number): number {
return round4(images * PRICE.dallePerImage);
}
export interface CostEntry {
provider: "openai" | "elevenlabs";
operation: "script" | "audio" | "art" | "repurpose";
units: number;
costUsd: number;
episodeId?: string;
userId?: string;
}
/** Record an AI usage/cost line for the admin monitoring dashboard. */
export async function recordCost(entry: CostEntry): Promise<void> {
await prisma.aiCostLog.create({
data: {
provider: entry.provider,
operation: entry.operation,
units: entry.units,
costUsd: entry.costUsd.toFixed(4),
episodeId: entry.episodeId,
userId: entry.userId,
},
});
}
function round4(n: number): number {
return Math.round(n * 10000) / 10000;
}