@diogonzafe/tokenwatch 0.1.17 → 0.2.1

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/storage.ts","../src/core/sync.ts","../prices.json","../src/providers/openai.ts","../src/providers/anthropic.ts","../src/providers/gemini.ts"],"sourcesContent":["export { createTracker } from './core/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 TrackerConfig,\n UsageEntry,\n Report,\n ModelStats,\n SessionStats,\n UserStats,\n ModelPrice,\n PriceMap,\n PricesFile,\n IStorage,\n TrackingMeta,\n} from './types/index.js'\n","import { z } from 'zod'\nimport type {\n Tracker,\n TrackerConfig,\n UsageEntry,\n Report,\n ModelStats,\n SessionStats,\n UserStats,\n ModelPrice,\n PriceMap,\n IStorage,\n} from '../types/index.js'\nimport { resolvePrice, findPrice, calculateCost } from './pricing.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\n\n// ─── Config validation schema ─────────────────────────────────────────────────\n\nconst ModelPriceSchema = z.object({\n input: z.number().nonnegative(),\n output: z.number().nonnegative(),\n maxInputTokens: z.number().positive().optional(),\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})\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 } = 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. Zero latency added to createTracker().\n let remotePrices: PriceMap | undefined\n if (syncPrices) {\n getRemotePrices()\n .then((result) => {\n if (result) remotePrices = result\n })\n .catch(() => {\n // best-effort — bundled prices remain in use\n })\n }\n\n let alertFired = false\n const startedAt = new Date().toISOString()\n\n function resolveModelPrice(model: string) {\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(entry.inputTokens, entry.outputTokens, price)\n const full: UsageEntry = {\n ...entry,\n costUSD,\n timestamp: new Date().toISOString(),\n }\n storage.record(full)\n maybeFireAlert()\n }\n\n function maybeFireAlert(): void {\n if (!alertThreshold || !webhookUrl || alertFired) return\n // Claim the slot before going async — prevents double-fire when two\n // track() calls happen before the first Promise resolves.\n alertFired = true\n Promise.resolve(storage.getAll()).then((entries) => {\n const total = computeTotal(entries)\n if (total < alertThreshold!) {\n alertFired = false // threshold not yet reached — release the slot\n return\n }\n const payload = {\n text: `[tokenwatch] Alert: total cost reached $${total.toFixed(4)} USD (threshold: $${alertThreshold})`,\n }\n fetch(webhookUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }).catch(() => {\n // fire-and-forget\n })\n }).catch(() => {\n alertFired = false // best-effort — release slot on storage error\n })\n }\n\n async function getReport(): Promise<Report> {\n const entries = await Promise.resolve(storage.getAll())\n const byModel: Record<string, ModelStats> = {}\n const bySession: Record<string, SessionStats> = {}\n const byUser: Record<string, UserStats> = {}\n\n let totalInput = 0\n let totalOutput = 0\n let totalCost = 0\n let lastTimestamp = startedAt\n\n for (const e of entries) {\n totalInput += e.inputTokens\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] ??= { costUSD: 0, calls: 0, tokens: { input: 0, output: 0 } })\n m.costUSD += e.costUSD\n m.calls += 1\n m.tokens.input += e.inputTokens\n m.tokens.output += e.outputTokens\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\n return {\n totalCostUSD: totalCost,\n totalTokens: { input: totalInput, output: totalOutput },\n byModel,\n bySession,\n byUser,\n period: { from: startedAt, to: lastTimestamp },\n }\n }\n\n async function reset(): Promise<void> {\n await Promise.resolve(storage.clearAll())\n alertFired = false\n }\n\n async function resetSession(sessionId: string): Promise<void> {\n await Promise.resolve(storage.clearSession(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 = 'timestamp,model,inputTokens,outputTokens,costUSD,sessionId,userId'\n const rows = entries.map((e) =>\n [\n csvEscape(e.timestamp),\n csvEscape(e.model),\n e.inputTokens,\n e.outputTokens,\n e.costUSD.toFixed(8),\n csvEscape(e.sessionId ?? ''),\n csvEscape(e.userId ?? ''),\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 { track, getReport, reset, resetSession, exportJSON, exportCSV, getModelInfo }\n}\n\nfunction computeTotal(entries: UsageEntry[]): number {\n return entries.reduce((sum, e) => sum + e.costUSD, 0)\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 */\nexport function calculateCost(\n inputTokens: number,\n outputTokens: number,\n price: ModelPrice,\n): number {\n return (inputTokens / 1_000_000) * price.input + (outputTokens / 1_000_000) * price.output\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 cost_usd REAL NOT NULL,\n session_id TEXT,\n user_id TEXT,\n timestamp TEXT NOT NULL\n )\n `)\n }\n\n record(entry: UsageEntry): void {\n this.db\n .prepare(\n `INSERT INTO usage\n (model, input_tokens, output_tokens, cost_usd, session_id, user_id, timestamp)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.model,\n entry.inputTokens,\n entry.outputTokens,\n entry.costUSD,\n entry.sessionId ?? null,\n entry.userId ?? 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 cost_usd: number\n session_id: string | null\n user_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 costUSD: r.cost_usd,\n ...(r.session_id != null && { sessionId: r.session_id }),\n ...(r.user_id != null && { userId: r.user_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 async function fetchRemotePrices(url = REMOTE_URL): Promise<PriceMap | 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 data.models\n } catch {\n return null\n }\n}\n\nexport async function loadCachedPrices(): Promise<PriceMap | 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 return data.models ?? null\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 map:\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<PriceMap | null> {\n const cached = await loadCachedPrices()\n if (cached) return cached\n return fetchRemotePrices()\n}\n","{\n \"updated_at\": \"2026-04-21\",\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 \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"maxInputTokens\": 128000\n },\n \"gpt-5\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-mini\": {\n \"input\": 0.25,\n \"output\": 2,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-nano\": {\n \"input\": 0.05,\n \"output\": 0.4,\n \"maxInputTokens\": 272000\n },\n \"claude-opus-4-6\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-6\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\n },\n \"claude-haiku-4-5\": {\n \"input\": 1,\n \"output\": 5,\n \"maxInputTokens\": 200000\n },\n \"gemini-2.5-pro\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"deepseek-chat\": {\n \"input\": 0.28,\n \"output\": 0.42,\n \"maxInputTokens\": 131072\n },\n \"deepseek-reasoner\": {\n \"input\": 0.28,\n \"output\": 0.42,\n \"maxInputTokens\": 131072\n },\n \"claude-opus-4-5\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-7\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-1\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4-5\": {\n \"input\": 3,\n \"output\": 15,\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 \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-2025-04-14\": {\n \"input\": 2,\n \"output\": 8,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-mini\": {\n \"input\": 0.4,\n \"output\": 1.6,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-mini-2025-04-14\": {\n \"input\": 0.4,\n \"output\": 1.6,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-nano\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-nano-2025-04-14\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.5-preview\": {\n \"input\": 75,\n \"output\": 150,\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 \"maxInputTokens\": 128000\n },\n \"gpt-4o-2024-11-20\": {\n \"input\": 2.5,\n \"output\": 10,\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 \"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 \"maxInputTokens\": 128000\n },\n \"gpt-realtime-2025-08-28\": {\n \"input\": 4,\n \"output\": 16,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-1.5-2026-02-23\": {\n \"input\": 4,\n \"output\": 16,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-mini-2025-10-06\": {\n \"input\": 0.6,\n \"output\": 2.4,\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 \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview-2024-12-17\": {\n \"input\": 5,\n \"output\": 20,\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 \"maxInputTokens\": 272000\n },\n \"gpt-5.1-chat-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1-codex-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-mini-2025-11-13\": {\n \"input\": 0.25,\n \"output\": 2,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-2025-08-07\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-chat\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-chat-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-codex\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-mini-2025-08-07\": {\n \"input\": 0.25,\n \"output\": 2,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-nano-2025-08-07\": {\n \"input\": 0.05,\n \"output\": 0.4,\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 \"maxInputTokens\": 272000\n },\n \"gpt-5.1-chat\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1-codex\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-max\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-mini\": {\n \"input\": 0.25,\n \"output\": 2,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-2025-12-11\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-chat\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-chat-2025-12-11\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-codex\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.3-chat\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.3-codex\": {\n \"input\": 1.75,\n \"output\": 14,\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 \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-2026-03-05\": {\n \"input\": 2.5,\n \"output\": 15,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-pro\": {\n \"input\": 30,\n \"output\": 180,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-pro-2026-03-05\": {\n \"input\": 30,\n \"output\": 180,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-mini\": {\n \"input\": 0.75,\n \"output\": 4.5,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.4-nano\": {\n \"input\": 0.2,\n \"output\": 1.25,\n \"maxInputTokens\": 272000\n },\n \"o1-2024-12-17\": {\n \"input\": 15,\n \"output\": 60,\n \"maxInputTokens\": 200000\n },\n \"o1-mini\": {\n \"input\": 1.21,\n \"output\": 4.84,\n \"maxInputTokens\": 128000\n },\n \"o1-mini-2024-09-12\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"maxInputTokens\": 128000\n },\n \"o1-preview\": {\n \"input\": 15,\n \"output\": 60,\n \"maxInputTokens\": 128000\n },\n \"o1-preview-2024-09-12\": {\n \"input\": 15,\n \"output\": 60,\n \"maxInputTokens\": 128000\n },\n \"o3-2025-04-16\": {\n \"input\": 2,\n \"output\": 8,\n \"maxInputTokens\": 200000\n },\n \"o3-mini\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"maxInputTokens\": 200000\n },\n \"o3-mini-2025-01-31\": {\n \"input\": 1.1,\n \"output\": 4.4,\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 \"maxInputTokens\": 200000\n },\n \"o4-mini-2025-04-16\": {\n \"input\": 1.1,\n \"output\": 4.4,\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 \"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 \"maxInputTokens\": 200000\n },\n \"claude-3-7-sonnet-20250219\": {\n \"input\": 3,\n \"output\": 15,\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-20240229\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-4-opus-20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-4-sonnet-20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-5-20250929\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4-5-20250929-v1:0\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-1-20250805\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-5-20251101\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-6-20260205\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-7-20260416\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\n },\n \"codex-mini-latest\": {\n \"input\": 1.5,\n \"output\": 6,\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 \"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 \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-001\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-lite\": {\n \"input\": 0.075,\n \"output\": 0.3,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-lite-001\": {\n \"input\": 0.075,\n \"output\": 0.3,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-image\": {\n \"input\": 0.3,\n \"output\": 2.5,\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 \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite-preview-09-2025\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-preview-09-2025\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-live-2.5-flash-preview-native-audio-09-2025\": {\n \"input\": 0.3,\n \"output\": 2,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite-preview-06-17\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3-pro-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-pro-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-pro-preview-customtools\": {\n \"input\": 2,\n \"output\": 12,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3-flash-preview\": {\n \"input\": 0.5,\n \"output\": 3,\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 \"maxInputTokens\": 1048576\n },\n \"gemini-flash-lite-latest\": {\n \"input\": 0.1,\n \"output\": 0.4,\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 \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview\": {\n \"input\": 5,\n \"output\": 20,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview-2025-06-03\": {\n \"input\": 5,\n \"output\": 20,\n \"maxInputTokens\": 128000\n },\n \"gpt-image-1.5\": {\n \"input\": 5,\n \"output\": 10\n },\n \"gpt-image-1.5-2025-12-16\": {\n \"input\": 5,\n \"output\": 10\n },\n \"gpt-5.1-chat-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-chat-latest\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.3-chat-latest\": {\n \"input\": 1.75,\n \"output\": 14,\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 \"maxInputTokens\": 32000\n },\n \"gpt-realtime-1.5\": {\n \"input\": 4,\n \"output\": 16,\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 \"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 \"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 \"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 \"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 \"maxInputTokens\": 200000\n },\n \"claude-opus-4-1@20250805\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-5@20251101\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-6@default\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-7@default\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-5@20250929\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4@20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4@20250514\": {\n \"input\": 3,\n \"output\": 15,\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 \"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 \"maxInputTokens\": 1048576\n },\n \"gemini-exp-1206\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"claude-sonnet-4-6@default\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\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 Usage {\n prompt_tokens?: number\n completion_tokens?: number\n input_tokens?: number\n output_tokens?: number\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\ntype OpenAILike = { chat: ChatLike } & Record<string, unknown>\n\n// ─── Augmented return type ────────────────────────────────────────────────────\n// The wrapped client's create() accepts TrackingMeta fields (__sessionId, __userId)\n// in addition to the original params — no `as any` needed at the call site.\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'> & {\n chat: Omit<T['chat'], 'completions'> & {\n completions: Omit<T['chat']['completions'], 'create'> & {\n create: AugmentedCreate<T['chat']['completions']['create']>\n }\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} {\n const { __sessionId, __userId, ...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 }\n}\n\nfunction extractUsage(usage: Usage | null | undefined): {\n inputTokens: number\n outputTokens: number\n} {\n if (!usage) return { inputTokens: 0, outputTokens: 0 }\n return {\n inputTokens: usage.prompt_tokens ?? usage.input_tokens ?? 0,\n outputTokens: usage.completion_tokens ?? usage.output_tokens ?? 0,\n }\n}\n\nfunction trackWithMeta(\n tracker: Tracker,\n model: string,\n inputTokens: number,\n outputTokens: number,\n sessionId: string | undefined,\n userId: string | undefined,\n): void {\n tracker.track({\n model,\n inputTokens,\n outputTokens,\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\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 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 } = 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, sessionId, userId)\n}\n\n// ─── Public wrapper ───────────────────────────────────────────────────────────\n\n/**\n * Wraps an OpenAI client (or any OpenAI-compatible client) to transparently\n * intercept chat.completions.create calls and report token usage to the tracker.\n *\n * The returned client is typed to accept __sessionId and __userId alongside the\n * 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 } = 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 tracker,\n )\n }\n\n const completion = result as Completion\n const { inputTokens, outputTokens } = extractUsage(completion.usage)\n trackWithMeta(\n tracker,\n completion.model ?? model,\n inputTokens,\n outputTokens,\n sessionId,\n userId,\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 return new Proxy(client, {\n get(target, prop) {\n if (prop === 'chat') return proxiedChat\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}\n\ninterface AnthropicMessage {\n model?: string\n usage?: AnthropicUsage | null\n}\n\ninterface AnthropicStreamEvent {\n type?: string\n usage?: AnthropicUsage | null\n message?: AnthropicMessage\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} {\n const { __sessionId, __userId, ...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 }\n}\n\nfunction extractUsage(usage: AnthropicUsage | null | undefined): {\n inputTokens: number\n outputTokens: number\n} {\n if (!usage) return { inputTokens: 0, outputTokens: 0 }\n return {\n inputTokens: usage.input_tokens ?? 0,\n outputTokens: usage.output_tokens ?? 0,\n }\n}\n\nfunction trackWithMeta(\n tracker: Tracker,\n model: string,\n inputTokens: number,\n outputTokens: number,\n sessionId: string | undefined,\n userId: string | undefined,\n): void {\n tracker.track({\n model,\n inputTokens,\n outputTokens,\n ...(sessionId !== undefined && { sessionId }),\n ...(userId !== undefined && { userId }),\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 tracker: Tracker,\n): AsyncGenerator<AnthropicStreamEvent> {\n let inputTokens = 0\n let outputTokens = 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 }\n if (event.type === 'message_delta' && event.usage) {\n outputTokens = event.usage.output_tokens ?? 0\n }\n }\n\n trackWithMeta(tracker, model, inputTokens, outputTokens, sessionId, userId)\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 and __userId alongside the\n * normal params — no type cast required at the call site.\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 } = 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 tracker,\n )\n }\n\n const message = result as AnthropicMessage\n const { inputTokens, outputTokens } = extractUsage(message.usage)\n trackWithMeta(\n tracker,\n message.model ?? model,\n inputTokens,\n outputTokens,\n sessionId,\n userId,\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 } 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 * 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 const modelInstance = target.getGenerativeModel(modelParams)\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 })\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 })\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/storage.ts","../src/core/sync.ts","../prices.json","../src/providers/openai.ts","../src/providers/anthropic.ts","../src/providers/gemini.ts"],"sourcesContent":["export { createTracker } from './core/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 TrackerConfig,\n UsageEntry,\n Report,\n ModelStats,\n SessionStats,\n UserStats,\n FeatureStats,\n ModelPrice,\n PriceMap,\n PricesFile,\n IStorage,\n TrackingMeta,\n} from './types/index.js'\n","import { z } from 'zod'\nimport type {\n Tracker,\n TrackerConfig,\n UsageEntry,\n Report,\n ModelStats,\n SessionStats,\n UserStats,\n FeatureStats,\n ModelPrice,\n PriceMap,\n IStorage,\n} from '../types/index.js'\nimport { resolvePrice, findPrice, calculateCost } from './pricing.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\n\n// ─── Config validation schema ─────────────────────────────────────────────────\n\nconst ModelPriceSchema = z.object({\n input: z.number().nonnegative(),\n output: z.number().nonnegative(),\n maxInputTokens: z.number().positive().optional(),\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})\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 } = 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. Zero latency added to createTracker().\n let remotePrices: PriceMap | undefined\n if (syncPrices) {\n getRemotePrices()\n .then((result) => {\n if (result) remotePrices = result\n })\n .catch(() => {\n // best-effort — bundled prices remain in use\n })\n }\n\n let alertFired = false\n const startedAt = new Date().toISOString()\n\n function resolveModelPrice(model: string) {\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 // Cost is always based on inputTokens + outputTokens only.\n // Provider wrappers are responsible for including any billing-relevant tokens\n // (e.g. OpenAI reasoning_tokens) in outputTokens before calling track().\n // reasoningTokens on UsageEntry is purely informational for the report.\n const costUSD = calculateCost(entry.inputTokens, entry.outputTokens, price)\n const full: UsageEntry = {\n ...entry,\n costUSD,\n timestamp: new Date().toISOString(),\n }\n storage.record(full)\n maybeFireAlert()\n }\n\n function maybeFireAlert(): void {\n if (!alertThreshold || !webhookUrl || alertFired) return\n // Claim the slot before going async — prevents double-fire when two\n // track() calls happen before the first Promise resolves.\n alertFired = true\n Promise.resolve(storage.getAll()).then((entries) => {\n const total = computeTotal(entries)\n if (total < alertThreshold!) {\n alertFired = false // threshold not yet reached — release the slot\n return\n }\n const payload = {\n text: `[tokenwatch] Alert: total cost reached $${total.toFixed(4)} USD (threshold: $${alertThreshold})`,\n }\n fetch(webhookUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }).catch(() => {\n // fire-and-forget\n })\n }).catch(() => {\n alertFired = false // best-effort — release slot on storage error\n })\n }\n\n async function getReport(): Promise<Report> {\n const entries = await Promise.resolve(storage.getAll())\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 lastTimestamp = startedAt\n\n for (const e of entries) {\n totalInput += e.inputTokens\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] ??= { costUSD: 0, calls: 0, tokens: { input: 0, output: 0, reasoning: 0 } })\n m.costUSD += e.costUSD\n m.calls += 1\n m.tokens.input += e.inputTokens\n m.tokens.output += e.outputTokens\n m.tokens.reasoning += e.reasoningTokens ?? 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 return {\n totalCostUSD: totalCost,\n totalTokens: { input: totalInput, output: totalOutput },\n byModel,\n bySession,\n byUser,\n byFeature,\n period: { from: startedAt, to: lastTimestamp },\n }\n }\n\n async function reset(): Promise<void> {\n await Promise.resolve(storage.clearAll())\n alertFired = false\n }\n\n async function resetSession(sessionId: string): Promise<void> {\n await Promise.resolve(storage.clearSession(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 = 'timestamp,model,inputTokens,outputTokens,reasoningTokens,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.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 { track, getReport, reset, resetSession, exportJSON, exportCSV, getModelInfo }\n}\n\nfunction computeTotal(entries: UsageEntry[]): number {\n return entries.reduce((sum, e) => sum + e.costUSD, 0)\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 */\nexport function calculateCost(\n inputTokens: number,\n outputTokens: number,\n price: ModelPrice,\n): number {\n return (inputTokens / 1_000_000) * price.input + (outputTokens / 1_000_000) * price.output\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 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\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 }\n\n record(entry: UsageEntry): void {\n this.db\n .prepare(\n `INSERT INTO usage\n (model, input_tokens, output_tokens, reasoning_tokens, 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.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 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 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 async function fetchRemotePrices(url = REMOTE_URL): Promise<PriceMap | 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 data.models\n } catch {\n return null\n }\n}\n\nexport async function loadCachedPrices(): Promise<PriceMap | 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 return data.models ?? null\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 map:\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<PriceMap | null> {\n const cached = await loadCachedPrices()\n if (cached) return cached\n return fetchRemotePrices()\n}\n","{\n \"updated_at\": \"2026-04-21\",\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 \"maxInputTokens\": 128000\n },\n \"gpt-4o-mini\": {\n \"input\": 0.15,\n \"output\": 0.6,\n \"maxInputTokens\": 128000\n },\n \"gpt-5\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-mini\": {\n \"input\": 0.25,\n \"output\": 2,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-nano\": {\n \"input\": 0.05,\n \"output\": 0.4,\n \"maxInputTokens\": 272000\n },\n \"claude-opus-4-6\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-6\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\n },\n \"claude-haiku-4-5\": {\n \"input\": 1,\n \"output\": 5,\n \"maxInputTokens\": 200000\n },\n \"gemini-2.5-pro\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"deepseek-chat\": {\n \"input\": 0.28,\n \"output\": 0.42,\n \"maxInputTokens\": 131072\n },\n \"deepseek-reasoner\": {\n \"input\": 0.28,\n \"output\": 0.42,\n \"maxInputTokens\": 131072\n },\n \"claude-opus-4-5\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-7\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-1\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4-5\": {\n \"input\": 3,\n \"output\": 15,\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 \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-2025-04-14\": {\n \"input\": 2,\n \"output\": 8,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-mini\": {\n \"input\": 0.4,\n \"output\": 1.6,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-mini-2025-04-14\": {\n \"input\": 0.4,\n \"output\": 1.6,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-nano\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.1-nano-2025-04-14\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1047576\n },\n \"gpt-4.5-preview\": {\n \"input\": 75,\n \"output\": 150,\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 \"maxInputTokens\": 128000\n },\n \"gpt-4o-2024-11-20\": {\n \"input\": 2.5,\n \"output\": 10,\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 \"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 \"maxInputTokens\": 128000\n },\n \"gpt-realtime-2025-08-28\": {\n \"input\": 4,\n \"output\": 16,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-1.5-2026-02-23\": {\n \"input\": 4,\n \"output\": 16,\n \"maxInputTokens\": 32000\n },\n \"gpt-realtime-mini-2025-10-06\": {\n \"input\": 0.6,\n \"output\": 2.4,\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 \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview-2024-12-17\": {\n \"input\": 5,\n \"output\": 20,\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 \"maxInputTokens\": 272000\n },\n \"gpt-5.1-chat-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1-codex-2025-11-13\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-mini-2025-11-13\": {\n \"input\": 0.25,\n \"output\": 2,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-2025-08-07\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-chat\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-chat-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5-codex\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-mini-2025-08-07\": {\n \"input\": 0.25,\n \"output\": 2,\n \"maxInputTokens\": 272000\n },\n \"gpt-5-nano-2025-08-07\": {\n \"input\": 0.05,\n \"output\": 0.4,\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 \"maxInputTokens\": 272000\n },\n \"gpt-5.1-chat\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.1-codex\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-max\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.1-codex-mini\": {\n \"input\": 0.25,\n \"output\": 2,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-2025-12-11\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.2-chat\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-chat-2025-12-11\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-codex\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.3-chat\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.3-codex\": {\n \"input\": 1.75,\n \"output\": 14,\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 \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-2026-03-05\": {\n \"input\": 2.5,\n \"output\": 15,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-pro\": {\n \"input\": 30,\n \"output\": 180,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-pro-2026-03-05\": {\n \"input\": 30,\n \"output\": 180,\n \"maxInputTokens\": 1050000\n },\n \"gpt-5.4-mini\": {\n \"input\": 0.75,\n \"output\": 4.5,\n \"maxInputTokens\": 272000\n },\n \"gpt-5.4-nano\": {\n \"input\": 0.2,\n \"output\": 1.25,\n \"maxInputTokens\": 272000\n },\n \"o1-2024-12-17\": {\n \"input\": 15,\n \"output\": 60,\n \"maxInputTokens\": 200000\n },\n \"o1-mini\": {\n \"input\": 1.21,\n \"output\": 4.84,\n \"maxInputTokens\": 128000\n },\n \"o1-mini-2024-09-12\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"maxInputTokens\": 128000\n },\n \"o1-preview\": {\n \"input\": 15,\n \"output\": 60,\n \"maxInputTokens\": 128000\n },\n \"o1-preview-2024-09-12\": {\n \"input\": 15,\n \"output\": 60,\n \"maxInputTokens\": 128000\n },\n \"o3-2025-04-16\": {\n \"input\": 2,\n \"output\": 8,\n \"maxInputTokens\": 200000\n },\n \"o3-mini\": {\n \"input\": 1.1,\n \"output\": 4.4,\n \"maxInputTokens\": 200000\n },\n \"o3-mini-2025-01-31\": {\n \"input\": 1.1,\n \"output\": 4.4,\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 \"maxInputTokens\": 200000\n },\n \"o4-mini-2025-04-16\": {\n \"input\": 1.1,\n \"output\": 4.4,\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 \"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 \"maxInputTokens\": 200000\n },\n \"claude-3-7-sonnet-20250219\": {\n \"input\": 3,\n \"output\": 15,\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-20240229\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-4-opus-20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-4-sonnet-20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-5-20250929\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4-5-20250929-v1:0\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-1-20250805\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-5-20251101\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-6-20260205\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-7-20260416\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-20250514\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\n },\n \"codex-mini-latest\": {\n \"input\": 1.5,\n \"output\": 6,\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 \"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 \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-001\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-lite\": {\n \"input\": 0.075,\n \"output\": 0.3,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.0-flash-lite-001\": {\n \"input\": 0.075,\n \"output\": 0.3,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-image\": {\n \"input\": 0.3,\n \"output\": 2.5,\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 \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite-preview-09-2025\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-preview-09-2025\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"gemini-live-2.5-flash-preview-native-audio-09-2025\": {\n \"input\": 0.3,\n \"output\": 2,\n \"maxInputTokens\": 1048576\n },\n \"gemini-2.5-flash-lite-preview-06-17\": {\n \"input\": 0.1,\n \"output\": 0.4,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3-pro-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-pro-preview\": {\n \"input\": 2,\n \"output\": 12,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3.1-pro-preview-customtools\": {\n \"input\": 2,\n \"output\": 12,\n \"maxInputTokens\": 1048576\n },\n \"gemini-3-flash-preview\": {\n \"input\": 0.5,\n \"output\": 3,\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 \"maxInputTokens\": 1048576\n },\n \"gemini-flash-lite-latest\": {\n \"input\": 0.1,\n \"output\": 0.4,\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 \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview\": {\n \"input\": 5,\n \"output\": 20,\n \"maxInputTokens\": 128000\n },\n \"gpt-4o-realtime-preview-2025-06-03\": {\n \"input\": 5,\n \"output\": 20,\n \"maxInputTokens\": 128000\n },\n \"gpt-image-1.5\": {\n \"input\": 5,\n \"output\": 10\n },\n \"gpt-image-1.5-2025-12-16\": {\n \"input\": 5,\n \"output\": 10\n },\n \"gpt-5.1-chat-latest\": {\n \"input\": 1.25,\n \"output\": 10,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.2-chat-latest\": {\n \"input\": 1.75,\n \"output\": 14,\n \"maxInputTokens\": 128000\n },\n \"gpt-5.3-chat-latest\": {\n \"input\": 1.75,\n \"output\": 14,\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 \"maxInputTokens\": 32000\n },\n \"gpt-realtime-1.5\": {\n \"input\": 4,\n \"output\": 16,\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 \"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 \"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 \"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 \"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 \"maxInputTokens\": 200000\n },\n \"claude-opus-4-1@20250805\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-5@20251101\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4-6@default\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-opus-4-7@default\": {\n \"input\": 5,\n \"output\": 25,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4-5@20250929\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 200000\n },\n \"claude-opus-4@20250514\": {\n \"input\": 15,\n \"output\": 75,\n \"maxInputTokens\": 200000\n },\n \"claude-sonnet-4\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\n },\n \"claude-sonnet-4@20250514\": {\n \"input\": 3,\n \"output\": 15,\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 \"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 \"maxInputTokens\": 1048576\n },\n \"gemini-exp-1206\": {\n \"input\": 0.3,\n \"output\": 2.5,\n \"maxInputTokens\": 1048576\n },\n \"claude-sonnet-4-6@default\": {\n \"input\": 3,\n \"output\": 15,\n \"maxInputTokens\": 1000000\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 Usage {\n prompt_tokens?: number\n completion_tokens?: number\n input_tokens?: number\n output_tokens?: number\n completion_tokens_details?: CompletionTokenDetails | 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} {\n if (!usage) return { inputTokens: 0, outputTokens: 0, reasoningTokens: 0 }\n return {\n inputTokens: usage.prompt_tokens ?? usage.input_tokens ?? 0,\n outputTokens: usage.completion_tokens ?? usage.output_tokens ?? 0,\n reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,\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): 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 ...(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 } = 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)\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 } = extractUsage(completion.usage)\n trackWithMeta(\n tracker,\n completion.model ?? model,\n inputTokens,\n outputTokens,\n reasoningTokens,\n sessionId,\n userId,\n feature,\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}\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} {\n if (!usage) return { inputTokens: 0, outputTokens: 0 }\n return {\n inputTokens: usage.input_tokens ?? 0,\n outputTokens: usage.output_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): 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 ...(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 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 }\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)\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 } = 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 )\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"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TrackerConfig, a as Tracker, b as TrackingMeta } from './index-Cy_sl3FI.cjs';
2
- export { I as IStorage, M as ModelPrice, c as ModelStats, P as PriceMap, d as PricesFile, R as Report, S as SessionStats, U as UsageEntry, e as UserStats } from './index-Cy_sl3FI.cjs';
1
+ import { T as TrackerConfig, a as Tracker, b as TrackingMeta } from './index-B_EmA3K7.cjs';
2
+ export { F as FeatureStats, I as IStorage, M as ModelPrice, c as ModelStats, P as PriceMap, d as PricesFile, R as Report, S as SessionStats, U as UsageEntry, e as UserStats } from './index-B_EmA3K7.cjs';
3
3
 
4
4
  declare function createTracker(config?: TrackerConfig): Tracker;
5
5
 
@@ -9,23 +9,31 @@ interface CompletionsLike {
9
9
  interface ChatLike {
10
10
  completions: CompletionsLike;
11
11
  }
12
+ interface EmbeddingsLike {
13
+ create(params: Record<string, unknown>): Promise<unknown>;
14
+ }
12
15
  type OpenAILike = {
13
16
  chat: ChatLike;
17
+ embeddings?: EmbeddingsLike;
14
18
  } & Record<string, unknown>;
15
19
  type AugmentedCreate$1<TCreate extends (...args: any[]) => any> = (params: Parameters<TCreate>[0] & TrackingMeta) => ReturnType<TCreate>;
16
- type WrappedOpenAI<T extends OpenAILike> = Omit<T, 'chat'> & {
20
+ type WrappedOpenAI<T extends OpenAILike> = Omit<T, 'chat' | 'embeddings'> & {
17
21
  chat: Omit<T['chat'], 'completions'> & {
18
22
  completions: Omit<T['chat']['completions'], 'create'> & {
19
23
  create: AugmentedCreate$1<T['chat']['completions']['create']>;
20
24
  };
21
25
  };
26
+ embeddings: T['embeddings'] extends EmbeddingsLike ? Omit<T['embeddings'], 'create'> & {
27
+ create: AugmentedCreate$1<T['embeddings']['create']>;
28
+ } : T['embeddings'];
22
29
  };
23
30
  /**
24
31
  * Wraps an OpenAI client (or any OpenAI-compatible client) to transparently
25
- * intercept chat.completions.create calls and report token usage to the tracker.
32
+ * intercept chat.completions.create and embeddings.create calls and report
33
+ * token usage to the tracker.
26
34
  *
27
- * The returned client is typed to accept __sessionId and __userId alongside the
28
- * normal params — no type cast required at the call site.
35
+ * The returned client is typed to accept __sessionId, __userId, and __feature
36
+ * alongside the normal params — no type cast required at the call site.
29
37
  */
30
38
  declare function wrapOpenAI<T extends OpenAILike>(client: T, tracker: Tracker): WrappedOpenAI<T>;
31
39
 
@@ -45,8 +53,12 @@ type WrappedAnthropic<T extends AnthropicLike> = Omit<T, 'messages'> & {
45
53
  * Wraps an Anthropic client to transparently intercept messages.create calls
46
54
  * and report token usage to the tracker.
47
55
  *
48
- * The returned client is typed to accept __sessionId and __userId alongside the
49
- * normal params — no type cast required at the call site.
56
+ * The returned client is typed to accept __sessionId, __userId, and __feature
57
+ * alongside the normal params — no type cast required at the call site.
58
+ *
59
+ * For extended thinking models, reasoningTokens is stored as an approximation
60
+ * (thinking block characters ÷ 4). It is informational only — thinking output
61
+ * is already included in outputTokens and is not double-counted in cost.
50
62
  */
51
63
  declare function wrapAnthropic<T extends AnthropicLike>(client: T, tracker: Tracker): WrappedAnthropic<T>;
52
64
 
@@ -79,6 +91,9 @@ interface GenAILike {
79
91
  * Wraps a GoogleGenerativeAI client to transparently intercept
80
92
  * generateContent / generateContentStream calls and report token usage.
81
93
  *
94
+ * Pass __feature in getGenerativeModel params to tag all calls from that model
95
+ * instance with a product feature name (appears in report.byFeature).
96
+ *
82
97
  * Returns the same type T that was passed in.
83
98
  */
84
99
  declare function wrapGemini<T extends GenAILike>(client: T, tracker: Tracker): T;