import type { ModelPricing } from "@/lib/ai/core/types"; /** * Anthropic pricing (USD per 1M tokens) — first-party API rates. * Source: https://platform.claude.com/docs/en/about-claude/pricing (audited 2026-09-08). * Cache reads are billed at 10% of input (Fable 5.1 / Mythos 5.1: $0.25 flat per MTok). * The Models API does not expose pricing, so this table is the only hand-maintained piece. */ export const ANTHROPIC_PRICING: Record = { "claude-fable-5-1": { inputPerMillion: 10, outputPerMillion: 50, cachedInputPerMillion: 0.25 }, "claude-mythos-5-1": { inputPerMillion: 10, outputPerMillion: 50, cachedInputPerMillion: 0.25 }, "claude-fable-5": { inputPerMillion: 10, outputPerMillion: 50, cachedInputPerMillion: 1 }, "claude-opus-5": { inputPerMillion: 5, outputPerMillion: 25, cachedInputPerMillion: 0.5 }, "claude-opus-4-8": { inputPerMillion: 5, outputPerMillion: 25, cachedInputPerMillion: 0.5 }, "claude-opus-4-7": { inputPerMillion: 5, outputPerMillion: 25, cachedInputPerMillion: 0.5 }, "claude-opus-4-6": { inputPerMillion: 5, outputPerMillion: 25, cachedInputPerMillion: 0.5 }, "claude-sonnet-5": { inputPerMillion: 2, outputPerMillion: 10, cachedInputPerMillion: 0.2 }, "claude-sonnet-4-6": { inputPerMillion: 3, outputPerMillion: 15, cachedInputPerMillion: 0.3 }, "claude-haiku-4-5": { inputPerMillion: 1, outputPerMillion: 5, cachedInputPerMillion: 0.1 }, "claude-opus-4-5": { inputPerMillion: 5, outputPerMillion: 25, cachedInputPerMillion: 0.5 }, "claude-sonnet-4-5": { inputPerMillion: 3, outputPerMillion: 15, cachedInputPerMillion: 0.3 }, "claude-opus-4-1": { inputPerMillion: 15, outputPerMillion: 75, cachedInputPerMillion: 1.5 }, "claude-opus-4": { inputPerMillion: 15, outputPerMillion: 75, cachedInputPerMillion: 1.5 }, "claude-sonnet-4": { inputPerMillion: 3, outputPerMillion: 15, cachedInputPerMillion: 0.3 }, "claude-3-7-sonnet": { inputPerMillion: 3, outputPerMillion: 15, cachedInputPerMillion: 0.3 }, "claude-3-5-haiku": { inputPerMillion: 0.8, outputPerMillion: 4, cachedInputPerMillion: 0.08 }, "claude-3-haiku": { inputPerMillion: 0.25, outputPerMillion: 1.25, cachedInputPerMillion: 0.03 }, }; export function anthropicPricingFor(modelId: string): ModelPricing | null { if (ANTHROPIC_PRICING[modelId]) return { ...ANTHROPIC_PRICING[modelId], source: "anthropic-pricing-page", asOf: "2026-09-08" }; // dated snapshots: claude-sonnet-4-5-20250929 → claude-sonnet-4-5 const base = modelId.replace(/-\d{8}$/, ""); if (ANTHROPIC_PRICING[base]) return { ...ANTHROPIC_PRICING[base], source: "anthropic-pricing-page", asOf: "2026-09-08" }; return null; } /** Models retired or scheduled for retirement per the deprecations page. */ export const ANTHROPIC_DEPRECATED = new Set(["claude-3-haiku-20240307", "claude-3-5-haiku-20241022", "claude-3-7-sonnet-20250219", "claude-opus-4-20250514", "claude-opus-4-1-20250805", "claude-sonnet-4-20250514"]); /** Ordering weight for the selector (higher first). */ export function anthropicSortWeight(id: string): number { if (id.startsWith("claude-fable-5-1")) return 100; if (id.startsWith("claude-opus-5")) return 95; if (id.startsWith("claude-sonnet-5")) return 90; if (id.startsWith("claude-fable-5")) return 85; if (id.startsWith("claude-opus-4-8")) return 80; if (id.startsWith("claude-opus-4-7")) return 75; if (id.startsWith("claude-sonnet-4-6")) return 70; if (id.startsWith("claude-opus-4-6")) return 68; if (id.startsWith("claude-haiku-4-5")) return 60; return 10; } export function anthropicFamily(id: string): string { if (id.includes("fable") || id.includes("mythos")) return "Fable"; if (id.includes("opus")) return "Opus"; if (id.includes("sonnet")) return "Sonnet"; if (id.includes("haiku")) return "Haiku"; return "Claude"; }