All files / server/ai costCalculator.ts

100% Statements 10/10
100% Branches 4/4
100% Functions 2/2
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55                1x                                                     11x   11x   2x 2x     9x 9x 9x     9x       8x    
// Cost calculation for different AI models
// Prices are per million tokens (MTok) in USD
 
interface ModelPricing {
  inputCostPerMTok: number;
  outputCostPerMTok: number;
}
 
const MODEL_PRICING: Record<string, ModelPricing> = {
  // Anthropic Claude
  "claude-sonnet-4": { inputCostPerMTok: 3, outputCostPerMTok: 15 },
  "claude-sonnet-4-5": { inputCostPerMTok: 3, outputCostPerMTok: 15 },
  "claude-opus-4": { inputCostPerMTok: 15, outputCostPerMTok: 75 },
  "claude-opus-4-5": { inputCostPerMTok: 15, outputCostPerMTok: 75 },
  "claude-3-5-sonnet-20241022": { inputCostPerMTok: 3, outputCostPerMTok: 15 },
 
  // OpenAI GPT
  "gpt-4": { inputCostPerMTok: 30, outputCostPerMTok: 60 },
  "gpt-4-turbo": { inputCostPerMTok: 10, outputCostPerMTok: 30 },
  "gpt-4-turbo-preview": { inputCostPerMTok: 10, outputCostPerMTok: 30 },
  "gpt-3.5-turbo": { inputCostPerMTok: 0.5, outputCostPerMTok: 1.5 },
  "gpt-4o": { inputCostPerMTok: 2.5, outputCostPerMTok: 10 },
  "gpt-4o-mini": { inputCostPerMTok: 0.15, outputCostPerMTok: 0.6 },
 
  // Google Gemini
  "gemini-2.0-flash": { inputCostPerMTok: 0.1, outputCostPerMTok: 0.4 },
  "gemini-1.5-pro": { inputCostPerMTok: 1.25, outputCostPerMTok: 5 },
  "gemini-1.5-flash": { inputCostPerMTok: 0.075, outputCostPerMTok: 0.3 },
};
 
export function calculateCost(
  modelName: string,
  promptTokens: number,
  completionTokens: number
): string {
  const pricing = MODEL_PRICING[modelName];
 
  if (!pricing) {
    // Default fallback pricing if model not found
    console.warn(`Unknown model pricing for ${modelName}, using default`);
    return "0.00";
  }
 
  const inputCost = (promptTokens / 1_000_000) * pricing.inputCostPerMTok;
  const outputCost = (completionTokens / 1_000_000) * pricing.outputCostPerMTok;
  const totalCost = inputCost + outputCost;
 
  // Return as string with 6 decimal places to avoid float precision issues
  return totalCost.toFixed(6);
}
 
export function getModelPricing(modelName: string): ModelPricing | null {
  return MODEL_PRICING[modelName] || null;
}