@diogonzafe/tokenwatch 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/tracker.ts","../src/core/pricing.ts","../src/core/suggestions.ts","../src/core/storage.ts","../src/core/sync.ts","../prices.json","../src/core/lazy-tracker.ts","../src/providers/openai.ts","../src/providers/anthropic.ts","../src/providers/gemini.ts"],"sourcesContent":["export { createTracker } from './core/tracker.js'\nexport { createLazyTracker } from './core/lazy-tracker.js'\nexport { wrapOpenAI } from './providers/openai.js'\nexport { wrapAnthropic } from './providers/anthropic.js'\nexport { wrapGemini } from './providers/gemini.js'\nexport { wrapDeepSeek } from './providers/deepseek.js'\n\nexport type {\n Tracker,\n LazyTracker,\n TrackerConfig,\n UsageEntry,\n Report,\n ReportOptions,\n CostForecast,\n ForecastOptions,\n ModelStats,\n SessionStats,\n UserStats,\n FeatureStats,\n ModelPrice,\n PriceMap,\n PricesFile,\n IStorage,\n IExporter,\n TrackingMeta,\n BudgetConfig,\n AnomalyDetectionConfig,\n} from './types/index.js'\n","import { z } from 'zod'\nimport type {\n Tracker,\n TrackerConfig,\n UsageEntry,\n Report,\n ReportOptions,\n CostForecast,\n ForecastOptions,\n ModelStats,\n SessionStats,\n UserStats,\n FeatureStats,\n ModelPrice,\n PriceMap,\n IStorage,\n BudgetConfig,\n IExporter,\n} from '../types/index.js'\nimport { resolvePrice, findPrice, calculateCost } from './pricing.js'\nimport { maybeSuggestCheaperModel } from './suggestions.js'\nimport { createStorage } from './storage.js'\nimport { getRemotePrices } from './sync.js'\nimport bundledPricesFile from '../../prices.json' assert { type: 'json' }\n\nconst bundledPrices: PriceMap = bundledPricesFile.models as PriceMap\nconst bundledUpdatedAt: string = (bundledPricesFile as { updated_at?: string }).updated_at ?? ''\n\n// ─── Config validation schema ─────────────────────────────────────────────────\n\nconst ModelPriceSchema = z.object({\n input: z.number().nonnegative(),\n output: z.number().nonnegative(),\n cachedInput: z.number().nonnegative().optional(),\n cacheCreationInput: z.number().nonnegative().optional(),\n maxInputTokens: z.number().positive().optional(),\n})\n\nconst BudgetConfigSchema = z.object({\n threshold: z.number().positive(),\n webhookUrl: z.string().url(),\n mode: z.enum(['once', 'always']).optional().default('once'),\n})\n\n// storage can be a string enum or an IStorage instance — validated separately\nconst TrackerConfigSchema = z.object({\n storage: z.union([z.enum(['memory', 'sqlite']), z.custom<IStorage>((v) => {\n return (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as IStorage).record === 'function' &&\n typeof (v as IStorage).getAll === 'function' &&\n typeof (v as IStorage).clearAll === 'function' &&\n typeof (v as IStorage).clearSession === 'function'\n )\n })]).optional().default('memory'),\n alertThreshold: z.number().positive().optional(),\n webhookUrl: z.string().url().optional(),\n syncPrices: z.boolean().optional().default(true),\n customPrices: z.record(z.string(), ModelPriceSchema).optional(),\n warnIfStaleAfterHours: z.number().nonnegative().optional().default(72),\n budgets: z.object({\n perUser: BudgetConfigSchema.optional(),\n perSession: BudgetConfigSchema.optional(),\n }).optional(),\n suggestions: z.boolean().optional().default(false),\n anomalyDetection: z.object({\n multiplierThreshold: z.number().positive(),\n webhookUrl: z.string().url(),\n windowHours: z.number().positive().optional().default(24),\n mode: z.enum(['once', 'always']).optional().default('once'),\n }).optional(),\n exporter: z.custom<IExporter>((v) => (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as IExporter).export === 'function'\n )).optional(),\n})\n\nexport function createTracker(config: TrackerConfig = {}): Tracker {\n const parsed = TrackerConfigSchema.safeParse(config)\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => ` ${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new Error(`[tokenwatch] Invalid config:\\n${issues}`)\n }\n\n const {\n storage: storageOption,\n alertThreshold,\n webhookUrl,\n syncPrices,\n customPrices,\n warnIfStaleAfterHours,\n budgets,\n suggestions,\n anomalyDetection,\n exporter,\n } = parsed.data\n\n const storage: IStorage =\n typeof storageOption === 'object'\n ? storageOption\n : createStorage(storageOption)\n\n // Fetch remote prices in the background — bundled prices are used as fallback\n // until the sync resolves. Negligible overhead added to createTracker().\n let remotePrices: PriceMap | undefined\n let pricesUpdatedAt: string = bundledUpdatedAt\n if (syncPrices) {\n getRemotePrices()\n .then((result) => {\n if (result) {\n remotePrices = result.models\n pricesUpdatedAt = result.updated_at\n }\n })\n .catch(() => {\n // best-effort — bundled prices remain in use\n })\n }\n\n // Warn if prices are stale (checked lazily on first access)\n let stalenessChecked = false\n function maybeWarnStaleness(): void {\n if (stalenessChecked || !warnIfStaleAfterHours) return\n stalenessChecked = true\n if (!pricesUpdatedAt) return\n try {\n const updatedMs = new Date(pricesUpdatedAt).getTime()\n const ageHours = (Date.now() - updatedMs) / (1000 * 60 * 60)\n if (ageHours > warnIfStaleAfterHours) {\n console.warn(\n `[tokenwatch] Price data is ${Math.round(ageHours)}h old (updated_at: ${pricesUpdatedAt}). ` +\n `Run \"tokenwatch sync\" to refresh, or set warnIfStaleAfterHours: 0 to suppress.`,\n )\n }\n } catch {\n // best-effort\n }\n }\n\n let alertFired = false\n const firedUserAlerts = new Set<string>()\n const firedSessionAlerts = new Set<string>()\n const firedAnomalyKeys = new Set<string>()\n const startedAt = new Date().toISOString()\n\n function resolveModelPrice(model: string) {\n maybeWarnStaleness()\n return resolvePrice(model, {\n bundledPrices,\n ...(customPrices !== undefined && { customPrices: customPrices as PriceMap }),\n ...(remotePrices !== undefined && { remotePrices }),\n })\n }\n\n function track(entry: Omit<UsageEntry, 'costUSD' | 'timestamp'>): void {\n const price = resolveModelPrice(entry.model)\n const costUSD = calculateCost(\n entry.inputTokens,\n entry.outputTokens,\n price,\n entry.cachedTokens,\n entry.cacheCreationTokens,\n )\n const full: UsageEntry = {\n ...entry,\n costUSD,\n timestamp: new Date().toISOString(),\n }\n storage.record(full)\n if (exporter) {\n Promise.resolve(exporter.export(full)).catch(() => { /* fire-and-forget */ })\n }\n maybeFireAlerts(full)\n if (anomalyDetection) maybeDetectAnomaly(full)\n if (suggestions) {\n maybeSuggestCheaperModel(entry.model, costUSD, entry.inputTokens, entry.outputTokens, {\n bundledPrices,\n ...(customPrices !== undefined && { customPrices: customPrices as PriceMap }),\n ...(remotePrices !== undefined && { remotePrices }),\n })\n }\n }\n\n function maybeFireAlerts(entry: UsageEntry): void {\n // Global threshold alert\n if (alertThreshold && webhookUrl && !alertFired) {\n alertFired = true\n Promise.resolve(storage.getAll()).then((entries) => {\n const total = computeTotal(entries)\n if (total < alertThreshold!) {\n alertFired = false\n return\n }\n fireWebhook(webhookUrl!, {\n text: `[tokenwatch] Alert: total cost reached $${total.toFixed(4)} USD (threshold: $${alertThreshold})`,\n })\n }).catch(() => {\n alertFired = false\n })\n }\n\n // Per-user budget alert\n if (budgets?.perUser && entry.userId) {\n const cfg = budgets.perUser\n const uid = entry.userId\n if (cfg.mode === 'always' || !firedUserAlerts.has(uid)) {\n // Claim the slot synchronously before going async — prevents double-fire\n if (cfg.mode !== 'always') firedUserAlerts.add(uid)\n Promise.resolve(storage.getAll()).then((entries) => {\n const userCost = entries\n .filter((e) => e.userId === uid)\n .reduce((s, e) => s + e.costUSD, 0)\n if (userCost >= cfg.threshold) {\n fireWebhook(cfg.webhookUrl, {\n text: `[tokenwatch] Budget alert: user \"${uid}\" reached $${userCost.toFixed(4)} USD (threshold: $${cfg.threshold})`,\n })\n } else {\n if (cfg.mode !== 'always') firedUserAlerts.delete(uid) // release — threshold not yet met\n }\n }).catch(() => {\n if (cfg.mode !== 'always') firedUserAlerts.delete(uid) // release on storage error\n })\n }\n }\n\n // Per-session budget alert\n if (budgets?.perSession && entry.sessionId) {\n const cfg = budgets.perSession\n const sid = entry.sessionId\n if (cfg.mode === 'always' || !firedSessionAlerts.has(sid)) {\n // Claim the slot synchronously before going async — prevents double-fire\n if (cfg.mode !== 'always') firedSessionAlerts.add(sid)\n Promise.resolve(storage.getAll()).then((entries) => {\n const sessionCost = entries\n .filter((e) => e.sessionId === sid)\n .reduce((s, e) => s + e.costUSD, 0)\n if (sessionCost >= cfg.threshold) {\n fireWebhook(cfg.webhookUrl, {\n text: `[tokenwatch] Budget alert: session \"${sid}\" reached $${sessionCost.toFixed(4)} USD (threshold: $${cfg.threshold})`,\n })\n } else {\n if (cfg.mode !== 'always') firedSessionAlerts.delete(sid) // release\n }\n }).catch(() => {\n if (cfg.mode !== 'always') firedSessionAlerts.delete(sid) // release on storage error\n })\n }\n }\n }\n\n function fireWebhook(url: string, payload: { text: string }): void {\n fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }).catch(() => {\n // fire-and-forget\n })\n }\n\n async function getReport(options?: ReportOptions): Promise<Report> {\n const allEntries = await Promise.resolve(storage.getAll())\n const entries = filterEntries(allEntries, options)\n\n const byModel: Record<string, ModelStats> = {}\n const bySession: Record<string, SessionStats> = {}\n const byUser: Record<string, UserStats> = {}\n const byFeature: Record<string, FeatureStats> = {}\n\n let totalInput = 0\n let totalOutput = 0\n let totalCost = 0\n let periodFrom = options ? (entries[0]?.timestamp ?? startedAt) : startedAt\n let lastTimestamp = periodFrom\n\n for (const e of entries) {\n totalInput += e.inputTokens + (e.cachedTokens ?? 0) + (e.cacheCreationTokens ?? 0)\n totalOutput += e.outputTokens\n totalCost += e.costUSD\n if (e.timestamp > lastTimestamp) lastTimestamp = e.timestamp\n\n // byModel\n const m = (byModel[e.model] ??= {\n costUSD: 0,\n calls: 0,\n tokens: { input: 0, output: 0, reasoning: 0, cached: 0 },\n })\n m.costUSD += e.costUSD\n m.calls += 1\n m.tokens.input += e.inputTokens + (e.cachedTokens ?? 0) + (e.cacheCreationTokens ?? 0)\n m.tokens.output += e.outputTokens\n m.tokens.reasoning += e.reasoningTokens ?? 0\n m.tokens.cached += e.cachedTokens ?? 0\n\n // bySession\n if (e.sessionId) {\n const s = (bySession[e.sessionId] ??= { costUSD: 0, calls: 0 })\n s.costUSD += e.costUSD\n s.calls += 1\n }\n\n // byUser\n if (e.userId) {\n const u = (byUser[e.userId] ??= { costUSD: 0, calls: 0 })\n u.costUSD += e.costUSD\n u.calls += 1\n }\n\n // byFeature\n if (e.feature) {\n const f = (byFeature[e.feature] ??= { costUSD: 0, calls: 0 })\n f.costUSD += e.costUSD\n f.calls += 1\n }\n }\n\n // When filtering, use the actual first entry's timestamp as period.from\n if (options && entries.length > 0) {\n periodFrom = entries[0]?.timestamp ?? periodFrom\n }\n\n return {\n totalCostUSD: totalCost,\n totalTokens: { input: totalInput, output: totalOutput },\n byModel,\n bySession,\n byUser,\n byFeature,\n period: { from: periodFrom, to: lastTimestamp },\n ...(pricesUpdatedAt ? { pricesUpdatedAt } : {}),\n }\n }\n\n async function getCostForecast(options: ForecastOptions = {}): Promise<CostForecast> {\n const windowHours = options.windowHours ?? 24\n const allEntries = await Promise.resolve(storage.getAll())\n\n const now = Date.now()\n const windowStart = now - windowHours * 60 * 60 * 1000\n const windowEntries = allEntries.filter(\n (e) => new Date(e.timestamp).getTime() >= windowStart,\n )\n\n if (windowEntries.length < 2) {\n return {\n burnRatePerHour: 0,\n projectedDailyCostUSD: 0,\n projectedMonthlyCostUSD: 0,\n basedOnHours: 0,\n basedOnPeriod: null,\n }\n }\n\n const first = windowEntries[0]?.timestamp ?? ''\n const last = windowEntries[windowEntries.length - 1]?.timestamp ?? ''\n const actualMs = new Date(last).getTime() - new Date(first).getTime()\n const actualHours = actualMs / (1000 * 60 * 60)\n\n if (actualHours < 0.001) {\n return {\n burnRatePerHour: 0,\n projectedDailyCostUSD: 0,\n projectedMonthlyCostUSD: 0,\n basedOnHours: 0,\n basedOnPeriod: { from: first, to: last },\n }\n }\n\n const totalCost = windowEntries.reduce((s, e) => s + e.costUSD, 0)\n const burnRatePerHour = totalCost / actualHours\n\n return {\n burnRatePerHour,\n projectedDailyCostUSD: burnRatePerHour * 24,\n projectedMonthlyCostUSD: burnRatePerHour * 24 * 30,\n basedOnHours: Math.round(actualHours * 100) / 100,\n basedOnPeriod: { from: first, to: last },\n }\n }\n\n function maybeDetectAnomaly(entry: UsageEntry): void {\n if (entry.costUSD <= 0) return\n const { multiplierThreshold, webhookUrl: aUrl, windowHours: wh, mode: modeRaw } = anomalyDetection!\n const wHours = wh ?? 24\n const mode = modeRaw ?? 'once'\n const windowStart = Date.now() - wHours * 60 * 60 * 1000\n const entryTs = new Date(entry.timestamp).getTime()\n\n function checkEntity(key: string, label: string, predicate: (e: UsageEntry) => boolean): void {\n if (mode !== 'always' && firedAnomalyKeys.has(key)) return\n if (mode !== 'always') firedAnomalyKeys.add(key)\n Promise.resolve(storage.getAll()).then((all) => {\n const history = all.filter(\n (e) =>\n predicate(e) &&\n new Date(e.timestamp).getTime() >= windowStart &&\n new Date(e.timestamp).getTime() !== entryTs,\n )\n if (history.length === 0) {\n if (mode !== 'always') firedAnomalyKeys.delete(key)\n return\n }\n const avg = history.reduce((s, e) => s + e.costUSD, 0) / history.length\n if (avg <= 0 || entry.costUSD <= avg * multiplierThreshold) {\n if (mode !== 'always') firedAnomalyKeys.delete(key)\n return\n }\n const multiple = (entry.costUSD / avg).toFixed(1)\n fireWebhook(aUrl, {\n text: `[tokenwatch] Anomaly: ${label} call cost $${entry.costUSD.toFixed(4)} is ${multiple}x above ${wHours}h average ($${avg.toFixed(4)})`,\n })\n }).catch(() => {\n if (mode !== 'always') firedAnomalyKeys.delete(key)\n })\n }\n\n if (entry.userId) {\n checkEntity(\n `user:${entry.userId}`,\n `user \"${entry.userId}\"`,\n (e) => e.userId === entry.userId,\n )\n }\n checkEntity(\n `model:${entry.model}`,\n `model \"${entry.model}\"`,\n (e) => e.model === entry.model,\n )\n }\n\n async function reset(): Promise<void> {\n await Promise.resolve(storage.clearAll())\n alertFired = false\n firedUserAlerts.clear()\n firedSessionAlerts.clear()\n firedAnomalyKeys.clear()\n }\n\n async function resetSession(sessionId: string): Promise<void> {\n await Promise.resolve(storage.clearSession(sessionId))\n firedSessionAlerts.delete(sessionId)\n }\n\n async function exportJSON(): Promise<string> {\n return JSON.stringify(await getReport(), null, 2)\n }\n\n async function exportCSV(): Promise<string> {\n const entries = await Promise.resolve(storage.getAll())\n const header =\n 'timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature'\n const rows = entries.map((e) =>\n [\n csvEscape(e.timestamp),\n csvEscape(e.model),\n e.inputTokens,\n e.outputTokens,\n e.reasoningTokens ?? 0,\n e.cachedTokens ?? 0,\n e.cacheCreationTokens ?? 0,\n e.costUSD.toFixed(8),\n csvEscape(e.sessionId ?? ''),\n csvEscape(e.userId ?? ''),\n csvEscape(e.feature ?? ''),\n ].join(','),\n )\n return [header, ...rows].join('\\n')\n }\n\n function getModelInfo(model: string): ModelPrice | null {\n return findPrice(model, {\n bundledPrices,\n ...(customPrices !== undefined && { customPrices: customPrices as PriceMap }),\n ...(remotePrices !== undefined && { remotePrices }),\n }) ?? null\n }\n\n return {\n track,\n getReport,\n getCostForecast,\n reset,\n resetSession,\n exportJSON,\n exportCSV,\n getModelInfo,\n }\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction computeTotal(entries: UsageEntry[]): number {\n return entries.reduce((sum, e) => sum + e.costUSD, 0)\n}\n\n/** Parse a 'last' shorthand like '24h', '7d' into milliseconds */\nfunction parseLastMs(last: string): number {\n const match = /^(\\d+(?:\\.\\d+)?)(h|d)$/.exec(last.trim())\n if (!match) throw new Error(`[tokenwatch] Invalid \"last\" value: \"${last}\". Use e.g. \"24h\", \"7d\".`)\n const value = parseFloat(match[1] ?? '0')\n const unit = match[2] ?? 'h'\n return unit === 'h' ? value * 60 * 60 * 1000 : value * 24 * 60 * 60 * 1000\n}\n\nfunction filterEntries(entries: UsageEntry[], options?: ReportOptions): UsageEntry[] {\n if (!options) return entries\n\n let sinceMs: number | undefined\n let untilMs: number | undefined\n\n if (options.last) {\n sinceMs = Date.now() - parseLastMs(options.last)\n } else if (options.since) {\n sinceMs = new Date(options.since).getTime()\n }\n if (options.until) {\n untilMs = new Date(options.until).getTime()\n }\n\n if (sinceMs === undefined && untilMs === undefined) return entries\n\n return entries.filter((e) => {\n const ts = new Date(e.timestamp).getTime()\n if (sinceMs !== undefined && ts < sinceMs) return false\n if (untilMs !== undefined && ts > untilMs) return false\n return true\n })\n}\n\n/** Wrap a CSV field value in double-quotes if it contains commas, quotes, or newlines. */\nfunction csvEscape(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`\n }\n return value\n}\n","import type { ModelPrice, PriceMap } from '../types/index.js'\n\n/**\n * Resolve price for a model using 3-layer priority:\n * 1. customPrices (user override)\n * 2. remotePrices (synced from GitHub, cached 24h)\n * 3. bundledPrices (always-present fallback)\n *\n * Falls back to zero-cost with a console warning when model is not found anywhere.\n */\nexport function resolvePrice(\n model: string,\n layers: {\n customPrices?: PriceMap\n remotePrices?: PriceMap\n bundledPrices: PriceMap\n },\n): ModelPrice {\n const { customPrices, remotePrices, bundledPrices } = layers\n\n const found =\n lookupInMap(model, customPrices) ??\n lookupInMap(model, remotePrices) ??\n lookupInMap(model, bundledPrices)\n\n if (found) return found\n\n console.warn(\n `[tokenwatch] Unknown model \"${model}\". Cost will be recorded as $0. ` +\n `Add it via customPrices or update prices with: tokenwatch sync`,\n )\n return { input: 0, output: 0 }\n}\n\n/**\n * Find price for a model without the zero-cost fallback.\n * Returns undefined if the model is not found in any layer.\n */\nexport function findPrice(\n model: string,\n layers: {\n customPrices?: PriceMap\n remotePrices?: PriceMap\n bundledPrices: PriceMap\n },\n): ModelPrice | undefined {\n const { customPrices, remotePrices, bundledPrices } = layers\n return (\n lookupInMap(model, customPrices) ??\n lookupInMap(model, remotePrices) ??\n lookupInMap(model, bundledPrices)\n )\n}\n\n/**\n * Look up a model in a PriceMap using:\n * 1. exact key match\n * 2. prefix match — map key is a prefix of the model string (e.g. \"gpt-4o\" matches \"gpt-4o-2024-11-20\")\n * 3. reverse prefix — model string is a prefix of a map key (unusual, safety net)\n */\nfunction lookupInMap(model: string, map: PriceMap | undefined): ModelPrice | undefined {\n if (!map) return undefined\n\n if (model in map) return map[model]\n\n // prefix match\n for (const key of Object.keys(map)) {\n if (model.startsWith(key) || key.startsWith(model)) {\n return map[key]\n }\n }\n\n return undefined\n}\n\n/**\n * Calculate cost in USD given token counts and per-million-token prices.\n *\n * - `inputTokens` — regular (non-cached) input tokens\n * - `outputTokens` — output tokens (includes reasoning tokens for OpenAI, which are billed as output)\n * - `cachedTokens` — cache-read input tokens (billed at price.cachedInput or full input price if absent)\n * - `cacheCreationTokens` — cache-creation input tokens, Anthropic only (billed at price.cacheCreationInput\n * or 1.25× input price if absent)\n */\nexport function calculateCost(\n inputTokens: number,\n outputTokens: number,\n price: ModelPrice,\n cachedTokens = 0,\n cacheCreationTokens = 0,\n): number {\n const regularInputCost = (inputTokens / 1_000_000) * price.input\n const cachedReadCost = (cachedTokens / 1_000_000) * (price.cachedInput ?? price.input)\n const cacheCreationCost =\n (cacheCreationTokens / 1_000_000) * (price.cacheCreationInput ?? price.input * 1.25)\n const outputCost = (outputTokens / 1_000_000) * price.output\n return regularInputCost + cachedReadCost + cacheCreationCost + outputCost\n}\n","import type { PriceMap } from '../types/index.js'\nimport { calculateCost } from './pricing.js'\n\nconst PROVIDER_PREFIXES = ['gpt-', 'claude-', 'gemini-', 'deepseek-'] as const\n\nfunction getProviderPrefix(model: string): string | undefined {\n return PROVIDER_PREFIXES.find((p) => model.startsWith(p))\n}\n\n/**\n * After a tracked call, check if there is a cheaper model in the same provider family\n * (defined by model name prefix). Logs a hint if savings are strictly greater than 50%.\n * No-ops if the model is unknown, costUSD is zero, or no cheaper candidate is found.\n */\nexport function maybeSuggestCheaperModel(\n model: string,\n costUSD: number,\n inputTokens: number,\n outputTokens: number,\n layers: { bundledPrices: PriceMap; customPrices?: PriceMap; remotePrices?: PriceMap },\n): void {\n if (costUSD <= 0) return\n\n const prefix = getProviderPrefix(model)\n if (!prefix) return\n\n // Merge layers: bundled < remote < custom (custom wins)\n const mergedMap: PriceMap = {\n ...layers.bundledPrices,\n ...(layers.remotePrices ?? {}),\n ...(layers.customPrices ?? {}),\n }\n\n let cheapestModel: string | undefined\n let cheapestCost = Infinity\n\n for (const key of Object.keys(mergedMap)) {\n if (key === model || !key.startsWith(prefix)) continue\n const price = mergedMap[key]\n if (!price) continue\n const candidateCost = calculateCost(inputTokens, outputTokens, price)\n if (candidateCost < cheapestCost) {\n cheapestCost = candidateCost\n cheapestModel = key\n }\n }\n\n // Must be strictly more than 50% cheaper\n if (cheapestModel === undefined || cheapestCost >= costUSD * 0.5) return\n\n const savingsPct = Math.round((1 - cheapestCost / costUSD) * 100)\n console.log(\n `[tokenwatch] Suggestion: ${cheapestModel} could handle this for ~$${cheapestCost.toFixed(4)} (${savingsPct}% cheaper than ${model})`,\n )\n}\n","import { createRequire } from 'node:module'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { mkdirSync } from 'node:fs'\nimport type { IStorage, UsageEntry } from '../types/index.js'\n\n// ─── Memory storage ───────────────────────────────────────────────────────────\n\nexport class MemoryStorage implements IStorage {\n private entries: UsageEntry[] = []\n\n record(entry: UsageEntry): void {\n this.entries.push(entry)\n }\n\n getAll(): UsageEntry[] {\n return [...this.entries]\n }\n\n clearAll(): void {\n this.entries = []\n }\n\n clearSession(sessionId: string): void {\n this.entries = this.entries.filter((e) => e.sessionId !== sessionId)\n }\n}\n\n// ─── SQLite storage ───────────────────────────────────────────────────────────\n\nconst DB_DIR = join(homedir(), '.tokenwatch')\nconst DB_PATH = join(DB_DIR, 'usage.db')\n\nexport class SqliteStorage implements IStorage {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private db: any\n\n constructor(dbPath = DB_PATH) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let BetterSqlite3: any\n try {\n // In CJS context globalThis.require is the native require; in ESM use createRequire.\n // This makes the lazy load work in both output formats produced by tsup.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const req: NodeRequire =\n typeof (globalThis as any).require === 'function'\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (globalThis as any).require\n : createRequire(import.meta.url)\n BetterSqlite3 = req('better-sqlite3')\n } catch {\n throw new Error(\n '[tokenwatch] SQLite storage requires better-sqlite3. ' +\n 'Run: npm install better-sqlite3',\n )\n }\n\n mkdirSync(DB_DIR, { recursive: true })\n this.db = new BetterSqlite3(dbPath)\n this.migrate()\n }\n\n private migrate(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS usage (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n reasoning_tokens INTEGER NOT NULL DEFAULT 0,\n cached_tokens INTEGER NOT NULL DEFAULT 0,\n cache_creation_tokens INTEGER NOT NULL DEFAULT 0,\n cost_usd REAL NOT NULL,\n session_id TEXT,\n user_id TEXT,\n feature TEXT,\n timestamp TEXT NOT NULL\n )\n `)\n // Incremental migrations for databases created before v0.2.0 / v0.3.0\n const cols = (this.db.prepare(`PRAGMA table_info(usage)`).all() as Array<{ name: string }>)\n .map((c) => c.name)\n if (!cols.includes('reasoning_tokens')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN reasoning_tokens INTEGER NOT NULL DEFAULT 0`)\n }\n if (!cols.includes('feature')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN feature TEXT`)\n }\n if (!cols.includes('cached_tokens')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN cached_tokens INTEGER NOT NULL DEFAULT 0`)\n }\n if (!cols.includes('cache_creation_tokens')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN cache_creation_tokens INTEGER NOT NULL DEFAULT 0`)\n }\n }\n\n record(entry: UsageEntry): void {\n this.db\n .prepare(\n `INSERT INTO usage\n (model, input_tokens, output_tokens, reasoning_tokens, cached_tokens, cache_creation_tokens,\n cost_usd, session_id, user_id, feature, timestamp)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.model,\n entry.inputTokens,\n entry.outputTokens,\n entry.reasoningTokens ?? 0,\n entry.cachedTokens ?? 0,\n entry.cacheCreationTokens ?? 0,\n entry.costUSD,\n entry.sessionId ?? null,\n entry.userId ?? null,\n entry.feature ?? null,\n entry.timestamp,\n )\n }\n\n getAll(): UsageEntry[] {\n const rows = this.db.prepare('SELECT * FROM usage ORDER BY timestamp ASC').all() as Array<{\n model: string\n input_tokens: number\n output_tokens: number\n reasoning_tokens: number\n cached_tokens: number\n cache_creation_tokens: number\n cost_usd: number\n session_id: string | null\n user_id: string | null\n feature: string | null\n timestamp: string\n }>\n\n return rows.map((r) => ({\n model: r.model,\n inputTokens: r.input_tokens,\n outputTokens: r.output_tokens,\n ...(r.reasoning_tokens > 0 && { reasoningTokens: r.reasoning_tokens }),\n ...(r.cached_tokens > 0 && { cachedTokens: r.cached_tokens }),\n ...(r.cache_creation_tokens > 0 && { cacheCreationTokens: r.cache_creation_tokens }),\n costUSD: r.cost_usd,\n ...(r.session_id != null && { sessionId: r.session_id }),\n ...(r.user_id != null && { userId: r.user_id }),\n ...(r.feature != null && { feature: r.feature }),\n timestamp: r.timestamp,\n }))\n }\n\n clearAll(): void {\n this.db.exec('DELETE FROM usage')\n }\n\n clearSession(sessionId: string): void {\n this.db.prepare('DELETE FROM usage WHERE session_id = ?').run(sessionId)\n }\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\nexport function createStorage(type: 'memory' | 'sqlite'): IStorage {\n if (type === 'sqlite') return new SqliteStorage()\n return new MemoryStorage()\n}\n","import { readFile, writeFile, mkdir } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport type { PricesFile, PriceMap } from '../types/index.js'\n\nconst CACHE_DIR = join(homedir(), '.tokenwatch')\nconst CACHE_FILE = join(CACHE_DIR, 'prices.json')\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000 // 24 hours\nconst REMOTE_URL =\n 'https://raw.githubusercontent.com/diogonzafe/tokenwatch/main/prices.json'\n\nexport interface PricesResult {\n models: PriceMap\n updated_at: string\n}\n\nexport async function fetchRemotePrices(url = REMOTE_URL): Promise<PricesResult | null> {\n try {\n const res = await fetch(url, { signal: AbortSignal.timeout(8_000) })\n if (!res.ok) return null\n const data = (await res.json()) as PricesFile\n if (!data?.models) return null\n await persistCache(data)\n return { models: data.models, updated_at: data.updated_at ?? '' }\n } catch {\n return null\n }\n}\n\nexport async function loadCachedPrices(): Promise<PricesResult | null> {\n if (!existsSync(CACHE_FILE)) return null\n try {\n const raw = await readFile(CACHE_FILE, 'utf8')\n const data = JSON.parse(raw) as PricesFile & { _cachedAt?: number }\n const age = Date.now() - (data._cachedAt ?? 0)\n if (age > CACHE_TTL_MS) return null\n if (!data.models) return null\n return { models: data.models, updated_at: data.updated_at ?? '' }\n } catch {\n return null\n }\n}\n\nasync function persistCache(data: PricesFile): Promise<void> {\n try {\n await mkdir(CACHE_DIR, { recursive: true })\n const payload = { ...data, _cachedAt: Date.now() }\n await writeFile(CACHE_FILE, JSON.stringify(payload, null, 2), 'utf8')\n } catch {\n // best-effort — never throw\n }\n}\n\n/**\n * Returns the best available remote price result:\n * 1. Valid local cache (< 24h)\n * 2. Fresh remote fetch (also updates cache)\n * 3. null if both fail\n */\nexport async function getRemotePrices(): Promise<PricesResult | null> {\n const cached = await loadCachedPrices()\n if (cached) return cached\n return fetchRemotePrices()\n}\n","{\n \"updated_at\": \"2026-04-23\",\n \"source\": \"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json\",\n \"models\": {\n \"gpt-4o\": {\n \"input\": 2.5,\n \"output\": 10,\n \"cachedInput\": 1.25,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 128000\n },\n \"gpt-5\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-mini\": {\n \"input\": 0.25,\n \"output\": 2,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-nano\": {\n \"input\": 0.05,\n \"output\": 0.4,\n \"cachedInput\": 0.005,\n \"maxInputTokens\": 272000\n },\n \"claude-opus-4-6\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-6\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"claude-haiku-4-5\": {\n \"input\": 1,\n \"output\": 5,\n \"cachedInput\": 0.1,\n \"cacheCreationInput\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"gemini-2.5-pro\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.03,\n \"maxInputTokens\": 1048576\n },\n \"deepseek-chat\": {\n \"input\": 0.28,\n \"output\": 0.42,\n \"cachedInput\": 0.028,\n \"maxInputTokens\": 131072\n },\n \"deepseek-reasoner\": {\n \"input\": 0.28,\n \"output\": 0.42,\n \"cachedInput\": 0.028,\n \"maxInputTokens\": 131072\n },\n \"claude-opus-4-5\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-7\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-1\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4-5\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"gpt-oss-120b\": {\n \"input\": 3,\n \"output\": 4.5,\n \"maxInputTokens\": 131072\n },\n \"gpt-3.5-turbo\": {\n \"input\": 0.5,\n \"output\": 1.5,\n \"maxInputTokens\": 16385\n },\n \"gpt-3.5-turbo-0125\": {\n \"input\": 0.5,\n \"output\": 1.5,\n \"maxInputTokens\": 16385\n },\n \"gpt-35-turbo\": {\n \"input\": 0.5,\n \"output\": 1.5,\n \"maxInputTokens\": 4097\n },\n \"gpt-35-turbo-0125\": {\n \"input\": 0.5,\n \"output\": 1.5,\n \"maxInputTokens\": 16384\n },\n \"gpt-35-turbo-1106\": {\n \"input\": 1,\n \"output\": 2,\n \"maxInputTokens\": 16384\n },\n \"gpt-35-turbo-16k\": {\n \"input\": 3,\n \"output\": 4,\n \"maxInputTokens\": 16385\n },\n \"gpt-35-turbo-16k-0613\": {\n \"input\": 3,\n \"output\": 4,\n \"maxInputTokens\": 16385\n },\n \"gpt-4\": {\n \"input\": 30,\n \"output\": 60,\n \"maxInputTokens\": 8192\n },\n \"gpt-4-0125-preview\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4-0613\": {\n \"input\": 30,\n \"output\": 60,\n \"maxInputTokens\": 8192\n },\n \"gpt-4-1106-preview\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4-32k\": {\n \"input\": 60,\n \"output\": 120,\n \"maxInputTokens\": 32768\n },\n \"gpt-4-32k-0613\": {\n \"input\": 60,\n \"output\": 120,\n \"maxInputTokens\": 32768\n },\n \"gpt-4-turbo\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4-turbo-2024-04-09\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4-turbo-vision-preview\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4.1\": {\n \"input\": 2,\n \"output\": 8,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-2025-04-14\": {\n \"input\": 2,\n \"output\": 8,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-mini\": {\n \"input\": 0.4,\n \"output\": 1.6,\n \"cachedInput\": 0.1,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-mini-2025-04-14\": {\n \"input\": 0.4,\n \"output\": 1.6,\n \"cachedInput\": 0.1,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-nano\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-nano-2025-04-14\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.5-preview\": {\n \"input\": 75,\n \"output\": 150,\n \"cachedInput\": 37.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-2024-05-13\": {\n \"input\": 5,\n \"output\": 15,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-2024-08-06\": {\n \"input\": 2.5,\n \"output\": 10,\n \"cachedInput\": 1.25,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-2024-11-20\": {\n \"input\": 2.5,\n \"output\": 10,\n \"cachedInput\": 1.25,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-2025-08-28\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-1.5-2026-02-23\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-mini-2025-10-06\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-audio-preview-2024-12-17\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-2024-07-18\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-audio-preview-2024-12-17\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-realtime-preview-2024-12-17\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"cachedInput\": 0.3,\n \"maxInputTokens\": 128000\n },\n \"gpt-realtime-2025-08-28\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 0.4,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-1.5-2026-02-23\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 4,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-mini-2025-10-06\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"cachedInput\": 0.06,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-transcribe\": {\n \"input\": 1.25,\n \"output\": 5,\n \"maxInputTokens\": 16000\n },\n \"gpt-4o-realtime-preview-2024-10-01\": {\n \"input\": 5,\n \"output\": 20,\n \"cachedInput\": 2.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview-2024-12-17\": {\n \"input\": 5,\n \"output\": 20,\n \"cachedInput\": 2.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-transcribe\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 16000\n },\n \"gpt-4o-transcribe-diarize\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 16000\n },\n \"gpt-5.1-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-chat-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1-codex-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-mini-2025-11-13\": {\n \"input\": 0.25,\n \"output\": 2,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-2025-08-07\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-chat\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-chat-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-codex\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-mini-2025-08-07\": {\n \"input\": 0.25,\n \"output\": 2,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-nano-2025-08-07\": {\n \"input\": 0.05,\n \"output\": 0.4,\n \"cachedInput\": 0.005,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-pro\": {\n \"input\": 15,\n \"output\": 120,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-chat\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1-codex\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-max\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-mini\": {\n \"input\": 0.25,\n \"output\": 2,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-2025-12-11\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-chat\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-chat-2025-12-11\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-codex\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.3-chat\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.3-codex\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-pro\": {\n \"input\": 21,\n \"output\": 168,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-pro-2025-12-11\": {\n \"input\": 21,\n \"output\": 168,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.4\": {\n \"input\": 2.5,\n \"output\": 15,\n \"cachedInput\": 0.25,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-2026-03-05\": {\n \"input\": 2.5,\n \"output\": 15,\n \"cachedInput\": 0.25,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-pro\": {\n \"input\": 30,\n \"output\": 180,\n \"cachedInput\": 3,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-pro-2026-03-05\": {\n \"input\": 30,\n \"output\": 180,\n \"cachedInput\": 3,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-mini\": {\n \"input\": 0.75,\n \"output\": 4.5,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.4-nano\": {\n \"input\": 0.2,\n \"output\": 1.25,\n \"cachedInput\": 0.02,\n \"maxInputTokens\": 272000\n },\n \"o1-2024-12-17\": {\n \"input\": 15,\n \"output\": 60,\n \"cachedInput\": 7.5,\n \"maxInputTokens\": 200000\n },\n \"o1-mini\": {\n \"input\": 1.21,\n \"output\": 4.84,\n \"cachedInput\": 0.605,\n \"maxInputTokens\": 128000\n },\n \"o1-mini-2024-09-12\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.55,\n \"maxInputTokens\": 128000\n },\n \"o1-preview\": {\n \"input\": 15,\n \"output\": 60,\n \"cachedInput\": 7.5,\n \"maxInputTokens\": 128000\n },\n \"o1-preview-2024-09-12\": {\n \"input\": 15,\n \"output\": 60,\n \"cachedInput\": 7.5,\n \"maxInputTokens\": 128000\n },\n \"o3-2025-04-16\": {\n \"input\": 2,\n \"output\": 8,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 200000\n },\n \"o3-mini\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.55,\n \"maxInputTokens\": 200000\n },\n \"o3-mini-2025-01-31\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.55,\n \"maxInputTokens\": 200000\n },\n \"o3-pro\": {\n \"input\": 20,\n \"output\": 80,\n \"maxInputTokens\": 200000\n },\n \"o3-pro-2025-06-10\": {\n \"input\": 20,\n \"output\": 80,\n \"maxInputTokens\": 200000\n },\n \"o4-mini\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.275,\n \"maxInputTokens\": 200000\n },\n \"o4-mini-2025-04-16\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.275,\n \"maxInputTokens\": 200000\n },\n \"deepseek-v3.2\": {\n \"input\": 0.28,\n \"output\": 0.4,\n \"maxInputTokens\": 163840\n },\n \"deepseek-v3.2-speciale\": {\n \"input\": 0.58,\n \"output\": 1.68,\n \"maxInputTokens\": 163840\n },\n \"deepseek-r1\": {\n \"input\": 0.55,\n \"output\": 2.19,\n \"maxInputTokens\": 65536\n },\n \"deepseek-v3\": {\n \"input\": 0.27,\n \"output\": 1.1,\n \"cachedInput\": 0.07,\n \"maxInputTokens\": 65536\n },\n \"deepseek-v3-0324\": {\n \"input\": 0.2,\n \"output\": 0.6,\n \"maxInputTokens\": 131072\n },\n \"chatgpt-4o-latest\": {\n \"input\": 5,\n \"output\": 15,\n \"maxInputTokens\": 128000\n },\n \"claude-haiku-4-5-20251001\": {\n \"input\": 1,\n \"output\": 5,\n \"cachedInput\": 0.1,\n \"cacheCreationInput\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"claude-3-7-sonnet-20250219\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-3-haiku-20240307\": {\n \"input\": 0.25,\n \"output\": 1.25,\n \"cachedInput\": 0.03,\n \"cacheCreationInput\": 0.3,\n \"maxInputTokens\": 200000\n },\n \"claude-3-opus-20240229\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-4-opus-20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-4-sonnet-20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-5-20250929\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4-5-20250929-v1:0\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-1-20250805\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-5-20251101\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-6-20260205\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-7-20260416\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"codex-mini-latest\": {\n \"input\": 1.5,\n \"output\": 6,\n \"cachedInput\": 0.375,\n \"maxInputTokens\": 200000\n },\n \"deepseek-ai/deepseek-r1\": {\n \"input\": 3,\n \"output\": 7,\n \"maxInputTokens\": 128000\n },\n \"deepseek-ai/deepseek-r1-0528\": {\n \"input\": 135000,\n \"output\": 540000,\n \"maxInputTokens\": 161000\n },\n \"deepseek-ai/deepseek-r1-0528-turbo\": {\n \"input\": 1,\n \"output\": 3,\n \"maxInputTokens\": 32768\n },\n \"deepseek-ai/deepseek-r1-distill-llama-70b\": {\n \"input\": 0.25,\n \"output\": 0.75,\n \"maxInputTokens\": 128000\n },\n \"deepseek-ai/deepseek-r1-distill-qwen-32b\": {\n \"input\": 0.15,\n \"output\": 0.15\n },\n \"deepseek-ai/deepseek-r1-turbo\": {\n \"input\": 1,\n \"output\": 3,\n \"maxInputTokens\": 40960\n },\n \"deepseek-ai/deepseek-v3\": {\n \"input\": 1.25,\n \"output\": 1.25,\n \"maxInputTokens\": 65536\n },\n \"deepseek-ai/deepseek-v3-0324\": {\n \"input\": 114000,\n \"output\": 275000,\n \"maxInputTokens\": 161000\n },\n \"deepseek-ai/deepseek-v3.1\": {\n \"input\": 55000,\n \"output\": 165000,\n \"maxInputTokens\": 128000\n },\n \"deepseek-ai/deepseek-v3.1-terminus\": {\n \"input\": 0.27,\n \"output\": 1,\n \"cachedInput\": 0.216,\n \"maxInputTokens\": 163840\n },\n \"deepseek-coder\": {\n \"input\": 0.14,\n \"output\": 0.28,\n \"maxInputTokens\": 128000\n },\n \"gemini-2.0-flash\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-001\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-lite\": {\n \"input\": 0.075,\n \"output\": 0.3,\n \"cachedInput\": 0.01875,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-lite-001\": {\n \"input\": 0.075,\n \"output\": 0.3,\n \"cachedInput\": 0.01875,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-image\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.03,\n \"maxInputTokens\": 32768\n },\n \"gemini-3-pro-image-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"maxInputTokens\": 65536\n },\n \"gemini-3.1-flash-image-preview\": {\n \"input\": 0.5,\n \"output\": 3,\n \"maxInputTokens\": 65536\n },\n \"gemini-3.1-flash-lite-preview\": {\n \"input\": 0.25,\n \"output\": 1.5,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.01,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite-preview-09-2025\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.01,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-preview-09-2025\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 1048576\n },\n \"gemini-live-2.5-flash-preview-native-audio-09-2025\": {\n \"input\": 0.3,\n \"output\": 2,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite-preview-06-17\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3-pro-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"cachedInput\": 0.2,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-pro-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"cachedInput\": 0.2,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-pro-preview-customtools\": {\n \"input\": 2,\n \"output\": 12,\n \"cachedInput\": 0.2,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3-flash-preview\": {\n \"input\": 0.5,\n \"output\": 3,\n \"cachedInput\": 0.05,\n \"maxInputTokens\": 1048576\n },\n \"gemini-robotics-er-1.5-preview\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-computer-use-preview-10-2025\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gemini-flash-latest\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.03,\n \"maxInputTokens\": 1048576\n },\n \"gemini-flash-lite-latest\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.01,\n \"maxInputTokens\": 1048576\n },\n \"gemini-gemma-2-27b-it\": {\n \"input\": 0.35,\n \"output\": 1.05,\n \"maxInputTokens\": 8192\n },\n \"gemini-gemma-2-9b-it\": {\n \"input\": 0.35,\n \"output\": 1.05,\n \"maxInputTokens\": 8192\n },\n \"deepseek-ai/deepseek-v3.2\": {\n \"input\": 0.28,\n \"output\": 0.4,\n \"maxInputTokens\": 163840\n },\n \"gpt-3.5-turbo-1106\": {\n \"input\": 1,\n \"output\": 2,\n \"maxInputTokens\": 16385\n },\n \"gpt-3.5-turbo-16k\": {\n \"input\": 3,\n \"output\": 4,\n \"maxInputTokens\": 16385\n },\n \"gpt-4-0314\": {\n \"input\": 30,\n \"output\": 60,\n \"maxInputTokens\": 8192\n },\n \"gpt-4-turbo-preview\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-audio-preview\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-audio-preview-2025-06-03\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-1.5\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-mini\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-mini-2025-12-15\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-audio-preview\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-realtime-preview\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"cachedInput\": 0.3,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview\": {\n \"input\": 5,\n \"output\": 20,\n \"cachedInput\": 2.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview-2025-06-03\": {\n \"input\": 5,\n \"output\": 20,\n \"cachedInput\": 2.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-image-1.5\": {\n \"input\": 5,\n \"output\": 10,\n \"cachedInput\": 1.25\n },\n \"gpt-image-1.5-2025-12-16\": {\n \"input\": 5,\n \"output\": 10,\n \"cachedInput\": 1.25\n },\n \"gpt-5.1-chat-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-chat-latest\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.3-chat-latest\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-pro-2025-10-06\": {\n \"input\": 15,\n \"output\": 120,\n \"maxInputTokens\": 128000\n },\n \"gpt-realtime\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 0.4,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-1.5\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 0.4,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-mini\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"maxInputTokens\": 128000\n },\n \"deepseek-r1-distill-llama-70b\": {\n \"input\": 0.99,\n \"output\": 0.99,\n \"maxInputTokens\": 8000\n },\n \"deepseek-llama3.3-70b\": {\n \"input\": 0.2,\n \"output\": 0.6,\n \"maxInputTokens\": 131072\n },\n \"deepseek-r1-0528\": {\n \"input\": 0.2,\n \"output\": 0.6,\n \"maxInputTokens\": 131072\n },\n \"deepseek-r1-671b\": {\n \"input\": 0.8,\n \"output\": 0.8,\n \"maxInputTokens\": 131072\n },\n \"deepseek-ai/deepseek-r1-distill-llama-8b\": {\n \"input\": 0.025,\n \"output\": 0.025\n },\n \"deepseek-ai/deepseek-r1-distill-qwen-1.5b\": {\n \"input\": 0.09,\n \"output\": 0.09\n },\n \"deepseek-ai/deepseek-r1-distill-qwen-14b\": {\n \"input\": 0.07,\n \"output\": 0.07\n },\n \"deepseek-ai/deepseek-r1-distill-qwen-7b\": {\n \"input\": 0.2,\n \"output\": 0.2\n },\n \"o1\": {\n \"input\": 15,\n \"output\": 60,\n \"cachedInput\": 7.5,\n \"maxInputTokens\": 200000\n },\n \"o1-pro\": {\n \"input\": 150,\n \"output\": 600,\n \"maxInputTokens\": 200000\n },\n \"o1-pro-2025-03-19\": {\n \"input\": 150,\n \"output\": 600,\n \"maxInputTokens\": 200000\n },\n \"o3\": {\n \"input\": 2,\n \"output\": 8,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 200000\n },\n \"gpt-oss-20b\": {\n \"input\": 0.09,\n \"output\": 0.36\n },\n \"deepseek-ai/deepseek-r1-0528-tput\": {\n \"input\": 0.55,\n \"output\": 2.19,\n \"maxInputTokens\": 128000\n },\n \"claude-3-5-haiku\": {\n \"input\": 1,\n \"output\": 5,\n \"maxInputTokens\": 200000\n },\n \"claude-3-5-haiku@20241022\": {\n \"input\": 1,\n \"output\": 5,\n \"maxInputTokens\": 200000\n },\n \"claude-haiku-4-5@20251001\": {\n \"input\": 1,\n \"output\": 5,\n \"cachedInput\": 0.1,\n \"cacheCreationInput\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"claude-3-5-sonnet\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-3-5-sonnet@20240620\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-3-7-sonnet@20250219\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-3-haiku\": {\n \"input\": 0.25,\n \"output\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"claude-3-haiku@20240307\": {\n \"input\": 0.25,\n \"output\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"claude-3-opus\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-3-opus@20240229\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-3-sonnet\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-3-sonnet@20240229\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-1@20250805\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-5@20251101\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-6@default\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-7@default\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-5@20250929\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4@20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4@20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"deepseek-ai/deepseek-v3.1-maas\": {\n \"input\": 1.35,\n \"output\": 5.4,\n \"maxInputTokens\": 163840\n },\n \"deepseek-ai/deepseek-v3.2-maas\": {\n \"input\": 0.56,\n \"output\": 1.68,\n \"maxInputTokens\": 163840\n },\n \"deepseek-ai/deepseek-r1-0528-maas\": {\n \"input\": 1.35,\n \"output\": 5.4,\n \"maxInputTokens\": 65336\n },\n \"deepseek-ai/deepseek-ocr-maas\": {\n \"input\": 0.3,\n \"output\": 1.2\n },\n \"deepseek-r1-8b\": {\n \"input\": 0.1,\n \"output\": 0.2,\n \"maxInputTokens\": 65536\n },\n \"deepseek-r1-7b-qwen\": {\n \"input\": 0.08,\n \"output\": 0.15,\n \"maxInputTokens\": 131072\n },\n \"deepseek-coder-6.7b\": {\n \"input\": 0.06,\n \"output\": 0.12,\n \"maxInputTokens\": 16384\n },\n \"gpt-4o-mini-transcribe-2025-03-20\": {\n \"input\": 1.25,\n \"output\": 5,\n \"maxInputTokens\": 16000\n },\n \"gpt-4o-mini-transcribe-2025-12-15\": {\n \"input\": 1.25,\n \"output\": 5,\n \"maxInputTokens\": 16000\n },\n \"gpt-realtime-mini-2025-12-15\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"cachedInput\": 0.06,\n \"maxInputTokens\": 128000\n },\n \"gemini-2.5-flash-native-audio-latest\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-native-audio-preview-09-2025\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-native-audio-preview-12-2025\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-flash-live-preview\": {\n \"input\": 0.75,\n \"output\": 4.5,\n \"maxInputTokens\": 131072\n },\n \"gemini-pro-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 1048576\n },\n \"gemini-exp-1206\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.03,\n \"maxInputTokens\": 1048576\n },\n \"claude-sonnet-4-6@default\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n }\n }\n}\n","import type {\n Tracker,\n TrackerConfig,\n LazyTracker,\n Report,\n CostForecast,\n ModelPrice,\n ReportOptions,\n ForecastOptions,\n} from '../types/index.js'\nimport { createTracker } from './tracker.js'\n\nconst CSV_HEADER =\n 'timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature'\n\nfunction emptyReport(): Report {\n const now = new Date().toISOString()\n return {\n totalCostUSD: 0,\n totalTokens: { input: 0, output: 0 },\n byModel: {},\n bySession: {},\n byUser: {},\n byFeature: {},\n period: { from: now, to: now },\n }\n}\n\nfunction zeroForecast(): CostForecast {\n return {\n burnRatePerHour: 0,\n projectedDailyCostUSD: 0,\n projectedMonthlyCostUSD: 0,\n basedOnHours: 0,\n basedOnPeriod: null,\n }\n}\n\n/**\n * Creates a lazy tracker that acts as a silent no-op until `init()` is called.\n *\n * Ideal for module-level singletons where the tracker is imported before `createTracker()`\n * can be called (e.g. Jest test environments, top-level module imports).\n *\n * @example\n * // tracker.ts — safe to import anywhere, even before init\n * export const tracker = createLazyTracker()\n *\n * // app.ts — initialize once at startup\n * tracker.init({ storage: 'sqlite', syncPrices: true })\n *\n * // test.ts — never call init() and track() becomes a silent no-op\n */\nexport function createLazyTracker(): LazyTracker {\n let delegate: Tracker | null = null\n\n return {\n init(config?: TrackerConfig): void {\n if (delegate !== null) {\n throw new Error(\n '[tokenwatch] LazyTracker already initialized. init() may only be called once.',\n )\n }\n try {\n delegate = createTracker(config ?? {})\n } catch (err) {\n // Leave delegate as null — tracker stays in no-op mode after a failed init\n throw err\n }\n },\n\n track(entry) {\n delegate?.track(entry)\n },\n\n async getReport(options?: ReportOptions): Promise<Report> {\n return delegate?.getReport(options) ?? emptyReport()\n },\n\n async getCostForecast(options?: ForecastOptions): Promise<CostForecast> {\n return delegate?.getCostForecast(options) ?? zeroForecast()\n },\n\n async reset(): Promise<void> {\n await delegate?.reset()\n },\n\n async resetSession(sessionId: string): Promise<void> {\n await delegate?.resetSession(sessionId)\n },\n\n async exportJSON(): Promise<string> {\n return delegate?.exportJSON() ?? '{}'\n },\n\n async exportCSV(): Promise<string> {\n return delegate?.exportCSV() ?? CSV_HEADER\n },\n\n getModelInfo(model: string): ModelPrice | null {\n return delegate?.getModelInfo(model) ?? null\n },\n }\n}\n","import type { Tracker, TrackingMeta } from '../types/index.js'\n\n// ─── Minimal structural types (no hard dep on openai package) ────────────────\n\ninterface CompletionTokenDetails {\n reasoning_tokens?: number\n}\n\ninterface PromptTokenDetails {\n cached_tokens?: number\n}\n\ninterface Usage {\n prompt_tokens?: number\n completion_tokens?: number\n input_tokens?: number\n output_tokens?: number\n completion_tokens_details?: CompletionTokenDetails | null\n prompt_tokens_details?: PromptTokenDetails | null\n}\n\ninterface Completion {\n model?: string\n usage?: Usage | null\n}\n\ninterface StreamChunk {\n model?: string\n usage?: Usage | null\n}\n\ninterface CompletionsLike {\n create(params: Record<string, unknown>): Promise<unknown>\n}\n\ninterface ChatLike {\n completions: CompletionsLike\n}\n\ninterface EmbeddingUsage {\n prompt_tokens?: number\n total_tokens?: number\n}\n\ninterface EmbeddingResponse {\n model?: string\n usage?: EmbeddingUsage | null\n}\n\ninterface EmbeddingsLike {\n create(params: Record<string, unknown>): Promise<unknown>\n}\n\ntype OpenAILike = { chat: ChatLike; embeddings?: EmbeddingsLike } & Record<string, unknown>\n\n// ─── Augmented return type ────────────────────────────────────────────────────\n\ntype AugmentedCreate<TCreate extends (...args: any[]) => any> = (\n params: Parameters<TCreate>[0] & TrackingMeta,\n) => ReturnType<TCreate>\n\ntype WrappedOpenAI<T extends OpenAILike> = Omit<T, 'chat' | 'embeddings'> & {\n chat: Omit<T['chat'], 'completions'> & {\n completions: Omit<T['chat']['completions'], 'create'> & {\n create: AugmentedCreate<T['chat']['completions']['create']>\n }\n }\n embeddings: T['embeddings'] extends EmbeddingsLike\n ? Omit<T['embeddings'], 'create'> & {\n create: AugmentedCreate<T['embeddings']['create']>\n }\n : T['embeddings']\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction extractMeta(params: Record<string, unknown>): {\n cleaned: Record<string, unknown>\n sessionId: string | undefined\n userId: string | undefined\n feature: string | undefined\n} {\n const { __sessionId, __userId, __feature, ...cleaned } = params as Record<string, unknown> & TrackingMeta\n return {\n cleaned,\n sessionId: typeof __sessionId === 'string' ? __sessionId : undefined,\n userId: typeof __userId === 'string' ? __userId : undefined,\n feature: typeof __feature === 'string' ? __feature : undefined,\n }\n}\n\nfunction extractUsage(usage: Usage | null | undefined): {\n inputTokens: number\n outputTokens: number\n reasoningTokens: number\n cachedTokens: number\n} {\n if (!usage) return { inputTokens: 0, outputTokens: 0, reasoningTokens: 0, cachedTokens: 0 }\n const totalInput = usage.prompt_tokens ?? usage.input_tokens ?? 0\n const cachedTokens = usage.prompt_tokens_details?.cached_tokens ?? 0\n return {\n // inputTokens = regular (non-cached) input; OpenAI prompt_tokens includes cached tokens\n inputTokens: totalInput - cachedTokens,\n outputTokens: usage.completion_tokens ?? usage.output_tokens ?? 0,\n reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,\n cachedTokens,\n }\n}\n\nfunction trackWithMeta(\n tracker: Tracker,\n model: string,\n inputTokens: number,\n outputTokens: number,\n reasoningTokens: number,\n sessionId: string | undefined,\n userId: string | undefined,\n feature: string | undefined,\n cachedTokens = 0,\n): void {\n // OpenAI bills reasoning_tokens at output price, separately from completion_tokens.\n // We fold them into outputTokens so the cost is correct, and also store them in\n // reasoningTokens so report.byModel[x].tokens.reasoning shows the breakdown.\n tracker.track({\n model,\n inputTokens,\n outputTokens: outputTokens + reasoningTokens,\n ...(reasoningTokens > 0 && { reasoningTokens }),\n ...(cachedTokens > 0 && { cachedTokens }),\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n}\n\n// ─── Streaming wrapper ────────────────────────────────────────────────────────\n\nasync function* wrapStream(\n stream: AsyncIterable<StreamChunk>,\n model: string,\n sessionId: string | undefined,\n userId: string | undefined,\n feature: string | undefined,\n tracker: Tracker,\n): AsyncGenerator<StreamChunk> {\n let lastChunk: StreamChunk | undefined\n for await (const chunk of stream) {\n lastChunk = chunk\n yield chunk\n }\n const { inputTokens, outputTokens, reasoningTokens, cachedTokens } = extractUsage(lastChunk?.usage)\n if (!lastChunk?.usage) {\n console.warn(\n `[tokenwatch] No usage data in stream for model \"${model}\". Cost recorded as $0. ` +\n `Pass stream_options: { include_usage: true } to get accurate costs.`,\n )\n }\n trackWithMeta(tracker, model, inputTokens, outputTokens, reasoningTokens, sessionId, userId, feature, cachedTokens)\n}\n\n// ─── Public wrapper ───────────────────────────────────────────────────────────\n\n/**\n * Wraps an OpenAI client (or any OpenAI-compatible client) to transparently\n * intercept chat.completions.create and embeddings.create calls and report\n * token usage to the tracker.\n *\n * The returned client is typed to accept __sessionId, __userId, and __feature\n * alongside the normal params — no type cast required at the call site.\n */\nexport function wrapOpenAI<T extends OpenAILike>(client: T, tracker: Tracker): WrappedOpenAI<T> {\n const proxiedCompletions = new Proxy(client.chat.completions, {\n get(target, prop) {\n if (prop !== 'create')\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n\n return async function (params: Record<string, unknown>) {\n const { cleaned, sessionId, userId, feature } = extractMeta(params)\n const model = typeof cleaned['model'] === 'string' ? cleaned['model'] : 'unknown'\n\n const result = await (target as CompletionsLike).create(cleaned)\n\n if (result && typeof result === 'object' && Symbol.asyncIterator in result) {\n return wrapStream(\n result as AsyncIterable<StreamChunk>,\n model,\n sessionId,\n userId,\n feature,\n tracker,\n )\n }\n\n const completion = result as Completion\n const { inputTokens, outputTokens, reasoningTokens, cachedTokens } = extractUsage(completion.usage)\n trackWithMeta(\n tracker,\n completion.model ?? model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n sessionId,\n userId,\n feature,\n cachedTokens,\n )\n\n return result\n }\n },\n })\n\n const proxiedChat = new Proxy(client.chat, {\n get(target, prop) {\n if (prop === 'completions') return proxiedCompletions\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n },\n })\n\n // Only proxy embeddings if the client exposes them\n const proxiedEmbeddings = client.embeddings\n ? new Proxy(client.embeddings, {\n get(target, prop) {\n if (prop !== 'create')\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n\n return async function (params: Record<string, unknown>) {\n const { cleaned, sessionId, userId, feature } = extractMeta(params)\n const model = typeof cleaned['model'] === 'string' ? cleaned['model'] : 'unknown'\n\n const result = await (target as EmbeddingsLike).create(cleaned)\n\n const embedding = result as EmbeddingResponse\n const inputTokens = embedding.usage?.total_tokens ?? 0\n // Embeddings have no output tokens or reasoning tokens\n trackWithMeta(tracker, embedding.model ?? model, inputTokens, 0, 0, sessionId, userId, feature)\n\n return result\n }\n },\n })\n : undefined\n\n return new Proxy(client, {\n get(target, prop) {\n if (prop === 'chat') return proxiedChat\n if (prop === 'embeddings') return proxiedEmbeddings\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n },\n }) as unknown as WrappedOpenAI<T>\n}\n","import type { Tracker, TrackingMeta } from '../types/index.js'\n\n// ─── Minimal structural types ─────────────────────────────────────────────────\n\ninterface AnthropicUsage {\n input_tokens?: number\n output_tokens?: number\n /** Tokens read from prompt cache — billed at ~10% of input price */\n cache_read_input_tokens?: number\n /** Tokens written to prompt cache — billed at ~125% of input price */\n cache_creation_input_tokens?: number\n}\n\ninterface ContentBlock {\n type: string\n}\n\ninterface ThinkingBlock extends ContentBlock {\n type: 'thinking'\n thinking?: string\n}\n\ninterface AnthropicMessage {\n model?: string\n usage?: AnthropicUsage | null\n content?: ContentBlock[]\n}\n\ninterface AnthropicStreamEvent {\n type?: string\n usage?: AnthropicUsage | null\n message?: AnthropicMessage\n /** Emitted on content_block_start — describes the block type */\n content_block?: ContentBlock\n /** Emitted on content_block_delta — carries incremental content */\n delta?: { type?: string; thinking?: string; text?: string }\n}\n\ninterface MessagesLike {\n create(params: Record<string, unknown>): Promise<unknown>\n}\n\ntype AnthropicLike = { messages: MessagesLike } & Record<string, unknown>\n\n// ─── Augmented return type ────────────────────────────────────────────────────\n\ntype AugmentedCreate<TCreate extends (...args: any[]) => any> = (\n params: Parameters<TCreate>[0] & TrackingMeta,\n) => ReturnType<TCreate>\n\ntype WrappedAnthropic<T extends AnthropicLike> = Omit<T, 'messages'> & {\n messages: Omit<T['messages'], 'create'> & {\n create: AugmentedCreate<T['messages']['create']>\n }\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction extractMeta(params: Record<string, unknown>): {\n cleaned: Record<string, unknown>\n sessionId: string | undefined\n userId: string | undefined\n feature: string | undefined\n} {\n const { __sessionId, __userId, __feature, ...cleaned } = params as Record<string, unknown> & TrackingMeta\n return {\n cleaned,\n sessionId: typeof __sessionId === 'string' ? __sessionId : undefined,\n userId: typeof __userId === 'string' ? __userId : undefined,\n feature: typeof __feature === 'string' ? __feature : undefined,\n }\n}\n\nfunction extractUsage(usage: AnthropicUsage | null | undefined): {\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n cacheCreationTokens: number\n} {\n if (!usage) return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, cacheCreationTokens: 0 }\n return {\n inputTokens: usage.input_tokens ?? 0,\n outputTokens: usage.output_tokens ?? 0,\n cachedTokens: usage.cache_read_input_tokens ?? 0,\n cacheCreationTokens: usage.cache_creation_input_tokens ?? 0,\n }\n}\n\n/**\n * Anthropic extended thinking: count characters from thinking content blocks\n * and divide by 4 as a rough token approximation.\n *\n * Note: Anthropic already includes thinking output tokens inside outputTokens\n * (message_delta usage.output_tokens). The reasoningTokens value stored here\n * is INFORMATIONAL ONLY — it is NOT added to the cost calculation to avoid\n * double-counting.\n */\nfunction extractThinkingTokenApprox(content: ContentBlock[] | undefined): number {\n if (!content) return 0\n const chars = content\n .filter((b): b is ThinkingBlock => b.type === 'thinking')\n .reduce((sum, b) => sum + (b.thinking?.length ?? 0), 0)\n return chars > 0 ? Math.round(chars / 4) : 0\n}\n\nfunction trackWithMeta(\n tracker: Tracker,\n model: string,\n inputTokens: number,\n outputTokens: number,\n reasoningTokens: number,\n sessionId: string | undefined,\n userId: string | undefined,\n feature: string | undefined,\n cachedTokens = 0,\n cacheCreationTokens = 0,\n): void {\n // Anthropic thinking output is already included in outputTokens — no adjustment needed.\n // reasoningTokens here is an approximation (thinking chars ÷ 4) stored purely for\n // report.byModel[x].tokens.reasoning. The tracker does NOT add it to cost.\n tracker.track({\n model,\n inputTokens,\n outputTokens,\n ...(reasoningTokens > 0 && { reasoningTokens }),\n ...(cachedTokens > 0 && { cachedTokens }),\n ...(cacheCreationTokens > 0 && { cacheCreationTokens }),\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n}\n\n// ─── Streaming wrapper ────────────────────────────────────────────────────────\n\nasync function* wrapStream(\n stream: AsyncIterable<AnthropicStreamEvent>,\n model: string,\n sessionId: string | undefined,\n userId: string | undefined,\n feature: string | undefined,\n tracker: Tracker,\n): AsyncGenerator<AnthropicStreamEvent> {\n let inputTokens = 0\n let outputTokens = 0\n let cachedTokens = 0\n let cacheCreationTokens = 0\n let currentBlockIsThinking = false\n let thinkingCharCount = 0\n\n for await (const event of stream) {\n yield event\n\n if (event.type === 'message_start' && event.message?.usage) {\n inputTokens = event.message.usage.input_tokens ?? 0\n cachedTokens = event.message.usage.cache_read_input_tokens ?? 0\n cacheCreationTokens = event.message.usage.cache_creation_input_tokens ?? 0\n }\n if (event.type === 'message_delta' && event.usage) {\n outputTokens = event.usage.output_tokens ?? 0\n }\n\n // Track thinking blocks for informational reasoningTokens approximation\n if (event.type === 'content_block_start') {\n currentBlockIsThinking = event.content_block?.type === 'thinking'\n }\n if (event.type === 'content_block_stop') {\n currentBlockIsThinking = false\n }\n if (event.type === 'content_block_delta' && currentBlockIsThinking && event.delta?.thinking) {\n thinkingCharCount += event.delta.thinking.length\n }\n }\n\n // reasoningTokens is approximate and informational — Anthropic thinking output\n // is already included in outputTokens, so it is NOT added to cost by the tracker.\n const reasoningTokens = thinkingCharCount > 0 ? Math.round(thinkingCharCount / 4) : 0\n trackWithMeta(tracker, model, inputTokens, outputTokens, reasoningTokens, sessionId, userId, feature, cachedTokens, cacheCreationTokens)\n}\n\n// ─── Public wrapper ───────────────────────────────────────────────────────────\n\n/**\n * Wraps an Anthropic client to transparently intercept messages.create calls\n * and report token usage to the tracker.\n *\n * The returned client is typed to accept __sessionId, __userId, and __feature\n * alongside the normal params — no type cast required at the call site.\n *\n * For extended thinking models, reasoningTokens is stored as an approximation\n * (thinking block characters ÷ 4). It is informational only — thinking output\n * is already included in outputTokens and is not double-counted in cost.\n */\nexport function wrapAnthropic<T extends AnthropicLike>(\n client: T,\n tracker: Tracker,\n): WrappedAnthropic<T> {\n const proxiedMessages = new Proxy(client.messages, {\n get(target, prop) {\n if (prop !== 'create')\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n\n return async function (params: Record<string, unknown>) {\n const { cleaned, sessionId, userId, feature } = extractMeta(params)\n const model = typeof cleaned['model'] === 'string' ? cleaned['model'] : 'unknown'\n\n const result = await (target as MessagesLike).create(cleaned)\n\n if (result && typeof result === 'object' && Symbol.asyncIterator in result) {\n return wrapStream(\n result as AsyncIterable<AnthropicStreamEvent>,\n model,\n sessionId,\n userId,\n feature,\n tracker,\n )\n }\n\n const message = result as AnthropicMessage\n const { inputTokens, outputTokens, cachedTokens, cacheCreationTokens } = extractUsage(message.usage)\n const reasoningTokens = extractThinkingTokenApprox(message.content)\n trackWithMeta(\n tracker,\n message.model ?? model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n sessionId,\n userId,\n feature,\n cachedTokens,\n cacheCreationTokens,\n )\n\n return result\n }\n },\n })\n\n return new Proxy(client, {\n get(target, prop) {\n if (prop === 'messages') return proxiedMessages\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n },\n }) as unknown as WrappedAnthropic<T>\n}\n","import type { Tracker, TrackingMeta } from '../types/index.js'\n\n// ─── Minimal structural types ─────────────────────────────────────────────────\n\ninterface UsageMetadata {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n}\n\ninterface GenerateContentResponse {\n usageMetadata?: UsageMetadata | null\n}\n\ninterface GenerativeModelLike {\n generateContent(params: unknown): Promise<{ response: GenerateContentResponse }>\n generateContentStream(\n params: unknown,\n ): Promise<{\n stream: AsyncIterable<{ usageMetadata?: UsageMetadata | null }>\n response: Promise<GenerateContentResponse>\n }>\n model?: string\n}\n\ninterface GenAILike {\n getGenerativeModel(params: { model: string } & Record<string, unknown>): GenerativeModelLike\n}\n\n// ─── Public wrapper ───────────────────────────────────────────────────────────\n\n/**\n * Wraps a GoogleGenerativeAI client to transparently intercept\n * generateContent / generateContentStream calls and report token usage.\n *\n * Pass __feature in getGenerativeModel params to tag all calls from that model\n * instance with a product feature name (appears in report.byFeature).\n *\n * Returns the same type T that was passed in.\n */\nexport function wrapGemini<T extends GenAILike>(client: T, tracker: Tracker): T {\n return new Proxy(client, {\n get(target, prop) {\n if (prop !== 'getGenerativeModel')\n return (target as Record<string | symbol, unknown>)[prop]\n\n return function (modelParams: { model: string } & Record<string, unknown>) {\n // Extract tracking meta from getGenerativeModel params\n const { __sessionId, __userId, __feature, ...cleanedParams } = modelParams as typeof modelParams & TrackingMeta\n const feature = typeof __feature === 'string' ? __feature : undefined\n const sessionId = typeof __sessionId === 'string' ? __sessionId : undefined\n const userId = typeof __userId === 'string' ? __userId : undefined\n\n const modelInstance = target.getGenerativeModel(cleanedParams as { model: string } & Record<string, unknown>)\n const modelId = modelParams.model\n\n return new Proxy(modelInstance, {\n get(mTarget, mProp) {\n if (mProp === 'generateContent') {\n return async function (params: unknown) {\n const result = await mTarget.generateContent(params)\n const meta = result.response.usageMetadata\n tracker.track({\n model: modelId,\n inputTokens: meta?.promptTokenCount ?? 0,\n outputTokens: meta?.candidatesTokenCount ?? 0,\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n\n return result\n }\n }\n\n if (mProp === 'generateContentStream') {\n return async function (params: unknown) {\n const streamResult = await mTarget.generateContentStream(params)\n\n // Consume usage from the resolved response promise after streaming\n streamResult.response\n .then((res) => {\n const meta = res.usageMetadata\n tracker.track({\n model: modelId,\n inputTokens: meta?.promptTokenCount ?? 0,\n outputTokens: meta?.candidatesTokenCount ?? 0,\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n })\n .catch(() => {\n // best-effort\n })\n\n return streamResult\n }\n }\n\n return (mTarget as unknown as Record<string | symbol, unknown>)[mProp]\n },\n })\n }\n },\n }) as T\n}\n"],"mappings":"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","names":["bundledPrices","import_node_fs","import_node_os","import_node_path","extractMeta","extractUsage","trackWithMeta","wrapStream"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/tracker.ts","../src/core/pricing.ts","../src/core/suggestions.ts","../src/core/storage.ts","../src/core/sync.ts","../prices.json","../src/core/lazy-tracker.ts","../src/providers/openai.ts","../src/providers/anthropic.ts","../src/providers/gemini.ts"],"sourcesContent":["export { createTracker } from './core/tracker.js'\nexport { createLazyTracker } from './core/lazy-tracker.js'\nexport { wrapOpenAI } from './providers/openai.js'\nexport { wrapAnthropic } from './providers/anthropic.js'\nexport { wrapGemini } from './providers/gemini.js'\nexport { wrapDeepSeek } from './providers/deepseek.js'\n\nexport type {\n Tracker,\n LazyTracker,\n TrackerConfig,\n UsageEntry,\n Report,\n ReportOptions,\n CostForecast,\n ForecastOptions,\n ModelStats,\n SessionStats,\n UserStats,\n FeatureStats,\n ModelPrice,\n PriceMap,\n PricesFile,\n IStorage,\n IExporter,\n TrackingMeta,\n BudgetConfig,\n AnomalyDetectionConfig,\n} from './types/index.js'\n","import { z } from 'zod'\nimport type {\n Tracker,\n TrackerConfig,\n UsageEntry,\n Report,\n ReportOptions,\n CostForecast,\n ForecastOptions,\n ModelStats,\n SessionStats,\n UserStats,\n FeatureStats,\n AppStats,\n ModelPrice,\n PriceMap,\n IStorage,\n BudgetConfig,\n IExporter,\n} from '../types/index.js'\nimport { resolvePrice, findPrice, calculateCost } from './pricing.js'\nimport { maybeSuggestCheaperModel } from './suggestions.js'\nimport { createStorage } from './storage.js'\nimport { getRemotePrices } from './sync.js'\nimport bundledPricesFile from '../../prices.json' assert { type: 'json' }\n\nconst bundledPrices: PriceMap = bundledPricesFile.models as PriceMap\nconst bundledUpdatedAt: string = (bundledPricesFile as { updated_at?: string }).updated_at ?? ''\n\n// ─── Config validation schema ─────────────────────────────────────────────────\n\nconst ModelPriceSchema = z.object({\n input: z.number().nonnegative(),\n output: z.number().nonnegative(),\n cachedInput: z.number().nonnegative().optional(),\n cacheCreationInput: z.number().nonnegative().optional(),\n maxInputTokens: z.number().positive().optional(),\n})\n\nconst BudgetConfigSchema = z.object({\n threshold: z.number().positive(),\n webhookUrl: z.string().url(),\n mode: z.enum(['once', 'always']).optional().default('once'),\n})\n\n// storage can be a string enum or an IStorage instance — validated separately\nconst TrackerConfigSchema = z.object({\n storage: z.union([z.enum(['memory', 'sqlite']), z.custom<IStorage>((v) => {\n return (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as IStorage).record === 'function' &&\n typeof (v as IStorage).getAll === 'function' &&\n typeof (v as IStorage).clearAll === 'function' &&\n typeof (v as IStorage).clearSession === 'function'\n )\n })]).optional().default('memory'),\n alertThreshold: z.number().positive().optional(),\n webhookUrl: z.string().url().optional(),\n syncPrices: z.boolean().optional().default(true),\n customPrices: z.record(z.string(), ModelPriceSchema).optional(),\n warnIfStaleAfterHours: z.number().nonnegative().optional().default(72),\n budgets: z.object({\n perUser: BudgetConfigSchema.optional(),\n perSession: BudgetConfigSchema.optional(),\n }).optional(),\n suggestions: z.boolean().optional().default(false),\n anomalyDetection: z.object({\n multiplierThreshold: z.number().positive(),\n webhookUrl: z.string().url(),\n windowHours: z.number().positive().optional().default(24),\n mode: z.enum(['once', 'always']).optional().default('once'),\n }).optional(),\n exporter: z.custom<IExporter>((v) => (\n v !== null &&\n typeof v === 'object' &&\n typeof (v as IExporter).export === 'function'\n )).optional(),\n appId: z.string().optional(),\n})\n\nexport function createTracker(config: TrackerConfig = {}): Tracker {\n const parsed = TrackerConfigSchema.safeParse(config)\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => ` ${i.path.join('.')}: ${i.message}`).join('\\n')\n throw new Error(`[tokenwatch] Invalid config:\\n${issues}`)\n }\n\n const {\n storage: storageOption,\n alertThreshold,\n webhookUrl,\n syncPrices,\n customPrices,\n warnIfStaleAfterHours,\n budgets,\n suggestions,\n anomalyDetection,\n exporter,\n appId,\n } = parsed.data\n\n const storage: IStorage =\n typeof storageOption === 'object'\n ? storageOption\n : createStorage(storageOption)\n\n // Fetch remote prices in the background — bundled prices are used as fallback\n // until the sync resolves. Negligible overhead added to createTracker().\n let remotePrices: PriceMap | undefined\n let pricesUpdatedAt: string = bundledUpdatedAt\n if (syncPrices) {\n getRemotePrices()\n .then((result) => {\n if (result) {\n remotePrices = result.models\n pricesUpdatedAt = result.updated_at\n }\n })\n .catch(() => {\n // best-effort — bundled prices remain in use\n })\n }\n\n // Warn if prices are stale (checked lazily on first access)\n let stalenessChecked = false\n function maybeWarnStaleness(): void {\n if (stalenessChecked || !warnIfStaleAfterHours) return\n stalenessChecked = true\n if (!pricesUpdatedAt) return\n try {\n const updatedMs = new Date(pricesUpdatedAt).getTime()\n const ageHours = (Date.now() - updatedMs) / (1000 * 60 * 60)\n if (ageHours > warnIfStaleAfterHours) {\n console.warn(\n `[tokenwatch] Price data is ${Math.round(ageHours)}h old (updated_at: ${pricesUpdatedAt}). ` +\n `Run \"tokenwatch sync\" to refresh, or set warnIfStaleAfterHours: 0 to suppress.`,\n )\n }\n } catch {\n // best-effort\n }\n }\n\n let alertFired = false\n const firedUserAlerts = new Set<string>()\n const firedSessionAlerts = new Set<string>()\n const firedAnomalyKeys = new Set<string>()\n const startedAt = new Date().toISOString()\n\n function resolveModelPrice(model: string) {\n maybeWarnStaleness()\n return resolvePrice(model, {\n bundledPrices,\n ...(customPrices !== undefined && { customPrices: customPrices as PriceMap }),\n ...(remotePrices !== undefined && { remotePrices }),\n })\n }\n\n function track(entry: Omit<UsageEntry, 'costUSD' | 'timestamp'>): void {\n const price = resolveModelPrice(entry.model)\n const costUSD = calculateCost(\n entry.inputTokens,\n entry.outputTokens,\n price,\n entry.cachedTokens,\n entry.cacheCreationTokens,\n )\n const full: UsageEntry = {\n ...entry,\n costUSD,\n timestamp: new Date().toISOString(),\n ...(appId !== undefined && entry.appId === undefined && { appId }),\n }\n storage.record(full)\n if (exporter) {\n Promise.resolve(exporter.export(full)).catch(() => { /* fire-and-forget */ })\n }\n maybeFireAlerts(full)\n if (anomalyDetection) maybeDetectAnomaly(full)\n if (suggestions) {\n maybeSuggestCheaperModel(entry.model, costUSD, entry.inputTokens, entry.outputTokens, {\n bundledPrices,\n ...(customPrices !== undefined && { customPrices: customPrices as PriceMap }),\n ...(remotePrices !== undefined && { remotePrices }),\n })\n }\n }\n\n function maybeFireAlerts(entry: UsageEntry): void {\n // Global threshold alert\n if (alertThreshold && webhookUrl && !alertFired) {\n alertFired = true\n Promise.resolve(storage.getAll()).then((entries) => {\n const total = computeTotal(entries)\n if (total < alertThreshold!) {\n alertFired = false\n return\n }\n fireWebhook(webhookUrl!, {\n text: `[tokenwatch] Alert: total cost reached $${total.toFixed(4)} USD (threshold: $${alertThreshold})`,\n })\n }).catch(() => {\n alertFired = false\n })\n }\n\n // Per-user budget alert\n if (budgets?.perUser && entry.userId) {\n const cfg = budgets.perUser\n const uid = entry.userId\n if (cfg.mode === 'always' || !firedUserAlerts.has(uid)) {\n // Claim the slot synchronously before going async — prevents double-fire\n if (cfg.mode !== 'always') firedUserAlerts.add(uid)\n Promise.resolve(storage.getAll()).then((entries) => {\n const userCost = entries\n .filter((e) => e.userId === uid)\n .reduce((s, e) => s + e.costUSD, 0)\n if (userCost >= cfg.threshold) {\n fireWebhook(cfg.webhookUrl, {\n text: `[tokenwatch] Budget alert: user \"${uid}\" reached $${userCost.toFixed(4)} USD (threshold: $${cfg.threshold})`,\n })\n } else {\n if (cfg.mode !== 'always') firedUserAlerts.delete(uid) // release — threshold not yet met\n }\n }).catch(() => {\n if (cfg.mode !== 'always') firedUserAlerts.delete(uid) // release on storage error\n })\n }\n }\n\n // Per-session budget alert\n if (budgets?.perSession && entry.sessionId) {\n const cfg = budgets.perSession\n const sid = entry.sessionId\n if (cfg.mode === 'always' || !firedSessionAlerts.has(sid)) {\n // Claim the slot synchronously before going async — prevents double-fire\n if (cfg.mode !== 'always') firedSessionAlerts.add(sid)\n Promise.resolve(storage.getAll()).then((entries) => {\n const sessionCost = entries\n .filter((e) => e.sessionId === sid)\n .reduce((s, e) => s + e.costUSD, 0)\n if (sessionCost >= cfg.threshold) {\n fireWebhook(cfg.webhookUrl, {\n text: `[tokenwatch] Budget alert: session \"${sid}\" reached $${sessionCost.toFixed(4)} USD (threshold: $${cfg.threshold})`,\n })\n } else {\n if (cfg.mode !== 'always') firedSessionAlerts.delete(sid) // release\n }\n }).catch(() => {\n if (cfg.mode !== 'always') firedSessionAlerts.delete(sid) // release on storage error\n })\n }\n }\n }\n\n function fireWebhook(url: string, payload: { text: string }): void {\n fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }).catch(() => {\n // fire-and-forget\n })\n }\n\n async function getReport(options?: ReportOptions): Promise<Report> {\n const allEntries = await Promise.resolve(storage.getAll())\n const entries = filterEntries(allEntries, options)\n\n const byModel: Record<string, ModelStats> = {}\n const bySession: Record<string, SessionStats> = {}\n const byUser: Record<string, UserStats> = {}\n const byFeature: Record<string, FeatureStats> = {}\n const byApp: Record<string, AppStats> = {}\n\n let totalInput = 0\n let totalOutput = 0\n let totalCost = 0\n let periodFrom = options ? (entries[0]?.timestamp ?? startedAt) : startedAt\n let lastTimestamp = periodFrom\n\n for (const e of entries) {\n totalInput += e.inputTokens + (e.cachedTokens ?? 0) + (e.cacheCreationTokens ?? 0)\n totalOutput += e.outputTokens\n totalCost += e.costUSD\n if (e.timestamp > lastTimestamp) lastTimestamp = e.timestamp\n\n // byModel\n const m = (byModel[e.model] ??= {\n costUSD: 0,\n calls: 0,\n tokens: { input: 0, output: 0, reasoning: 0, cached: 0 },\n })\n m.costUSD += e.costUSD\n m.calls += 1\n m.tokens.input += e.inputTokens + (e.cachedTokens ?? 0) + (e.cacheCreationTokens ?? 0)\n m.tokens.output += e.outputTokens\n m.tokens.reasoning += e.reasoningTokens ?? 0\n m.tokens.cached += e.cachedTokens ?? 0\n\n // bySession\n if (e.sessionId) {\n const s = (bySession[e.sessionId] ??= { costUSD: 0, calls: 0 })\n s.costUSD += e.costUSD\n s.calls += 1\n }\n\n // byUser\n if (e.userId) {\n const u = (byUser[e.userId] ??= { costUSD: 0, calls: 0 })\n u.costUSD += e.costUSD\n u.calls += 1\n }\n\n // byFeature\n if (e.feature) {\n const f = (byFeature[e.feature] ??= { costUSD: 0, calls: 0 })\n f.costUSD += e.costUSD\n f.calls += 1\n }\n\n // byApp\n if (e.appId) {\n const a = (byApp[e.appId] ??= { costUSD: 0, calls: 0 })\n a.costUSD += e.costUSD\n a.calls += 1\n }\n }\n\n // When filtering, use the actual first entry's timestamp as period.from\n if (options && entries.length > 0) {\n periodFrom = entries[0]?.timestamp ?? periodFrom\n }\n\n return {\n totalCostUSD: totalCost,\n totalTokens: { input: totalInput, output: totalOutput },\n byModel,\n bySession,\n byUser,\n byFeature,\n byApp,\n period: { from: periodFrom, to: lastTimestamp },\n ...(pricesUpdatedAt ? { pricesUpdatedAt } : {}),\n }\n }\n\n async function getCostForecast(options: ForecastOptions = {}): Promise<CostForecast> {\n const windowHours = options.windowHours ?? 24\n const allEntries = await Promise.resolve(storage.getAll())\n\n const now = Date.now()\n const windowStart = now - windowHours * 60 * 60 * 1000\n const windowEntries = allEntries.filter(\n (e) => new Date(e.timestamp).getTime() >= windowStart,\n )\n\n if (windowEntries.length < 2) {\n return {\n burnRatePerHour: 0,\n projectedDailyCostUSD: 0,\n projectedMonthlyCostUSD: 0,\n basedOnHours: 0,\n basedOnPeriod: null,\n }\n }\n\n const first = windowEntries[0]?.timestamp ?? ''\n const last = windowEntries[windowEntries.length - 1]?.timestamp ?? ''\n const actualMs = new Date(last).getTime() - new Date(first).getTime()\n const actualHours = actualMs / (1000 * 60 * 60)\n\n if (actualHours < 0.001) {\n return {\n burnRatePerHour: 0,\n projectedDailyCostUSD: 0,\n projectedMonthlyCostUSD: 0,\n basedOnHours: 0,\n basedOnPeriod: { from: first, to: last },\n }\n }\n\n const totalCost = windowEntries.reduce((s, e) => s + e.costUSD, 0)\n const burnRatePerHour = totalCost / actualHours\n\n return {\n burnRatePerHour,\n projectedDailyCostUSD: burnRatePerHour * 24,\n projectedMonthlyCostUSD: burnRatePerHour * 24 * 30,\n basedOnHours: Math.round(actualHours * 100) / 100,\n basedOnPeriod: { from: first, to: last },\n }\n }\n\n function maybeDetectAnomaly(entry: UsageEntry): void {\n if (entry.costUSD <= 0) return\n const { multiplierThreshold, webhookUrl: aUrl, windowHours: wh, mode: modeRaw } = anomalyDetection!\n const wHours = wh ?? 24\n const mode = modeRaw ?? 'once'\n const windowStart = Date.now() - wHours * 60 * 60 * 1000\n const entryTs = new Date(entry.timestamp).getTime()\n\n function checkEntity(key: string, label: string, predicate: (e: UsageEntry) => boolean): void {\n if (mode !== 'always' && firedAnomalyKeys.has(key)) return\n if (mode !== 'always') firedAnomalyKeys.add(key)\n Promise.resolve(storage.getAll()).then((all) => {\n const history = all.filter(\n (e) =>\n predicate(e) &&\n new Date(e.timestamp).getTime() >= windowStart &&\n new Date(e.timestamp).getTime() !== entryTs,\n )\n if (history.length === 0) {\n if (mode !== 'always') firedAnomalyKeys.delete(key)\n return\n }\n const avg = history.reduce((s, e) => s + e.costUSD, 0) / history.length\n if (avg <= 0 || entry.costUSD <= avg * multiplierThreshold) {\n if (mode !== 'always') firedAnomalyKeys.delete(key)\n return\n }\n const multiple = (entry.costUSD / avg).toFixed(1)\n fireWebhook(aUrl, {\n text: `[tokenwatch] Anomaly: ${label} call cost $${entry.costUSD.toFixed(4)} is ${multiple}x above ${wHours}h average ($${avg.toFixed(4)})`,\n })\n }).catch(() => {\n if (mode !== 'always') firedAnomalyKeys.delete(key)\n })\n }\n\n if (entry.userId) {\n checkEntity(\n `user:${entry.userId}`,\n `user \"${entry.userId}\"`,\n (e) => e.userId === entry.userId,\n )\n }\n checkEntity(\n `model:${entry.model}`,\n `model \"${entry.model}\"`,\n (e) => e.model === entry.model,\n )\n }\n\n async function reset(): Promise<void> {\n await Promise.resolve(storage.clearAll())\n alertFired = false\n firedUserAlerts.clear()\n firedSessionAlerts.clear()\n firedAnomalyKeys.clear()\n }\n\n async function resetSession(sessionId: string): Promise<void> {\n await Promise.resolve(storage.clearSession(sessionId))\n firedSessionAlerts.delete(sessionId)\n }\n\n async function exportJSON(): Promise<string> {\n return JSON.stringify(await getReport(), null, 2)\n }\n\n async function exportCSV(): Promise<string> {\n const entries = await Promise.resolve(storage.getAll())\n const header =\n 'timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature,appId'\n const rows = entries.map((e) =>\n [\n csvEscape(e.timestamp),\n csvEscape(e.model),\n e.inputTokens,\n e.outputTokens,\n e.reasoningTokens ?? 0,\n e.cachedTokens ?? 0,\n e.cacheCreationTokens ?? 0,\n e.costUSD.toFixed(8),\n csvEscape(e.sessionId ?? ''),\n csvEscape(e.userId ?? ''),\n csvEscape(e.feature ?? ''),\n csvEscape(e.appId ?? ''),\n ].join(','),\n )\n return [header, ...rows].join('\\n')\n }\n\n function getModelInfo(model: string): ModelPrice | null {\n return findPrice(model, {\n bundledPrices,\n ...(customPrices !== undefined && { customPrices: customPrices as PriceMap }),\n ...(remotePrices !== undefined && { remotePrices }),\n }) ?? null\n }\n\n return {\n track,\n getReport,\n getCostForecast,\n reset,\n resetSession,\n exportJSON,\n exportCSV,\n getModelInfo,\n }\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction computeTotal(entries: UsageEntry[]): number {\n return entries.reduce((sum, e) => sum + e.costUSD, 0)\n}\n\n/** Parse a 'last' shorthand like '24h', '7d' into milliseconds */\nfunction parseLastMs(last: string): number {\n const match = /^(\\d+(?:\\.\\d+)?)(h|d)$/.exec(last.trim())\n if (!match) throw new Error(`[tokenwatch] Invalid \"last\" value: \"${last}\". Use e.g. \"24h\", \"7d\".`)\n const value = parseFloat(match[1] ?? '0')\n const unit = match[2] ?? 'h'\n return unit === 'h' ? value * 60 * 60 * 1000 : value * 24 * 60 * 60 * 1000\n}\n\nfunction filterEntries(entries: UsageEntry[], options?: ReportOptions): UsageEntry[] {\n if (!options) return entries\n\n let sinceMs: number | undefined\n let untilMs: number | undefined\n\n if (options.last) {\n sinceMs = Date.now() - parseLastMs(options.last)\n } else if (options.since) {\n sinceMs = new Date(options.since).getTime()\n }\n if (options.until) {\n untilMs = new Date(options.until).getTime()\n }\n\n if (sinceMs === undefined && untilMs === undefined) return entries\n\n return entries.filter((e) => {\n const ts = new Date(e.timestamp).getTime()\n if (sinceMs !== undefined && ts < sinceMs) return false\n if (untilMs !== undefined && ts > untilMs) return false\n return true\n })\n}\n\n/** Wrap a CSV field value in double-quotes if it contains commas, quotes, or newlines. */\nfunction csvEscape(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`\n }\n return value\n}\n","import type { ModelPrice, PriceMap } from '../types/index.js'\n\n/**\n * Resolve price for a model using 3-layer priority:\n * 1. customPrices (user override)\n * 2. remotePrices (synced from GitHub, cached 24h)\n * 3. bundledPrices (always-present fallback)\n *\n * Falls back to zero-cost with a console warning when model is not found anywhere.\n */\nexport function resolvePrice(\n model: string,\n layers: {\n customPrices?: PriceMap\n remotePrices?: PriceMap\n bundledPrices: PriceMap\n },\n): ModelPrice {\n const { customPrices, remotePrices, bundledPrices } = layers\n\n const found =\n lookupInMap(model, customPrices) ??\n lookupInMap(model, remotePrices) ??\n lookupInMap(model, bundledPrices)\n\n if (found) return found\n\n console.warn(\n `[tokenwatch] Unknown model \"${model}\". Cost will be recorded as $0. ` +\n `Add it via customPrices or update prices with: tokenwatch sync`,\n )\n return { input: 0, output: 0 }\n}\n\n/**\n * Find price for a model without the zero-cost fallback.\n * Returns undefined if the model is not found in any layer.\n */\nexport function findPrice(\n model: string,\n layers: {\n customPrices?: PriceMap\n remotePrices?: PriceMap\n bundledPrices: PriceMap\n },\n): ModelPrice | undefined {\n const { customPrices, remotePrices, bundledPrices } = layers\n return (\n lookupInMap(model, customPrices) ??\n lookupInMap(model, remotePrices) ??\n lookupInMap(model, bundledPrices)\n )\n}\n\n/**\n * Look up a model in a PriceMap using:\n * 1. exact key match\n * 2. prefix match — map key is a prefix of the model string (e.g. \"gpt-4o\" matches \"gpt-4o-2024-11-20\")\n * 3. reverse prefix — model string is a prefix of a map key (unusual, safety net)\n */\nfunction lookupInMap(model: string, map: PriceMap | undefined): ModelPrice | undefined {\n if (!map) return undefined\n\n if (model in map) return map[model]\n\n // prefix match\n for (const key of Object.keys(map)) {\n if (model.startsWith(key) || key.startsWith(model)) {\n return map[key]\n }\n }\n\n return undefined\n}\n\n/**\n * Calculate cost in USD given token counts and per-million-token prices.\n *\n * - `inputTokens` — regular (non-cached) input tokens\n * - `outputTokens` — output tokens (includes reasoning tokens for OpenAI, which are billed as output)\n * - `cachedTokens` — cache-read input tokens (billed at price.cachedInput or full input price if absent)\n * - `cacheCreationTokens` — cache-creation input tokens, Anthropic only (billed at price.cacheCreationInput\n * or 1.25× input price if absent)\n */\nexport function calculateCost(\n inputTokens: number,\n outputTokens: number,\n price: ModelPrice,\n cachedTokens = 0,\n cacheCreationTokens = 0,\n): number {\n const regularInputCost = (inputTokens / 1_000_000) * price.input\n const cachedReadCost = (cachedTokens / 1_000_000) * (price.cachedInput ?? price.input)\n const cacheCreationCost =\n (cacheCreationTokens / 1_000_000) * (price.cacheCreationInput ?? price.input * 1.25)\n const outputCost = (outputTokens / 1_000_000) * price.output\n return regularInputCost + cachedReadCost + cacheCreationCost + outputCost\n}\n","import type { PriceMap } from '../types/index.js'\nimport { calculateCost } from './pricing.js'\n\nconst PROVIDER_PREFIXES = ['gpt-', 'claude-', 'gemini-', 'deepseek-'] as const\n\nfunction getProviderPrefix(model: string): string | undefined {\n return PROVIDER_PREFIXES.find((p) => model.startsWith(p))\n}\n\n/**\n * After a tracked call, check if there is a cheaper model in the same provider family\n * (defined by model name prefix). Logs a hint if savings are strictly greater than 50%.\n * No-ops if the model is unknown, costUSD is zero, or no cheaper candidate is found.\n */\nexport function maybeSuggestCheaperModel(\n model: string,\n costUSD: number,\n inputTokens: number,\n outputTokens: number,\n layers: { bundledPrices: PriceMap; customPrices?: PriceMap; remotePrices?: PriceMap },\n): void {\n if (costUSD <= 0) return\n\n const prefix = getProviderPrefix(model)\n if (!prefix) return\n\n // Merge layers: bundled < remote < custom (custom wins)\n const mergedMap: PriceMap = {\n ...layers.bundledPrices,\n ...(layers.remotePrices ?? {}),\n ...(layers.customPrices ?? {}),\n }\n\n let cheapestModel: string | undefined\n let cheapestCost = Infinity\n\n for (const key of Object.keys(mergedMap)) {\n if (key === model || !key.startsWith(prefix)) continue\n const price = mergedMap[key]\n if (!price) continue\n const candidateCost = calculateCost(inputTokens, outputTokens, price)\n if (candidateCost < cheapestCost) {\n cheapestCost = candidateCost\n cheapestModel = key\n }\n }\n\n // Must be strictly more than 50% cheaper\n if (cheapestModel === undefined || cheapestCost >= costUSD * 0.5) return\n\n const savingsPct = Math.round((1 - cheapestCost / costUSD) * 100)\n console.log(\n `[tokenwatch] Suggestion: ${cheapestModel} could handle this for ~$${cheapestCost.toFixed(4)} (${savingsPct}% cheaper than ${model})`,\n )\n}\n","import { createRequire } from 'node:module'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { mkdirSync } from 'node:fs'\nimport type { IStorage, UsageEntry } from '../types/index.js'\n\n// ─── Memory storage ───────────────────────────────────────────────────────────\n\nexport class MemoryStorage implements IStorage {\n private entries: UsageEntry[] = []\n\n record(entry: UsageEntry): void {\n this.entries.push(entry)\n }\n\n getAll(): UsageEntry[] {\n return [...this.entries]\n }\n\n clearAll(): void {\n this.entries = []\n }\n\n clearSession(sessionId: string): void {\n this.entries = this.entries.filter((e) => e.sessionId !== sessionId)\n }\n}\n\n// ─── SQLite storage ───────────────────────────────────────────────────────────\n\nconst DB_DIR = join(homedir(), '.tokenwatch')\nconst DB_PATH = join(DB_DIR, 'usage.db')\n\nexport class SqliteStorage implements IStorage {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private db: any\n\n constructor(dbPath = DB_PATH) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let BetterSqlite3: any\n try {\n // In CJS context globalThis.require is the native require; in ESM use createRequire.\n // This makes the lazy load work in both output formats produced by tsup.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const req: NodeRequire =\n typeof (globalThis as any).require === 'function'\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (globalThis as any).require\n : createRequire(import.meta.url)\n BetterSqlite3 = req('better-sqlite3')\n } catch {\n throw new Error(\n '[tokenwatch] SQLite storage requires better-sqlite3. ' +\n 'Run: npm install better-sqlite3',\n )\n }\n\n mkdirSync(DB_DIR, { recursive: true })\n this.db = new BetterSqlite3(dbPath)\n this.migrate()\n }\n\n private migrate(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS usage (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n reasoning_tokens INTEGER NOT NULL DEFAULT 0,\n cached_tokens INTEGER NOT NULL DEFAULT 0,\n cache_creation_tokens INTEGER NOT NULL DEFAULT 0,\n cost_usd REAL NOT NULL,\n session_id TEXT,\n user_id TEXT,\n feature TEXT,\n app_id TEXT,\n timestamp TEXT NOT NULL\n )\n `)\n // Incremental migrations for databases created before v0.2.0 / v0.3.0\n const cols = (this.db.prepare(`PRAGMA table_info(usage)`).all() as Array<{ name: string }>)\n .map((c) => c.name)\n if (!cols.includes('reasoning_tokens')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN reasoning_tokens INTEGER NOT NULL DEFAULT 0`)\n }\n if (!cols.includes('feature')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN feature TEXT`)\n }\n if (!cols.includes('cached_tokens')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN cached_tokens INTEGER NOT NULL DEFAULT 0`)\n }\n if (!cols.includes('cache_creation_tokens')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN cache_creation_tokens INTEGER NOT NULL DEFAULT 0`)\n }\n if (!cols.includes('app_id')) {\n this.db.exec(`ALTER TABLE usage ADD COLUMN app_id TEXT`)\n }\n }\n\n record(entry: UsageEntry): void {\n this.db\n .prepare(\n `INSERT INTO usage\n (model, input_tokens, output_tokens, reasoning_tokens, cached_tokens, cache_creation_tokens,\n cost_usd, session_id, user_id, feature, app_id, timestamp)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.model,\n entry.inputTokens,\n entry.outputTokens,\n entry.reasoningTokens ?? 0,\n entry.cachedTokens ?? 0,\n entry.cacheCreationTokens ?? 0,\n entry.costUSD,\n entry.sessionId ?? null,\n entry.userId ?? null,\n entry.feature ?? null,\n entry.appId ?? null,\n entry.timestamp,\n )\n }\n\n getAll(): UsageEntry[] {\n const rows = this.db.prepare('SELECT * FROM usage ORDER BY timestamp ASC').all() as Array<{\n model: string\n input_tokens: number\n output_tokens: number\n reasoning_tokens: number\n cached_tokens: number\n cache_creation_tokens: number\n cost_usd: number\n session_id: string | null\n user_id: string | null\n feature: string | null\n app_id: string | null\n timestamp: string\n }>\n\n return rows.map((r) => ({\n model: r.model,\n inputTokens: r.input_tokens,\n outputTokens: r.output_tokens,\n ...(r.reasoning_tokens > 0 && { reasoningTokens: r.reasoning_tokens }),\n ...(r.cached_tokens > 0 && { cachedTokens: r.cached_tokens }),\n ...(r.cache_creation_tokens > 0 && { cacheCreationTokens: r.cache_creation_tokens }),\n costUSD: r.cost_usd,\n ...(r.session_id != null && { sessionId: r.session_id }),\n ...(r.user_id != null && { userId: r.user_id }),\n ...(r.feature != null && { feature: r.feature }),\n ...(r.app_id != null && { appId: r.app_id }),\n timestamp: r.timestamp,\n }))\n }\n\n clearAll(): void {\n this.db.exec('DELETE FROM usage')\n }\n\n clearSession(sessionId: string): void {\n this.db.prepare('DELETE FROM usage WHERE session_id = ?').run(sessionId)\n }\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\nexport function createStorage(type: 'memory' | 'sqlite'): IStorage {\n if (type === 'sqlite') return new SqliteStorage()\n return new MemoryStorage()\n}\n","import { readFile, writeFile, mkdir } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport type { PricesFile, PriceMap } from '../types/index.js'\n\nconst CACHE_DIR = join(homedir(), '.tokenwatch')\nconst CACHE_FILE = join(CACHE_DIR, 'prices.json')\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000 // 24 hours\nconst REMOTE_URL =\n 'https://raw.githubusercontent.com/diogonzafe/tokenwatch/main/prices.json'\n\nexport interface PricesResult {\n models: PriceMap\n updated_at: string\n}\n\nexport async function fetchRemotePrices(url = REMOTE_URL): Promise<PricesResult | null> {\n try {\n const res = await fetch(url, { signal: AbortSignal.timeout(8_000) })\n if (!res.ok) return null\n const data = (await res.json()) as PricesFile\n if (!data?.models) return null\n await persistCache(data)\n return { models: data.models, updated_at: data.updated_at ?? '' }\n } catch {\n return null\n }\n}\n\nexport async function loadCachedPrices(): Promise<PricesResult | null> {\n if (!existsSync(CACHE_FILE)) return null\n try {\n const raw = await readFile(CACHE_FILE, 'utf8')\n const data = JSON.parse(raw) as PricesFile & { _cachedAt?: number }\n const age = Date.now() - (data._cachedAt ?? 0)\n if (age > CACHE_TTL_MS) return null\n if (!data.models) return null\n return { models: data.models, updated_at: data.updated_at ?? '' }\n } catch {\n return null\n }\n}\n\nasync function persistCache(data: PricesFile): Promise<void> {\n try {\n await mkdir(CACHE_DIR, { recursive: true })\n const payload = { ...data, _cachedAt: Date.now() }\n await writeFile(CACHE_FILE, JSON.stringify(payload, null, 2), 'utf8')\n } catch {\n // best-effort — never throw\n }\n}\n\n/**\n * Returns the best available remote price result:\n * 1. Valid local cache (< 24h)\n * 2. Fresh remote fetch (also updates cache)\n * 3. null if both fail\n */\nexport async function getRemotePrices(): Promise<PricesResult | null> {\n const cached = await loadCachedPrices()\n if (cached) return cached\n return fetchRemotePrices()\n}\n","{\n \"updated_at\": \"2026-06-09\",\n \"source\": \"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json\",\n \"models\": {\n \"gpt-4o\": {\n \"input\": 2.5,\n \"output\": 10,\n \"cachedInput\": 1.25,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 128000\n },\n \"gpt-5\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-mini\": {\n \"input\": 0.25,\n \"output\": 2,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-nano\": {\n \"input\": 0.05,\n \"output\": 0.4,\n \"cachedInput\": 0.005,\n \"maxInputTokens\": 272000\n },\n \"claude-opus-4-6\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-6\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"maxInputTokens\": 200000\n },\n \"claude-haiku-4-5\": {\n \"input\": 1,\n \"output\": 5,\n \"cachedInput\": 0.1,\n \"maxInputTokens\": 200000\n },\n \"gemini-2.5-pro\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.03,\n \"maxInputTokens\": 1048576\n },\n \"deepseek-chat\": {\n \"input\": 0.28,\n \"output\": 0.42,\n \"cachedInput\": 0.028,\n \"maxInputTokens\": 131072\n },\n \"deepseek-reasoner\": {\n \"input\": 0.28,\n \"output\": 0.42,\n \"cachedInput\": 0.028,\n \"maxInputTokens\": 131072\n },\n \"claude-opus-4-5\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-7\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-1\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4-5\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"maxInputTokens\": 200000\n },\n \"gpt-oss-120b\": {\n \"input\": 3,\n \"output\": 4.5,\n \"maxInputTokens\": 131072\n },\n \"gpt-3.5-turbo\": {\n \"input\": 0.5,\n \"output\": 1.5,\n \"maxInputTokens\": 16385\n },\n \"gpt-3.5-turbo-0125\": {\n \"input\": 0.5,\n \"output\": 1.5,\n \"maxInputTokens\": 16385\n },\n \"gpt-35-turbo\": {\n \"input\": 0.5,\n \"output\": 1.5,\n \"maxInputTokens\": 4097\n },\n \"gpt-35-turbo-0125\": {\n \"input\": 0.5,\n \"output\": 1.5,\n \"maxInputTokens\": 16384\n },\n \"gpt-35-turbo-1106\": {\n \"input\": 1,\n \"output\": 2,\n \"maxInputTokens\": 16384\n },\n \"gpt-35-turbo-16k\": {\n \"input\": 3,\n \"output\": 4,\n \"maxInputTokens\": 16385\n },\n \"gpt-35-turbo-16k-0613\": {\n \"input\": 3,\n \"output\": 4,\n \"maxInputTokens\": 16385\n },\n \"gpt-4\": {\n \"input\": 30,\n \"output\": 60,\n \"maxInputTokens\": 8192\n },\n \"gpt-4-0125-preview\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4-0613\": {\n \"input\": 30,\n \"output\": 60,\n \"maxInputTokens\": 8192\n },\n \"gpt-4-1106-preview\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4-32k\": {\n \"input\": 60,\n \"output\": 120,\n \"maxInputTokens\": 32768\n },\n \"gpt-4-32k-0613\": {\n \"input\": 60,\n \"output\": 120,\n \"maxInputTokens\": 32768\n },\n \"gpt-4-turbo\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4-turbo-2024-04-09\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4-turbo-vision-preview\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4.1\": {\n \"input\": 2,\n \"output\": 8,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-2025-04-14\": {\n \"input\": 2,\n \"output\": 8,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-mini\": {\n \"input\": 0.4,\n \"output\": 1.6,\n \"cachedInput\": 0.1,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-mini-2025-04-14\": {\n \"input\": 0.4,\n \"output\": 1.6,\n \"cachedInput\": 0.1,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-nano\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-nano-2025-04-14\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.5-preview\": {\n \"input\": 75,\n \"output\": 150,\n \"cachedInput\": 37.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-2024-05-13\": {\n \"input\": 5,\n \"output\": 15,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-2024-08-06\": {\n \"input\": 2.5,\n \"output\": 10,\n \"cachedInput\": 1.25,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-2024-11-20\": {\n \"input\": 2.5,\n \"output\": 10,\n \"cachedInput\": 1.25,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-2025-08-28\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-1.5-2026-02-23\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-mini-2025-10-06\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-audio-preview-2024-12-17\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-2024-07-18\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-audio-preview-2024-12-17\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-realtime-preview-2024-12-17\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"cachedInput\": 0.3,\n \"maxInputTokens\": 128000\n },\n \"gpt-realtime-2025-08-28\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 0.4,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-1.5-2026-02-23\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 4,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-mini-2025-10-06\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"cachedInput\": 0.06,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-transcribe\": {\n \"input\": 1.25,\n \"output\": 5,\n \"maxInputTokens\": 16000\n },\n \"gpt-4o-realtime-preview-2024-10-01\": {\n \"input\": 5,\n \"output\": 20,\n \"cachedInput\": 2.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview-2024-12-17\": {\n \"input\": 5,\n \"output\": 20,\n \"cachedInput\": 2.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-transcribe\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 16000\n },\n \"gpt-4o-transcribe-diarize\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 16000\n },\n \"gpt-5.1-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-chat-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1-codex-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-mini-2025-11-13\": {\n \"input\": 0.25,\n \"output\": 2,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-2025-08-07\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-chat\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-chat-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-codex\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-mini-2025-08-07\": {\n \"input\": 0.25,\n \"output\": 2,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-nano-2025-08-07\": {\n \"input\": 0.05,\n \"output\": 0.4,\n \"cachedInput\": 0.005,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-pro\": {\n \"input\": 15,\n \"output\": 120,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-chat\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1-codex\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-max\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-mini\": {\n \"input\": 0.25,\n \"output\": 2,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-2025-12-11\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-chat\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-chat-2025-12-11\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-codex\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.3-chat\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.3-codex\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-pro\": {\n \"input\": 21,\n \"output\": 168,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-pro-2025-12-11\": {\n \"input\": 21,\n \"output\": 168,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.4\": {\n \"input\": 2.5,\n \"output\": 15,\n \"cachedInput\": 0.25,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-2026-03-05\": {\n \"input\": 2.5,\n \"output\": 15,\n \"cachedInput\": 0.25,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-pro\": {\n \"input\": 30,\n \"output\": 180,\n \"cachedInput\": 3,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-pro-2026-03-05\": {\n \"input\": 30,\n \"output\": 180,\n \"cachedInput\": 3,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-mini\": {\n \"input\": 0.75,\n \"output\": 4.5,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.4-nano\": {\n \"input\": 0.2,\n \"output\": 1.25,\n \"cachedInput\": 0.02,\n \"maxInputTokens\": 272000\n },\n \"o1-2024-12-17\": {\n \"input\": 15,\n \"output\": 60,\n \"cachedInput\": 7.5,\n \"maxInputTokens\": 200000\n },\n \"o1-mini\": {\n \"input\": 1.21,\n \"output\": 4.84,\n \"cachedInput\": 0.605,\n \"maxInputTokens\": 128000\n },\n \"o1-mini-2024-09-12\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.55,\n \"maxInputTokens\": 128000\n },\n \"o1-preview\": {\n \"input\": 15,\n \"output\": 60,\n \"cachedInput\": 7.5,\n \"maxInputTokens\": 128000\n },\n \"o1-preview-2024-09-12\": {\n \"input\": 15,\n \"output\": 60,\n \"cachedInput\": 7.5,\n \"maxInputTokens\": 128000\n },\n \"o3-2025-04-16\": {\n \"input\": 2,\n \"output\": 8,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 200000\n },\n \"o3-mini\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.55,\n \"maxInputTokens\": 200000\n },\n \"o3-mini-2025-01-31\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.55,\n \"maxInputTokens\": 200000\n },\n \"o3-pro\": {\n \"input\": 20,\n \"output\": 80,\n \"maxInputTokens\": 200000\n },\n \"o3-pro-2025-06-10\": {\n \"input\": 20,\n \"output\": 80,\n \"maxInputTokens\": 200000\n },\n \"o4-mini\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.275,\n \"maxInputTokens\": 200000\n },\n \"o4-mini-2025-04-16\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"cachedInput\": 0.275,\n \"maxInputTokens\": 200000\n },\n \"deepseek-v3.2\": {\n \"input\": 0.28,\n \"output\": 0.4,\n \"maxInputTokens\": 163840\n },\n \"deepseek-v3.2-speciale\": {\n \"input\": 0.58,\n \"output\": 1.68,\n \"maxInputTokens\": 163840\n },\n \"deepseek-r1\": {\n \"input\": 1.35,\n \"output\": 5.4,\n \"maxInputTokens\": 128000\n },\n \"deepseek-v3\": {\n \"input\": 0.27,\n \"output\": 1.1,\n \"cachedInput\": 0.07,\n \"maxInputTokens\": 65536\n },\n \"deepseek-v3-0324\": {\n \"input\": 0.2,\n \"output\": 0.6,\n \"maxInputTokens\": 131072\n },\n \"chatgpt-4o-latest\": {\n \"input\": 5,\n \"output\": 15,\n \"maxInputTokens\": 128000\n },\n \"claude-haiku-4-5-20251001\": {\n \"input\": 1,\n \"output\": 5,\n \"cachedInput\": 0.1,\n \"cacheCreationInput\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"claude-3-7-sonnet-20250219\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-3-haiku-20240307\": {\n \"input\": 0.25,\n \"output\": 1.25,\n \"cachedInput\": 0.03,\n \"cacheCreationInput\": 0.3,\n \"maxInputTokens\": 200000\n },\n \"claude-3-opus-20240229\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-4-opus-20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-4-sonnet-20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-5-20250929\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4-5-20250929-v1:0\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-1-20250805\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-5-20251101\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-6-20260205\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-7-20260416\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"codex-mini-latest\": {\n \"input\": 1.5,\n \"output\": 6,\n \"cachedInput\": 0.375,\n \"maxInputTokens\": 200000\n },\n \"deepseek-ai/deepseek-r1\": {\n \"input\": 3,\n \"output\": 7,\n \"maxInputTokens\": 128000\n },\n \"deepseek-ai/deepseek-r1-0528\": {\n \"input\": 135000,\n \"output\": 540000,\n \"maxInputTokens\": 161000\n },\n \"deepseek-ai/deepseek-r1-0528-turbo\": {\n \"input\": 1,\n \"output\": 3,\n \"maxInputTokens\": 32768\n },\n \"deepseek-ai/deepseek-r1-distill-llama-70b\": {\n \"input\": 0.25,\n \"output\": 0.75,\n \"maxInputTokens\": 128000\n },\n \"deepseek-ai/deepseek-r1-distill-qwen-32b\": {\n \"input\": 0.15,\n \"output\": 0.15\n },\n \"deepseek-ai/deepseek-r1-turbo\": {\n \"input\": 1,\n \"output\": 3,\n \"maxInputTokens\": 40960\n },\n \"deepseek-ai/deepseek-v3\": {\n \"input\": 1.25,\n \"output\": 1.25,\n \"maxInputTokens\": 65536\n },\n \"deepseek-ai/deepseek-v3-0324\": {\n \"input\": 114000,\n \"output\": 275000,\n \"maxInputTokens\": 161000\n },\n \"deepseek-ai/deepseek-v3.1\": {\n \"input\": 55000,\n \"output\": 165000,\n \"maxInputTokens\": 128000\n },\n \"deepseek-ai/deepseek-v3.1-terminus\": {\n \"input\": 0.27,\n \"output\": 1,\n \"cachedInput\": 0.216,\n \"maxInputTokens\": 163840\n },\n \"deepseek-coder\": {\n \"input\": 0.14,\n \"output\": 0.28,\n \"maxInputTokens\": 128000\n },\n \"gemini-2.0-flash\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-001\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-lite\": {\n \"input\": 0.075,\n \"output\": 0.3,\n \"cachedInput\": 0.01875,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-lite-001\": {\n \"input\": 0.075,\n \"output\": 0.3,\n \"cachedInput\": 0.01875,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-image\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.03,\n \"maxInputTokens\": 32768\n },\n \"gemini-3-pro-image-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"maxInputTokens\": 65536\n },\n \"gemini-3.1-flash-image-preview\": {\n \"input\": 0.5,\n \"output\": 3,\n \"maxInputTokens\": 65536\n },\n \"gemini-3.1-flash-lite-preview\": {\n \"input\": 0.25,\n \"output\": 1.5,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.01,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite-preview-09-2025\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.01,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-preview-09-2025\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 1048576\n },\n \"gemini-live-2.5-flash-preview-native-audio-09-2025\": {\n \"input\": 0.3,\n \"output\": 2,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite-preview-06-17\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3-pro-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"cachedInput\": 0.2,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-pro-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"cachedInput\": 0.2,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-pro-preview-customtools\": {\n \"input\": 2,\n \"output\": 12,\n \"cachedInput\": 0.2,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3-flash-preview\": {\n \"input\": 0.5,\n \"output\": 3,\n \"cachedInput\": 0.05,\n \"maxInputTokens\": 1048576\n },\n \"gemini-robotics-er-1.5-preview\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-computer-use-preview-10-2025\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gemini-flash-latest\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.03,\n \"maxInputTokens\": 1048576\n },\n \"gemini-flash-lite-latest\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"cachedInput\": 0.01,\n \"maxInputTokens\": 1048576\n },\n \"gemini-gemma-2-27b-it\": {\n \"input\": 0.35,\n \"output\": 1.05,\n \"maxInputTokens\": 8192\n },\n \"gemini-gemma-2-9b-it\": {\n \"input\": 0.35,\n \"output\": 1.05,\n \"maxInputTokens\": 8192\n },\n \"deepseek-ai/deepseek-v3.2\": {\n \"input\": 0.28,\n \"output\": 0.4,\n \"maxInputTokens\": 163840\n },\n \"gpt-3.5-turbo-1106\": {\n \"input\": 1,\n \"output\": 2,\n \"maxInputTokens\": 16385\n },\n \"gpt-3.5-turbo-16k\": {\n \"input\": 3,\n \"output\": 4,\n \"maxInputTokens\": 16385\n },\n \"gpt-4-0314\": {\n \"input\": 30,\n \"output\": 60,\n \"maxInputTokens\": 8192\n },\n \"gpt-4-turbo-preview\": {\n \"input\": 10,\n \"output\": 30,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-audio-preview\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-audio-preview-2025-06-03\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-1.5\": {\n \"input\": 2.5,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-mini\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"maxInputTokens\": 128000\n },\n \"gpt-audio-mini-2025-12-15\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-audio-preview\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini-realtime-preview\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"cachedInput\": 0.3,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview\": {\n \"input\": 5,\n \"output\": 20,\n \"cachedInput\": 2.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview-2025-06-03\": {\n \"input\": 5,\n \"output\": 20,\n \"cachedInput\": 2.5,\n \"maxInputTokens\": 128000\n },\n \"gpt-image-1.5\": {\n \"input\": 5,\n \"output\": 10,\n \"cachedInput\": 1.25\n },\n \"gpt-image-1.5-2025-12-16\": {\n \"input\": 5,\n \"output\": 10,\n \"cachedInput\": 1.25\n },\n \"gpt-5.1-chat-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-chat-latest\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.3-chat-latest\": {\n \"input\": 1.75,\n \"output\": 14,\n \"cachedInput\": 0.175,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-pro-2025-10-06\": {\n \"input\": 15,\n \"output\": 120,\n \"maxInputTokens\": 128000\n },\n \"gpt-realtime\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 0.4,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-1.5\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 0.4,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-mini\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"maxInputTokens\": 128000\n },\n \"deepseek-r1-distill-llama-70b\": {\n \"input\": 0.99,\n \"output\": 0.99,\n \"maxInputTokens\": 32768\n },\n \"deepseek-llama3.3-70b\": {\n \"input\": 0.2,\n \"output\": 0.6,\n \"maxInputTokens\": 131072\n },\n \"deepseek-r1-0528\": {\n \"input\": 0.2,\n \"output\": 0.6,\n \"maxInputTokens\": 131072\n },\n \"deepseek-r1-671b\": {\n \"input\": 0.8,\n \"output\": 0.8,\n \"maxInputTokens\": 131072\n },\n \"deepseek-ai/deepseek-r1-distill-llama-8b\": {\n \"input\": 0.025,\n \"output\": 0.025\n },\n \"deepseek-ai/deepseek-r1-distill-qwen-1.5b\": {\n \"input\": 0.09,\n \"output\": 0.09\n },\n \"deepseek-ai/deepseek-r1-distill-qwen-14b\": {\n \"input\": 0.07,\n \"output\": 0.07\n },\n \"deepseek-ai/deepseek-r1-distill-qwen-7b\": {\n \"input\": 0.2,\n \"output\": 0.2\n },\n \"o1\": {\n \"input\": 15,\n \"output\": 60,\n \"cachedInput\": 7.5,\n \"maxInputTokens\": 200000\n },\n \"o1-pro\": {\n \"input\": 150,\n \"output\": 600,\n \"maxInputTokens\": 200000\n },\n \"o1-pro-2025-03-19\": {\n \"input\": 150,\n \"output\": 600,\n \"maxInputTokens\": 200000\n },\n \"o3\": {\n \"input\": 2,\n \"output\": 8,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 200000\n },\n \"gpt-oss-20b\": {\n \"input\": 0.09,\n \"output\": 0.36\n },\n \"deepseek-ai/deepseek-r1-0528-tput\": {\n \"input\": 0.55,\n \"output\": 2.19,\n \"maxInputTokens\": 128000\n },\n \"claude-3-5-haiku\": {\n \"input\": 1,\n \"output\": 5,\n \"maxInputTokens\": 200000\n },\n \"claude-3-5-haiku@20241022\": {\n \"input\": 1,\n \"output\": 5,\n \"maxInputTokens\": 200000\n },\n \"claude-haiku-4-5@20251001\": {\n \"input\": 1,\n \"output\": 5,\n \"cachedInput\": 0.1,\n \"cacheCreationInput\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"claude-3-5-sonnet\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-3-5-sonnet@20240620\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-3-7-sonnet@20250219\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-3-haiku\": {\n \"input\": 0.25,\n \"output\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"claude-3-haiku@20240307\": {\n \"input\": 0.25,\n \"output\": 1.25,\n \"maxInputTokens\": 200000\n },\n \"claude-3-opus\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-3-opus@20240229\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-3-sonnet\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-3-sonnet@20240229\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-1@20250805\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-5@20251101\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-6@default\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-7@default\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-5@20250929\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4@20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"cachedInput\": 1.5,\n \"cacheCreationInput\": 18.75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4@20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"deepseek-ai/deepseek-v3.1-maas\": {\n \"input\": 1.35,\n \"output\": 5.4,\n \"maxInputTokens\": 163840\n },\n \"deepseek-ai/deepseek-v3.2-maas\": {\n \"input\": 0.56,\n \"output\": 1.68,\n \"maxInputTokens\": 163840\n },\n \"deepseek-ai/deepseek-r1-0528-maas\": {\n \"input\": 1.35,\n \"output\": 5.4,\n \"maxInputTokens\": 65336\n },\n \"deepseek-ai/deepseek-ocr-maas\": {\n \"input\": 0.3,\n \"output\": 1.2\n },\n \"deepseek-r1-8b\": {\n \"input\": 0.1,\n \"output\": 0.2,\n \"maxInputTokens\": 65536\n },\n \"deepseek-r1-7b-qwen\": {\n \"input\": 0.08,\n \"output\": 0.15,\n \"maxInputTokens\": 131072\n },\n \"deepseek-coder-6.7b\": {\n \"input\": 0.06,\n \"output\": 0.12,\n \"maxInputTokens\": 16384\n },\n \"gpt-4o-mini-transcribe-2025-03-20\": {\n \"input\": 1.25,\n \"output\": 5,\n \"maxInputTokens\": 16000\n },\n \"gpt-4o-mini-transcribe-2025-12-15\": {\n \"input\": 1.25,\n \"output\": 5,\n \"maxInputTokens\": 16000\n },\n \"gpt-realtime-mini-2025-12-15\": {\n \"input\": 0.6,\n \"output\": 2.4,\n \"cachedInput\": 0.06,\n \"maxInputTokens\": 128000\n },\n \"gemini-2.5-flash-native-audio-latest\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-native-audio-preview-09-2025\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-native-audio-preview-12-2025\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-flash-live-preview\": {\n \"input\": 0.75,\n \"output\": 4.5,\n \"maxInputTokens\": 131072\n },\n \"gemini-pro-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"cachedInput\": 0.125,\n \"maxInputTokens\": 1048576\n },\n \"gemini-exp-1206\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"cachedInput\": 0.03,\n \"maxInputTokens\": 1048576\n },\n \"claude-sonnet-4-6@default\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"cacheCreationInput\": 3.75,\n \"maxInputTokens\": 1000000\n },\n \"gpt-5.5\": {\n \"input\": 5,\n \"output\": 30,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.5-2026-04-23\": {\n \"input\": 5,\n \"output\": 30,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.5-pro\": {\n \"input\": 30,\n \"output\": 180,\n \"cachedInput\": 3,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.5-pro-2026-04-23\": {\n \"input\": 30,\n \"output\": 180,\n \"cachedInput\": 3,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-mini-2026-03-17\": {\n \"input\": 0.75,\n \"output\": 4.5,\n \"cachedInput\": 0.075,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.4-nano-2026-03-17\": {\n \"input\": 0.2,\n \"output\": 1.25,\n \"cachedInput\": 0.02,\n \"maxInputTokens\": 272000\n },\n \"gpt-image-2\": {\n \"input\": 5,\n \"output\": 10,\n \"cachedInput\": 1.25\n },\n \"gpt-image-2-2026-04-21\": {\n \"input\": 5,\n \"output\": 10,\n \"cachedInput\": 1.25\n },\n \"gpt-realtime-2\": {\n \"input\": 4,\n \"output\": 16,\n \"cachedInput\": 0.4,\n \"maxInputTokens\": 32000\n },\n \"gemini-3.5-flash\": {\n \"input\": 1.5,\n \"output\": 9,\n \"cachedInput\": 0.15,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-flash-lite\": {\n \"input\": 0.25,\n \"output\": 1.5,\n \"cachedInput\": 0.025,\n \"maxInputTokens\": 1048576\n },\n \"claude-opus-4-8\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-8@default\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"cacheCreationInput\": 6.25,\n \"maxInputTokens\": 1000000\n },\n \"claude-4-sonnet\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"maxInputTokens\": 200000\n },\n \"claude-4-opus\": {\n \"input\": 5,\n \"output\": 25,\n \"cachedInput\": 0.5,\n \"maxInputTokens\": 200000\n },\n \"claude-3-7-sonnet\": {\n \"input\": 3,\n \"output\": 15,\n \"cachedInput\": 0.3,\n \"maxInputTokens\": 200000\n }\n }\n}\n","import type {\n Tracker,\n TrackerConfig,\n LazyTracker,\n Report,\n CostForecast,\n ModelPrice,\n ReportOptions,\n ForecastOptions,\n} from '../types/index.js'\nimport { createTracker } from './tracker.js'\n\nconst CSV_HEADER =\n 'timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature,appId'\n\nfunction emptyReport(): Report {\n const now = new Date().toISOString()\n return {\n totalCostUSD: 0,\n totalTokens: { input: 0, output: 0 },\n byModel: {},\n bySession: {},\n byUser: {},\n byFeature: {},\n byApp: {},\n period: { from: now, to: now },\n }\n}\n\nfunction zeroForecast(): CostForecast {\n return {\n burnRatePerHour: 0,\n projectedDailyCostUSD: 0,\n projectedMonthlyCostUSD: 0,\n basedOnHours: 0,\n basedOnPeriod: null,\n }\n}\n\n/**\n * Creates a lazy tracker that acts as a silent no-op until `init()` is called.\n *\n * Ideal for module-level singletons where the tracker is imported before `createTracker()`\n * can be called (e.g. Jest test environments, top-level module imports).\n *\n * @example\n * // tracker.ts — safe to import anywhere, even before init\n * export const tracker = createLazyTracker()\n *\n * // app.ts — initialize once at startup\n * tracker.init({ storage: 'sqlite', syncPrices: true })\n *\n * // test.ts — never call init() and track() becomes a silent no-op\n */\nexport function createLazyTracker(): LazyTracker {\n let delegate: Tracker | null = null\n\n return {\n init(config?: TrackerConfig): void {\n if (delegate !== null) {\n throw new Error(\n '[tokenwatch] LazyTracker already initialized. init() may only be called once.',\n )\n }\n try {\n delegate = createTracker(config ?? {})\n } catch (err) {\n // Leave delegate as null — tracker stays in no-op mode after a failed init\n throw err\n }\n },\n\n track(entry) {\n delegate?.track(entry)\n },\n\n async getReport(options?: ReportOptions): Promise<Report> {\n return delegate?.getReport(options) ?? emptyReport()\n },\n\n async getCostForecast(options?: ForecastOptions): Promise<CostForecast> {\n return delegate?.getCostForecast(options) ?? zeroForecast()\n },\n\n async reset(): Promise<void> {\n await delegate?.reset()\n },\n\n async resetSession(sessionId: string): Promise<void> {\n await delegate?.resetSession(sessionId)\n },\n\n async exportJSON(): Promise<string> {\n return delegate?.exportJSON() ?? '{}'\n },\n\n async exportCSV(): Promise<string> {\n return delegate?.exportCSV() ?? CSV_HEADER\n },\n\n getModelInfo(model: string): ModelPrice | null {\n return delegate?.getModelInfo(model) ?? null\n },\n }\n}\n","import type { Tracker, TrackingMeta } from '../types/index.js'\n\n// ─── Minimal structural types (no hard dep on openai package) ────────────────\n\ninterface CompletionTokenDetails {\n reasoning_tokens?: number\n}\n\ninterface PromptTokenDetails {\n cached_tokens?: number\n}\n\ninterface Usage {\n prompt_tokens?: number\n completion_tokens?: number\n input_tokens?: number\n output_tokens?: number\n completion_tokens_details?: CompletionTokenDetails | null\n prompt_tokens_details?: PromptTokenDetails | null\n}\n\ninterface Completion {\n model?: string\n usage?: Usage | null\n}\n\ninterface StreamChunk {\n model?: string\n usage?: Usage | null\n}\n\ninterface CompletionsLike {\n create(params: Record<string, unknown>): Promise<unknown>\n}\n\ninterface ChatLike {\n completions: CompletionsLike\n}\n\ninterface EmbeddingUsage {\n prompt_tokens?: number\n total_tokens?: number\n}\n\ninterface EmbeddingResponse {\n model?: string\n usage?: EmbeddingUsage | null\n}\n\ninterface EmbeddingsLike {\n create(params: Record<string, unknown>): Promise<unknown>\n}\n\ntype OpenAILike = { chat: ChatLike; embeddings?: EmbeddingsLike } & Record<string, unknown>\n\n// ─── Augmented return type ────────────────────────────────────────────────────\n\ntype AugmentedCreate<TCreate extends (...args: any[]) => any> = (\n params: Parameters<TCreate>[0] & TrackingMeta,\n) => ReturnType<TCreate>\n\ntype WrappedOpenAI<T extends OpenAILike> = Omit<T, 'chat' | 'embeddings'> & {\n chat: Omit<T['chat'], 'completions'> & {\n completions: Omit<T['chat']['completions'], 'create'> & {\n create: AugmentedCreate<T['chat']['completions']['create']>\n }\n }\n embeddings: T['embeddings'] extends EmbeddingsLike\n ? Omit<T['embeddings'], 'create'> & {\n create: AugmentedCreate<T['embeddings']['create']>\n }\n : T['embeddings']\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction extractMeta(params: Record<string, unknown>): {\n cleaned: Record<string, unknown>\n sessionId: string | undefined\n userId: string | undefined\n feature: string | undefined\n} {\n const { __sessionId, __userId, __feature, ...cleaned } = params as Record<string, unknown> & TrackingMeta\n return {\n cleaned,\n sessionId: typeof __sessionId === 'string' ? __sessionId : undefined,\n userId: typeof __userId === 'string' ? __userId : undefined,\n feature: typeof __feature === 'string' ? __feature : undefined,\n }\n}\n\nfunction extractUsage(usage: Usage | null | undefined): {\n inputTokens: number\n outputTokens: number\n reasoningTokens: number\n cachedTokens: number\n} {\n if (!usage) return { inputTokens: 0, outputTokens: 0, reasoningTokens: 0, cachedTokens: 0 }\n const totalInput = usage.prompt_tokens ?? usage.input_tokens ?? 0\n const cachedTokens = usage.prompt_tokens_details?.cached_tokens ?? 0\n return {\n // inputTokens = regular (non-cached) input; OpenAI prompt_tokens includes cached tokens\n inputTokens: totalInput - cachedTokens,\n outputTokens: usage.completion_tokens ?? usage.output_tokens ?? 0,\n reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,\n cachedTokens,\n }\n}\n\nfunction trackWithMeta(\n tracker: Tracker,\n model: string,\n inputTokens: number,\n outputTokens: number,\n reasoningTokens: number,\n sessionId: string | undefined,\n userId: string | undefined,\n feature: string | undefined,\n cachedTokens = 0,\n): void {\n // OpenAI bills reasoning_tokens at output price, separately from completion_tokens.\n // We fold them into outputTokens so the cost is correct, and also store them in\n // reasoningTokens so report.byModel[x].tokens.reasoning shows the breakdown.\n tracker.track({\n model,\n inputTokens,\n outputTokens: outputTokens + reasoningTokens,\n ...(reasoningTokens > 0 && { reasoningTokens }),\n ...(cachedTokens > 0 && { cachedTokens }),\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n}\n\n// ─── Streaming wrapper ────────────────────────────────────────────────────────\n\nasync function* wrapStream(\n stream: AsyncIterable<StreamChunk>,\n model: string,\n sessionId: string | undefined,\n userId: string | undefined,\n feature: string | undefined,\n tracker: Tracker,\n): AsyncGenerator<StreamChunk> {\n let lastChunk: StreamChunk | undefined\n for await (const chunk of stream) {\n lastChunk = chunk\n yield chunk\n }\n const { inputTokens, outputTokens, reasoningTokens, cachedTokens } = extractUsage(lastChunk?.usage)\n if (!lastChunk?.usage) {\n console.warn(\n `[tokenwatch] No usage data in stream for model \"${model}\". Cost recorded as $0. ` +\n `Pass stream_options: { include_usage: true } to get accurate costs.`,\n )\n }\n trackWithMeta(tracker, model, inputTokens, outputTokens, reasoningTokens, sessionId, userId, feature, cachedTokens)\n}\n\n// ─── Public wrapper ───────────────────────────────────────────────────────────\n\n/**\n * Wraps an OpenAI client (or any OpenAI-compatible client) to transparently\n * intercept chat.completions.create and embeddings.create calls and report\n * token usage to the tracker.\n *\n * The returned client is typed to accept __sessionId, __userId, and __feature\n * alongside the normal params — no type cast required at the call site.\n */\nexport function wrapOpenAI<T extends OpenAILike>(client: T, tracker: Tracker): WrappedOpenAI<T> {\n const proxiedCompletions = new Proxy(client.chat.completions, {\n get(target, prop) {\n if (prop !== 'create')\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n\n return async function (params: Record<string, unknown>) {\n const { cleaned, sessionId, userId, feature } = extractMeta(params)\n const model = typeof cleaned['model'] === 'string' ? cleaned['model'] : 'unknown'\n\n const result = await (target as CompletionsLike).create(cleaned)\n\n if (result && typeof result === 'object' && Symbol.asyncIterator in result) {\n return wrapStream(\n result as AsyncIterable<StreamChunk>,\n model,\n sessionId,\n userId,\n feature,\n tracker,\n )\n }\n\n const completion = result as Completion\n const { inputTokens, outputTokens, reasoningTokens, cachedTokens } = extractUsage(completion.usage)\n trackWithMeta(\n tracker,\n completion.model ?? model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n sessionId,\n userId,\n feature,\n cachedTokens,\n )\n\n return result\n }\n },\n })\n\n const proxiedChat = new Proxy(client.chat, {\n get(target, prop) {\n if (prop === 'completions') return proxiedCompletions\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n },\n })\n\n // Only proxy embeddings if the client exposes them\n const proxiedEmbeddings = client.embeddings\n ? new Proxy(client.embeddings, {\n get(target, prop) {\n if (prop !== 'create')\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n\n return async function (params: Record<string, unknown>) {\n const { cleaned, sessionId, userId, feature } = extractMeta(params)\n const model = typeof cleaned['model'] === 'string' ? cleaned['model'] : 'unknown'\n\n const result = await (target as EmbeddingsLike).create(cleaned)\n\n const embedding = result as EmbeddingResponse\n const inputTokens = embedding.usage?.total_tokens ?? 0\n // Embeddings have no output tokens or reasoning tokens\n trackWithMeta(tracker, embedding.model ?? model, inputTokens, 0, 0, sessionId, userId, feature)\n\n return result\n }\n },\n })\n : undefined\n\n return new Proxy(client, {\n get(target, prop) {\n if (prop === 'chat') return proxiedChat\n if (prop === 'embeddings') return proxiedEmbeddings\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n },\n }) as unknown as WrappedOpenAI<T>\n}\n","import type { Tracker, TrackingMeta } from '../types/index.js'\n\n// ─── Minimal structural types ─────────────────────────────────────────────────\n\ninterface AnthropicUsage {\n input_tokens?: number\n output_tokens?: number\n /** Tokens read from prompt cache — billed at ~10% of input price */\n cache_read_input_tokens?: number\n /** Tokens written to prompt cache — billed at ~125% of input price */\n cache_creation_input_tokens?: number\n}\n\ninterface ContentBlock {\n type: string\n}\n\ninterface ThinkingBlock extends ContentBlock {\n type: 'thinking'\n thinking?: string\n}\n\ninterface AnthropicMessage {\n model?: string\n usage?: AnthropicUsage | null\n content?: ContentBlock[]\n}\n\ninterface AnthropicStreamEvent {\n type?: string\n usage?: AnthropicUsage | null\n message?: AnthropicMessage\n /** Emitted on content_block_start — describes the block type */\n content_block?: ContentBlock\n /** Emitted on content_block_delta — carries incremental content */\n delta?: { type?: string; thinking?: string; text?: string }\n}\n\ninterface MessagesLike {\n create(params: Record<string, unknown>): Promise<unknown>\n}\n\ntype AnthropicLike = { messages: MessagesLike } & Record<string, unknown>\n\n// ─── Augmented return type ────────────────────────────────────────────────────\n\ntype AugmentedCreate<TCreate extends (...args: any[]) => any> = (\n params: Parameters<TCreate>[0] & TrackingMeta,\n) => ReturnType<TCreate>\n\ntype WrappedAnthropic<T extends AnthropicLike> = Omit<T, 'messages'> & {\n messages: Omit<T['messages'], 'create'> & {\n create: AugmentedCreate<T['messages']['create']>\n }\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction extractMeta(params: Record<string, unknown>): {\n cleaned: Record<string, unknown>\n sessionId: string | undefined\n userId: string | undefined\n feature: string | undefined\n} {\n const { __sessionId, __userId, __feature, ...cleaned } = params as Record<string, unknown> & TrackingMeta\n return {\n cleaned,\n sessionId: typeof __sessionId === 'string' ? __sessionId : undefined,\n userId: typeof __userId === 'string' ? __userId : undefined,\n feature: typeof __feature === 'string' ? __feature : undefined,\n }\n}\n\nfunction extractUsage(usage: AnthropicUsage | null | undefined): {\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n cacheCreationTokens: number\n} {\n if (!usage) return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, cacheCreationTokens: 0 }\n return {\n inputTokens: usage.input_tokens ?? 0,\n outputTokens: usage.output_tokens ?? 0,\n cachedTokens: usage.cache_read_input_tokens ?? 0,\n cacheCreationTokens: usage.cache_creation_input_tokens ?? 0,\n }\n}\n\n/**\n * Anthropic extended thinking: count characters from thinking content blocks\n * and divide by 4 as a rough token approximation.\n *\n * Note: Anthropic already includes thinking output tokens inside outputTokens\n * (message_delta usage.output_tokens). The reasoningTokens value stored here\n * is INFORMATIONAL ONLY — it is NOT added to the cost calculation to avoid\n * double-counting.\n */\nfunction extractThinkingTokenApprox(content: ContentBlock[] | undefined): number {\n if (!content) return 0\n const chars = content\n .filter((b): b is ThinkingBlock => b.type === 'thinking')\n .reduce((sum, b) => sum + (b.thinking?.length ?? 0), 0)\n return chars > 0 ? Math.round(chars / 4) : 0\n}\n\nfunction trackWithMeta(\n tracker: Tracker,\n model: string,\n inputTokens: number,\n outputTokens: number,\n reasoningTokens: number,\n sessionId: string | undefined,\n userId: string | undefined,\n feature: string | undefined,\n cachedTokens = 0,\n cacheCreationTokens = 0,\n): void {\n // Anthropic thinking output is already included in outputTokens — no adjustment needed.\n // reasoningTokens here is an approximation (thinking chars ÷ 4) stored purely for\n // report.byModel[x].tokens.reasoning. The tracker does NOT add it to cost.\n tracker.track({\n model,\n inputTokens,\n outputTokens,\n ...(reasoningTokens > 0 && { reasoningTokens }),\n ...(cachedTokens > 0 && { cachedTokens }),\n ...(cacheCreationTokens > 0 && { cacheCreationTokens }),\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n}\n\n// ─── Streaming wrapper ────────────────────────────────────────────────────────\n\nasync function* wrapStream(\n stream: AsyncIterable<AnthropicStreamEvent>,\n model: string,\n sessionId: string | undefined,\n userId: string | undefined,\n feature: string | undefined,\n tracker: Tracker,\n): AsyncGenerator<AnthropicStreamEvent> {\n let inputTokens = 0\n let outputTokens = 0\n let cachedTokens = 0\n let cacheCreationTokens = 0\n let currentBlockIsThinking = false\n let thinkingCharCount = 0\n\n for await (const event of stream) {\n yield event\n\n if (event.type === 'message_start' && event.message?.usage) {\n inputTokens = event.message.usage.input_tokens ?? 0\n cachedTokens = event.message.usage.cache_read_input_tokens ?? 0\n cacheCreationTokens = event.message.usage.cache_creation_input_tokens ?? 0\n }\n if (event.type === 'message_delta' && event.usage) {\n outputTokens = event.usage.output_tokens ?? 0\n }\n\n // Track thinking blocks for informational reasoningTokens approximation\n if (event.type === 'content_block_start') {\n currentBlockIsThinking = event.content_block?.type === 'thinking'\n }\n if (event.type === 'content_block_stop') {\n currentBlockIsThinking = false\n }\n if (event.type === 'content_block_delta' && currentBlockIsThinking && event.delta?.thinking) {\n thinkingCharCount += event.delta.thinking.length\n }\n }\n\n // reasoningTokens is approximate and informational — Anthropic thinking output\n // is already included in outputTokens, so it is NOT added to cost by the tracker.\n const reasoningTokens = thinkingCharCount > 0 ? Math.round(thinkingCharCount / 4) : 0\n trackWithMeta(tracker, model, inputTokens, outputTokens, reasoningTokens, sessionId, userId, feature, cachedTokens, cacheCreationTokens)\n}\n\n// ─── Public wrapper ───────────────────────────────────────────────────────────\n\n/**\n * Wraps an Anthropic client to transparently intercept messages.create calls\n * and report token usage to the tracker.\n *\n * The returned client is typed to accept __sessionId, __userId, and __feature\n * alongside the normal params — no type cast required at the call site.\n *\n * For extended thinking models, reasoningTokens is stored as an approximation\n * (thinking block characters ÷ 4). It is informational only — thinking output\n * is already included in outputTokens and is not double-counted in cost.\n */\nexport function wrapAnthropic<T extends AnthropicLike>(\n client: T,\n tracker: Tracker,\n): WrappedAnthropic<T> {\n const proxiedMessages = new Proxy(client.messages, {\n get(target, prop) {\n if (prop !== 'create')\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n\n return async function (params: Record<string, unknown>) {\n const { cleaned, sessionId, userId, feature } = extractMeta(params)\n const model = typeof cleaned['model'] === 'string' ? cleaned['model'] : 'unknown'\n\n const result = await (target as MessagesLike).create(cleaned)\n\n if (result && typeof result === 'object' && Symbol.asyncIterator in result) {\n return wrapStream(\n result as AsyncIterable<AnthropicStreamEvent>,\n model,\n sessionId,\n userId,\n feature,\n tracker,\n )\n }\n\n const message = result as AnthropicMessage\n const { inputTokens, outputTokens, cachedTokens, cacheCreationTokens } = extractUsage(message.usage)\n const reasoningTokens = extractThinkingTokenApprox(message.content)\n trackWithMeta(\n tracker,\n message.model ?? model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n sessionId,\n userId,\n feature,\n cachedTokens,\n cacheCreationTokens,\n )\n\n return result\n }\n },\n })\n\n return new Proxy(client, {\n get(target, prop) {\n if (prop === 'messages') return proxiedMessages\n return (target as unknown as Record<string | symbol, unknown>)[prop]\n },\n }) as unknown as WrappedAnthropic<T>\n}\n","import type { Tracker, TrackingMeta } from '../types/index.js'\n\n// ─── Minimal structural types ─────────────────────────────────────────────────\n\ninterface UsageMetadata {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n}\n\ninterface GenerateContentResponse {\n usageMetadata?: UsageMetadata | null\n}\n\ninterface GenerativeModelLike {\n generateContent(params: unknown): Promise<{ response: GenerateContentResponse }>\n generateContentStream(\n params: unknown,\n ): Promise<{\n stream: AsyncIterable<{ usageMetadata?: UsageMetadata | null }>\n response: Promise<GenerateContentResponse>\n }>\n model?: string\n}\n\ninterface GenAILike {\n getGenerativeModel(params: { model: string } & Record<string, unknown>): GenerativeModelLike\n}\n\n// ─── Public wrapper ───────────────────────────────────────────────────────────\n\n/**\n * Wraps a GoogleGenerativeAI client to transparently intercept\n * generateContent / generateContentStream calls and report token usage.\n *\n * Pass __feature in getGenerativeModel params to tag all calls from that model\n * instance with a product feature name (appears in report.byFeature).\n *\n * Returns the same type T that was passed in.\n */\nexport function wrapGemini<T extends GenAILike>(client: T, tracker: Tracker): T {\n return new Proxy(client, {\n get(target, prop) {\n if (prop !== 'getGenerativeModel')\n return (target as Record<string | symbol, unknown>)[prop]\n\n return function (modelParams: { model: string } & Record<string, unknown>) {\n // Extract tracking meta from getGenerativeModel params\n const { __sessionId, __userId, __feature, ...cleanedParams } = modelParams as typeof modelParams & TrackingMeta\n const feature = typeof __feature === 'string' ? __feature : undefined\n const sessionId = typeof __sessionId === 'string' ? __sessionId : undefined\n const userId = typeof __userId === 'string' ? __userId : undefined\n\n const modelInstance = target.getGenerativeModel(cleanedParams as { model: string } & Record<string, unknown>)\n const modelId = modelParams.model\n\n return new Proxy(modelInstance, {\n get(mTarget, mProp) {\n if (mProp === 'generateContent') {\n return async function (params: unknown) {\n const result = await mTarget.generateContent(params)\n const meta = result.response.usageMetadata\n tracker.track({\n model: modelId,\n inputTokens: meta?.promptTokenCount ?? 0,\n outputTokens: meta?.candidatesTokenCount ?? 0,\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n\n return result\n }\n }\n\n if (mProp === 'generateContentStream') {\n return async function (params: unknown) {\n const streamResult = await mTarget.generateContentStream(params)\n\n // Consume usage from the resolved response promise after streaming\n streamResult.response\n .then((res) => {\n const meta = res.usageMetadata\n tracker.track({\n model: modelId,\n inputTokens: meta?.promptTokenCount ?? 0,\n outputTokens: meta?.candidatesTokenCount ?? 0,\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\n ...(feature !== undefined && { feature }),\n })\n })\n .catch(() => {\n // best-effort\n })\n\n return streamResult\n }\n }\n\n return (mTarget as unknown as Record<string | symbol, unknown>)[mProp]\n },\n })\n }\n },\n }) as T\n}\n"],"mappings":"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","names":["bundledPrices","import_node_fs","import_node_os","import_node_path","extractMeta","extractUsage","trackWithMeta","wrapStream"]}