@diogonzafe/tokenwatch 0.1.5 → 0.1.7

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.
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../bin/cli.ts","../src/core/sync.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { join, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { fetchRemotePrices } from '../src/core/sync.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst COMMANDS = ['sync', 'prices', 'report', 'help']\n\nfunction loadBundledPrices(): Record<string, { input: number; output: number }> {\n const pricesPath = join(__dirname, '..', 'prices.json')\n const raw = readFileSync(pricesPath, 'utf8')\n const data = JSON.parse(raw) as {\n updated_at: string\n models: Record<string, { input: number; output: number }>\n }\n return data.models\n}\n\nasync function cmdSync(): Promise<void> {\n console.log('Fetching latest prices from remote...')\n const result = await fetchRemotePrices()\n if (result) {\n console.log(`✓ Prices updated. ${Object.keys(result).length} models cached.`)\n } else {\n console.error('✗ Failed to fetch remote prices. Check your internet connection.')\n process.exit(1)\n }\n}\n\nfunction cmdPrices(): void {\n const models = loadBundledPrices()\n const rows = Object.entries(models).map(([name, price]) => ({\n model: name,\n input: `$${price.input.toFixed(2)}/M`,\n output: `$${price.output.toFixed(2)}/M`,\n }))\n\n const maxName = Math.max(...rows.map((r) => r.model.length), 5)\n const header = `${'Model'.padEnd(maxName)} ${'Input'.padStart(12)} ${'Output'.padStart(12)}`\n const sep = '-'.repeat(header.length)\n\n console.log(header)\n console.log(sep)\n for (const row of rows) {\n console.log(`${row.model.padEnd(maxName)} ${row.input.padStart(12)} ${row.output.padStart(12)}`)\n }\n}\n\nfunction cmdHelp(): void {\n console.log(`\ntokenwatch — CLI\n\nCommands:\n sync Fetch and cache latest model prices from remote\n prices List all bundled models and their current prices\n report Show last saved usage report (requires SQLite storage)\n help Show this help message\n`.trim())\n}\n\nasync function main(): Promise<void> {\n const [, , cmd, ...args] = process.argv\n void args\n\n switch (cmd) {\n case 'sync':\n await cmdSync()\n break\n case 'prices':\n cmdPrices()\n break\n case 'report':\n console.log('report command requires SQLite storage to be configured in your app.')\n break\n case 'help':\n case undefined:\n cmdHelp()\n break\n default:\n console.error(`Unknown command: ${cmd}\\nRun \"tokenwatch help\" for usage.`)\n process.exit(1)\n }\n}\n\nmain().catch((err: unknown) => {\n console.error(err)\n process.exit(1)\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"],"mappings":";;;;AACA,IAAAA,kBAA6B;AAC7B,IAAAC,oBAA8B;AAC9B,sBAA8B;;;ACH9B,sBAA2C;AAC3C,qBAA2B;AAC3B,qBAAwB;AACxB,uBAAqB;AAGrB,IAAM,gBAAY,2BAAK,wBAAQ,GAAG,aAAa;AAC/C,IAAM,iBAAa,uBAAK,WAAW,aAAa;AAChD,IAAM,eAAe,KAAK,KAAK,KAAK;AACpC,IAAM,aACJ;AAEF,eAAsB,kBAAkB,MAAM,YAAsC;AAClF,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,YAAY,QAAQ,GAAK,EAAE,CAAC;AACnE,QAAI,CAAC,IAAI,GAAI,QAAO;AACpB,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,QAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,UAAM,aAAa,IAAI;AACvB,WAAO,KAAK;AAAA,EACd,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAeA,eAAe,aAAa,MAAiC;AAC3D,MAAI;AACF,cAAM,uBAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAC1C,UAAM,UAAU,EAAE,GAAG,MAAM,WAAW,KAAK,IAAI,EAAE;AACjD,cAAM,2BAAU,YAAY,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,MAAM;AAAA,EACtE,QAAQ;AAAA,EAER;AACF;;;AD9CA;AAMA,IAAM,gBAAY,+BAAQ,+BAAc,YAAY,GAAG,CAAC;AAIxD,SAAS,oBAAuE;AAC9E,QAAM,iBAAa,wBAAK,WAAW,MAAM,aAAa;AACtD,QAAM,UAAM,8BAAa,YAAY,MAAM;AAC3C,QAAM,OAAO,KAAK,MAAM,GAAG;AAI3B,SAAO,KAAK;AACd;AAEA,eAAe,UAAyB;AACtC,UAAQ,IAAI,uCAAuC;AACnD,QAAM,SAAS,MAAM,kBAAkB;AACvC,MAAI,QAAQ;AACV,YAAQ,IAAI,0BAAqB,OAAO,KAAK,MAAM,EAAE,MAAM,iBAAiB;AAAA,EAC9E,OAAO;AACL,YAAQ,MAAM,uEAAkE;AAChF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,SAAS,YAAkB;AACzB,QAAM,SAAS,kBAAkB;AACjC,QAAM,OAAO,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;AAAA,IAC1D,OAAO;AAAA,IACP,OAAO,IAAI,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,IACjC,QAAQ,IAAI,MAAM,OAAO,QAAQ,CAAC,CAAC;AAAA,EACrC,EAAE;AAEF,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,GAAG,CAAC;AAC9D,QAAM,SAAS,GAAG,QAAQ,OAAO,OAAO,CAAC,KAAK,QAAQ,SAAS,EAAE,CAAC,KAAK,SAAS,SAAS,EAAE,CAAC;AAC5F,QAAM,MAAM,IAAI,OAAO,OAAO,MAAM;AAEpC,UAAQ,IAAI,MAAM;AAClB,UAAQ,IAAI,GAAG;AACf,aAAW,OAAO,MAAM;AACtB,YAAQ,IAAI,GAAG,IAAI,MAAM,OAAO,OAAO,CAAC,KAAK,IAAI,MAAM,SAAS,EAAE,CAAC,KAAK,IAAI,OAAO,SAAS,EAAE,CAAC,EAAE;AAAA,EACnG;AACF;AAEA,SAAS,UAAgB;AACvB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQZ,KAAK,CAAC;AACR;AAEA,eAAe,OAAsB;AACnC,QAAM,CAAC,EAAE,EAAE,KAAK,GAAG,IAAI,IAAI,QAAQ;AACnC,OAAK;AAEL,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,YAAM,QAAQ;AACd;AAAA,IACF,KAAK;AACH,gBAAU;AACV;AAAA,IACF,KAAK;AACH,cAAQ,IAAI,sEAAsE;AAClF;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AACH,cAAQ;AACR;AAAA,IACF;AACE,cAAQ,MAAM,oBAAoB,GAAG;AAAA,iCAAoC;AACzE,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,QAAiB;AAC7B,UAAQ,MAAM,GAAG;AACjB,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["import_node_fs","import_node_path"]}
1
+ {"version":3,"sources":["../bin/cli.ts","../src/core/sync.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { join, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { fetchRemotePrices } from '../src/core/sync.js'\nimport type { PricesFile } from '../src/types/index.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst COMMANDS = ['sync', 'prices', 'report', 'help']\n\nfunction loadBundledPrices(): PricesFile['models'] {\n const pricesPath = join(__dirname, '..', 'prices.json')\n const raw = readFileSync(pricesPath, 'utf8')\n const data = JSON.parse(raw) as PricesFile\n return data.models\n}\n\nasync function cmdSync(): Promise<void> {\n console.log('Fetching latest prices from remote...')\n const result = await fetchRemotePrices()\n if (result) {\n console.log(`✓ Prices updated. ${Object.keys(result).length} models cached.`)\n } else {\n console.error('✗ Failed to fetch remote prices. Check your internet connection.')\n process.exit(1)\n }\n}\n\nfunction cmdPrices(): void {\n const models = loadBundledPrices()\n const rows = Object.entries(models).map(([name, price]) => ({\n model: name,\n input: `$${price.input.toFixed(2)}/M`,\n output: `$${price.output.toFixed(2)}/M`,\n }))\n\n const maxName = Math.max(...rows.map((r) => r.model.length), 5)\n const header = `${'Model'.padEnd(maxName)} ${'Input'.padStart(12)} ${'Output'.padStart(12)}`\n const sep = '-'.repeat(header.length)\n\n console.log(header)\n console.log(sep)\n for (const row of rows) {\n console.log(`${row.model.padEnd(maxName)} ${row.input.padStart(12)} ${row.output.padStart(12)}`)\n }\n}\n\nfunction cmdHelp(): void {\n console.log(`\ntokenwatch — CLI\n\nCommands:\n sync Fetch and cache latest model prices from remote\n prices List all bundled models and their current prices\n report Show last saved usage report (requires SQLite storage)\n help Show this help message\n`.trim())\n}\n\nasync function main(): Promise<void> {\n const [, , cmd, ...args] = process.argv\n void args\n\n switch (cmd) {\n case 'sync':\n await cmdSync()\n break\n case 'prices':\n cmdPrices()\n break\n case 'report':\n console.log('report command requires SQLite storage to be configured in your app.')\n break\n case 'help':\n case undefined:\n cmdHelp()\n break\n default:\n console.error(`Unknown command: ${cmd}\\nRun \"tokenwatch help\" for usage.`)\n process.exit(1)\n }\n}\n\nmain().catch((err: unknown) => {\n console.error(err)\n process.exit(1)\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"],"mappings":"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","names":["import_node_fs","import_node_path"]}
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../bin/cli.ts","../src/core/sync.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { join, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { fetchRemotePrices } from '../src/core/sync.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst COMMANDS = ['sync', 'prices', 'report', 'help']\n\nfunction loadBundledPrices(): Record<string, { input: number; output: number }> {\n const pricesPath = join(__dirname, '..', 'prices.json')\n const raw = readFileSync(pricesPath, 'utf8')\n const data = JSON.parse(raw) as {\n updated_at: string\n models: Record<string, { input: number; output: number }>\n }\n return data.models\n}\n\nasync function cmdSync(): Promise<void> {\n console.log('Fetching latest prices from remote...')\n const result = await fetchRemotePrices()\n if (result) {\n console.log(`✓ Prices updated. ${Object.keys(result).length} models cached.`)\n } else {\n console.error('✗ Failed to fetch remote prices. Check your internet connection.')\n process.exit(1)\n }\n}\n\nfunction cmdPrices(): void {\n const models = loadBundledPrices()\n const rows = Object.entries(models).map(([name, price]) => ({\n model: name,\n input: `$${price.input.toFixed(2)}/M`,\n output: `$${price.output.toFixed(2)}/M`,\n }))\n\n const maxName = Math.max(...rows.map((r) => r.model.length), 5)\n const header = `${'Model'.padEnd(maxName)} ${'Input'.padStart(12)} ${'Output'.padStart(12)}`\n const sep = '-'.repeat(header.length)\n\n console.log(header)\n console.log(sep)\n for (const row of rows) {\n console.log(`${row.model.padEnd(maxName)} ${row.input.padStart(12)} ${row.output.padStart(12)}`)\n }\n}\n\nfunction cmdHelp(): void {\n console.log(`\ntokenwatch — CLI\n\nCommands:\n sync Fetch and cache latest model prices from remote\n prices List all bundled models and their current prices\n report Show last saved usage report (requires SQLite storage)\n help Show this help message\n`.trim())\n}\n\nasync function main(): Promise<void> {\n const [, , cmd, ...args] = process.argv\n void args\n\n switch (cmd) {\n case 'sync':\n await cmdSync()\n break\n case 'prices':\n cmdPrices()\n break\n case 'report':\n console.log('report command requires SQLite storage to be configured in your app.')\n break\n case 'help':\n case undefined:\n cmdHelp()\n break\n default:\n console.error(`Unknown command: ${cmd}\\nRun \"tokenwatch help\" for usage.`)\n process.exit(1)\n }\n}\n\nmain().catch((err: unknown) => {\n console.error(err)\n process.exit(1)\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"],"mappings":"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","names":["join","join"]}
1
+ {"version":3,"sources":["../bin/cli.ts","../src/core/sync.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { join, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { fetchRemotePrices } from '../src/core/sync.js'\nimport type { PricesFile } from '../src/types/index.js'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nconst COMMANDS = ['sync', 'prices', 'report', 'help']\n\nfunction loadBundledPrices(): PricesFile['models'] {\n const pricesPath = join(__dirname, '..', 'prices.json')\n const raw = readFileSync(pricesPath, 'utf8')\n const data = JSON.parse(raw) as PricesFile\n return data.models\n}\n\nasync function cmdSync(): Promise<void> {\n console.log('Fetching latest prices from remote...')\n const result = await fetchRemotePrices()\n if (result) {\n console.log(`✓ Prices updated. ${Object.keys(result).length} models cached.`)\n } else {\n console.error('✗ Failed to fetch remote prices. Check your internet connection.')\n process.exit(1)\n }\n}\n\nfunction cmdPrices(): void {\n const models = loadBundledPrices()\n const rows = Object.entries(models).map(([name, price]) => ({\n model: name,\n input: `$${price.input.toFixed(2)}/M`,\n output: `$${price.output.toFixed(2)}/M`,\n }))\n\n const maxName = Math.max(...rows.map((r) => r.model.length), 5)\n const header = `${'Model'.padEnd(maxName)} ${'Input'.padStart(12)} ${'Output'.padStart(12)}`\n const sep = '-'.repeat(header.length)\n\n console.log(header)\n console.log(sep)\n for (const row of rows) {\n console.log(`${row.model.padEnd(maxName)} ${row.input.padStart(12)} ${row.output.padStart(12)}`)\n }\n}\n\nfunction cmdHelp(): void {\n console.log(`\ntokenwatch — CLI\n\nCommands:\n sync Fetch and cache latest model prices from remote\n prices List all bundled models and their current prices\n report Show last saved usage report (requires SQLite storage)\n help Show this help message\n`.trim())\n}\n\nasync function main(): Promise<void> {\n const [, , cmd, ...args] = process.argv\n void args\n\n switch (cmd) {\n case 'sync':\n await cmdSync()\n break\n case 'prices':\n cmdPrices()\n break\n case 'report':\n console.log('report command requires SQLite storage to be configured in your app.')\n break\n case 'help':\n case undefined:\n cmdHelp()\n break\n default:\n console.error(`Unknown command: ${cmd}\\nRun \"tokenwatch help\" for usage.`)\n process.exit(1)\n }\n}\n\nmain().catch((err: unknown) => {\n console.error(err)\n process.exit(1)\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"],"mappings":"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","names":["join","join"]}
package/dist/index.cjs CHANGED
@@ -1558,12 +1558,7 @@ function wrapOpenAI(client, tracker) {
1558
1558
  return async function(params) {
1559
1559
  const { cleaned, sessionId, userId } = extractMeta(params);
1560
1560
  const model = typeof cleaned["model"] === "string" ? cleaned["model"] : "unknown";
1561
- let result;
1562
- try {
1563
- result = await target.create(cleaned);
1564
- } catch (err) {
1565
- throw err;
1566
- }
1561
+ const result = await target.create(cleaned);
1567
1562
  if (result && typeof result === "object" && Symbol.asyncIterator in result) {
1568
1563
  return wrapStream(
1569
1564
  result,
@@ -1648,12 +1643,7 @@ function wrapAnthropic(client, tracker) {
1648
1643
  return async function(params) {
1649
1644
  const { cleaned, sessionId, userId } = extractMeta2(params);
1650
1645
  const model = typeof cleaned["model"] === "string" ? cleaned["model"] : "unknown";
1651
- let result;
1652
- try {
1653
- result = await target.create(cleaned);
1654
- } catch (err) {
1655
- throw err;
1656
- }
1646
+ const result = await target.create(cleaned);
1657
1647
  if (result && typeof result === "object" && Symbol.asyncIterator in result) {
1658
1648
  return wrapStream2(
1659
1649
  result,
@@ -1698,12 +1688,7 @@ function wrapGemini(client, tracker) {
1698
1688
  get(mTarget, mProp) {
1699
1689
  if (mProp === "generateContent") {
1700
1690
  return async function(params) {
1701
- let result;
1702
- try {
1703
- result = await mTarget.generateContent(params);
1704
- } catch (err) {
1705
- throw err;
1706
- }
1691
+ const result = await mTarget.generateContent(params);
1707
1692
  const meta = result.response.usageMetadata;
1708
1693
  tracker.track({
1709
1694
  model: modelId,
@@ -1715,12 +1700,7 @@ function wrapGemini(client, tracker) {
1715
1700
  }
1716
1701
  if (mProp === "generateContentStream") {
1717
1702
  return async function(params) {
1718
- let streamResult;
1719
- try {
1720
- streamResult = await mTarget.generateContentStream(params);
1721
- } catch (err) {
1722
- throw err;
1723
- }
1703
+ const streamResult = await mTarget.generateContentStream(params);
1724
1704
  streamResult.response.then((res) => {
1725
1705
  const meta = res.usageMetadata;
1726
1706
  tracker.track({
@@ -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} 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\nconst TrackerConfigSchema = z.object({\n storage: z.enum(['memory', 'sqlite']).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: storageType,\n alertThreshold,\n webhookUrl,\n syncPrices,\n customPrices,\n } = parsed.data\n\n const storage = createStorage(storageType)\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 const total = computeTotal(storage.getAll())\n if (total >= alertThreshold) {\n alertFired = true\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 }\n }\n\n function getReport(): Report {\n const entries = 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 function reset(): void {\n storage.clearAll()\n alertFired = false\n }\n\n function resetSession(sessionId: string): void {\n storage.clearSession(sessionId)\n }\n\n function exportJSON(): string {\n return JSON.stringify(getReport(), null, 2)\n }\n\n function exportCSV(): string {\n const entries = storage.getAll()\n const header = 'timestamp,model,inputTokens,outputTokens,costUSD,sessionId,userId'\n const rows = entries.map((e) =>\n [\n e.timestamp,\n e.model,\n e.inputTokens,\n e.outputTokens,\n e.costUSD.toFixed(8),\n e.sessionId ?? '',\n 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","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').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-16\",\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 let result: unknown\n try {\n result = await (target as CompletionsLike).create(cleaned)\n } catch (err) {\n throw err\n }\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 let result: unknown\n try {\n result = await (target as MessagesLike).create(cleaned)\n } catch (err) {\n throw err\n }\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 let result: { response: GenerateContentResponse }\n try {\n result = await mTarget.generateContent(params)\n } catch (err) {\n throw err\n }\n\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 let streamResult: {\n stream: AsyncIterable<{ usageMetadata?: UsageMetadata | null }>\n response: Promise<GenerateContentResponse>\n }\n try {\n streamResult = await mTarget.generateContentStream(params)\n } catch (err) {\n throw err\n }\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 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} 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\nconst TrackerConfigSchema = z.object({\n storage: z.enum(['memory', 'sqlite']).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: storageType,\n alertThreshold,\n webhookUrl,\n syncPrices,\n customPrices,\n } = parsed.data\n\n const storage = createStorage(storageType)\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 const total = computeTotal(storage.getAll())\n if (total >= alertThreshold) {\n alertFired = true\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 }\n }\n\n function getReport(): Report {\n const entries = 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 function reset(): void {\n storage.clearAll()\n alertFired = false\n }\n\n function resetSession(sessionId: string): void {\n storage.clearSession(sessionId)\n }\n\n function exportJSON(): string {\n return JSON.stringify(getReport(), null, 2)\n }\n\n function exportCSV(): string {\n const entries = storage.getAll()\n const header = 'timestamp,model,inputTokens,outputTokens,costUSD,sessionId,userId'\n const rows = entries.map((e) =>\n [\n e.timestamp,\n e.model,\n e.inputTokens,\n e.outputTokens,\n e.costUSD.toFixed(8),\n e.sessionId ?? '',\n 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","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').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-16\",\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"]}
package/dist/index.js CHANGED
@@ -1527,12 +1527,7 @@ function wrapOpenAI(client, tracker) {
1527
1527
  return async function(params) {
1528
1528
  const { cleaned, sessionId, userId } = extractMeta(params);
1529
1529
  const model = typeof cleaned["model"] === "string" ? cleaned["model"] : "unknown";
1530
- let result;
1531
- try {
1532
- result = await target.create(cleaned);
1533
- } catch (err) {
1534
- throw err;
1535
- }
1530
+ const result = await target.create(cleaned);
1536
1531
  if (result && typeof result === "object" && Symbol.asyncIterator in result) {
1537
1532
  return wrapStream(
1538
1533
  result,
@@ -1617,12 +1612,7 @@ function wrapAnthropic(client, tracker) {
1617
1612
  return async function(params) {
1618
1613
  const { cleaned, sessionId, userId } = extractMeta2(params);
1619
1614
  const model = typeof cleaned["model"] === "string" ? cleaned["model"] : "unknown";
1620
- let result;
1621
- try {
1622
- result = await target.create(cleaned);
1623
- } catch (err) {
1624
- throw err;
1625
- }
1615
+ const result = await target.create(cleaned);
1626
1616
  if (result && typeof result === "object" && Symbol.asyncIterator in result) {
1627
1617
  return wrapStream2(
1628
1618
  result,
@@ -1667,12 +1657,7 @@ function wrapGemini(client, tracker) {
1667
1657
  get(mTarget, mProp) {
1668
1658
  if (mProp === "generateContent") {
1669
1659
  return async function(params) {
1670
- let result;
1671
- try {
1672
- result = await mTarget.generateContent(params);
1673
- } catch (err) {
1674
- throw err;
1675
- }
1660
+ const result = await mTarget.generateContent(params);
1676
1661
  const meta = result.response.usageMetadata;
1677
1662
  tracker.track({
1678
1663
  model: modelId,
@@ -1684,12 +1669,7 @@ function wrapGemini(client, tracker) {
1684
1669
  }
1685
1670
  if (mProp === "generateContentStream") {
1686
1671
  return async function(params) {
1687
- let streamResult;
1688
- try {
1689
- streamResult = await mTarget.generateContentStream(params);
1690
- } catch (err) {
1691
- throw err;
1692
- }
1672
+ const streamResult = await mTarget.generateContentStream(params);
1693
1673
  streamResult.response.then((res) => {
1694
1674
  const meta = res.usageMetadata;
1695
1675
  tracker.track({
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../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":["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} 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\nconst TrackerConfigSchema = z.object({\n storage: z.enum(['memory', 'sqlite']).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: storageType,\n alertThreshold,\n webhookUrl,\n syncPrices,\n customPrices,\n } = parsed.data\n\n const storage = createStorage(storageType)\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 const total = computeTotal(storage.getAll())\n if (total >= alertThreshold) {\n alertFired = true\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 }\n }\n\n function getReport(): Report {\n const entries = 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 function reset(): void {\n storage.clearAll()\n alertFired = false\n }\n\n function resetSession(sessionId: string): void {\n storage.clearSession(sessionId)\n }\n\n function exportJSON(): string {\n return JSON.stringify(getReport(), null, 2)\n }\n\n function exportCSV(): string {\n const entries = storage.getAll()\n const header = 'timestamp,model,inputTokens,outputTokens,costUSD,sessionId,userId'\n const rows = entries.map((e) =>\n [\n e.timestamp,\n e.model,\n e.inputTokens,\n e.outputTokens,\n e.costUSD.toFixed(8),\n e.sessionId ?? '',\n 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","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').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-16\",\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 let result: unknown\n try {\n result = await (target as CompletionsLike).create(cleaned)\n } catch (err) {\n throw err\n }\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 let result: unknown\n try {\n result = await (target as MessagesLike).create(cleaned)\n } catch (err) {\n throw err\n }\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 let result: { response: GenerateContentResponse }\n try {\n result = await mTarget.generateContent(params)\n } catch (err) {\n throw err\n }\n\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 let streamResult: {\n stream: AsyncIterable<{ usageMetadata?: UsageMetadata | null }>\n response: Promise<GenerateContentResponse>\n }\n try {\n streamResult = await mTarget.generateContentStream(params)\n } catch (err) {\n throw err\n }\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","homedir","join","extractMeta","extractUsage","trackWithMeta","wrapStream"]}
1
+ {"version":3,"sources":["../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":["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} 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\nconst TrackerConfigSchema = z.object({\n storage: z.enum(['memory', 'sqlite']).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: storageType,\n alertThreshold,\n webhookUrl,\n syncPrices,\n customPrices,\n } = parsed.data\n\n const storage = createStorage(storageType)\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 const total = computeTotal(storage.getAll())\n if (total >= alertThreshold) {\n alertFired = true\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 }\n }\n\n function getReport(): Report {\n const entries = 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 function reset(): void {\n storage.clearAll()\n alertFired = false\n }\n\n function resetSession(sessionId: string): void {\n storage.clearSession(sessionId)\n }\n\n function exportJSON(): string {\n return JSON.stringify(getReport(), null, 2)\n }\n\n function exportCSV(): string {\n const entries = storage.getAll()\n const header = 'timestamp,model,inputTokens,outputTokens,costUSD,sessionId,userId'\n const rows = entries.map((e) =>\n [\n e.timestamp,\n e.model,\n e.inputTokens,\n e.outputTokens,\n e.costUSD.toFixed(8),\n e.sessionId ?? '',\n 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","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').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-16\",\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","homedir","join","extractMeta","extractUsage","trackWithMeta","wrapStream"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diogonzafe/tokenwatch",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Transparent wrapper to track LLM API costs in real-time by session, user and model",
5
5
  "author": "diogonzafe",
6
6
  "license": "MIT",