vibezcheck 0.5.12 → 0.5.13
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/ai-sdk/index.js +11 -0
- package/dist/ai-sdk/index.js.map +1 -1
- package/dist/ai-sdk/index.mjs +11 -0
- package/dist/ai-sdk/index.mjs.map +1 -1
- package/dist/ai-sdk/middleware.js +11 -0
- package/dist/ai-sdk/middleware.js.map +1 -1
- package/dist/ai-sdk/middleware.mjs +11 -0
- package/dist/ai-sdk/middleware.mjs.map +1 -1
- package/dist/billing/index.js +11 -0
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +11 -0
- package/dist/billing/index.mjs.map +1 -1
- package/dist/cli/index.js +8 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +8 -1
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -0
- package/dist/index.mjs.map +1 -1
- package/dist/meter/index.js +11 -0
- package/dist/meter/index.js.map +1 -1
- package/dist/meter/index.mjs +11 -0
- package/dist/meter/index.mjs.map +1 -1
- package/dist/pricing/index.js +11 -0
- package/dist/pricing/index.js.map +1 -1
- package/dist/pricing/index.mjs +11 -0
- package/dist/pricing/index.mjs.map +1 -1
- package/manifest/pricing-v1.json +4904 -974
- package/package.json +2 -1
package/dist/meter/index.mjs
CHANGED
|
@@ -547,6 +547,10 @@ var MODEL_PRICING_TABLE = {
|
|
|
547
547
|
"text-embedding-3-large": { inputPer1M: 0.13, outputPer1M: 0 },
|
|
548
548
|
"text-embedding-ada-002": { inputPer1M: 0.1, outputPer1M: 0 },
|
|
549
549
|
// --- Anthropic (Modern & Extended Thinking) ---
|
|
550
|
+
"claude-haiku-5.5": { inputPer1M: 0.1, outputPer1M: 0.5, cachedInputPer1M: 0.01 },
|
|
551
|
+
"claude-sonnet-5.5": { inputPer1M: 2, outputPer1M: 10, cachedInputPer1M: 0.1 },
|
|
552
|
+
"claude-opus-5.5": { inputPer1M: 4, outputPer1M: 20, cachedInputPer1M: 0.2 },
|
|
553
|
+
"claude-opus-5.5-fast": { inputPer1M: 8, outputPer1M: 40, cachedInputPer1M: 0.4 },
|
|
550
554
|
"claude-3-7-sonnet": { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },
|
|
551
555
|
"claude-sonnet-5": { inputPer1M: 2, outputPer1M: 10, cachedInputPer1M: 0.3 },
|
|
552
556
|
"claude-3-5-sonnet": { inputPer1M: 3, outputPer1M: 15, cachedInputPer1M: 0.3 },
|
|
@@ -561,6 +565,8 @@ var MODEL_PRICING_TABLE = {
|
|
|
561
565
|
"claude-2.0": { inputPer1M: 8, outputPer1M: 24 },
|
|
562
566
|
"claude-instant-1.2": { inputPer1M: 1.63, outputPer1M: 5.51 },
|
|
563
567
|
// --- Google Gemini (Modern & Thoughts) ---
|
|
568
|
+
"gemini-3.8-flash": { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.075 },
|
|
569
|
+
"gemini-nano-banana-2.1": { inputPer1M: 1.5, outputPer1M: 7.5, cachedInputPer1M: 0.15 },
|
|
564
570
|
"gemini-3.7-flash": { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },
|
|
565
571
|
"gemini-3.1-pro": { inputPer1M: 2, outputPer1M: 12, cachedInputPer1M: 0.5 },
|
|
566
572
|
"gemini-3.5-flash": { inputPer1M: 1.5, outputPer1M: 9, cachedInputPer1M: 0.38 },
|
|
@@ -583,6 +589,7 @@ var MODEL_PRICING_TABLE = {
|
|
|
583
589
|
"grok-2-vision": { inputPer1M: 2, outputPer1M: 10 },
|
|
584
590
|
"grok-beta": { inputPer1M: 5, outputPer1M: 15 },
|
|
585
591
|
// --- Mistral ---
|
|
592
|
+
"mistral-large-4": { inputPer1M: 0.68, outputPer1M: 2.09, cachedInputPer1M: 0.07 },
|
|
586
593
|
"mistral-large-3": { inputPer1M: 2, outputPer1M: 6 },
|
|
587
594
|
"mistral-large-latest": { inputPer1M: 2, outputPer1M: 6 },
|
|
588
595
|
"mistral-large-2411": { inputPer1M: 2, outputPer1M: 6 },
|
|
@@ -664,6 +671,9 @@ var MODEL_ALIASES = {
|
|
|
664
671
|
"sonnet-3.5": "claude-3-5-sonnet",
|
|
665
672
|
"haiku": "claude-3-5-haiku",
|
|
666
673
|
"haiku-3.5": "claude-3-5-haiku",
|
|
674
|
+
"haiku-5.5": "claude-haiku-5.5",
|
|
675
|
+
"sonnet-5.5": "claude-sonnet-5.5",
|
|
676
|
+
"opus-5.5": "claude-opus-5.5",
|
|
667
677
|
"opus": "claude-3-opus",
|
|
668
678
|
"claude-2": "claude-2.0",
|
|
669
679
|
"claude-instant": "claude-instant-1.2",
|
|
@@ -673,6 +683,7 @@ var MODEL_ALIASES = {
|
|
|
673
683
|
// Gemini Shorthands
|
|
674
684
|
"flash": "gemini-2.0-flash",
|
|
675
685
|
"pro": "gemini-1.5-pro",
|
|
686
|
+
"gemini-banana": "gemini-nano-banana-2.1",
|
|
676
687
|
// Meta / Groq Shorthands
|
|
677
688
|
"llama-3.3-70b": "llama-3.3-70b-versatile",
|
|
678
689
|
"llama-3.1-70b": "llama-3.1-70b-versatile",
|
package/dist/meter/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/meter/batcher.ts","../../src/meter/extractors/openai.ts","../../src/meter/extractors/anthropic.ts","../../src/meter/extractors/gemini.ts","../../src/meter/extractors/generic.ts","../../src/meter/extractors/index.ts","../../src/pricing/sync.ts","../../src/pricing/table.ts","../../src/pricing/calculator.ts","../../src/customers/helpers.ts","../../src/meter/stream.ts","../../src/meter/client.ts","../../src/meter/index.ts"],"sourcesContent":["import type { UsageEvent, UsageSummary, MeterOptions } from '../types';\r\n\r\n/**\r\n * Detects whether the current runtime is a serverless environment\r\n * (AWS Lambda, Vercel Serverless, Cloudflare Workers/Pages, Netlify, Deno Deploy, Next.js)\r\n */\r\nexport function isServerlessEnvironment(): boolean {\r\n if (typeof process !== 'undefined' && process.env) {\r\n if (\r\n process.env.VERCEL ||\r\n process.env.AWS_LAMBDA_FUNCTION_NAME ||\r\n process.env.LAMBDA_TASK_ROOT ||\r\n process.env.NETLIFY ||\r\n process.env.DENO_DEPLOYMENT_ID ||\r\n process.env.CF_PAGES ||\r\n process.env.NEXT_RUNTIME\r\n ) {\r\n return true;\r\n }\r\n }\r\n if (typeof globalThis !== 'undefined') {\r\n const g = globalThis as any;\r\n if (g.EdgeRuntime || g.WebSocketPair) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nconst activeBatchers = new Set<MeterBatcher>();\r\nlet exitListenerAttached = false;\r\n\r\nfunction ensureExitListener() {\r\n if (exitListenerAttached) return;\r\n if (typeof process !== 'undefined' && typeof process.once === 'function') {\r\n try {\r\n process.once('beforeExit', () => {\r\n for (const batcher of activeBatchers) {\r\n batcher.flush().catch(() => {});\r\n }\r\n });\r\n exitListenerAttached = true;\r\n } catch {\r\n // Fallback for restricted sandboxes\r\n }\r\n }\r\n}\r\n\r\nexport class MeterBatcher {\r\n private queue: UsageEvent[] = [];\r\n private timer: NodeJS.Timeout | null = null;\r\n private isFlushing: boolean = false;\r\n private readonly maxBatchSize: number;\r\n private readonly flushIntervalMs: number;\r\n private readonly isExplicitFlushInterval: boolean;\r\n private readonly onUsageCallback?: (event: UsageEvent) => void | Promise<void>;\r\n private readonly onBatchCallback?: (events: UsageEvent[]) => void | Promise<void>;\r\n private readonly onErrorCallback?: (error: Error, events: UsageEvent[]) => void;\r\n private readonly debug: boolean;\r\n\r\n // In-memory ledger for local stats\r\n private totalRequests = 0;\r\n private totalTokens = 0;\r\n private totalInputTokens = 0;\r\n private totalOutputTokens = 0;\r\n private totalReasoningTokens = 0;\r\n private totalCostUSD = 0;\r\n private byModel: Record<string, { requests: number; tokens: number; costUSD: number }> = {};\r\n\r\n constructor(options: MeterOptions = {}) {\r\n this.maxBatchSize = options.batching?.maxBatchSize ?? 50;\r\n this.flushIntervalMs = options.batching?.flushIntervalMs ?? 50;\r\n this.isExplicitFlushInterval = options.batching?.flushIntervalMs !== undefined;\r\n this.onUsageCallback = options.onUsage;\r\n this.onBatchCallback = options.onBatch;\r\n this.onErrorCallback = options.onError;\r\n this.debug = options.debug ?? false;\r\n\r\n activeBatchers.add(this);\r\n ensureExitListener();\r\n }\r\n\r\n /**\r\n * Enqueue a usage event for batch dispatching\r\n */\r\n public enqueue(event: UsageEvent): void {\r\n // 1. Update in-memory local ledger\r\n this.recordInLedger(event);\r\n\r\n // 2. Fire onUsage hook immediately\r\n if (this.onUsageCallback) {\r\n try {\r\n const res = this.onUsageCallback(event);\r\n if (res instanceof Promise) {\r\n res.catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\r\n });\r\n }\r\n } catch (err) {\r\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\r\n }\r\n }\r\n\r\n // 3. If no onBatch handler is configured, we run in immediate local mode\r\n if (!this.onBatchCallback) {\r\n if (this.debug) {\r\n console.log(\r\n `[vibezcheck:local] 📊 ${event.model} | Tokens: ${event.usage.totalTokens} | Cost: $${event.cost.totalUSD.toFixed(6)}`\r\n );\r\n }\r\n return;\r\n }\r\n\r\n // 4. Queue for batch dispatch\r\n this.queue.push(event);\r\n\r\n if (this.queue.length >= this.maxBatchSize) {\r\n this.flush().catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Batch flush error:', err);\r\n });\r\n return;\r\n }\r\n\r\n // 5. Serverless Lifecycle Spooling: Auto-register with after() or waitUntil()\r\n if (typeof globalThis !== 'undefined') {\r\n const g = globalThis as any;\r\n if (typeof g.after === 'function') {\r\n g.after(() => this.flush().catch(() => {}));\r\n return;\r\n }\r\n if (typeof g.waitUntil === 'function') {\r\n g.waitUntil(this.flush().catch(() => {}));\r\n return;\r\n }\r\n }\r\n\r\n // In serverless environments where timers are frozen on response, auto-flush immediately unless explicit interval given\r\n if (isServerlessEnvironment() && !this.isExplicitFlushInterval) {\r\n this.flush().catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Serverless auto-flush error:', err);\r\n });\r\n return;\r\n }\r\n\r\n if (!this.timer) {\r\n this.timer = setTimeout(() => {\r\n this.timer = null;\r\n this.flush().catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Debounce flush error:', err);\r\n });\r\n }, this.flushIntervalMs);\r\n }\r\n }\r\n\r\n /**\r\n * Immediately flush all queued events\r\n */\r\n public async flush(): Promise<void> {\r\n if (this.timer) {\r\n clearTimeout(this.timer);\r\n this.timer = null;\r\n }\r\n\r\n if (this.queue.length === 0 || !this.onBatchCallback || this.isFlushing) {\r\n return;\r\n }\r\n\r\n this.isFlushing = true;\r\n const eventsToSend = [...this.queue];\r\n this.queue = [];\r\n\r\n try {\r\n await this.onBatchCallback(eventsToSend);\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n if (this.debug) {\r\n console.error('[vibezcheck] Failed to flush meter event batch:', err);\r\n }\r\n if (this.onErrorCallback) {\r\n this.onErrorCallback(err, eventsToSend);\r\n }\r\n } finally {\r\n this.isFlushing = false;\r\n // If new items were queued while flushing, trigger another flush\r\n if (this.queue.length > 0) {\r\n this.flush().catch(() => {});\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates internal in-memory ledger\r\n */\r\n private recordInLedger(event: UsageEvent): void {\r\n this.totalRequests += 1;\r\n this.totalTokens += event.usage.totalTokens;\r\n this.totalInputTokens += event.usage.inputTokens;\r\n this.totalOutputTokens += event.usage.outputTokens;\r\n this.totalReasoningTokens += event.usage.reasoningTokens ?? 0;\r\n this.totalCostUSD += event.cost.totalUSD;\r\n\r\n const modelKey = event.model;\r\n if (!this.byModel[modelKey]) {\r\n this.byModel[modelKey] = { requests: 0, tokens: 0, costUSD: 0 };\r\n }\r\n this.byModel[modelKey].requests += 1;\r\n this.byModel[modelKey].tokens += event.usage.totalTokens;\r\n this.byModel[modelKey].costUSD += event.cost.totalUSD;\r\n }\r\n\r\n /**\r\n * Get in-memory usage summary\r\n */\r\n public getSummary(): UsageSummary {\r\n return {\r\n totalRequests: this.totalRequests,\r\n totalTokens: this.totalTokens,\r\n totalInputTokens: this.totalInputTokens,\r\n totalOutputTokens: this.totalOutputTokens,\r\n totalReasoningTokens: this.totalReasoningTokens,\r\n totalCostUSD: Number(this.totalCostUSD.toFixed(6)),\r\n byModel: { ...this.byModel },\r\n };\r\n }\r\n\r\n /**\r\n * Reset in-memory ledger\r\n */\r\n public resetLedger(): void {\r\n this.totalRequests = 0;\r\n this.totalTokens = 0;\r\n this.totalInputTokens = 0;\r\n this.totalOutputTokens = 0;\r\n this.totalReasoningTokens = 0;\r\n this.totalCostUSD = 0;\r\n this.byModel = {};\r\n }\r\n}\r\n","import type { TokenUsage } from '../../types';\r\n\r\nexport interface ExtractedUsage {\r\n model: string;\r\n provider: string;\r\n usage: TokenUsage;\r\n}\r\n\r\n/**\r\n * Extracts token usage from OpenAI synchronous responses (ChatCompletion, Responses, Embeddings)\r\n */\r\nexport function extractOpenAIResponseUsage(response: any): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // 1. Standard OpenAI ChatCompletion\r\n if ('choices' in response && 'usage' in response && response.usage) {\r\n const rawUsage = response.usage;\r\n const model = response.model || 'gpt-4o';\r\n\r\n const inputTokens = rawUsage.prompt_tokens ?? 0;\r\n const outputTokens = rawUsage.completion_tokens ?? 0;\r\n const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens ?? 0;\r\n const cachedTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? 0;\r\n\r\n return {\r\n model,\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n // 2. OpenAI Embeddings Response\r\n if ('data' in response && 'usage' in response && response.usage && 'model' in response) {\r\n const rawUsage = response.usage;\r\n const inputTokens = rawUsage.prompt_tokens ?? 0;\r\n\r\n return {\r\n model: response.model || 'text-embedding-3-small',\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens: 0,\r\n totalTokens: inputTokens,\r\n },\r\n };\r\n }\r\n\r\n // 3. OpenAI Responses API (New standard)\r\n if ('status' in response && 'usage' in response && response.usage) {\r\n const rawUsage = response.usage;\r\n const model = response.model || 'gpt-5.6-sol';\r\n\r\n const inputTokens = rawUsage.input_tokens ?? rawUsage.prompt_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? rawUsage.completion_tokens ?? 0;\r\n const reasoningTokens =\r\n rawUsage.output_token_details?.reasoning_tokens ??\r\n rawUsage.completion_tokens_details?.reasoning_tokens ??\r\n 0;\r\n const cachedTokens =\r\n rawUsage.input_token_details?.cached_tokens ??\r\n rawUsage.prompt_tokens_details?.cached_tokens ??\r\n 0;\r\n\r\n return {\r\n model,\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Extracts token usage from an individual OpenAI stream chunk or stream accumulator\r\n */\r\nexport function inspectOpenAIStreamChunk(chunk: any): {\r\n model?: string;\r\n usage?: TokenUsage;\r\n} {\r\n if (!chunk || typeof chunk !== 'object') return {};\r\n\r\n const model = chunk.model;\r\n\r\n // Final chunk with usage object (when stream_options: { include_usage: true }, finish chunk, or Groq / DeepSeek / Mistral stream ending)\r\n const rawUsage =\r\n (chunk.type === 'finish' ? chunk.usage : null) ||\r\n chunk.usage ||\r\n chunk.token_usage ||\r\n chunk.x_groq?.usage ||\r\n chunk.usageMetadata;\r\n if (rawUsage) {\r\n let inputTokens = 0;\r\n let outputTokens = 0;\r\n let reasoningTokens = 0;\r\n let cachedTokens = 0;\r\n\r\n if (typeof rawUsage.inputTokens === 'object' && rawUsage.inputTokens !== null) {\r\n inputTokens = rawUsage.inputTokens.total ?? rawUsage.inputTokens.noCache ?? 0;\r\n cachedTokens = rawUsage.inputTokens.cacheRead ?? 0;\r\n } else if (typeof rawUsage.promptTokens === 'number') {\r\n inputTokens = rawUsage.promptTokens;\r\n } else if (typeof rawUsage.inputTokens === 'number') {\r\n inputTokens = rawUsage.inputTokens;\r\n } else {\r\n inputTokens =\r\n rawUsage.prompt_tokens ??\r\n rawUsage.input_tokens ??\r\n rawUsage.promptTokenCount ??\r\n 0;\r\n }\r\n\r\n if (typeof rawUsage.outputTokens === 'object' && rawUsage.outputTokens !== null) {\r\n outputTokens = rawUsage.outputTokens.total ?? rawUsage.outputTokens.text ?? 0;\r\n reasoningTokens = rawUsage.outputTokens.reasoning ?? 0;\r\n } else if (typeof rawUsage.completionTokens === 'number') {\r\n outputTokens = rawUsage.completionTokens;\r\n } else if (typeof rawUsage.outputTokens === 'number') {\r\n outputTokens = rawUsage.outputTokens;\r\n } else {\r\n outputTokens =\r\n rawUsage.completion_tokens ??\r\n rawUsage.output_tokens ??\r\n rawUsage.candidatesTokenCount ??\r\n 0;\r\n }\r\n\r\n if (!reasoningTokens) {\r\n reasoningTokens =\r\n rawUsage.completion_tokens_details?.reasoning_tokens ??\r\n rawUsage.output_token_details?.reasoning_tokens ??\r\n rawUsage.reasoning_tokens ??\r\n rawUsage.reasoningTokens ??\r\n rawUsage.thoughtsTokenCount ??\r\n 0;\r\n }\r\n\r\n if (!cachedTokens) {\r\n cachedTokens =\r\n rawUsage.prompt_tokens_details?.cached_tokens ??\r\n rawUsage.input_token_details?.cached_tokens ??\r\n rawUsage.prompt_cache_hit_tokens ??\r\n rawUsage.cached_tokens ??\r\n rawUsage.cachedTokens ??\r\n rawUsage.cachedContentTokenCount ??\r\n 0;\r\n }\r\n\r\n return {\r\n model,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n // Response API stream event (response.completed or response.done)\r\n if (chunk.type === 'response.completed' || chunk.type === 'response.done') {\r\n if (chunk.response?.usage) {\r\n const rawUsage = chunk.response.usage;\r\n const inputTokens = rawUsage.input_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? 0;\r\n const reasoningTokens = rawUsage.output_token_details?.reasoning_tokens ?? 0;\r\n const cachedTokens = rawUsage.input_token_details?.cached_tokens ?? 0;\r\n\r\n return {\r\n model: chunk.response.model || model,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n }\r\n\r\n return { model };\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from Anthropic synchronous responses\r\n */\r\nexport function extractAnthropicResponseUsage(response: any): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Anthropic Message response has type: 'message' or role: 'assistant' with usage\r\n if (response.type === 'message' || ('content' in response && 'usage' in response)) {\r\n const rawUsage = response.usage || {};\r\n const model = response.model || 'claude-3-7-sonnet';\r\n\r\n const inputTokens = rawUsage.input_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? 0;\r\n const cachedTokens = rawUsage.cache_read_input_tokens ?? 0;\r\n const cacheWriteTokens = rawUsage.cache_creation_input_tokens ?? 0;\r\n\r\n // Check content blocks for thinking/reasoning tokens count or thinking blocks\r\n let reasoningTokens: number | undefined = undefined;\r\n if (Array.isArray(response.content)) {\r\n const thinkingBlocks = response.content.filter((b: any) => b.type === 'thinking');\r\n if (thinkingBlocks.length > 0) {\r\n // Approximate or extract explicit thinking tokens if present in metadata\r\n reasoningTokens = (rawUsage as any).thinking_tokens ?? undefined;\r\n }\r\n }\r\n\r\n return {\r\n model,\r\n provider: 'anthropic',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens,\r\n visibleOutputTokens:\r\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n cacheWriteTokens: cacheWriteTokens > 0 ? cacheWriteTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Accumulates stream events across an Anthropic raw message stream\r\n */\r\nexport class AnthropicStreamAccumulator {\r\n private model: string = 'claude-3-7-sonnet';\r\n private inputTokens: number = 0;\r\n private outputTokens: number = 0;\r\n private cachedTokens: number = 0;\r\n private cacheWriteTokens: number = 0;\r\n private reasoningTokens: number = 0;\r\n\r\n processEvent(event: any): void {\r\n if (!event || typeof event !== 'object') return;\r\n\r\n // 1. message_start (contains model and initial input usage)\r\n if (event.type === 'message_start' && event.message) {\r\n if (event.message.model) {\r\n this.model = event.message.model;\r\n }\r\n if (event.message.usage) {\r\n this.inputTokens = event.message.usage.input_tokens ?? 0;\r\n this.cachedTokens = event.message.usage.cache_read_input_tokens ?? 0;\r\n this.cacheWriteTokens = event.message.usage.cache_creation_input_tokens ?? 0;\r\n }\r\n }\r\n\r\n // 2. message_delta (contains final output usage)\r\n if (event.type === 'message_delta' && event.usage) {\r\n this.outputTokens = event.usage.output_tokens ?? 0;\r\n if (event.usage.thinking_tokens) {\r\n this.reasoningTokens = event.usage.thinking_tokens;\r\n }\r\n }\r\n\r\n // 3. content_block_start / content_block_delta for thinking blocks\r\n if (event.type === 'content_block_start' && event.content_block?.type === 'thinking') {\r\n // thinking block detected\r\n }\r\n }\r\n\r\n getUsage(): ExtractedUsage {\r\n return {\r\n model: this.model,\r\n provider: 'anthropic',\r\n usage: {\r\n inputTokens: this.inputTokens,\r\n outputTokens: this.outputTokens,\r\n totalTokens: this.inputTokens + this.outputTokens,\r\n reasoningTokens: this.reasoningTokens > 0 ? this.reasoningTokens : undefined,\r\n visibleOutputTokens:\r\n this.reasoningTokens > 0\r\n ? Math.max(0, this.outputTokens - this.reasoningTokens)\r\n : this.outputTokens,\r\n cachedTokens: this.cachedTokens > 0 ? this.cachedTokens : undefined,\r\n cacheWriteTokens: this.cacheWriteTokens > 0 ? this.cacheWriteTokens : undefined,\r\n },\r\n };\r\n }\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from Google Gemini API response or chunk\r\n */\r\nexport function extractGeminiResponseUsage(\r\n response: any,\r\n fallbackModel: string = 'gemini-3.7-flash'\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Gemini returns usageMetadata on response or GenerateContentResult\r\n const usageMetadata = response.usageMetadata || response.response?.usageMetadata;\r\n\r\n if (usageMetadata) {\r\n const inputTokens = usageMetadata.promptTokenCount ?? 0;\r\n const baseOutputTokens = usageMetadata.candidatesTokenCount ?? 0;\r\n const thoughtsTokenCount =\r\n usageMetadata.thoughtsTokenCount ?? (usageMetadata as any).reasoningTokenCount ?? 0;\r\n const cachedTokens = usageMetadata.cachedContentTokenCount ?? 0;\r\n\r\n const totalOutput = baseOutputTokens + thoughtsTokenCount;\r\n const model = response.model || response.response?.model || fallbackModel;\r\n\r\n return {\r\n model,\r\n provider: 'google',\r\n usage: {\r\n inputTokens,\r\n outputTokens: totalOutput,\r\n totalTokens: inputTokens + totalOutput,\r\n reasoningTokens: thoughtsTokenCount > 0 ? thoughtsTokenCount : undefined,\r\n visibleOutputTokens: baseOutputTokens,\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from generic LLM provider objects (DeepSeek, Groq, Mistral, Ollama, Cohere, Together)\r\n */\r\nexport function extractGenericResponseUsage(\r\n response: any,\r\n fallbackModel: string = 'generic-llm',\r\n fallbackProvider: string = 'generic'\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Check common usage property locations\r\n const usage = response.usage || response.token_usage || response.usageMetadata;\r\n\r\n if (usage) {\r\n let inputTokens = 0;\r\n let outputTokens = 0;\r\n let reasoningTokens = 0;\r\n let cachedTokens = 0;\r\n\r\n if (typeof usage.inputTokens === 'object' && usage.inputTokens !== null) {\r\n inputTokens = usage.inputTokens.total ?? usage.inputTokens.noCache ?? 0;\r\n cachedTokens = usage.inputTokens.cacheRead ?? 0;\r\n } else if (typeof usage.promptTokens === 'number') {\r\n inputTokens = usage.promptTokens;\r\n } else if (typeof usage.inputTokens === 'number') {\r\n inputTokens = usage.inputTokens;\r\n } else {\r\n inputTokens =\r\n usage.prompt_tokens ??\r\n usage.input_tokens ??\r\n usage.promptTokenCount ??\r\n usage.prompt_eval_count ??\r\n 0;\r\n }\r\n\r\n if (typeof usage.outputTokens === 'object' && usage.outputTokens !== null) {\r\n outputTokens = usage.outputTokens.total ?? usage.outputTokens.text ?? 0;\r\n reasoningTokens = usage.outputTokens.reasoning ?? 0;\r\n } else if (typeof usage.completionTokens === 'number') {\r\n outputTokens = usage.completionTokens;\r\n } else if (typeof usage.outputTokens === 'number') {\r\n outputTokens = usage.outputTokens;\r\n } else {\r\n outputTokens =\r\n usage.completion_tokens ??\r\n usage.output_tokens ??\r\n usage.candidatesTokenCount ??\r\n usage.eval_count ??\r\n 0;\r\n }\r\n\r\n if (!reasoningTokens) {\r\n reasoningTokens =\r\n usage.reasoning_tokens ??\r\n usage.thoughtsTokenCount ??\r\n usage.completion_tokens_details?.reasoning_tokens ??\r\n 0;\r\n }\r\n\r\n if (!cachedTokens) {\r\n cachedTokens =\r\n usage.prompt_tokens_details?.cached_tokens ??\r\n usage.cached_tokens ??\r\n usage.cachedContentTokenCount ??\r\n 0;\r\n }\r\n\r\n const model = response.model || fallbackModel;\r\n const provider = response.provider || fallbackProvider;\r\n\r\n return {\r\n model,\r\n provider,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n","import type { ExtractedUsage } from './openai';\r\nimport { extractOpenAIResponseUsage } from './openai';\r\nimport { extractAnthropicResponseUsage } from './anthropic';\r\nimport { extractGeminiResponseUsage } from './gemini';\r\nimport { extractGenericResponseUsage } from './generic';\r\n\r\nexport * from './openai';\r\nexport * from './anthropic';\r\nexport * from './gemini';\r\nexport * from './generic';\r\n\r\n/**\r\n * Universal polymorphic response detector\r\n */\r\nexport function detectAndExtractUsage(\r\n response: any,\r\n fallbackModel?: string,\r\n fallbackProvider?: string\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // 1. Try OpenAI\r\n const openaiResult = extractOpenAIResponseUsage(response);\r\n if (openaiResult) return openaiResult;\r\n\r\n // 2. Try Anthropic\r\n const anthropicResult = extractAnthropicResponseUsage(response);\r\n if (anthropicResult) return anthropicResult;\r\n\r\n // 3. Try Gemini\r\n const geminiResult = extractGeminiResponseUsage(response, fallbackModel);\r\n if (geminiResult) return geminiResult;\r\n\r\n // 4. Try Generic\r\n const genericResult = extractGenericResponseUsage(response, fallbackModel, fallbackProvider);\r\n if (genericResult) return genericResult;\r\n\r\n return null;\r\n}\r\n","import type { ModelPricingRates } from '../types';\nimport { normalizeModelKey } from './table';\n\nexport interface PricingSyncOptions {\n /**\n * Remote manifest URL to fetch pricing from.\n * Defaults to the official hosted pricing-v1.json manifest.\n */\n manifestUrl?: string;\n\n /**\n * Request timeout in milliseconds (default: 3000ms).\n */\n timeoutMs?: number;\n\n /**\n * Custom fetch implementation (defaults to globalThis.fetch).\n */\n fetch?: typeof fetch;\n\n /**\n * Maximum cache age in milliseconds before re-fetching (default: 3600_000 = 1 hour).\n */\n cacheTtlMs?: number;\n\n /**\n * If true, bypass cache TTL and force an immediate re-fetch.\n */\n force?: boolean;\n\n /**\n * Fallback manifest JSON string or object to seed cache if network fails.\n */\n fallbackManifest?: unknown;\n\n /**\n * Custom headers for authentication or versioning.\n */\n headers?: Record<string, string>;\n}\n\nexport interface PricingSyncStatus {\n status: 'idle' | 'syncing' | 'synced' | 'failed';\n lastSyncTime: number | null;\n lastSyncETag: string | null;\n cachedModelsCount: number;\n lastError: string | null;\n}\n\nexport interface StripePricingItem {\n publisher?: string;\n provider?: string;\n model: string;\n prices_per_1m: {\n input_token?: number | null;\n output_token?: number | null;\n cached_input?: number | null;\n cached_output?: number | null;\n cached_read?: number | null;\n cached_write?: number | null;\n };\n}\n\nexport const DEFAULT_MANIFEST_URL =\n 'https://raw.githubusercontent.com/seeyouin2x5x/vibezcheck-sdk/main/manifest/pricing-v1.json';\n\nexport const VERCEL_GATEWAY_MODELS_URL = 'https://ai-gateway.vercel.sh/v1/models';\n\nexport interface VercelGatewayModelItem {\n id: string;\n name?: string;\n owned_by?: string;\n type?: string;\n pricing?: {\n input?: string | number | null;\n output?: string | number | null;\n input_cache_read?: string | number | null;\n input_cache_write?: string | number | null;\n };\n prices_per_1m?: {\n input_token?: number | null;\n output_token?: number | null;\n cached_input?: number | null;\n cached_write?: number | null;\n };\n}\n\nconst DEFAULT_TIMEOUT_MS = 3000;\nconst DEFAULT_CACHE_TTL_MS = 3600_000; // 1 hour\n\n// In-memory fast cache\nconst dynamicPricingCache: Record<string, ModelPricingRates> = {};\n\nlet lastSyncTime: number | null = null;\nlet lastSyncETag: string | null = null;\nlet syncStatus: 'idle' | 'syncing' | 'synced' | 'failed' = 'idle';\nlet lastError: string | null = null;\n\n/**\n * Synchronously retrieves a rate from the dynamic pricing cache\n */\nexport function getDynamicRate(model: string): ModelPricingRates | undefined {\n if (!model) return undefined;\n const key = model.toLowerCase().trim();\n if (dynamicPricingCache[key]) {\n return dynamicPricingCache[key];\n }\n const normalized = normalizeModelKey(key);\n if (dynamicPricingCache[normalized]) {\n return dynamicPricingCache[normalized];\n }\n return undefined;\n}\n\n/**\n * Returns the count of models currently held in dynamic cache\n */\nexport function getDynamicCacheSize(): number {\n return Object.keys(dynamicPricingCache).length;\n}\n\n/**\n * Resets the in-memory dynamic pricing cache\n */\nexport function clearDynamicCache(): void {\n for (const k of Object.keys(dynamicPricingCache)) {\n delete dynamicPricingCache[k];\n }\n lastSyncTime = null;\n lastSyncETag = null;\n syncStatus = 'idle';\n lastError = null;\n}\n\n/**\n * Current synchronization status and telemetry\n */\nexport function getSyncStatus(): PricingSyncStatus {\n return {\n status: syncStatus,\n lastSyncTime,\n lastSyncETag,\n cachedModelsCount: Object.keys(dynamicPricingCache).length,\n lastError,\n };\n}\n\n/**\n * Ingests and registers an array of Stripe rate items or a manifest object into cache\n */\nexport function seedPricingCache(manifest: unknown): number {\n if (!manifest || typeof manifest !== 'object') {\n return 0;\n }\n\n let count = 0;\n\n // Case 1: Array of pricing items (Stripe or Vercel)\n if (Array.isArray(manifest)) {\n for (const item of manifest) {\n if (registerStripeItem(item) || registerVercelGatewayItem(item)) {\n count++;\n }\n }\n return count;\n }\n\n const obj = manifest as Record<string, any>;\n\n // Case 2: Vercel Gateway direct endpoint response: { object: \"list\", data: [...] }\n if (obj.object === 'list' && Array.isArray(obj.data)) {\n for (const item of obj.data) {\n if (registerVercelGatewayItem(item) || registerStripeItem(item)) {\n count++;\n }\n }\n return count;\n }\n\n // Case 3: Object with models array (e.g. { models: [...] })\n if (Array.isArray(obj.models)) {\n for (const item of obj.models) {\n if (registerStripeItem(item) || registerVercelGatewayItem(item)) {\n count++;\n }\n }\n }\n\n // Case 4: Object with vercel_gateway_models array\n if (Array.isArray(obj.vercel_gateway_models)) {\n for (const item of obj.vercel_gateway_models) {\n if (registerVercelGatewayItem(item) || registerStripeItem(item)) {\n count++;\n }\n }\n }\n\n // Case 5: Object with rates dictionary (e.g. { rates: { \"gpt-4o\": { inputPer1M: 2.5, ... } } })\n const ratesDict = obj.rates && typeof obj.rates === 'object' ? obj.rates : obj;\n for (const [key, val] of Object.entries(ratesDict)) {\n if (\n key === 'models' ||\n key === 'rates' ||\n key === 'version' ||\n key === '$schema' ||\n key === 'sources' ||\n key === 'vercel_gateway_models'\n ) {\n continue;\n }\n const v = val as any;\n if (v && typeof v === 'object' && typeof v.inputPer1M === 'number' && typeof v.outputPer1M === 'number') {\n registerRate(key, {\n inputPer1M: Math.max(0, v.inputPer1M),\n outputPer1M: Math.max(0, v.outputPer1M),\n cachedInputPer1M: typeof v.cachedInputPer1M === 'number' ? Math.max(0, v.cachedInputPer1M) : undefined,\n reasoningPer1M: typeof v.reasoningPer1M === 'number' ? Math.max(0, v.reasoningPer1M) : undefined,\n cacheWritePer1M: typeof v.cacheWritePer1M === 'number' ? Math.max(0, v.cacheWritePer1M) : undefined,\n currency: typeof v.currency === 'string' ? v.currency : 'USD',\n });\n count++;\n }\n }\n\n return count;\n}\n\nfunction registerRate(key: string, rate: ModelPricingRates): void {\n const cleanKey = key.toLowerCase().trim();\n dynamicPricingCache[cleanKey] = rate;\n const normalized = normalizeModelKey(cleanKey);\n dynamicPricingCache[normalized] = rate;\n}\n\nfunction registerVercelGatewayItem(entry: any): boolean {\n if (!entry || typeof entry !== 'object') return false;\n const modelId = typeof entry.id === 'string' ? entry.id : typeof entry.model === 'string' ? entry.model : null;\n if (!modelId) return false;\n\n // If entry has prices_per_1m already precomputed\n if (entry.prices_per_1m && typeof entry.prices_per_1m.input_token === 'number' && typeof entry.prices_per_1m.output_token === 'number') {\n return registerStripeItem({ ...entry, model: modelId });\n }\n\n const p = entry.pricing;\n if (!p || typeof p !== 'object') return false;\n\n const inSingle = p.input !== undefined && p.input !== null ? parseFloat(String(p.input)) : null;\n const outSingle = p.output !== undefined && p.output !== null ? parseFloat(String(p.output)) : null;\n if (inSingle === null || isNaN(inSingle) || outSingle === null || isNaN(outSingle)) {\n return false;\n }\n\n const roundRate = (v: number) => Math.round(v * 1e6) / 1e6;\n\n const rateObj: ModelPricingRates = {\n inputPer1M: Math.max(0, roundRate(inSingle * 1_000_000)),\n outputPer1M: Math.max(0, roundRate(outSingle * 1_000_000)),\n currency: 'USD',\n };\n\n if (p.input_cache_read !== undefined && p.input_cache_read !== null) {\n const cr = parseFloat(String(p.input_cache_read));\n if (!isNaN(cr)) {\n rateObj.cachedInputPer1M = Math.max(0, roundRate(cr * 1_000_000));\n }\n }\n if (p.input_cache_write !== undefined && p.input_cache_write !== null) {\n const cw = parseFloat(String(p.input_cache_write));\n if (!isNaN(cw)) {\n rateObj.cacheWritePer1M = Math.max(0, roundRate(cw * 1_000_000));\n }\n }\n\n const fullId = modelId.toLowerCase().trim();\n registerRate(fullId, rateObj);\n\n if (fullId.includes('/')) {\n const stripped = fullId.split('/').slice(1).join('/');\n registerRate(stripped, rateObj);\n }\n\n if (entry.owned_by && typeof entry.owned_by === 'string') {\n const owner = entry.owned_by.toLowerCase().replace(/\\s+/g, '-');\n dynamicPricingCache[`${owner}/${fullId}`] = rateObj;\n }\n\n return true;\n}\n\nfunction registerStripeItem(entry: any): boolean {\n const modelKey = typeof entry.model === 'string' ? entry.model : typeof entry.id === 'string' ? entry.id : null;\n if (!entry || typeof entry !== 'object' || !modelKey) {\n return false;\n }\n const p = entry.prices_per_1m;\n if (!p || typeof p !== 'object') return false;\n if (typeof p.input_token !== 'number' || typeof p.output_token !== 'number') return false;\n\n const rateObj: ModelPricingRates = {\n inputPer1M: Math.max(0, p.input_token),\n outputPer1M: Math.max(0, p.output_token),\n currency: 'USD',\n };\n\n if (typeof p.cached_input === 'number') {\n rateObj.cachedInputPer1M = Math.max(0, p.cached_input);\n } else if (typeof p.cached_read === 'number') {\n rateObj.cachedInputPer1M = Math.max(0, p.cached_read);\n }\n\n if (typeof p.cached_write === 'number') {\n rateObj.cacheWritePer1M = Math.max(0, p.cached_write);\n }\n\n const baseKey = modelKey.toLowerCase().trim();\n registerRate(baseKey, rateObj);\n\n if (entry.publisher && typeof entry.publisher === 'string') {\n const pub = entry.publisher.toLowerCase().replace(/\\s+/g, '-');\n dynamicPricingCache[`${pub}/${baseKey}`] = rateObj;\n if (pub === 'mistral-ai') {\n dynamicPricingCache[`mistral/${baseKey}`] = rateObj;\n }\n }\n\n if (entry.provider && typeof entry.provider === 'string') {\n const prov = entry.provider.toLowerCase().replace(/\\s+/g, '-');\n dynamicPricingCache[`${prov}/${baseKey}`] = rateObj;\n }\n\n return true;\n}\n\n/**\n * Asynchronously synchronizes the LLM pricing manifest from a remote endpoint.\n *\n * Guaranteed Safe & Non-Throwing:\n * If network is down, request times out, or manifest is invalid, returns false\n * and seamlessly preserves existing cached or bundled rates (offline fallback).\n */\nexport async function syncPricingManifest(options: PricingSyncOptions = {}): Promise<boolean> {\n const ttl = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n const now = Date.now();\n\n // If cache is fresh and not forced, reuse existing cache\n if (!options.force && lastSyncTime !== null && now - lastSyncTime < ttl && Object.keys(dynamicPricingCache).length > 0) {\n return true;\n }\n\n const url = options.manifestUrl || DEFAULT_MANIFEST_URL;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const fetchFn = options.fetch || globalThis.fetch;\n\n if (typeof fetchFn !== 'function') {\n // No fetch available in environment; try fallback manifest\n if (options.fallbackManifest) {\n seedPricingCache(options.fallbackManifest);\n lastSyncTime = now;\n syncStatus = 'synced';\n return true;\n }\n syncStatus = 'failed';\n lastError = 'Fetch API unavailable in runtime environment';\n return false;\n }\n\n syncStatus = 'syncing';\n\n const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timeoutId = controller ? setTimeout(() => controller.abort(), timeoutMs) : null;\n\n try {\n const reqHeaders: Record<string, string> = {\n Accept: 'application/json',\n ...(options.headers || {}),\n };\n\n if (lastSyncETag && !options.force) {\n reqHeaders['If-None-Match'] = lastSyncETag;\n }\n\n const response = await fetchFn(url, {\n method: 'GET',\n headers: reqHeaders,\n signal: controller?.signal,\n });\n\n if (timeoutId) clearTimeout(timeoutId);\n\n // 304 Not Modified: Existing dynamic cache is still up to date\n if (response.status === 304) {\n lastSyncTime = now;\n syncStatus = 'synced';\n lastError = null;\n return true;\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`);\n }\n\n const etag = response.headers?.get ? response.headers.get('etag') : null;\n if (etag) {\n lastSyncETag = etag;\n }\n\n const data = await response.json();\n const seeded = seedPricingCache(data);\n\n if (seeded === 0) {\n throw new Error('Manifest contains no recognizable pricing rates');\n }\n\n lastSyncTime = now;\n syncStatus = 'synced';\n lastError = null;\n return true;\n } catch (err: any) {\n if (timeoutId) clearTimeout(timeoutId);\n\n syncStatus = 'failed';\n lastError = err?.message || 'Unknown network error';\n\n // Seed fallback if provided\n if (options.fallbackManifest) {\n seedPricingCache(options.fallbackManifest);\n }\n\n // Graceful offline fallback: Never throw, return false\n return false;\n }\n}\n\n/**\n * Non-blocking, fire-and-forget background synchronization.\n * Triggers sync in background without awaiting or crashing if network is unavailable.\n */\nexport function triggerBackgroundSync(options: PricingSyncOptions = {}): void {\n syncPricingManifest(options).catch(() => {\n // Silently caught - offline fallback preserved\n });\n}\n\n/**\n * Synchronizes LLM token pricing directly from Vercel AI Gateway (https://ai-gateway.vercel.sh/v1/models).\n * Converts single-token rates into per-1M-token rates and populates dynamic cache.\n */\nexport async function syncVercelGateway(options: PricingSyncOptions = {}): Promise<boolean> {\n return syncPricingManifest({\n manifestUrl: VERCEL_GATEWAY_MODELS_URL,\n ...options,\n });\n}\n\n/**\n * Non-blocking, fire-and-forget background synchronization from Vercel AI Gateway.\n */\nexport function triggerVercelGatewaySync(options: PricingSyncOptions = {}): void {\n syncVercelGateway(options).catch(() => {\n // Silently caught - offline fallback preserved\n });\n}\n\n","import type { ModelPricingRates } from '../types';\r\nimport { getDynamicRate } from './sync';\r\n\r\n/**\r\n * Built-in Registry of Model Pricing (USD per 1 Million Tokens)\r\n * Sourced from official 2026 provider pricing tables.\r\n */\r\nexport const MODEL_PRICING_TABLE: Record<string, ModelPricingRates> = {\r\n // --- OpenAI (Modern & Reasoning) ---\r\n 'gpt-5.6-sol': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\r\n 'gpt-5.6-terra': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.2 },\r\n 'gpt-5.6-luna': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\r\n 'gpt-5': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\r\n 'gpt-5-mini': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\r\n 'o1': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\r\n 'o1-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\r\n 'o3': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\r\n 'o3-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\r\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10.0, cachedInputPer1M: 1.25 },\r\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.075 },\r\n 'gpt-4.5': { inputPer1M: 75.0, outputPer1M: 150.0, cachedInputPer1M: 37.5 },\r\n 'gpt-4.5-preview': { inputPer1M: 75.0, outputPer1M: 150.0, cachedInputPer1M: 37.5 },\r\n 'chatgpt-4o-latest': { inputPer1M: 5.0, outputPer1M: 15.0 },\r\n 'gpt-4.1': { inputPer1M: 2.0, outputPer1M: 8.0, cachedInputPer1M: 1.0 },\r\n 'gpt-4.1-nano': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.05 },\r\n 'gpt-6-astra': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 0.5 },\r\n 'gpt-6-astra-fast': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\r\n 'gpt-image-2.5-flare': { inputPer1M: 0.0, outputPer1M: 0.04 },\r\n 'gpt-image-2.5-sunburst': { inputPer1M: 0.0, outputPer1M: 0.08 },\r\n\r\n // --- OpenAI (Legacy & Backward Compatibility) ---\r\n 'gpt-4-turbo': { inputPer1M: 10.0, outputPer1M: 30.0, cachedInputPer1M: 5.0 },\r\n 'gpt-4-turbo-preview': { inputPer1M: 10.0, outputPer1M: 30.0, cachedInputPer1M: 5.0 },\r\n 'gpt-4': { inputPer1M: 30.0, outputPer1M: 60.0 },\r\n 'gpt-4-32k': { inputPer1M: 60.0, outputPer1M: 120.0 },\r\n 'gpt-3.5-turbo': { inputPer1M: 0.5, outputPer1M: 1.5 },\r\n 'gpt-3.5-turbo-16k': { inputPer1M: 3.0, outputPer1M: 4.0 },\r\n 'text-embedding-3-small': { inputPer1M: 0.02, outputPer1M: 0.0 },\r\n 'text-embedding-3-large': { inputPer1M: 0.13, outputPer1M: 0.0 },\r\n 'text-embedding-ada-002': { inputPer1M: 0.10, outputPer1M: 0.0 },\r\n\r\n // --- Anthropic (Modern & Extended Thinking) ---\r\n 'claude-3-7-sonnet': { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },\r\n 'claude-sonnet-5': { inputPer1M: 2.0, outputPer1M: 10.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-5-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-5-haiku': { inputPer1M: 0.8, outputPer1M: 4.0, cachedInputPer1M: 0.08 },\r\n 'haiku-4.5': { inputPer1M: 1.0, outputPer1M: 5.0, cachedInputPer1M: 0.1 },\r\n 'claude-opus-5': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 1.5 },\r\n 'claude-3-opus': { inputPer1M: 15.0, outputPer1M: 75.0, cachedInputPer1M: 1.5 },\r\n\r\n // --- Anthropic (Legacy & Backward Compatibility) ---\r\n 'claude-3-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-haiku': { inputPer1M: 0.25, outputPer1M: 1.25, cachedInputPer1M: 0.025 },\r\n 'claude-2.1': { inputPer1M: 8.0, outputPer1M: 24.0 },\r\n 'claude-2.0': { inputPer1M: 8.0, outputPer1M: 24.0 },\r\n 'claude-instant-1.2': { inputPer1M: 1.63, outputPer1M: 5.51 },\r\n\r\n // --- Google Gemini (Modern & Thoughts) ---\r\n 'gemini-3.7-flash': { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },\r\n 'gemini-3.1-pro': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.5 },\r\n 'gemini-3.5-flash': { inputPer1M: 1.5, outputPer1M: 9.0, cachedInputPer1M: 0.38 },\r\n 'gemini-3.1-flash-lite': { inputPer1M: 0.25, outputPer1M: 1.5, cachedInputPer1M: 0.06 },\r\n 'gemini-2.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n 'gemini-2.5-flash': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.0375 },\r\n 'gemini-2.0-flash': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.025 },\r\n 'gemini-2.0-flash-lite': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\r\n 'gemini-2.0-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n\r\n // --- Google Gemini (Legacy & Backward Compatibility) ---\r\n 'gemini-1.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n 'gemini-1.5-flash': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\r\n 'gemini-1.5-flash-8b': { inputPer1M: 0.0375, outputPer1M: 0.15, cachedInputPer1M: 0.009375 },\r\n 'gemini-1.0-pro': { inputPer1M: 0.5, outputPer1M: 1.5 },\r\n\r\n // --- xAI Grok ---\r\n 'grok-4.6': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'grok-3': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'grok-3-mini': { inputPer1M: 0.3, outputPer1M: 1.5 },\r\n 'grok-2': { inputPer1M: 2.0, outputPer1M: 10.0 },\r\n 'grok-2-vision': { inputPer1M: 2.0, outputPer1M: 10.0 },\r\n 'grok-beta': { inputPer1M: 5.0, outputPer1M: 15.0 },\r\n\r\n // --- Mistral ---\r\n 'mistral-large-3': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'mistral-large-latest': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'mistral-large-2411': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'codestral-latest': { inputPer1M: 0.3, outputPer1M: 0.9 },\r\n 'mistral-medium-latest': { inputPer1M: 2.7, outputPer1M: 8.1 },\r\n 'mistral-medium-3-5': { inputPer1M: 2.0, outputPer1M: 6.0, cachedInputPer1M: 0.4 },\r\n 'mistral-medium-2604': { inputPer1M: 2.0, outputPer1M: 6.0, cachedInputPer1M: 0.4 },\r\n 'magistral-small-latest': { inputPer1M: 0.5, outputPer1M: 1.5, cachedInputPer1M: 0.1 },\r\n 'magistral-medium-latest': { inputPer1M: 2.0, outputPer1M: 6.0, cachedInputPer1M: 0.4 },\r\n 'mistral-small-latest': { inputPer1M: 0.2, outputPer1M: 0.6 },\r\n 'mistral-small-2603': { inputPer1M: 0.2, outputPer1M: 0.6, cachedInputPer1M: 0.05 },\r\n 'mistral-vibe-cli-fast': { inputPer1M: 0.2, outputPer1M: 0.6, cachedInputPer1M: 0.05 },\r\n 'mistral-vibe-cli-latest': { inputPer1M: 0.2, outputPer1M: 0.6, cachedInputPer1M: 0.05 },\r\n 'codestral-2508': { inputPer1M: 0.3, outputPer1M: 0.9, cachedInputPer1M: 0.08 },\r\n 'codestral-embed': { inputPer1M: 0.1, outputPer1M: 0.0 },\r\n 'mistral-embed-2312': { inputPer1M: 0.1, outputPer1M: 0.0 },\r\n 'zai-glm-5-2': { inputPer1M: 0.6, outputPer1M: 2.2, cachedInputPer1M: 0.15 },\r\n 'glm-5-2': { inputPer1M: 0.6, outputPer1M: 2.2, cachedInputPer1M: 0.15 },\r\n 'labs-leanstral-1-5': { inputPer1M: 0.2, outputPer1M: 0.6, cachedInputPer1M: 0.05 },\r\n 'ministral-8b-latest': { inputPer1M: 0.1, outputPer1M: 0.1 },\r\n 'ministral-3b-latest': { inputPer1M: 0.04, outputPer1M: 0.04 },\r\n 'open-mistral-7b': { inputPer1M: 0.2, outputPer1M: 0.2 },\r\n 'open-mixtral-8x7b': { inputPer1M: 0.7, outputPer1M: 0.7 },\r\n 'open-mixtral-8x22b': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n\r\n // --- Groq & Meta Llama LPUs ---\r\n 'llama-3.3-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\r\n 'llama-3.1-405b': { inputPer1M: 3.0, outputPer1M: 3.0 },\r\n 'llama-3.1-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\r\n 'llama-3.1-8b-instant': { inputPer1M: 0.05, outputPer1M: 0.08 },\r\n 'llama-3.2-1b-preview': { inputPer1M: 0.04, outputPer1M: 0.04 },\r\n 'llama-3.2-3b-preview': { inputPer1M: 0.06, outputPer1M: 0.06 },\r\n 'llama-3.2-11b-vision': { inputPer1M: 0.18, outputPer1M: 0.18 },\r\n 'llama-3.2-90b-vision': { inputPer1M: 0.90, outputPer1M: 0.90 },\r\n 'deepseek-r1-distill-llama-70b': { inputPer1M: 0.75, outputPer1M: 0.99 },\r\n 'deepseek-r1-distill-qwen-32b': { inputPer1M: 0.49, outputPer1M: 0.49 },\r\n 'qwen-2.5-32b': { inputPer1M: 0.29, outputPer1M: 0.39 },\r\n 'qwen-2.5-72b': { inputPer1M: 0.35, outputPer1M: 0.40 },\r\n 'mixtral-8x7b-32768': { inputPer1M: 0.24, outputPer1M: 0.24 },\r\n 'gemma2-9b-it': { inputPer1M: 0.20, outputPer1M: 0.20 },\r\n\r\n // --- DeepSeek ---\r\n 'deepseek-v4-pro': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\r\n 'deepseek-v4.1-flash': { inputPer1M: 0.20, outputPer1M: 0.60, cachedInputPer1M: 0.05 },\r\n 'deepseek-v4-flash': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\r\n 'deepseek-v3': { inputPer1M: 0.14, outputPer1M: 0.28, cachedInputPer1M: 0.014 },\r\n 'deepseek-chat': { inputPer1M: 0.14, outputPer1M: 0.28, cachedInputPer1M: 0.014 },\r\n 'deepseek-r1': { inputPer1M: 0.55, outputPer1M: 2.19, cachedInputPer1M: 0.14 },\r\n 'deepseek-reasoner': { inputPer1M: 0.55, outputPer1M: 2.19, cachedInputPer1M: 0.14 },\r\n\r\n // --- Gateway, Inception & InclusionAI Models ---\r\n 'mercury-2.5': { inputPer1M: 0.25, outputPer1M: 0.75, cachedInputPer1M: 0.05 },\r\n 'mercury-2': { inputPer1M: 0.25, outputPer1M: 0.75, cachedInputPer1M: 0.05 },\r\n 'ling-3.0-flash-sante': { inputPer1M: 0.15, outputPer1M: 0.45, cachedInputPer1M: 0.03 },\r\n 'ling-3.0-flash': { inputPer1M: 0.15, outputPer1M: 0.45, cachedInputPer1M: 0.03 },\r\n\r\n // --- Cohere ---\r\n 'command-r-plus': { inputPer1M: 2.5, outputPer1M: 10.0 },\r\n 'command-r': { inputPer1M: 0.15, outputPer1M: 0.6 },\r\n 'command': { inputPer1M: 1.0, outputPer1M: 2.0 },\r\n 'command-light': { inputPer1M: 0.3, outputPer1M: 0.6 },\r\n 'embed-english-v3.0': { inputPer1M: 0.10, outputPer1M: 0.0 },\r\n\r\n // --- Perplexity ---\r\n 'sonar': { inputPer1M: 1.0, outputPer1M: 1.0 },\r\n 'sonar-pro': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'sonar-reasoning': { inputPer1M: 1.0, outputPer1M: 5.0 },\r\n 'sonar-reasoning-pro': { inputPer1M: 2.0, outputPer1M: 8.0 },\r\n};\r\n\r\n/**\r\n * Common model alias map to normalize nicknames, shorthands, and legacy IDs\r\n */\r\nexport const MODEL_ALIASES: Record<string, string> = {\r\n // OpenAI Shorthands & Aliases\r\n 'gpt4': 'gpt-4',\r\n 'gpt4o': 'gpt-4o',\r\n 'gpt-4-preview': 'gpt-4-turbo',\r\n 'gpt-4-0125-preview': 'gpt-4-turbo',\r\n 'gpt-4-1106-preview': 'gpt-4-turbo',\r\n 'gpt-3.5': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-0125': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-1106': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-16k-0613': 'gpt-3.5-turbo-16k',\r\n\r\n // Anthropic Shorthands\r\n 'sonnet': 'claude-3-5-sonnet',\r\n 'sonnet-3.7': 'claude-3-7-sonnet',\r\n 'sonnet-3.5': 'claude-3-5-sonnet',\r\n 'haiku': 'claude-3-5-haiku',\r\n 'haiku-3.5': 'claude-3-5-haiku',\r\n 'opus': 'claude-3-opus',\r\n 'claude-2': 'claude-2.0',\r\n 'claude-instant': 'claude-instant-1.2',\r\n\r\n // DeepSeek Shorthands\r\n 'r1': 'deepseek-r1',\r\n 'v3': 'deepseek-v3',\r\n\r\n // Gemini Shorthands\r\n 'flash': 'gemini-2.0-flash',\r\n 'pro': 'gemini-1.5-pro',\r\n\r\n // Meta / Groq Shorthands\r\n 'llama-3.3-70b': 'llama-3.3-70b-versatile',\r\n 'llama-3.1-70b': 'llama-3.1-70b-versatile',\r\n 'llama-3.1-8b': 'llama-3.1-8b-instant',\r\n 'llama-3-70b': 'llama-3.1-70b-versatile',\r\n 'llama-3-8b': 'llama-3.1-8b-instant',\r\n\r\n // Mistral Shorthands\r\n 'codestral': 'codestral-latest',\r\n 'mistral-large': 'mistral-large-latest',\r\n 'mistral-small': 'mistral-small-latest',\r\n 'magistral': 'magistral-small-latest',\r\n 'magistral-small': 'magistral-small-latest',\r\n 'magistral-medium': 'magistral-medium-latest',\r\n 'mistral-3.5': 'mistral-medium-3-5',\r\n 'mistral-medium-3.5': 'mistral-medium-3-5',\r\n 'gpt-image-2.5': 'gpt-image-2.5-flare',\r\n 'gpt-image-sunburst': 'gpt-image-2.5-sunburst',\r\n 'gpt-image-flare': 'gpt-image-2.5-flare',\r\n};\r\n\r\n/**\r\n * Dynamic in-memory registry allowing runtime custom price registration\r\n */\r\nconst customPricingRegistry: Record<string, ModelPricingRates> = {};\r\n\r\n/**\r\n * Normalize model identifier to match pricing table keys:\r\n * - Strips AWS Bedrock prefixes (e.g. 'anthropic.claude-3-5-sonnet-20241022-v2:0' -> 'claude-3-5-sonnet')\r\n * - Strips provider prefixes (e.g. 'openai/gpt-4o' -> 'gpt-4o', 'deepseek/deepseek-r1' -> 'deepseek-r1')\r\n * - Strips date suffixes (e.g. '-20240307', '-20250219')\r\n * - Resolves shorthands and aliases\r\n */\r\nexport function normalizeModelKey(rawModel: string): string {\r\n if (!rawModel) return 'unknown';\r\n\r\n let model = rawModel.toLowerCase().trim();\r\n\r\n // Strip AWS Bedrock model prefix (e.g. 'us.anthropic.claude-3-5-sonnet...', 'meta.llama3-...')\r\n model = model.replace(/^[a-z0-9_-]+\\.(anthropic|meta|amazon|cohere|mistral|ai21)\\./i, '');\r\n model = model.replace(/^(anthropic|meta|amazon|cohere|mistral|ai21)\\./i, '');\r\n\r\n // Strip AWS Bedrock version suffix (e.g. '-v1:0', '-v2:0', ':0')\r\n model = model.replace(/-v\\d+(:\\d+)?$/, '');\r\n model = model.replace(/:\\d+$/, '');\r\n\r\n // Strip provider prefix if present (e.g. 'openai/gpt-4o' -> 'gpt-4o', 'meta-llama/llama-3.3-70b-instruct' -> 'llama-3.3-70b-instruct')\r\n if (model.includes('/')) {\r\n model = model.split('/').slice(1).join('/');\r\n }\r\n\r\n // Remove trailing version/mode tags (e.g. ':latest', ':free', ':beta')\r\n model = model.replace(/:(latest|free|beta)$/, '');\r\n\r\n // Remove date suffixes like -20240307 or -20250219 or -2024-08-06\r\n model = model.replace(/-\\d{8}$/, '');\r\n model = model.replace(/-\\d{4}-\\d{2}-\\d{2}$/, '');\r\n\r\n // Normalize Bedrock Meta format (e.g. llama3-1-70b -> llama-3.1-70b)\r\n model = model.replace(/llama(\\d+)-(\\d+)-/g, 'llama-$1.$2-');\r\n model = model.replace(/llama(\\d+)\\.(\\d+)-/g, 'llama-$1.$2-');\r\n\r\n // Check aliases before fine-tuning\r\n if (MODEL_ALIASES[model]) {\r\n return MODEL_ALIASES[model];\r\n }\r\n\r\n // Remove common modifier suffixes if not directly matching table\r\n if (!MODEL_PRICING_TABLE[model]) {\r\n const withoutInstruct = model.replace(/-(instruct|chat|preview)$/, '');\r\n if (MODEL_PRICING_TABLE[withoutInstruct]) {\r\n return withoutInstruct;\r\n }\r\n if (MODEL_ALIASES[withoutInstruct]) {\r\n return MODEL_ALIASES[withoutInstruct];\r\n }\r\n }\r\n\r\n return model;\r\n}\r\n\r\n/**\r\n * Retrieve pricing rates for a given model\r\n */\r\nexport function getModelPricing(modelName: string): ModelPricingRates {\r\n const normalized = normalizeModelKey(modelName);\r\n\r\n // Check custom registry first\r\n if (customPricingRegistry[normalized]) {\r\n return customPricingRegistry[normalized];\r\n }\r\n if (customPricingRegistry[modelName]) {\r\n return customPricingRegistry[modelName];\r\n }\r\n\r\n // Check dynamic synced manifest cache\r\n const dynamicRate = getDynamicRate(modelName) || getDynamicRate(normalized);\r\n if (dynamicRate) {\r\n return dynamicRate;\r\n }\r\n\r\n // Check built-in table with normalized key\r\n if (MODEL_PRICING_TABLE[normalized]) {\r\n return MODEL_PRICING_TABLE[normalized];\r\n }\r\n // Check built-in table with direct key\r\n if (MODEL_PRICING_TABLE[modelName]) {\r\n return MODEL_PRICING_TABLE[modelName];\r\n }\r\n\r\n // Check alias table fallback\r\n const alias = MODEL_ALIASES[modelName.toLowerCase().trim()];\r\n if (alias) {\r\n const dynamicAlias = getDynamicRate(alias);\r\n if (dynamicAlias) return dynamicAlias;\r\n if (MODEL_PRICING_TABLE[alias]) {\r\n return MODEL_PRICING_TABLE[alias];\r\n }\r\n }\r\n\r\n // Fallback defaults for unknown models (conservative estimates: $1.00 in, $3.00 out)\r\n return {\r\n inputPer1M: 1.0,\r\n outputPer1M: 3.0,\r\n cachedInputPer1M: 0.5,\r\n };\r\n}\r\n\r\n/**\r\n * Register or override pricing rates for a custom model\r\n */\r\nexport function registerModelPricing(modelName: string, rates: ModelPricingRates): void {\r\n const normalized = normalizeModelKey(modelName);\r\n customPricingRegistry[normalized] = rates;\r\n customPricingRegistry[modelName] = rates;\r\n}\r\n","import type { InferenceCost, TokenUsage, InlineRateConfig, ModelPricingRates } from '../types';\nimport { getModelPricing } from './table';\n\nexport interface CalculateCostParams {\n model: string;\n inputTokens?: number;\n outputTokens?: number;\n promptTokens?: number;\n completionTokens?: number;\n reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n markupMultiplier?: number;\n markup?: number;\n margin?: number;\n minimumChargeUSD?: number;\n customRate?: InlineRateConfig;\n}\n\nexport interface TokenUsageInput {\n inputTokens?: number;\n outputTokens?: number;\n promptTokens?: number;\n completionTokens?: number;\n reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n}\n\nexport interface CalculateCostOptions {\n markupMultiplier?: number;\n markup?: number;\n margin?: number;\n minimumChargeUSD?: number;\n customRate?: InlineRateConfig;\n}\n\n/**\n * BigInt Nano-Precision Financial Math Engine\n * 1 USD = 1,000,000,000 Nano-USD (10^9)\n * 1 token at $1.00 / 1M = $0.000001 = 1,000 Nano-USD\n * Prevents IEEE 754 floating point precision drift on micro-transactions.\n *\n * Supports both:\n * 1. calculateCost('gpt-4o-mini', { promptTokens: 1240, completionTokens: 150 })\n * 2. calculateCost({ model: 'gpt-4o-mini', inputTokens: 1240, outputTokens: 150 })\n */\nexport function calculateCost(\n modelOrParams: string | CalculateCostParams,\n usage?: TokenUsageInput,\n optionsOrMarkup?: number | CalculateCostOptions\n): InferenceCost {\n let params: CalculateCostParams;\n\n if (typeof modelOrParams === 'string') {\n const opts =\n typeof optionsOrMarkup === 'number'\n ? { markupMultiplier: optionsOrMarkup }\n : optionsOrMarkup || {};\n params = {\n model: modelOrParams,\n inputTokens: usage?.inputTokens ?? usage?.promptTokens ?? 0,\n outputTokens: usage?.outputTokens ?? usage?.completionTokens ?? 0,\n reasoningTokens: usage?.reasoningTokens,\n cachedTokens: usage?.cachedTokens,\n cacheWriteTokens: usage?.cacheWriteTokens,\n markupMultiplier: opts.markupMultiplier ?? opts.markup ?? opts.margin,\n minimumChargeUSD: opts.minimumChargeUSD,\n customRate: opts.customRate,\n };\n } else {\n params = {\n ...modelOrParams,\n inputTokens: modelOrParams.inputTokens ?? modelOrParams.promptTokens ?? 0,\n outputTokens: modelOrParams.outputTokens ?? modelOrParams.completionTokens ?? 0,\n markupMultiplier:\n modelOrParams.markupMultiplier ?? modelOrParams.markup ?? modelOrParams.margin,\n };\n }\n let rates: ModelPricingRates;\n\n if (params.customRate) {\n const outRate = params.customRate.out ?? params.customRate.output ?? 0;\n rates = {\n inputPer1M: params.customRate.in,\n outputPer1M: outRate,\n reasoningPer1M: params.customRate.reasoning ?? outRate,\n cachedInputPer1M: params.customRate.cached ?? params.customRate.in * 0.15,\n currency: 'USD',\n };\n } else {\n rates = getModelPricing(params.model);\n }\n\n const inputTokens = BigInt(Math.max(0, params.inputTokens ?? 0));\n const outputTokens = BigInt(Math.max(0, params.outputTokens ?? 0));\n const reasoningTokens = BigInt(Math.max(0, params.reasoningTokens ?? 0));\n const cachedTokens = BigInt(Math.max(0, params.cachedTokens ?? 0));\n\n // Regular input tokens (minus any cached tokens)\n const regularInputTokens = inputTokens > cachedTokens ? inputTokens - cachedTokens : 0n;\n\n // Convert rate per 1M tokens to integer nano-dollars per single token (rate * 1,000)\n // Using 10^9 nano-precision\n const rateInputNano = BigInt(Math.round(rates.inputPer1M * 1_000));\n const cachedPer1M = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15;\n const rateCachedNano = BigInt(Math.round(cachedPer1M * 1_000));\n const rateOutputNano = BigInt(Math.round(rates.outputPer1M * 1_000));\n const reasoningPer1M = rates.reasoningPer1M ?? rates.outputPer1M;\n const rateReasoningNano = BigInt(Math.round(reasoningPer1M * 1_000));\n\n // Compute component nano costs\n const regularInputCostNano = regularInputTokens * rateInputNano;\n const cachedInputCostNano = cachedTokens * rateCachedNano;\n const inputCostNano = regularInputCostNano + cachedInputCostNano;\n const outputCostNano = outputTokens * rateOutputNano;\n const reasoningCostNano = reasoningTokens * rateReasoningNano;\n\n // Prompt cache savings discount\n const standardCacheCostNano = cachedTokens * rateInputNano;\n const cachedDiscountNano =\n standardCacheCostNano > cachedInputCostNano ? standardCacheCostNano - cachedInputCostNano : 0n;\n\n // Total wholesale cost\n const wholesaleNano = inputCostNano + outputCostNano;\n\n // Retail calculation\n const markup = params.markupMultiplier ?? 1.0;\n let billedNano = wholesaleNano;\n let hasRetail = false;\n\n if (markup !== 1.0 || params.minimumChargeUSD !== undefined) {\n hasRetail = true;\n const markupMultiplierNano = BigInt(Math.round(markup * 1_000));\n billedNano = (wholesaleNano * markupMultiplierNano) / 1_000n;\n\n if (params.minimumChargeUSD !== undefined && params.minimumChargeUSD > 0) {\n const minChargeNano = BigInt(Math.round(params.minimumChargeUSD * 1_000_000_000));\n if (billedNano < minChargeNano) {\n billedNano = minChargeNano;\n }\n }\n }\n\n const inputCostUSD = Number(inputCostNano) / 1_000_000_000;\n const outputCostUSD = Number(outputCostNano) / 1_000_000_000;\n const reasoningCostUSD = Number(reasoningCostNano) / 1_000_000_000;\n const cachedDiscountUSD = Number(cachedDiscountNano) / 1_000_000_000;\n const totalUSD = Number(wholesaleNano) / 1_000_000_000;\n const wholesaleTotalUSD = totalUSD;\n const billedUSD = Number(billedNano) / 1_000_000_000;\n const profitUSD = Math.max(0, billedUSD - wholesaleTotalUSD);\n const retailUSD = hasRetail ? billedUSD : undefined;\n\n return {\n inputCostUSD: Number(inputCostUSD.toFixed(8)),\n outputCostUSD: Number(outputCostUSD.toFixed(8)),\n reasoningCostUSD: reasoningTokens > 0n ? Number(reasoningCostUSD.toFixed(8)) : undefined,\n cachedDiscountUSD: cachedTokens > 0n ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n savingsUSD: cachedTokens > 0n ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n totalUSD: Number(totalUSD.toFixed(8)),\n wholesaleTotalUSD: Number(wholesaleTotalUSD.toFixed(8)),\n wholesaleUSD: Number(wholesaleTotalUSD.toFixed(8)),\n billedUSD: Number(billedUSD.toFixed(8)),\n profitUSD: Number(profitUSD.toFixed(8)),\n retailUSD: retailUSD !== undefined ? Number(retailUSD.toFixed(8)) : undefined,\n currency: rates.currency || 'USD',\n };\n}\n\n/**\n * Calculates cost directly from a TokenUsage object\n */\nexport function calculateUsageCost(\n model: string,\n usage: TokenUsage,\n optionsOrMarkup?: number | { markupMultiplier?: number; minimumChargeUSD?: number; customRate?: InlineRateConfig }\n): InferenceCost {\n const options =\n typeof optionsOrMarkup === 'number'\n ? { markupMultiplier: optionsOrMarkup }\n : optionsOrMarkup || {};\n\n return calculateCost({\n model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n reasoningTokens: usage.reasoningTokens,\n cachedTokens: usage.cachedTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n markupMultiplier: options.markupMultiplier,\n minimumChargeUSD: options.minimumChargeUSD,\n customRate: options.customRate,\n });\n}\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n","import type { UsageEvent, StreamWrapOptions } from '../types';\r\nimport { inspectOpenAIStreamChunk } from './extractors/openai';\r\nimport { AnthropicStreamAccumulator } from './extractors/anthropic';\r\nimport { extractGeminiResponseUsage } from './extractors/gemini';\r\nimport { calculateUsageCost } from '../pricing/calculator';\r\nimport { normalizeCustomer } from '../customers/helpers';\r\n\r\nexport type UsageDispatchedCallback = (event: UsageEvent) => void;\r\n\r\n/**\r\n * Wraps an OpenAI async iterable stream to capture usage at stream conclusion\r\n */\r\nexport function wrapOpenAIStream<T extends AsyncIterable<any>>(\r\n stream: T,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n let detectedModel = options.model || 'gpt-4o';\r\n let finalUsage: any = null;\r\n\r\n const wrappedAsyncIterable = {\r\n async *[Symbol.asyncIterator]() {\r\n try {\r\n for await (const chunk of stream) {\r\n const inspected = inspectOpenAIStreamChunk(chunk);\r\n if (inspected.model) {\r\n detectedModel = inspected.model;\r\n }\r\n if (inspected.usage) {\r\n finalUsage = inspected.usage;\r\n }\r\n yield chunk;\r\n }\r\n } finally {\r\n if (finalUsage) {\r\n const cost = calculateUsageCost(detectedModel, finalUsage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: detectedModel,\r\n provider: 'openai',\r\n usage: finalUsage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(event);\r\n if (options.onUsage) {\r\n options.onUsage(event);\r\n }\r\n }\r\n }\r\n },\r\n };\r\n\r\n return wrappedAsyncIterable as unknown as T;\r\n}\r\n\r\n/**\r\n * Wraps an Anthropic message stream to accumulate message_start and message_delta usage\r\n */\r\nexport function wrapAnthropicStream<T extends AsyncIterable<any>>(\r\n stream: T,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n const accumulator = new AnthropicStreamAccumulator();\r\n\r\n const wrappedAsyncIterable = {\r\n async *[Symbol.asyncIterator]() {\r\n try {\r\n for await (const event of stream) {\r\n accumulator.processEvent(event);\r\n yield event;\r\n }\r\n } finally {\r\n const extracted = accumulator.getUsage();\r\n const model = options.model || extracted.model;\r\n const cost = calculateUsageCost(model, extracted.usage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const usageEvent: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model,\r\n provider: 'anthropic',\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(usageEvent);\r\n if (options.onUsage) {\r\n options.onUsage(usageEvent);\r\n }\r\n }\r\n },\r\n };\r\n\r\n return wrappedAsyncIterable as unknown as T;\r\n}\r\n\r\n/**\r\n * Wraps a Google Gemini GenerateContentStreamResult\r\n */\r\nexport function wrapGeminiStream(\r\n result: any,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): any {\r\n if (!result || !result.stream) return result;\r\n\r\n const originalStream = result.stream;\r\n const model = options.model || 'gemini-3.7-flash';\r\n let lastChunkWithUsage: any = null;\r\n\r\n const wrappedStream = (async function* () {\r\n try {\r\n for await (const chunk of originalStream) {\r\n if (chunk.usageMetadata) {\r\n lastChunkWithUsage = chunk;\r\n }\r\n yield chunk;\r\n }\r\n } finally {\r\n if (lastChunkWithUsage) {\r\n const extracted = extractGeminiResponseUsage(lastChunkWithUsage, model);\r\n if (extracted) {\r\n const cost = calculateUsageCost(extracted.model, extracted.usage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: extracted.model,\r\n provider: 'google',\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(event);\r\n if (options.onUsage) {\r\n options.onUsage(event);\r\n }\r\n }\r\n }\r\n }\r\n })();\r\n\r\n return {\r\n ...result,\r\n stream: wrappedStream,\r\n };\r\n}\r\n\r\n/**\r\n * Universal Stream Wrapper\r\n */\r\nexport function wrapUniversalStream<T>(\r\n stream: T,\r\n options: StreamWrapOptions = {},\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n if (!stream || typeof stream !== 'object') return stream;\r\n\r\n // 1. Check Gemini stream\r\n if ('stream' in stream && 'response' in stream) {\r\n return wrapGeminiStream(stream, options, onComplete);\r\n }\r\n\r\n // 2. Check if stream is an AsyncIterable\r\n if (Symbol.asyncIterator in stream) {\r\n // If provider is explicitly anthropic or model is claude\r\n if (options.provider === 'anthropic' || options.model?.toLowerCase().includes('claude')) {\r\n return wrapAnthropicStream(stream as any, options, onComplete);\r\n }\r\n // Default to universal stream wrapper which detects usage chunks polymorphically\r\n return wrapOpenAIStream(stream as any, options, onComplete);\r\n }\r\n\r\n return stream;\r\n}\r\n","import type {\r\n MeterOptions,\r\n StreamWrapOptions,\r\n RecordUsageOptions,\r\n UsageEvent,\r\n UsageSummary,\r\n CustomerParam,\r\n} from '../types';\r\nimport { MeterBatcher } from './batcher';\r\nimport { detectAndExtractUsage } from './extractors';\r\nimport { calculateUsageCost } from '../pricing/calculator';\r\nimport { wrapUniversalStream } from './stream';\r\nimport { normalizeCustomer } from '../customers/helpers';\r\n\r\nexport class VibezMeter {\r\n private batcher: MeterBatcher;\r\n private markupMultiplier?: number;\r\n\r\n constructor(options: MeterOptions = {}) {\r\n this.markupMultiplier = options.pricing?.margin ?? options.pricing?.markup ?? options.markupMultiplier;\r\n this.batcher = new MeterBatcher(options);\r\n }\r\n\r\n /**\r\n * Track token usage from a non-streaming response object (OpenAI, Anthropic, Gemini, etc.)\r\n */\r\n public trackUsage(\r\n response: any,\r\n options: {\r\n customer?: CustomerParam;\r\n customerId?: string;\r\n model?: string;\r\n provider?: string;\r\n metadata?: Record<string, string | number | boolean>;\r\n } = {}\r\n ): UsageEvent | null {\r\n const extracted = detectAndExtractUsage(response, options.model, options.provider);\r\n if (!extracted) {\r\n return null;\r\n }\r\n\r\n const model = options.model || extracted.model;\r\n const cost = calculateUsageCost(model, extracted.usage, this.markupMultiplier);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const mergedMeta = {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n };\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model,\r\n provider: extracted.provider,\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: mergedMeta,\r\n };\r\n\r\n this.batcher.enqueue(event);\r\n return event;\r\n }\r\n\r\n /**\r\n * Wrap any LLM stream (OpenAI, Anthropic, Gemini) with zero added latency\r\n */\r\n public wrapStream<T>(stream: T, options: StreamWrapOptions = {}): T {\r\n return wrapUniversalStream(stream, options, (event) => {\r\n this.batcher.enqueue(event);\r\n });\r\n }\r\n\r\n /**\r\n * Directly record token usage manually\r\n */\r\n public recordUsage(options: RecordUsageOptions & { customer?: CustomerParam }): UsageEvent {\r\n const inputTokens = options.inputTokens ?? 0;\r\n const outputTokens = options.outputTokens ?? 0;\r\n const reasoningTokens = options.reasoningTokens;\r\n const cachedTokens = options.cachedTokens;\r\n\r\n const usage = {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens,\r\n visibleOutputTokens:\r\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\r\n cachedTokens,\r\n };\r\n\r\n const cost = calculateUsageCost(options.model, usage, this.markupMultiplier);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const mergedMeta = {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n };\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: options.model,\r\n provider: options.provider || 'custom',\r\n usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: mergedMeta,\r\n };\r\n\r\n this.batcher.enqueue(event);\r\n return event;\r\n }\r\n\r\n /**\r\n * Flush pending events (vital for Serverless & Edge environments)\r\n */\r\n public async flush(): Promise<void> {\r\n await this.batcher.flush();\r\n }\r\n\r\n /**\r\n * Get in-memory aggregated usage statistics\r\n */\r\n public getUsageSummary(): UsageSummary {\r\n return this.batcher.getSummary();\r\n }\r\n\r\n /**\r\n * Reset in-memory ledger\r\n */\r\n public resetSummary(): void {\r\n this.batcher.resetLedger();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create a VibezMeter instance\r\n */\r\nexport function createMeter(options: MeterOptions = {}): VibezMeter {\r\n return new VibezMeter(options);\r\n}\r\n","export * from './client';\r\nexport * from './batcher';\r\nexport * from './stream';\r\nexport * from './extractors';\r\n\r\nimport { createMeter } from './client';\r\nimport type { StreamWrapOptions, CustomerParam } from '../types';\r\n\r\n// Default singleton instance\r\nconst defaultMeter = createMeter();\r\n\r\n/**\r\n * Convenient standalone stream wrapper\r\n */\r\nexport function wrapStream<T>(stream: T, options?: StreamWrapOptions): T {\r\n return defaultMeter.wrapStream(stream, options);\r\n}\r\n\r\n/**\r\n * Convenient standalone usage tracker\r\n */\r\nexport function trackTokens(\r\n response: any,\r\n options?: { customer?: CustomerParam; customerId?: string; model?: string }\r\n) {\r\n return defaultMeter.trackUsage(response, options);\r\n}\r\n"],"mappings":"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","names":["rawUsage","customerObj"]}
|
|
1
|
+
{"version":3,"sources":["../../src/meter/batcher.ts","../../src/meter/extractors/openai.ts","../../src/meter/extractors/anthropic.ts","../../src/meter/extractors/gemini.ts","../../src/meter/extractors/generic.ts","../../src/meter/extractors/index.ts","../../src/pricing/sync.ts","../../src/pricing/table.ts","../../src/pricing/calculator.ts","../../src/customers/helpers.ts","../../src/meter/stream.ts","../../src/meter/client.ts","../../src/meter/index.ts"],"sourcesContent":["import type { UsageEvent, UsageSummary, MeterOptions } from '../types';\r\n\r\n/**\r\n * Detects whether the current runtime is a serverless environment\r\n * (AWS Lambda, Vercel Serverless, Cloudflare Workers/Pages, Netlify, Deno Deploy, Next.js)\r\n */\r\nexport function isServerlessEnvironment(): boolean {\r\n if (typeof process !== 'undefined' && process.env) {\r\n if (\r\n process.env.VERCEL ||\r\n process.env.AWS_LAMBDA_FUNCTION_NAME ||\r\n process.env.LAMBDA_TASK_ROOT ||\r\n process.env.NETLIFY ||\r\n process.env.DENO_DEPLOYMENT_ID ||\r\n process.env.CF_PAGES ||\r\n process.env.NEXT_RUNTIME\r\n ) {\r\n return true;\r\n }\r\n }\r\n if (typeof globalThis !== 'undefined') {\r\n const g = globalThis as any;\r\n if (g.EdgeRuntime || g.WebSocketPair) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nconst activeBatchers = new Set<MeterBatcher>();\r\nlet exitListenerAttached = false;\r\n\r\nfunction ensureExitListener() {\r\n if (exitListenerAttached) return;\r\n if (typeof process !== 'undefined' && typeof process.once === 'function') {\r\n try {\r\n process.once('beforeExit', () => {\r\n for (const batcher of activeBatchers) {\r\n batcher.flush().catch(() => {});\r\n }\r\n });\r\n exitListenerAttached = true;\r\n } catch {\r\n // Fallback for restricted sandboxes\r\n }\r\n }\r\n}\r\n\r\nexport class MeterBatcher {\r\n private queue: UsageEvent[] = [];\r\n private timer: NodeJS.Timeout | null = null;\r\n private isFlushing: boolean = false;\r\n private readonly maxBatchSize: number;\r\n private readonly flushIntervalMs: number;\r\n private readonly isExplicitFlushInterval: boolean;\r\n private readonly onUsageCallback?: (event: UsageEvent) => void | Promise<void>;\r\n private readonly onBatchCallback?: (events: UsageEvent[]) => void | Promise<void>;\r\n private readonly onErrorCallback?: (error: Error, events: UsageEvent[]) => void;\r\n private readonly debug: boolean;\r\n\r\n // In-memory ledger for local stats\r\n private totalRequests = 0;\r\n private totalTokens = 0;\r\n private totalInputTokens = 0;\r\n private totalOutputTokens = 0;\r\n private totalReasoningTokens = 0;\r\n private totalCostUSD = 0;\r\n private byModel: Record<string, { requests: number; tokens: number; costUSD: number }> = {};\r\n\r\n constructor(options: MeterOptions = {}) {\r\n this.maxBatchSize = options.batching?.maxBatchSize ?? 50;\r\n this.flushIntervalMs = options.batching?.flushIntervalMs ?? 50;\r\n this.isExplicitFlushInterval = options.batching?.flushIntervalMs !== undefined;\r\n this.onUsageCallback = options.onUsage;\r\n this.onBatchCallback = options.onBatch;\r\n this.onErrorCallback = options.onError;\r\n this.debug = options.debug ?? false;\r\n\r\n activeBatchers.add(this);\r\n ensureExitListener();\r\n }\r\n\r\n /**\r\n * Enqueue a usage event for batch dispatching\r\n */\r\n public enqueue(event: UsageEvent): void {\r\n // 1. Update in-memory local ledger\r\n this.recordInLedger(event);\r\n\r\n // 2. Fire onUsage hook immediately\r\n if (this.onUsageCallback) {\r\n try {\r\n const res = this.onUsageCallback(event);\r\n if (res instanceof Promise) {\r\n res.catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\r\n });\r\n }\r\n } catch (err) {\r\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\r\n }\r\n }\r\n\r\n // 3. If no onBatch handler is configured, we run in immediate local mode\r\n if (!this.onBatchCallback) {\r\n if (this.debug) {\r\n console.log(\r\n `[vibezcheck:local] 📊 ${event.model} | Tokens: ${event.usage.totalTokens} | Cost: $${event.cost.totalUSD.toFixed(6)}`\r\n );\r\n }\r\n return;\r\n }\r\n\r\n // 4. Queue for batch dispatch\r\n this.queue.push(event);\r\n\r\n if (this.queue.length >= this.maxBatchSize) {\r\n this.flush().catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Batch flush error:', err);\r\n });\r\n return;\r\n }\r\n\r\n // 5. Serverless Lifecycle Spooling: Auto-register with after() or waitUntil()\r\n if (typeof globalThis !== 'undefined') {\r\n const g = globalThis as any;\r\n if (typeof g.after === 'function') {\r\n g.after(() => this.flush().catch(() => {}));\r\n return;\r\n }\r\n if (typeof g.waitUntil === 'function') {\r\n g.waitUntil(this.flush().catch(() => {}));\r\n return;\r\n }\r\n }\r\n\r\n // In serverless environments where timers are frozen on response, auto-flush immediately unless explicit interval given\r\n if (isServerlessEnvironment() && !this.isExplicitFlushInterval) {\r\n this.flush().catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Serverless auto-flush error:', err);\r\n });\r\n return;\r\n }\r\n\r\n if (!this.timer) {\r\n this.timer = setTimeout(() => {\r\n this.timer = null;\r\n this.flush().catch((err) => {\r\n if (this.debug) console.error('[vibezcheck] Debounce flush error:', err);\r\n });\r\n }, this.flushIntervalMs);\r\n }\r\n }\r\n\r\n /**\r\n * Immediately flush all queued events\r\n */\r\n public async flush(): Promise<void> {\r\n if (this.timer) {\r\n clearTimeout(this.timer);\r\n this.timer = null;\r\n }\r\n\r\n if (this.queue.length === 0 || !this.onBatchCallback || this.isFlushing) {\r\n return;\r\n }\r\n\r\n this.isFlushing = true;\r\n const eventsToSend = [...this.queue];\r\n this.queue = [];\r\n\r\n try {\r\n await this.onBatchCallback(eventsToSend);\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n if (this.debug) {\r\n console.error('[vibezcheck] Failed to flush meter event batch:', err);\r\n }\r\n if (this.onErrorCallback) {\r\n this.onErrorCallback(err, eventsToSend);\r\n }\r\n } finally {\r\n this.isFlushing = false;\r\n // If new items were queued while flushing, trigger another flush\r\n if (this.queue.length > 0) {\r\n this.flush().catch(() => {});\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates internal in-memory ledger\r\n */\r\n private recordInLedger(event: UsageEvent): void {\r\n this.totalRequests += 1;\r\n this.totalTokens += event.usage.totalTokens;\r\n this.totalInputTokens += event.usage.inputTokens;\r\n this.totalOutputTokens += event.usage.outputTokens;\r\n this.totalReasoningTokens += event.usage.reasoningTokens ?? 0;\r\n this.totalCostUSD += event.cost.totalUSD;\r\n\r\n const modelKey = event.model;\r\n if (!this.byModel[modelKey]) {\r\n this.byModel[modelKey] = { requests: 0, tokens: 0, costUSD: 0 };\r\n }\r\n this.byModel[modelKey].requests += 1;\r\n this.byModel[modelKey].tokens += event.usage.totalTokens;\r\n this.byModel[modelKey].costUSD += event.cost.totalUSD;\r\n }\r\n\r\n /**\r\n * Get in-memory usage summary\r\n */\r\n public getSummary(): UsageSummary {\r\n return {\r\n totalRequests: this.totalRequests,\r\n totalTokens: this.totalTokens,\r\n totalInputTokens: this.totalInputTokens,\r\n totalOutputTokens: this.totalOutputTokens,\r\n totalReasoningTokens: this.totalReasoningTokens,\r\n totalCostUSD: Number(this.totalCostUSD.toFixed(6)),\r\n byModel: { ...this.byModel },\r\n };\r\n }\r\n\r\n /**\r\n * Reset in-memory ledger\r\n */\r\n public resetLedger(): void {\r\n this.totalRequests = 0;\r\n this.totalTokens = 0;\r\n this.totalInputTokens = 0;\r\n this.totalOutputTokens = 0;\r\n this.totalReasoningTokens = 0;\r\n this.totalCostUSD = 0;\r\n this.byModel = {};\r\n }\r\n}\r\n","import type { TokenUsage } from '../../types';\r\n\r\nexport interface ExtractedUsage {\r\n model: string;\r\n provider: string;\r\n usage: TokenUsage;\r\n}\r\n\r\n/**\r\n * Extracts token usage from OpenAI synchronous responses (ChatCompletion, Responses, Embeddings)\r\n */\r\nexport function extractOpenAIResponseUsage(response: any): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // 1. Standard OpenAI ChatCompletion\r\n if ('choices' in response && 'usage' in response && response.usage) {\r\n const rawUsage = response.usage;\r\n const model = response.model || 'gpt-4o';\r\n\r\n const inputTokens = rawUsage.prompt_tokens ?? 0;\r\n const outputTokens = rawUsage.completion_tokens ?? 0;\r\n const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens ?? 0;\r\n const cachedTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? 0;\r\n\r\n return {\r\n model,\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n // 2. OpenAI Embeddings Response\r\n if ('data' in response && 'usage' in response && response.usage && 'model' in response) {\r\n const rawUsage = response.usage;\r\n const inputTokens = rawUsage.prompt_tokens ?? 0;\r\n\r\n return {\r\n model: response.model || 'text-embedding-3-small',\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens: 0,\r\n totalTokens: inputTokens,\r\n },\r\n };\r\n }\r\n\r\n // 3. OpenAI Responses API (New standard)\r\n if ('status' in response && 'usage' in response && response.usage) {\r\n const rawUsage = response.usage;\r\n const model = response.model || 'gpt-5.6-sol';\r\n\r\n const inputTokens = rawUsage.input_tokens ?? rawUsage.prompt_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? rawUsage.completion_tokens ?? 0;\r\n const reasoningTokens =\r\n rawUsage.output_token_details?.reasoning_tokens ??\r\n rawUsage.completion_tokens_details?.reasoning_tokens ??\r\n 0;\r\n const cachedTokens =\r\n rawUsage.input_token_details?.cached_tokens ??\r\n rawUsage.prompt_tokens_details?.cached_tokens ??\r\n 0;\r\n\r\n return {\r\n model,\r\n provider: 'openai',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Extracts token usage from an individual OpenAI stream chunk or stream accumulator\r\n */\r\nexport function inspectOpenAIStreamChunk(chunk: any): {\r\n model?: string;\r\n usage?: TokenUsage;\r\n} {\r\n if (!chunk || typeof chunk !== 'object') return {};\r\n\r\n const model = chunk.model;\r\n\r\n // Final chunk with usage object (when stream_options: { include_usage: true }, finish chunk, or Groq / DeepSeek / Mistral stream ending)\r\n const rawUsage =\r\n (chunk.type === 'finish' ? chunk.usage : null) ||\r\n chunk.usage ||\r\n chunk.token_usage ||\r\n chunk.x_groq?.usage ||\r\n chunk.usageMetadata;\r\n if (rawUsage) {\r\n let inputTokens = 0;\r\n let outputTokens = 0;\r\n let reasoningTokens = 0;\r\n let cachedTokens = 0;\r\n\r\n if (typeof rawUsage.inputTokens === 'object' && rawUsage.inputTokens !== null) {\r\n inputTokens = rawUsage.inputTokens.total ?? rawUsage.inputTokens.noCache ?? 0;\r\n cachedTokens = rawUsage.inputTokens.cacheRead ?? 0;\r\n } else if (typeof rawUsage.promptTokens === 'number') {\r\n inputTokens = rawUsage.promptTokens;\r\n } else if (typeof rawUsage.inputTokens === 'number') {\r\n inputTokens = rawUsage.inputTokens;\r\n } else {\r\n inputTokens =\r\n rawUsage.prompt_tokens ??\r\n rawUsage.input_tokens ??\r\n rawUsage.promptTokenCount ??\r\n 0;\r\n }\r\n\r\n if (typeof rawUsage.outputTokens === 'object' && rawUsage.outputTokens !== null) {\r\n outputTokens = rawUsage.outputTokens.total ?? rawUsage.outputTokens.text ?? 0;\r\n reasoningTokens = rawUsage.outputTokens.reasoning ?? 0;\r\n } else if (typeof rawUsage.completionTokens === 'number') {\r\n outputTokens = rawUsage.completionTokens;\r\n } else if (typeof rawUsage.outputTokens === 'number') {\r\n outputTokens = rawUsage.outputTokens;\r\n } else {\r\n outputTokens =\r\n rawUsage.completion_tokens ??\r\n rawUsage.output_tokens ??\r\n rawUsage.candidatesTokenCount ??\r\n 0;\r\n }\r\n\r\n if (!reasoningTokens) {\r\n reasoningTokens =\r\n rawUsage.completion_tokens_details?.reasoning_tokens ??\r\n rawUsage.output_token_details?.reasoning_tokens ??\r\n rawUsage.reasoning_tokens ??\r\n rawUsage.reasoningTokens ??\r\n rawUsage.thoughtsTokenCount ??\r\n 0;\r\n }\r\n\r\n if (!cachedTokens) {\r\n cachedTokens =\r\n rawUsage.prompt_tokens_details?.cached_tokens ??\r\n rawUsage.input_token_details?.cached_tokens ??\r\n rawUsage.prompt_cache_hit_tokens ??\r\n rawUsage.cached_tokens ??\r\n rawUsage.cachedTokens ??\r\n rawUsage.cachedContentTokenCount ??\r\n 0;\r\n }\r\n\r\n return {\r\n model,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n // Response API stream event (response.completed or response.done)\r\n if (chunk.type === 'response.completed' || chunk.type === 'response.done') {\r\n if (chunk.response?.usage) {\r\n const rawUsage = chunk.response.usage;\r\n const inputTokens = rawUsage.input_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? 0;\r\n const reasoningTokens = rawUsage.output_token_details?.reasoning_tokens ?? 0;\r\n const cachedTokens = rawUsage.input_token_details?.cached_tokens ?? 0;\r\n\r\n return {\r\n model: chunk.response.model || model,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n }\r\n\r\n return { model };\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from Anthropic synchronous responses\r\n */\r\nexport function extractAnthropicResponseUsage(response: any): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Anthropic Message response has type: 'message' or role: 'assistant' with usage\r\n if (response.type === 'message' || ('content' in response && 'usage' in response)) {\r\n const rawUsage = response.usage || {};\r\n const model = response.model || 'claude-3-7-sonnet';\r\n\r\n const inputTokens = rawUsage.input_tokens ?? 0;\r\n const outputTokens = rawUsage.output_tokens ?? 0;\r\n const cachedTokens = rawUsage.cache_read_input_tokens ?? 0;\r\n const cacheWriteTokens = rawUsage.cache_creation_input_tokens ?? 0;\r\n\r\n // Check content blocks for thinking/reasoning tokens count or thinking blocks\r\n let reasoningTokens: number | undefined = undefined;\r\n if (Array.isArray(response.content)) {\r\n const thinkingBlocks = response.content.filter((b: any) => b.type === 'thinking');\r\n if (thinkingBlocks.length > 0) {\r\n // Approximate or extract explicit thinking tokens if present in metadata\r\n reasoningTokens = (rawUsage as any).thinking_tokens ?? undefined;\r\n }\r\n }\r\n\r\n return {\r\n model,\r\n provider: 'anthropic',\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens,\r\n visibleOutputTokens:\r\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n cacheWriteTokens: cacheWriteTokens > 0 ? cacheWriteTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Accumulates stream events across an Anthropic raw message stream\r\n */\r\nexport class AnthropicStreamAccumulator {\r\n private model: string = 'claude-3-7-sonnet';\r\n private inputTokens: number = 0;\r\n private outputTokens: number = 0;\r\n private cachedTokens: number = 0;\r\n private cacheWriteTokens: number = 0;\r\n private reasoningTokens: number = 0;\r\n\r\n processEvent(event: any): void {\r\n if (!event || typeof event !== 'object') return;\r\n\r\n // 1. message_start (contains model and initial input usage)\r\n if (event.type === 'message_start' && event.message) {\r\n if (event.message.model) {\r\n this.model = event.message.model;\r\n }\r\n if (event.message.usage) {\r\n this.inputTokens = event.message.usage.input_tokens ?? 0;\r\n this.cachedTokens = event.message.usage.cache_read_input_tokens ?? 0;\r\n this.cacheWriteTokens = event.message.usage.cache_creation_input_tokens ?? 0;\r\n }\r\n }\r\n\r\n // 2. message_delta (contains final output usage)\r\n if (event.type === 'message_delta' && event.usage) {\r\n this.outputTokens = event.usage.output_tokens ?? 0;\r\n if (event.usage.thinking_tokens) {\r\n this.reasoningTokens = event.usage.thinking_tokens;\r\n }\r\n }\r\n\r\n // 3. content_block_start / content_block_delta for thinking blocks\r\n if (event.type === 'content_block_start' && event.content_block?.type === 'thinking') {\r\n // thinking block detected\r\n }\r\n }\r\n\r\n getUsage(): ExtractedUsage {\r\n return {\r\n model: this.model,\r\n provider: 'anthropic',\r\n usage: {\r\n inputTokens: this.inputTokens,\r\n outputTokens: this.outputTokens,\r\n totalTokens: this.inputTokens + this.outputTokens,\r\n reasoningTokens: this.reasoningTokens > 0 ? this.reasoningTokens : undefined,\r\n visibleOutputTokens:\r\n this.reasoningTokens > 0\r\n ? Math.max(0, this.outputTokens - this.reasoningTokens)\r\n : this.outputTokens,\r\n cachedTokens: this.cachedTokens > 0 ? this.cachedTokens : undefined,\r\n cacheWriteTokens: this.cacheWriteTokens > 0 ? this.cacheWriteTokens : undefined,\r\n },\r\n };\r\n }\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from Google Gemini API response or chunk\r\n */\r\nexport function extractGeminiResponseUsage(\r\n response: any,\r\n fallbackModel: string = 'gemini-3.7-flash'\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Gemini returns usageMetadata on response or GenerateContentResult\r\n const usageMetadata = response.usageMetadata || response.response?.usageMetadata;\r\n\r\n if (usageMetadata) {\r\n const inputTokens = usageMetadata.promptTokenCount ?? 0;\r\n const baseOutputTokens = usageMetadata.candidatesTokenCount ?? 0;\r\n const thoughtsTokenCount =\r\n usageMetadata.thoughtsTokenCount ?? (usageMetadata as any).reasoningTokenCount ?? 0;\r\n const cachedTokens = usageMetadata.cachedContentTokenCount ?? 0;\r\n\r\n const totalOutput = baseOutputTokens + thoughtsTokenCount;\r\n const model = response.model || response.response?.model || fallbackModel;\r\n\r\n return {\r\n model,\r\n provider: 'google',\r\n usage: {\r\n inputTokens,\r\n outputTokens: totalOutput,\r\n totalTokens: inputTokens + totalOutput,\r\n reasoningTokens: thoughtsTokenCount > 0 ? thoughtsTokenCount : undefined,\r\n visibleOutputTokens: baseOutputTokens,\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n","import type { TokenUsage } from '../../types';\r\nimport type { ExtractedUsage } from './openai';\r\n\r\n/**\r\n * Extracts token usage from generic LLM provider objects (DeepSeek, Groq, Mistral, Ollama, Cohere, Together)\r\n */\r\nexport function extractGenericResponseUsage(\r\n response: any,\r\n fallbackModel: string = 'generic-llm',\r\n fallbackProvider: string = 'generic'\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // Check common usage property locations\r\n const usage = response.usage || response.token_usage || response.usageMetadata;\r\n\r\n if (usage) {\r\n let inputTokens = 0;\r\n let outputTokens = 0;\r\n let reasoningTokens = 0;\r\n let cachedTokens = 0;\r\n\r\n if (typeof usage.inputTokens === 'object' && usage.inputTokens !== null) {\r\n inputTokens = usage.inputTokens.total ?? usage.inputTokens.noCache ?? 0;\r\n cachedTokens = usage.inputTokens.cacheRead ?? 0;\r\n } else if (typeof usage.promptTokens === 'number') {\r\n inputTokens = usage.promptTokens;\r\n } else if (typeof usage.inputTokens === 'number') {\r\n inputTokens = usage.inputTokens;\r\n } else {\r\n inputTokens =\r\n usage.prompt_tokens ??\r\n usage.input_tokens ??\r\n usage.promptTokenCount ??\r\n usage.prompt_eval_count ??\r\n 0;\r\n }\r\n\r\n if (typeof usage.outputTokens === 'object' && usage.outputTokens !== null) {\r\n outputTokens = usage.outputTokens.total ?? usage.outputTokens.text ?? 0;\r\n reasoningTokens = usage.outputTokens.reasoning ?? 0;\r\n } else if (typeof usage.completionTokens === 'number') {\r\n outputTokens = usage.completionTokens;\r\n } else if (typeof usage.outputTokens === 'number') {\r\n outputTokens = usage.outputTokens;\r\n } else {\r\n outputTokens =\r\n usage.completion_tokens ??\r\n usage.output_tokens ??\r\n usage.candidatesTokenCount ??\r\n usage.eval_count ??\r\n 0;\r\n }\r\n\r\n if (!reasoningTokens) {\r\n reasoningTokens =\r\n usage.reasoning_tokens ??\r\n usage.thoughtsTokenCount ??\r\n usage.completion_tokens_details?.reasoning_tokens ??\r\n 0;\r\n }\r\n\r\n if (!cachedTokens) {\r\n cachedTokens =\r\n usage.prompt_tokens_details?.cached_tokens ??\r\n usage.cached_tokens ??\r\n usage.cachedContentTokenCount ??\r\n 0;\r\n }\r\n\r\n const model = response.model || fallbackModel;\r\n const provider = response.provider || fallbackProvider;\r\n\r\n return {\r\n model,\r\n provider,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\r\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\r\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\r\n },\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n","import type { ExtractedUsage } from './openai';\r\nimport { extractOpenAIResponseUsage } from './openai';\r\nimport { extractAnthropicResponseUsage } from './anthropic';\r\nimport { extractGeminiResponseUsage } from './gemini';\r\nimport { extractGenericResponseUsage } from './generic';\r\n\r\nexport * from './openai';\r\nexport * from './anthropic';\r\nexport * from './gemini';\r\nexport * from './generic';\r\n\r\n/**\r\n * Universal polymorphic response detector\r\n */\r\nexport function detectAndExtractUsage(\r\n response: any,\r\n fallbackModel?: string,\r\n fallbackProvider?: string\r\n): ExtractedUsage | null {\r\n if (!response || typeof response !== 'object') return null;\r\n\r\n // 1. Try OpenAI\r\n const openaiResult = extractOpenAIResponseUsage(response);\r\n if (openaiResult) return openaiResult;\r\n\r\n // 2. Try Anthropic\r\n const anthropicResult = extractAnthropicResponseUsage(response);\r\n if (anthropicResult) return anthropicResult;\r\n\r\n // 3. Try Gemini\r\n const geminiResult = extractGeminiResponseUsage(response, fallbackModel);\r\n if (geminiResult) return geminiResult;\r\n\r\n // 4. Try Generic\r\n const genericResult = extractGenericResponseUsage(response, fallbackModel, fallbackProvider);\r\n if (genericResult) return genericResult;\r\n\r\n return null;\r\n}\r\n","import type { ModelPricingRates } from '../types';\nimport { normalizeModelKey } from './table';\n\nexport interface PricingSyncOptions {\n /**\n * Remote manifest URL to fetch pricing from.\n * Defaults to the official hosted pricing-v1.json manifest.\n */\n manifestUrl?: string;\n\n /**\n * Request timeout in milliseconds (default: 3000ms).\n */\n timeoutMs?: number;\n\n /**\n * Custom fetch implementation (defaults to globalThis.fetch).\n */\n fetch?: typeof fetch;\n\n /**\n * Maximum cache age in milliseconds before re-fetching (default: 3600_000 = 1 hour).\n */\n cacheTtlMs?: number;\n\n /**\n * If true, bypass cache TTL and force an immediate re-fetch.\n */\n force?: boolean;\n\n /**\n * Fallback manifest JSON string or object to seed cache if network fails.\n */\n fallbackManifest?: unknown;\n\n /**\n * Custom headers for authentication or versioning.\n */\n headers?: Record<string, string>;\n}\n\nexport interface PricingSyncStatus {\n status: 'idle' | 'syncing' | 'synced' | 'failed';\n lastSyncTime: number | null;\n lastSyncETag: string | null;\n cachedModelsCount: number;\n lastError: string | null;\n}\n\nexport interface StripePricingItem {\n publisher?: string;\n provider?: string;\n model: string;\n prices_per_1m: {\n input_token?: number | null;\n output_token?: number | null;\n cached_input?: number | null;\n cached_output?: number | null;\n cached_read?: number | null;\n cached_write?: number | null;\n };\n}\n\nexport const DEFAULT_MANIFEST_URL =\n 'https://raw.githubusercontent.com/seeyouin2x5x/vibezcheck-sdk/main/manifest/pricing-v1.json';\n\nexport const VERCEL_GATEWAY_MODELS_URL = 'https://ai-gateway.vercel.sh/v1/models';\n\nexport interface VercelGatewayModelItem {\n id: string;\n name?: string;\n owned_by?: string;\n type?: string;\n pricing?: {\n input?: string | number | null;\n output?: string | number | null;\n input_cache_read?: string | number | null;\n input_cache_write?: string | number | null;\n };\n prices_per_1m?: {\n input_token?: number | null;\n output_token?: number | null;\n cached_input?: number | null;\n cached_write?: number | null;\n };\n}\n\nconst DEFAULT_TIMEOUT_MS = 3000;\nconst DEFAULT_CACHE_TTL_MS = 3600_000; // 1 hour\n\n// In-memory fast cache\nconst dynamicPricingCache: Record<string, ModelPricingRates> = {};\n\nlet lastSyncTime: number | null = null;\nlet lastSyncETag: string | null = null;\nlet syncStatus: 'idle' | 'syncing' | 'synced' | 'failed' = 'idle';\nlet lastError: string | null = null;\n\n/**\n * Synchronously retrieves a rate from the dynamic pricing cache\n */\nexport function getDynamicRate(model: string): ModelPricingRates | undefined {\n if (!model) return undefined;\n const key = model.toLowerCase().trim();\n if (dynamicPricingCache[key]) {\n return dynamicPricingCache[key];\n }\n const normalized = normalizeModelKey(key);\n if (dynamicPricingCache[normalized]) {\n return dynamicPricingCache[normalized];\n }\n return undefined;\n}\n\n/**\n * Returns the count of models currently held in dynamic cache\n */\nexport function getDynamicCacheSize(): number {\n return Object.keys(dynamicPricingCache).length;\n}\n\n/**\n * Resets the in-memory dynamic pricing cache\n */\nexport function clearDynamicCache(): void {\n for (const k of Object.keys(dynamicPricingCache)) {\n delete dynamicPricingCache[k];\n }\n lastSyncTime = null;\n lastSyncETag = null;\n syncStatus = 'idle';\n lastError = null;\n}\n\n/**\n * Current synchronization status and telemetry\n */\nexport function getSyncStatus(): PricingSyncStatus {\n return {\n status: syncStatus,\n lastSyncTime,\n lastSyncETag,\n cachedModelsCount: Object.keys(dynamicPricingCache).length,\n lastError,\n };\n}\n\n/**\n * Ingests and registers an array of Stripe rate items or a manifest object into cache\n */\nexport function seedPricingCache(manifest: unknown): number {\n if (!manifest || typeof manifest !== 'object') {\n return 0;\n }\n\n let count = 0;\n\n // Case 1: Array of pricing items (Stripe or Vercel)\n if (Array.isArray(manifest)) {\n for (const item of manifest) {\n if (registerStripeItem(item) || registerVercelGatewayItem(item)) {\n count++;\n }\n }\n return count;\n }\n\n const obj = manifest as Record<string, any>;\n\n // Case 2: Vercel Gateway direct endpoint response: { object: \"list\", data: [...] }\n if (obj.object === 'list' && Array.isArray(obj.data)) {\n for (const item of obj.data) {\n if (registerVercelGatewayItem(item) || registerStripeItem(item)) {\n count++;\n }\n }\n return count;\n }\n\n // Case 3: Object with models array (e.g. { models: [...] })\n if (Array.isArray(obj.models)) {\n for (const item of obj.models) {\n if (registerStripeItem(item) || registerVercelGatewayItem(item)) {\n count++;\n }\n }\n }\n\n // Case 4: Object with vercel_gateway_models array\n if (Array.isArray(obj.vercel_gateway_models)) {\n for (const item of obj.vercel_gateway_models) {\n if (registerVercelGatewayItem(item) || registerStripeItem(item)) {\n count++;\n }\n }\n }\n\n // Case 5: Object with rates dictionary (e.g. { rates: { \"gpt-4o\": { inputPer1M: 2.5, ... } } })\n const ratesDict = obj.rates && typeof obj.rates === 'object' ? obj.rates : obj;\n for (const [key, val] of Object.entries(ratesDict)) {\n if (\n key === 'models' ||\n key === 'rates' ||\n key === 'version' ||\n key === '$schema' ||\n key === 'sources' ||\n key === 'vercel_gateway_models'\n ) {\n continue;\n }\n const v = val as any;\n if (v && typeof v === 'object' && typeof v.inputPer1M === 'number' && typeof v.outputPer1M === 'number') {\n registerRate(key, {\n inputPer1M: Math.max(0, v.inputPer1M),\n outputPer1M: Math.max(0, v.outputPer1M),\n cachedInputPer1M: typeof v.cachedInputPer1M === 'number' ? Math.max(0, v.cachedInputPer1M) : undefined,\n reasoningPer1M: typeof v.reasoningPer1M === 'number' ? Math.max(0, v.reasoningPer1M) : undefined,\n cacheWritePer1M: typeof v.cacheWritePer1M === 'number' ? Math.max(0, v.cacheWritePer1M) : undefined,\n currency: typeof v.currency === 'string' ? v.currency : 'USD',\n });\n count++;\n }\n }\n\n return count;\n}\n\nfunction registerRate(key: string, rate: ModelPricingRates): void {\n const cleanKey = key.toLowerCase().trim();\n dynamicPricingCache[cleanKey] = rate;\n const normalized = normalizeModelKey(cleanKey);\n dynamicPricingCache[normalized] = rate;\n}\n\nfunction registerVercelGatewayItem(entry: any): boolean {\n if (!entry || typeof entry !== 'object') return false;\n const modelId = typeof entry.id === 'string' ? entry.id : typeof entry.model === 'string' ? entry.model : null;\n if (!modelId) return false;\n\n // If entry has prices_per_1m already precomputed\n if (entry.prices_per_1m && typeof entry.prices_per_1m.input_token === 'number' && typeof entry.prices_per_1m.output_token === 'number') {\n return registerStripeItem({ ...entry, model: modelId });\n }\n\n const p = entry.pricing;\n if (!p || typeof p !== 'object') return false;\n\n const inSingle = p.input !== undefined && p.input !== null ? parseFloat(String(p.input)) : null;\n const outSingle = p.output !== undefined && p.output !== null ? parseFloat(String(p.output)) : null;\n if (inSingle === null || isNaN(inSingle) || outSingle === null || isNaN(outSingle)) {\n return false;\n }\n\n const roundRate = (v: number) => Math.round(v * 1e6) / 1e6;\n\n const rateObj: ModelPricingRates = {\n inputPer1M: Math.max(0, roundRate(inSingle * 1_000_000)),\n outputPer1M: Math.max(0, roundRate(outSingle * 1_000_000)),\n currency: 'USD',\n };\n\n if (p.input_cache_read !== undefined && p.input_cache_read !== null) {\n const cr = parseFloat(String(p.input_cache_read));\n if (!isNaN(cr)) {\n rateObj.cachedInputPer1M = Math.max(0, roundRate(cr * 1_000_000));\n }\n }\n if (p.input_cache_write !== undefined && p.input_cache_write !== null) {\n const cw = parseFloat(String(p.input_cache_write));\n if (!isNaN(cw)) {\n rateObj.cacheWritePer1M = Math.max(0, roundRate(cw * 1_000_000));\n }\n }\n\n const fullId = modelId.toLowerCase().trim();\n registerRate(fullId, rateObj);\n\n if (fullId.includes('/')) {\n const stripped = fullId.split('/').slice(1).join('/');\n registerRate(stripped, rateObj);\n }\n\n if (entry.owned_by && typeof entry.owned_by === 'string') {\n const owner = entry.owned_by.toLowerCase().replace(/\\s+/g, '-');\n dynamicPricingCache[`${owner}/${fullId}`] = rateObj;\n }\n\n return true;\n}\n\nfunction registerStripeItem(entry: any): boolean {\n const modelKey = typeof entry.model === 'string' ? entry.model : typeof entry.id === 'string' ? entry.id : null;\n if (!entry || typeof entry !== 'object' || !modelKey) {\n return false;\n }\n const p = entry.prices_per_1m;\n if (!p || typeof p !== 'object') return false;\n if (typeof p.input_token !== 'number' || typeof p.output_token !== 'number') return false;\n\n const rateObj: ModelPricingRates = {\n inputPer1M: Math.max(0, p.input_token),\n outputPer1M: Math.max(0, p.output_token),\n currency: 'USD',\n };\n\n if (typeof p.cached_input === 'number') {\n rateObj.cachedInputPer1M = Math.max(0, p.cached_input);\n } else if (typeof p.cached_read === 'number') {\n rateObj.cachedInputPer1M = Math.max(0, p.cached_read);\n }\n\n if (typeof p.cached_write === 'number') {\n rateObj.cacheWritePer1M = Math.max(0, p.cached_write);\n }\n\n const baseKey = modelKey.toLowerCase().trim();\n registerRate(baseKey, rateObj);\n\n if (entry.publisher && typeof entry.publisher === 'string') {\n const pub = entry.publisher.toLowerCase().replace(/\\s+/g, '-');\n dynamicPricingCache[`${pub}/${baseKey}`] = rateObj;\n if (pub === 'mistral-ai') {\n dynamicPricingCache[`mistral/${baseKey}`] = rateObj;\n }\n }\n\n if (entry.provider && typeof entry.provider === 'string') {\n const prov = entry.provider.toLowerCase().replace(/\\s+/g, '-');\n dynamicPricingCache[`${prov}/${baseKey}`] = rateObj;\n }\n\n return true;\n}\n\n/**\n * Asynchronously synchronizes the LLM pricing manifest from a remote endpoint.\n *\n * Guaranteed Safe & Non-Throwing:\n * If network is down, request times out, or manifest is invalid, returns false\n * and seamlessly preserves existing cached or bundled rates (offline fallback).\n */\nexport async function syncPricingManifest(options: PricingSyncOptions = {}): Promise<boolean> {\n const ttl = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;\n const now = Date.now();\n\n // If cache is fresh and not forced, reuse existing cache\n if (!options.force && lastSyncTime !== null && now - lastSyncTime < ttl && Object.keys(dynamicPricingCache).length > 0) {\n return true;\n }\n\n const url = options.manifestUrl || DEFAULT_MANIFEST_URL;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const fetchFn = options.fetch || globalThis.fetch;\n\n if (typeof fetchFn !== 'function') {\n // No fetch available in environment; try fallback manifest\n if (options.fallbackManifest) {\n seedPricingCache(options.fallbackManifest);\n lastSyncTime = now;\n syncStatus = 'synced';\n return true;\n }\n syncStatus = 'failed';\n lastError = 'Fetch API unavailable in runtime environment';\n return false;\n }\n\n syncStatus = 'syncing';\n\n const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timeoutId = controller ? setTimeout(() => controller.abort(), timeoutMs) : null;\n\n try {\n const reqHeaders: Record<string, string> = {\n Accept: 'application/json',\n ...(options.headers || {}),\n };\n\n if (lastSyncETag && !options.force) {\n reqHeaders['If-None-Match'] = lastSyncETag;\n }\n\n const response = await fetchFn(url, {\n method: 'GET',\n headers: reqHeaders,\n signal: controller?.signal,\n });\n\n if (timeoutId) clearTimeout(timeoutId);\n\n // 304 Not Modified: Existing dynamic cache is still up to date\n if (response.status === 304) {\n lastSyncTime = now;\n syncStatus = 'synced';\n lastError = null;\n return true;\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`);\n }\n\n const etag = response.headers?.get ? response.headers.get('etag') : null;\n if (etag) {\n lastSyncETag = etag;\n }\n\n const data = await response.json();\n const seeded = seedPricingCache(data);\n\n if (seeded === 0) {\n throw new Error('Manifest contains no recognizable pricing rates');\n }\n\n lastSyncTime = now;\n syncStatus = 'synced';\n lastError = null;\n return true;\n } catch (err: any) {\n if (timeoutId) clearTimeout(timeoutId);\n\n syncStatus = 'failed';\n lastError = err?.message || 'Unknown network error';\n\n // Seed fallback if provided\n if (options.fallbackManifest) {\n seedPricingCache(options.fallbackManifest);\n }\n\n // Graceful offline fallback: Never throw, return false\n return false;\n }\n}\n\n/**\n * Non-blocking, fire-and-forget background synchronization.\n * Triggers sync in background without awaiting or crashing if network is unavailable.\n */\nexport function triggerBackgroundSync(options: PricingSyncOptions = {}): void {\n syncPricingManifest(options).catch(() => {\n // Silently caught - offline fallback preserved\n });\n}\n\n/**\n * Synchronizes LLM token pricing directly from Vercel AI Gateway (https://ai-gateway.vercel.sh/v1/models).\n * Converts single-token rates into per-1M-token rates and populates dynamic cache.\n */\nexport async function syncVercelGateway(options: PricingSyncOptions = {}): Promise<boolean> {\n return syncPricingManifest({\n manifestUrl: VERCEL_GATEWAY_MODELS_URL,\n ...options,\n });\n}\n\n/**\n * Non-blocking, fire-and-forget background synchronization from Vercel AI Gateway.\n */\nexport function triggerVercelGatewaySync(options: PricingSyncOptions = {}): void {\n syncVercelGateway(options).catch(() => {\n // Silently caught - offline fallback preserved\n });\n}\n\n","import type { ModelPricingRates } from '../types';\r\nimport { getDynamicRate } from './sync';\r\n\r\n/**\r\n * Built-in Registry of Model Pricing (USD per 1 Million Tokens)\r\n * Sourced from official 2026 provider pricing tables.\r\n */\r\nexport const MODEL_PRICING_TABLE: Record<string, ModelPricingRates> = {\r\n // --- OpenAI (Modern & Reasoning) ---\r\n 'gpt-5.6-sol': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\r\n 'gpt-5.6-terra': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.2 },\r\n 'gpt-5.6-luna': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\r\n 'gpt-5': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\r\n 'gpt-5-mini': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\r\n 'o1': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\r\n 'o1-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\r\n 'o3': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\r\n 'o3-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\r\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10.0, cachedInputPer1M: 1.25 },\r\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.075 },\r\n 'gpt-4.5': { inputPer1M: 75.0, outputPer1M: 150.0, cachedInputPer1M: 37.5 },\r\n 'gpt-4.5-preview': { inputPer1M: 75.0, outputPer1M: 150.0, cachedInputPer1M: 37.5 },\r\n 'chatgpt-4o-latest': { inputPer1M: 5.0, outputPer1M: 15.0 },\r\n 'gpt-4.1': { inputPer1M: 2.0, outputPer1M: 8.0, cachedInputPer1M: 1.0 },\r\n 'gpt-4.1-nano': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.05 },\r\n 'gpt-6-astra': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 0.5 },\r\n 'gpt-6-astra-fast': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\r\n 'gpt-image-2.5-flare': { inputPer1M: 0.0, outputPer1M: 0.04 },\r\n 'gpt-image-2.5-sunburst': { inputPer1M: 0.0, outputPer1M: 0.08 },\r\n\r\n // --- OpenAI (Legacy & Backward Compatibility) ---\r\n 'gpt-4-turbo': { inputPer1M: 10.0, outputPer1M: 30.0, cachedInputPer1M: 5.0 },\r\n 'gpt-4-turbo-preview': { inputPer1M: 10.0, outputPer1M: 30.0, cachedInputPer1M: 5.0 },\r\n 'gpt-4': { inputPer1M: 30.0, outputPer1M: 60.0 },\r\n 'gpt-4-32k': { inputPer1M: 60.0, outputPer1M: 120.0 },\r\n 'gpt-3.5-turbo': { inputPer1M: 0.5, outputPer1M: 1.5 },\r\n 'gpt-3.5-turbo-16k': { inputPer1M: 3.0, outputPer1M: 4.0 },\r\n 'text-embedding-3-small': { inputPer1M: 0.02, outputPer1M: 0.0 },\r\n 'text-embedding-3-large': { inputPer1M: 0.13, outputPer1M: 0.0 },\r\n 'text-embedding-ada-002': { inputPer1M: 0.10, outputPer1M: 0.0 },\r\n\r\n // --- Anthropic (Modern & Extended Thinking) ---\r\n 'claude-haiku-5.5': { inputPer1M: 0.1, outputPer1M: 0.5, cachedInputPer1M: 0.01 },\r\n 'claude-sonnet-5.5': { inputPer1M: 2.0, outputPer1M: 10.0, cachedInputPer1M: 0.1 },\r\n 'claude-opus-5.5': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.2 },\r\n 'claude-opus-5.5-fast': { inputPer1M: 8.0, outputPer1M: 40.0, cachedInputPer1M: 0.4 },\r\n 'claude-3-7-sonnet': { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },\r\n 'claude-sonnet-5': { inputPer1M: 2.0, outputPer1M: 10.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-5-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-5-haiku': { inputPer1M: 0.8, outputPer1M: 4.0, cachedInputPer1M: 0.08 },\r\n 'haiku-4.5': { inputPer1M: 1.0, outputPer1M: 5.0, cachedInputPer1M: 0.1 },\r\n 'claude-opus-5': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 1.5 },\r\n 'claude-3-opus': { inputPer1M: 15.0, outputPer1M: 75.0, cachedInputPer1M: 1.5 },\r\n\r\n // --- Anthropic (Legacy & Backward Compatibility) ---\r\n 'claude-3-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\r\n 'claude-3-haiku': { inputPer1M: 0.25, outputPer1M: 1.25, cachedInputPer1M: 0.025 },\r\n 'claude-2.1': { inputPer1M: 8.0, outputPer1M: 24.0 },\r\n 'claude-2.0': { inputPer1M: 8.0, outputPer1M: 24.0 },\r\n 'claude-instant-1.2': { inputPer1M: 1.63, outputPer1M: 5.51 },\r\n\r\n // --- Google Gemini (Modern & Thoughts) ---\r\n 'gemini-3.8-flash': { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.075 },\r\n 'gemini-nano-banana-2.1': { inputPer1M: 1.5, outputPer1M: 7.5, cachedInputPer1M: 0.15 },\r\n 'gemini-3.7-flash': { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },\r\n 'gemini-3.1-pro': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.5 },\r\n 'gemini-3.5-flash': { inputPer1M: 1.5, outputPer1M: 9.0, cachedInputPer1M: 0.38 },\r\n 'gemini-3.1-flash-lite': { inputPer1M: 0.25, outputPer1M: 1.5, cachedInputPer1M: 0.06 },\r\n 'gemini-2.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n 'gemini-2.5-flash': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.0375 },\r\n 'gemini-2.0-flash': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.025 },\r\n 'gemini-2.0-flash-lite': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\r\n 'gemini-2.0-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n\r\n // --- Google Gemini (Legacy & Backward Compatibility) ---\r\n 'gemini-1.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\r\n 'gemini-1.5-flash': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\r\n 'gemini-1.5-flash-8b': { inputPer1M: 0.0375, outputPer1M: 0.15, cachedInputPer1M: 0.009375 },\r\n 'gemini-1.0-pro': { inputPer1M: 0.5, outputPer1M: 1.5 },\r\n\r\n // --- xAI Grok ---\r\n 'grok-4.6': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'grok-3': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'grok-3-mini': { inputPer1M: 0.3, outputPer1M: 1.5 },\r\n 'grok-2': { inputPer1M: 2.0, outputPer1M: 10.0 },\r\n 'grok-2-vision': { inputPer1M: 2.0, outputPer1M: 10.0 },\r\n 'grok-beta': { inputPer1M: 5.0, outputPer1M: 15.0 },\r\n\r\n // --- Mistral ---\r\n 'mistral-large-4': { inputPer1M: 0.68, outputPer1M: 2.09, cachedInputPer1M: 0.07 },\r\n 'mistral-large-3': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'mistral-large-latest': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'mistral-large-2411': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n 'codestral-latest': { inputPer1M: 0.3, outputPer1M: 0.9 },\r\n 'mistral-medium-latest': { inputPer1M: 2.7, outputPer1M: 8.1 },\r\n 'mistral-medium-3-5': { inputPer1M: 2.0, outputPer1M: 6.0, cachedInputPer1M: 0.4 },\r\n 'mistral-medium-2604': { inputPer1M: 2.0, outputPer1M: 6.0, cachedInputPer1M: 0.4 },\r\n 'magistral-small-latest': { inputPer1M: 0.5, outputPer1M: 1.5, cachedInputPer1M: 0.1 },\r\n 'magistral-medium-latest': { inputPer1M: 2.0, outputPer1M: 6.0, cachedInputPer1M: 0.4 },\r\n 'mistral-small-latest': { inputPer1M: 0.2, outputPer1M: 0.6 },\r\n 'mistral-small-2603': { inputPer1M: 0.2, outputPer1M: 0.6, cachedInputPer1M: 0.05 },\r\n 'mistral-vibe-cli-fast': { inputPer1M: 0.2, outputPer1M: 0.6, cachedInputPer1M: 0.05 },\r\n 'mistral-vibe-cli-latest': { inputPer1M: 0.2, outputPer1M: 0.6, cachedInputPer1M: 0.05 },\r\n 'codestral-2508': { inputPer1M: 0.3, outputPer1M: 0.9, cachedInputPer1M: 0.08 },\r\n 'codestral-embed': { inputPer1M: 0.1, outputPer1M: 0.0 },\r\n 'mistral-embed-2312': { inputPer1M: 0.1, outputPer1M: 0.0 },\r\n 'zai-glm-5-2': { inputPer1M: 0.6, outputPer1M: 2.2, cachedInputPer1M: 0.15 },\r\n 'glm-5-2': { inputPer1M: 0.6, outputPer1M: 2.2, cachedInputPer1M: 0.15 },\r\n 'labs-leanstral-1-5': { inputPer1M: 0.2, outputPer1M: 0.6, cachedInputPer1M: 0.05 },\r\n 'ministral-8b-latest': { inputPer1M: 0.1, outputPer1M: 0.1 },\r\n 'ministral-3b-latest': { inputPer1M: 0.04, outputPer1M: 0.04 },\r\n 'open-mistral-7b': { inputPer1M: 0.2, outputPer1M: 0.2 },\r\n 'open-mixtral-8x7b': { inputPer1M: 0.7, outputPer1M: 0.7 },\r\n 'open-mixtral-8x22b': { inputPer1M: 2.0, outputPer1M: 6.0 },\r\n\r\n // --- Groq & Meta Llama LPUs ---\r\n 'llama-3.3-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\r\n 'llama-3.1-405b': { inputPer1M: 3.0, outputPer1M: 3.0 },\r\n 'llama-3.1-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\r\n 'llama-3.1-8b-instant': { inputPer1M: 0.05, outputPer1M: 0.08 },\r\n 'llama-3.2-1b-preview': { inputPer1M: 0.04, outputPer1M: 0.04 },\r\n 'llama-3.2-3b-preview': { inputPer1M: 0.06, outputPer1M: 0.06 },\r\n 'llama-3.2-11b-vision': { inputPer1M: 0.18, outputPer1M: 0.18 },\r\n 'llama-3.2-90b-vision': { inputPer1M: 0.90, outputPer1M: 0.90 },\r\n 'deepseek-r1-distill-llama-70b': { inputPer1M: 0.75, outputPer1M: 0.99 },\r\n 'deepseek-r1-distill-qwen-32b': { inputPer1M: 0.49, outputPer1M: 0.49 },\r\n 'qwen-2.5-32b': { inputPer1M: 0.29, outputPer1M: 0.39 },\r\n 'qwen-2.5-72b': { inputPer1M: 0.35, outputPer1M: 0.40 },\r\n 'mixtral-8x7b-32768': { inputPer1M: 0.24, outputPer1M: 0.24 },\r\n 'gemma2-9b-it': { inputPer1M: 0.20, outputPer1M: 0.20 },\r\n\r\n // --- DeepSeek ---\r\n 'deepseek-v4-pro': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\r\n 'deepseek-v4.1-flash': { inputPer1M: 0.20, outputPer1M: 0.60, cachedInputPer1M: 0.05 },\r\n 'deepseek-v4-flash': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\r\n 'deepseek-v3': { inputPer1M: 0.14, outputPer1M: 0.28, cachedInputPer1M: 0.014 },\r\n 'deepseek-chat': { inputPer1M: 0.14, outputPer1M: 0.28, cachedInputPer1M: 0.014 },\r\n 'deepseek-r1': { inputPer1M: 0.55, outputPer1M: 2.19, cachedInputPer1M: 0.14 },\r\n 'deepseek-reasoner': { inputPer1M: 0.55, outputPer1M: 2.19, cachedInputPer1M: 0.14 },\r\n\r\n // --- Gateway, Inception & InclusionAI Models ---\r\n 'mercury-2.5': { inputPer1M: 0.25, outputPer1M: 0.75, cachedInputPer1M: 0.05 },\r\n 'mercury-2': { inputPer1M: 0.25, outputPer1M: 0.75, cachedInputPer1M: 0.05 },\r\n 'ling-3.0-flash-sante': { inputPer1M: 0.15, outputPer1M: 0.45, cachedInputPer1M: 0.03 },\r\n 'ling-3.0-flash': { inputPer1M: 0.15, outputPer1M: 0.45, cachedInputPer1M: 0.03 },\r\n\r\n // --- Cohere ---\r\n 'command-r-plus': { inputPer1M: 2.5, outputPer1M: 10.0 },\r\n 'command-r': { inputPer1M: 0.15, outputPer1M: 0.6 },\r\n 'command': { inputPer1M: 1.0, outputPer1M: 2.0 },\r\n 'command-light': { inputPer1M: 0.3, outputPer1M: 0.6 },\r\n 'embed-english-v3.0': { inputPer1M: 0.10, outputPer1M: 0.0 },\r\n\r\n // --- Perplexity ---\r\n 'sonar': { inputPer1M: 1.0, outputPer1M: 1.0 },\r\n 'sonar-pro': { inputPer1M: 3.0, outputPer1M: 15.0 },\r\n 'sonar-reasoning': { inputPer1M: 1.0, outputPer1M: 5.0 },\r\n 'sonar-reasoning-pro': { inputPer1M: 2.0, outputPer1M: 8.0 },\r\n};\r\n\r\n/**\r\n * Common model alias map to normalize nicknames, shorthands, and legacy IDs\r\n */\r\nexport const MODEL_ALIASES: Record<string, string> = {\r\n // OpenAI Shorthands & Aliases\r\n 'gpt4': 'gpt-4',\r\n 'gpt4o': 'gpt-4o',\r\n 'gpt-4-preview': 'gpt-4-turbo',\r\n 'gpt-4-0125-preview': 'gpt-4-turbo',\r\n 'gpt-4-1106-preview': 'gpt-4-turbo',\r\n 'gpt-3.5': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-0125': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-1106': 'gpt-3.5-turbo',\r\n 'gpt-3.5-turbo-16k-0613': 'gpt-3.5-turbo-16k',\r\n\r\n // Anthropic Shorthands\r\n 'sonnet': 'claude-3-5-sonnet',\r\n 'sonnet-3.7': 'claude-3-7-sonnet',\r\n 'sonnet-3.5': 'claude-3-5-sonnet',\r\n 'haiku': 'claude-3-5-haiku',\r\n 'haiku-3.5': 'claude-3-5-haiku',\r\n 'haiku-5.5': 'claude-haiku-5.5',\r\n 'sonnet-5.5': 'claude-sonnet-5.5',\r\n 'opus-5.5': 'claude-opus-5.5',\r\n 'opus': 'claude-3-opus',\r\n 'claude-2': 'claude-2.0',\r\n 'claude-instant': 'claude-instant-1.2',\r\n\r\n // DeepSeek Shorthands\r\n 'r1': 'deepseek-r1',\r\n 'v3': 'deepseek-v3',\r\n\r\n // Gemini Shorthands\r\n 'flash': 'gemini-2.0-flash',\r\n 'pro': 'gemini-1.5-pro',\r\n 'gemini-banana': 'gemini-nano-banana-2.1',\r\n\r\n // Meta / Groq Shorthands\r\n 'llama-3.3-70b': 'llama-3.3-70b-versatile',\r\n 'llama-3.1-70b': 'llama-3.1-70b-versatile',\r\n 'llama-3.1-8b': 'llama-3.1-8b-instant',\r\n 'llama-3-70b': 'llama-3.1-70b-versatile',\r\n 'llama-3-8b': 'llama-3.1-8b-instant',\r\n\r\n // Mistral Shorthands\r\n 'codestral': 'codestral-latest',\r\n 'mistral-large': 'mistral-large-latest',\r\n 'mistral-small': 'mistral-small-latest',\r\n 'magistral': 'magistral-small-latest',\r\n 'magistral-small': 'magistral-small-latest',\r\n 'magistral-medium': 'magistral-medium-latest',\r\n 'mistral-3.5': 'mistral-medium-3-5',\r\n 'mistral-medium-3.5': 'mistral-medium-3-5',\r\n 'gpt-image-2.5': 'gpt-image-2.5-flare',\r\n 'gpt-image-sunburst': 'gpt-image-2.5-sunburst',\r\n 'gpt-image-flare': 'gpt-image-2.5-flare',\r\n};\r\n\r\n/**\r\n * Dynamic in-memory registry allowing runtime custom price registration\r\n */\r\nconst customPricingRegistry: Record<string, ModelPricingRates> = {};\r\n\r\n/**\r\n * Normalize model identifier to match pricing table keys:\r\n * - Strips AWS Bedrock prefixes (e.g. 'anthropic.claude-3-5-sonnet-20241022-v2:0' -> 'claude-3-5-sonnet')\r\n * - Strips provider prefixes (e.g. 'openai/gpt-4o' -> 'gpt-4o', 'deepseek/deepseek-r1' -> 'deepseek-r1')\r\n * - Strips date suffixes (e.g. '-20240307', '-20250219')\r\n * - Resolves shorthands and aliases\r\n */\r\nexport function normalizeModelKey(rawModel: string): string {\r\n if (!rawModel) return 'unknown';\r\n\r\n let model = rawModel.toLowerCase().trim();\r\n\r\n // Strip AWS Bedrock model prefix (e.g. 'us.anthropic.claude-3-5-sonnet...', 'meta.llama3-...')\r\n model = model.replace(/^[a-z0-9_-]+\\.(anthropic|meta|amazon|cohere|mistral|ai21)\\./i, '');\r\n model = model.replace(/^(anthropic|meta|amazon|cohere|mistral|ai21)\\./i, '');\r\n\r\n // Strip AWS Bedrock version suffix (e.g. '-v1:0', '-v2:0', ':0')\r\n model = model.replace(/-v\\d+(:\\d+)?$/, '');\r\n model = model.replace(/:\\d+$/, '');\r\n\r\n // Strip provider prefix if present (e.g. 'openai/gpt-4o' -> 'gpt-4o', 'meta-llama/llama-3.3-70b-instruct' -> 'llama-3.3-70b-instruct')\r\n if (model.includes('/')) {\r\n model = model.split('/').slice(1).join('/');\r\n }\r\n\r\n // Remove trailing version/mode tags (e.g. ':latest', ':free', ':beta')\r\n model = model.replace(/:(latest|free|beta)$/, '');\r\n\r\n // Remove date suffixes like -20240307 or -20250219 or -2024-08-06\r\n model = model.replace(/-\\d{8}$/, '');\r\n model = model.replace(/-\\d{4}-\\d{2}-\\d{2}$/, '');\r\n\r\n // Normalize Bedrock Meta format (e.g. llama3-1-70b -> llama-3.1-70b)\r\n model = model.replace(/llama(\\d+)-(\\d+)-/g, 'llama-$1.$2-');\r\n model = model.replace(/llama(\\d+)\\.(\\d+)-/g, 'llama-$1.$2-');\r\n\r\n // Check aliases before fine-tuning\r\n if (MODEL_ALIASES[model]) {\r\n return MODEL_ALIASES[model];\r\n }\r\n\r\n // Remove common modifier suffixes if not directly matching table\r\n if (!MODEL_PRICING_TABLE[model]) {\r\n const withoutInstruct = model.replace(/-(instruct|chat|preview)$/, '');\r\n if (MODEL_PRICING_TABLE[withoutInstruct]) {\r\n return withoutInstruct;\r\n }\r\n if (MODEL_ALIASES[withoutInstruct]) {\r\n return MODEL_ALIASES[withoutInstruct];\r\n }\r\n }\r\n\r\n return model;\r\n}\r\n\r\n/**\r\n * Retrieve pricing rates for a given model\r\n */\r\nexport function getModelPricing(modelName: string): ModelPricingRates {\r\n const normalized = normalizeModelKey(modelName);\r\n\r\n // Check custom registry first\r\n if (customPricingRegistry[normalized]) {\r\n return customPricingRegistry[normalized];\r\n }\r\n if (customPricingRegistry[modelName]) {\r\n return customPricingRegistry[modelName];\r\n }\r\n\r\n // Check dynamic synced manifest cache\r\n const dynamicRate = getDynamicRate(modelName) || getDynamicRate(normalized);\r\n if (dynamicRate) {\r\n return dynamicRate;\r\n }\r\n\r\n // Check built-in table with normalized key\r\n if (MODEL_PRICING_TABLE[normalized]) {\r\n return MODEL_PRICING_TABLE[normalized];\r\n }\r\n // Check built-in table with direct key\r\n if (MODEL_PRICING_TABLE[modelName]) {\r\n return MODEL_PRICING_TABLE[modelName];\r\n }\r\n\r\n // Check alias table fallback\r\n const alias = MODEL_ALIASES[modelName.toLowerCase().trim()];\r\n if (alias) {\r\n const dynamicAlias = getDynamicRate(alias);\r\n if (dynamicAlias) return dynamicAlias;\r\n if (MODEL_PRICING_TABLE[alias]) {\r\n return MODEL_PRICING_TABLE[alias];\r\n }\r\n }\r\n\r\n // Fallback defaults for unknown models (conservative estimates: $1.00 in, $3.00 out)\r\n return {\r\n inputPer1M: 1.0,\r\n outputPer1M: 3.0,\r\n cachedInputPer1M: 0.5,\r\n };\r\n}\r\n\r\n/**\r\n * Register or override pricing rates for a custom model\r\n */\r\nexport function registerModelPricing(modelName: string, rates: ModelPricingRates): void {\r\n const normalized = normalizeModelKey(modelName);\r\n customPricingRegistry[normalized] = rates;\r\n customPricingRegistry[modelName] = rates;\r\n}\r\n","import type { InferenceCost, TokenUsage, InlineRateConfig, ModelPricingRates } from '../types';\nimport { getModelPricing } from './table';\n\nexport interface CalculateCostParams {\n model: string;\n inputTokens?: number;\n outputTokens?: number;\n promptTokens?: number;\n completionTokens?: number;\n reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n markupMultiplier?: number;\n markup?: number;\n margin?: number;\n minimumChargeUSD?: number;\n customRate?: InlineRateConfig;\n}\n\nexport interface TokenUsageInput {\n inputTokens?: number;\n outputTokens?: number;\n promptTokens?: number;\n completionTokens?: number;\n reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n}\n\nexport interface CalculateCostOptions {\n markupMultiplier?: number;\n markup?: number;\n margin?: number;\n minimumChargeUSD?: number;\n customRate?: InlineRateConfig;\n}\n\n/**\n * BigInt Nano-Precision Financial Math Engine\n * 1 USD = 1,000,000,000 Nano-USD (10^9)\n * 1 token at $1.00 / 1M = $0.000001 = 1,000 Nano-USD\n * Prevents IEEE 754 floating point precision drift on micro-transactions.\n *\n * Supports both:\n * 1. calculateCost('gpt-4o-mini', { promptTokens: 1240, completionTokens: 150 })\n * 2. calculateCost({ model: 'gpt-4o-mini', inputTokens: 1240, outputTokens: 150 })\n */\nexport function calculateCost(\n modelOrParams: string | CalculateCostParams,\n usage?: TokenUsageInput,\n optionsOrMarkup?: number | CalculateCostOptions\n): InferenceCost {\n let params: CalculateCostParams;\n\n if (typeof modelOrParams === 'string') {\n const opts =\n typeof optionsOrMarkup === 'number'\n ? { markupMultiplier: optionsOrMarkup }\n : optionsOrMarkup || {};\n params = {\n model: modelOrParams,\n inputTokens: usage?.inputTokens ?? usage?.promptTokens ?? 0,\n outputTokens: usage?.outputTokens ?? usage?.completionTokens ?? 0,\n reasoningTokens: usage?.reasoningTokens,\n cachedTokens: usage?.cachedTokens,\n cacheWriteTokens: usage?.cacheWriteTokens,\n markupMultiplier: opts.markupMultiplier ?? opts.markup ?? opts.margin,\n minimumChargeUSD: opts.minimumChargeUSD,\n customRate: opts.customRate,\n };\n } else {\n params = {\n ...modelOrParams,\n inputTokens: modelOrParams.inputTokens ?? modelOrParams.promptTokens ?? 0,\n outputTokens: modelOrParams.outputTokens ?? modelOrParams.completionTokens ?? 0,\n markupMultiplier:\n modelOrParams.markupMultiplier ?? modelOrParams.markup ?? modelOrParams.margin,\n };\n }\n let rates: ModelPricingRates;\n\n if (params.customRate) {\n const outRate = params.customRate.out ?? params.customRate.output ?? 0;\n rates = {\n inputPer1M: params.customRate.in,\n outputPer1M: outRate,\n reasoningPer1M: params.customRate.reasoning ?? outRate,\n cachedInputPer1M: params.customRate.cached ?? params.customRate.in * 0.15,\n currency: 'USD',\n };\n } else {\n rates = getModelPricing(params.model);\n }\n\n const inputTokens = BigInt(Math.max(0, params.inputTokens ?? 0));\n const outputTokens = BigInt(Math.max(0, params.outputTokens ?? 0));\n const reasoningTokens = BigInt(Math.max(0, params.reasoningTokens ?? 0));\n const cachedTokens = BigInt(Math.max(0, params.cachedTokens ?? 0));\n\n // Regular input tokens (minus any cached tokens)\n const regularInputTokens = inputTokens > cachedTokens ? inputTokens - cachedTokens : 0n;\n\n // Convert rate per 1M tokens to integer nano-dollars per single token (rate * 1,000)\n // Using 10^9 nano-precision\n const rateInputNano = BigInt(Math.round(rates.inputPer1M * 1_000));\n const cachedPer1M = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15;\n const rateCachedNano = BigInt(Math.round(cachedPer1M * 1_000));\n const rateOutputNano = BigInt(Math.round(rates.outputPer1M * 1_000));\n const reasoningPer1M = rates.reasoningPer1M ?? rates.outputPer1M;\n const rateReasoningNano = BigInt(Math.round(reasoningPer1M * 1_000));\n\n // Compute component nano costs\n const regularInputCostNano = regularInputTokens * rateInputNano;\n const cachedInputCostNano = cachedTokens * rateCachedNano;\n const inputCostNano = regularInputCostNano + cachedInputCostNano;\n const outputCostNano = outputTokens * rateOutputNano;\n const reasoningCostNano = reasoningTokens * rateReasoningNano;\n\n // Prompt cache savings discount\n const standardCacheCostNano = cachedTokens * rateInputNano;\n const cachedDiscountNano =\n standardCacheCostNano > cachedInputCostNano ? standardCacheCostNano - cachedInputCostNano : 0n;\n\n // Total wholesale cost\n const wholesaleNano = inputCostNano + outputCostNano;\n\n // Retail calculation\n const markup = params.markupMultiplier ?? 1.0;\n let billedNano = wholesaleNano;\n let hasRetail = false;\n\n if (markup !== 1.0 || params.minimumChargeUSD !== undefined) {\n hasRetail = true;\n const markupMultiplierNano = BigInt(Math.round(markup * 1_000));\n billedNano = (wholesaleNano * markupMultiplierNano) / 1_000n;\n\n if (params.minimumChargeUSD !== undefined && params.minimumChargeUSD > 0) {\n const minChargeNano = BigInt(Math.round(params.minimumChargeUSD * 1_000_000_000));\n if (billedNano < minChargeNano) {\n billedNano = minChargeNano;\n }\n }\n }\n\n const inputCostUSD = Number(inputCostNano) / 1_000_000_000;\n const outputCostUSD = Number(outputCostNano) / 1_000_000_000;\n const reasoningCostUSD = Number(reasoningCostNano) / 1_000_000_000;\n const cachedDiscountUSD = Number(cachedDiscountNano) / 1_000_000_000;\n const totalUSD = Number(wholesaleNano) / 1_000_000_000;\n const wholesaleTotalUSD = totalUSD;\n const billedUSD = Number(billedNano) / 1_000_000_000;\n const profitUSD = Math.max(0, billedUSD - wholesaleTotalUSD);\n const retailUSD = hasRetail ? billedUSD : undefined;\n\n return {\n inputCostUSD: Number(inputCostUSD.toFixed(8)),\n outputCostUSD: Number(outputCostUSD.toFixed(8)),\n reasoningCostUSD: reasoningTokens > 0n ? Number(reasoningCostUSD.toFixed(8)) : undefined,\n cachedDiscountUSD: cachedTokens > 0n ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n savingsUSD: cachedTokens > 0n ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n totalUSD: Number(totalUSD.toFixed(8)),\n wholesaleTotalUSD: Number(wholesaleTotalUSD.toFixed(8)),\n wholesaleUSD: Number(wholesaleTotalUSD.toFixed(8)),\n billedUSD: Number(billedUSD.toFixed(8)),\n profitUSD: Number(profitUSD.toFixed(8)),\n retailUSD: retailUSD !== undefined ? Number(retailUSD.toFixed(8)) : undefined,\n currency: rates.currency || 'USD',\n };\n}\n\n/**\n * Calculates cost directly from a TokenUsage object\n */\nexport function calculateUsageCost(\n model: string,\n usage: TokenUsage,\n optionsOrMarkup?: number | { markupMultiplier?: number; minimumChargeUSD?: number; customRate?: InlineRateConfig }\n): InferenceCost {\n const options =\n typeof optionsOrMarkup === 'number'\n ? { markupMultiplier: optionsOrMarkup }\n : optionsOrMarkup || {};\n\n return calculateCost({\n model,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n reasoningTokens: usage.reasoningTokens,\n cachedTokens: usage.cachedTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n markupMultiplier: options.markupMultiplier,\n minimumChargeUSD: options.minimumChargeUSD,\n customRate: options.customRate,\n });\n}\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n","import type { UsageEvent, StreamWrapOptions } from '../types';\r\nimport { inspectOpenAIStreamChunk } from './extractors/openai';\r\nimport { AnthropicStreamAccumulator } from './extractors/anthropic';\r\nimport { extractGeminiResponseUsage } from './extractors/gemini';\r\nimport { calculateUsageCost } from '../pricing/calculator';\r\nimport { normalizeCustomer } from '../customers/helpers';\r\n\r\nexport type UsageDispatchedCallback = (event: UsageEvent) => void;\r\n\r\n/**\r\n * Wraps an OpenAI async iterable stream to capture usage at stream conclusion\r\n */\r\nexport function wrapOpenAIStream<T extends AsyncIterable<any>>(\r\n stream: T,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n let detectedModel = options.model || 'gpt-4o';\r\n let finalUsage: any = null;\r\n\r\n const wrappedAsyncIterable = {\r\n async *[Symbol.asyncIterator]() {\r\n try {\r\n for await (const chunk of stream) {\r\n const inspected = inspectOpenAIStreamChunk(chunk);\r\n if (inspected.model) {\r\n detectedModel = inspected.model;\r\n }\r\n if (inspected.usage) {\r\n finalUsage = inspected.usage;\r\n }\r\n yield chunk;\r\n }\r\n } finally {\r\n if (finalUsage) {\r\n const cost = calculateUsageCost(detectedModel, finalUsage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: detectedModel,\r\n provider: 'openai',\r\n usage: finalUsage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(event);\r\n if (options.onUsage) {\r\n options.onUsage(event);\r\n }\r\n }\r\n }\r\n },\r\n };\r\n\r\n return wrappedAsyncIterable as unknown as T;\r\n}\r\n\r\n/**\r\n * Wraps an Anthropic message stream to accumulate message_start and message_delta usage\r\n */\r\nexport function wrapAnthropicStream<T extends AsyncIterable<any>>(\r\n stream: T,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n const accumulator = new AnthropicStreamAccumulator();\r\n\r\n const wrappedAsyncIterable = {\r\n async *[Symbol.asyncIterator]() {\r\n try {\r\n for await (const event of stream) {\r\n accumulator.processEvent(event);\r\n yield event;\r\n }\r\n } finally {\r\n const extracted = accumulator.getUsage();\r\n const model = options.model || extracted.model;\r\n const cost = calculateUsageCost(model, extracted.usage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const usageEvent: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model,\r\n provider: 'anthropic',\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(usageEvent);\r\n if (options.onUsage) {\r\n options.onUsage(usageEvent);\r\n }\r\n }\r\n },\r\n };\r\n\r\n return wrappedAsyncIterable as unknown as T;\r\n}\r\n\r\n/**\r\n * Wraps a Google Gemini GenerateContentStreamResult\r\n */\r\nexport function wrapGeminiStream(\r\n result: any,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): any {\r\n if (!result || !result.stream) return result;\r\n\r\n const originalStream = result.stream;\r\n const model = options.model || 'gemini-3.7-flash';\r\n let lastChunkWithUsage: any = null;\r\n\r\n const wrappedStream = (async function* () {\r\n try {\r\n for await (const chunk of originalStream) {\r\n if (chunk.usageMetadata) {\r\n lastChunkWithUsage = chunk;\r\n }\r\n yield chunk;\r\n }\r\n } finally {\r\n if (lastChunkWithUsage) {\r\n const extracted = extractGeminiResponseUsage(lastChunkWithUsage, model);\r\n if (extracted) {\r\n const cost = calculateUsageCost(extracted.model, extracted.usage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: extracted.model,\r\n provider: 'google',\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(event);\r\n if (options.onUsage) {\r\n options.onUsage(event);\r\n }\r\n }\r\n }\r\n }\r\n })();\r\n\r\n return {\r\n ...result,\r\n stream: wrappedStream,\r\n };\r\n}\r\n\r\n/**\r\n * Universal Stream Wrapper\r\n */\r\nexport function wrapUniversalStream<T>(\r\n stream: T,\r\n options: StreamWrapOptions = {},\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n if (!stream || typeof stream !== 'object') return stream;\r\n\r\n // 1. Check Gemini stream\r\n if ('stream' in stream && 'response' in stream) {\r\n return wrapGeminiStream(stream, options, onComplete);\r\n }\r\n\r\n // 2. Check if stream is an AsyncIterable\r\n if (Symbol.asyncIterator in stream) {\r\n // If provider is explicitly anthropic or model is claude\r\n if (options.provider === 'anthropic' || options.model?.toLowerCase().includes('claude')) {\r\n return wrapAnthropicStream(stream as any, options, onComplete);\r\n }\r\n // Default to universal stream wrapper which detects usage chunks polymorphically\r\n return wrapOpenAIStream(stream as any, options, onComplete);\r\n }\r\n\r\n return stream;\r\n}\r\n","import type {\r\n MeterOptions,\r\n StreamWrapOptions,\r\n RecordUsageOptions,\r\n UsageEvent,\r\n UsageSummary,\r\n CustomerParam,\r\n} from '../types';\r\nimport { MeterBatcher } from './batcher';\r\nimport { detectAndExtractUsage } from './extractors';\r\nimport { calculateUsageCost } from '../pricing/calculator';\r\nimport { wrapUniversalStream } from './stream';\r\nimport { normalizeCustomer } from '../customers/helpers';\r\n\r\nexport class VibezMeter {\r\n private batcher: MeterBatcher;\r\n private markupMultiplier?: number;\r\n\r\n constructor(options: MeterOptions = {}) {\r\n this.markupMultiplier = options.pricing?.margin ?? options.pricing?.markup ?? options.markupMultiplier;\r\n this.batcher = new MeterBatcher(options);\r\n }\r\n\r\n /**\r\n * Track token usage from a non-streaming response object (OpenAI, Anthropic, Gemini, etc.)\r\n */\r\n public trackUsage(\r\n response: any,\r\n options: {\r\n customer?: CustomerParam;\r\n customerId?: string;\r\n model?: string;\r\n provider?: string;\r\n metadata?: Record<string, string | number | boolean>;\r\n } = {}\r\n ): UsageEvent | null {\r\n const extracted = detectAndExtractUsage(response, options.model, options.provider);\r\n if (!extracted) {\r\n return null;\r\n }\r\n\r\n const model = options.model || extracted.model;\r\n const cost = calculateUsageCost(model, extracted.usage, this.markupMultiplier);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const mergedMeta = {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n };\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model,\r\n provider: extracted.provider,\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: mergedMeta,\r\n };\r\n\r\n this.batcher.enqueue(event);\r\n return event;\r\n }\r\n\r\n /**\r\n * Wrap any LLM stream (OpenAI, Anthropic, Gemini) with zero added latency\r\n */\r\n public wrapStream<T>(stream: T, options: StreamWrapOptions = {}): T {\r\n return wrapUniversalStream(stream, options, (event) => {\r\n this.batcher.enqueue(event);\r\n });\r\n }\r\n\r\n /**\r\n * Directly record token usage manually\r\n */\r\n public recordUsage(options: RecordUsageOptions & { customer?: CustomerParam }): UsageEvent {\r\n const inputTokens = options.inputTokens ?? 0;\r\n const outputTokens = options.outputTokens ?? 0;\r\n const reasoningTokens = options.reasoningTokens;\r\n const cachedTokens = options.cachedTokens;\r\n\r\n const usage = {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens,\r\n visibleOutputTokens:\r\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\r\n cachedTokens,\r\n };\r\n\r\n const cost = calculateUsageCost(options.model, usage, this.markupMultiplier);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const mergedMeta = {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n };\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: options.model,\r\n provider: options.provider || 'custom',\r\n usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: mergedMeta,\r\n };\r\n\r\n this.batcher.enqueue(event);\r\n return event;\r\n }\r\n\r\n /**\r\n * Flush pending events (vital for Serverless & Edge environments)\r\n */\r\n public async flush(): Promise<void> {\r\n await this.batcher.flush();\r\n }\r\n\r\n /**\r\n * Get in-memory aggregated usage statistics\r\n */\r\n public getUsageSummary(): UsageSummary {\r\n return this.batcher.getSummary();\r\n }\r\n\r\n /**\r\n * Reset in-memory ledger\r\n */\r\n public resetSummary(): void {\r\n this.batcher.resetLedger();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create a VibezMeter instance\r\n */\r\nexport function createMeter(options: MeterOptions = {}): VibezMeter {\r\n return new VibezMeter(options);\r\n}\r\n","export * from './client';\r\nexport * from './batcher';\r\nexport * from './stream';\r\nexport * from './extractors';\r\n\r\nimport { createMeter } from './client';\r\nimport type { StreamWrapOptions, CustomerParam } from '../types';\r\n\r\n// Default singleton instance\r\nconst defaultMeter = createMeter();\r\n\r\n/**\r\n * Convenient standalone stream wrapper\r\n */\r\nexport function wrapStream<T>(stream: T, options?: StreamWrapOptions): T {\r\n return defaultMeter.wrapStream(stream, options);\r\n}\r\n\r\n/**\r\n * Convenient standalone usage tracker\r\n */\r\nexport function trackTokens(\r\n response: any,\r\n options?: { customer?: CustomerParam; customerId?: string; model?: string }\r\n) {\r\n return defaultMeter.trackUsage(response, options);\r\n}\r\n"],"mappings":"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","names":["rawUsage","customerObj"]}
|