vibezcheck 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +131 -197
  2. package/bin/vibezcheck.js +4 -0
  3. package/dist/ai-sdk/index.d.mts +78 -9
  4. package/dist/ai-sdk/index.d.ts +78 -9
  5. package/dist/ai-sdk/index.js +278 -64
  6. package/dist/ai-sdk/index.js.map +1 -1
  7. package/dist/ai-sdk/index.mjs +282 -64
  8. package/dist/ai-sdk/index.mjs.map +1 -1
  9. package/dist/cli/index.d.mts +1 -0
  10. package/dist/cli/index.d.ts +1 -0
  11. package/dist/cli/index.js +232 -0
  12. package/dist/cli/index.js.map +1 -0
  13. package/dist/cli/index.mjs +209 -0
  14. package/dist/cli/index.mjs.map +1 -0
  15. package/dist/{client-MJ3tl7bz.d.mts → client--iq93FQg.d.mts} +1 -1
  16. package/dist/{client-txrE0D_D.d.ts → client-kJN_Znan.d.ts} +1 -1
  17. package/dist/index.d.mts +50 -26
  18. package/dist/index.d.ts +50 -26
  19. package/dist/index.js +299 -104
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +303 -104
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/meter/index.d.mts +2 -2
  24. package/dist/meter/index.d.ts +2 -2
  25. package/dist/meter/index.js +28 -7
  26. package/dist/meter/index.js.map +1 -1
  27. package/dist/meter/index.mjs +28 -7
  28. package/dist/meter/index.mjs.map +1 -1
  29. package/dist/pricing/index.d.mts +8 -2
  30. package/dist/pricing/index.d.ts +8 -2
  31. package/dist/pricing/index.js +28 -7
  32. package/dist/pricing/index.js.map +1 -1
  33. package/dist/pricing/index.mjs +28 -7
  34. package/dist/pricing/index.mjs.map +1 -1
  35. package/dist/react/index.d.mts +95 -17
  36. package/dist/react/index.d.ts +95 -17
  37. package/dist/react/index.js +468 -7
  38. package/dist/react/index.js.map +1 -1
  39. package/dist/react/index.mjs +468 -10
  40. package/dist/react/index.mjs.map +1 -1
  41. package/dist/types-Zbzxg-Ka.d.mts +261 -0
  42. package/dist/types-Zbzxg-Ka.d.ts +261 -0
  43. package/package.json +6 -2
  44. package/dist/types-CSrSmsd1.d.mts +0 -159
  45. package/dist/types-CSrSmsd1.d.ts +0 -159
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/meter/client.ts","../../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/table.ts","../../src/pricing/calculator.ts","../../src/meter/stream.ts","../../src/meter/index.ts"],"sourcesContent":["import Stripe from 'stripe';\nimport type {\n MeterOptions,\n StreamWrapOptions,\n RecordUsageOptions,\n UsageEvent,\n UsageSummary,\n CustomerParam,\n} from '../types';\nimport { MeterBatcher } from './batcher';\nimport { detectAndExtractUsage } from './extractors';\nimport { calculateUsageCost } from '../pricing/calculator';\nimport { wrapUniversalStream } from './stream';\n\nexport class VibezMeter {\n private batcher: MeterBatcher;\n private stripeClient?: Stripe;\n private markupMultiplier?: number;\n\n constructor(options: MeterOptions = {}) {\n this.markupMultiplier = options.markupMultiplier;\n\n // Initialize Stripe client if apiKey or stripe instance is provided\n if (options.stripe) {\n this.stripeClient = options.stripe;\n } else if (options.apiKey || process.env.STRIPE_SECRET_KEY) {\n const key = options.apiKey || process.env.STRIPE_SECRET_KEY!;\n this.stripeClient = new Stripe(key, {\n appInfo: {\n name: 'vibezcheck',\n version: '0.1.0',\n url: 'https://vibezcheck.xyz',\n },\n });\n }\n\n this.batcher = new MeterBatcher({\n ...options,\n stripe: this.stripeClient,\n });\n }\n\n /**\n * Track token usage from a non-streaming response object (OpenAI, Anthropic, Gemini, etc.)\n */\n public trackUsage(\n response: any,\n options: {\n customer?: CustomerParam;\n customerId?: string;\n model?: string;\n provider?: string;\n metadata?: Record<string, string | number | boolean>;\n } = {}\n ): UsageEvent | null {\n const extracted = detectAndExtractUsage(response, options.model, options.provider);\n if (!extracted) {\n return null;\n }\n\n const model = options.model || extracted.model;\n const cost = calculateUsageCost(model, extracted.usage, this.markupMultiplier);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const event: UsageEvent = {\n timestamp: new Date().toISOString(),\n model,\n provider: extracted.provider,\n usage: extracted.usage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n this.batcher.enqueue(event);\n return event;\n }\n\n /**\n * Wrap any LLM stream (OpenAI, Anthropic, Gemini) with zero added latency\n */\n public wrapStream<T>(stream: T, options: StreamWrapOptions = {}): T {\n return wrapUniversalStream(stream, options, (event) => {\n this.batcher.enqueue(event);\n });\n }\n\n /**\n * Directly record token usage manually\n */\n public recordUsage(options: RecordUsageOptions): UsageEvent {\n const inputTokens = options.inputTokens ?? 0;\n const outputTokens = options.outputTokens ?? 0;\n const reasoningTokens = options.reasoningTokens;\n const cachedTokens = options.cachedTokens;\n\n const usage = {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens,\n visibleOutputTokens:\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\n cachedTokens,\n };\n\n const cost = calculateUsageCost(options.model, usage, this.markupMultiplier);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const event: UsageEvent = {\n timestamp: new Date().toISOString(),\n model: options.model,\n provider: options.provider || 'custom',\n usage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n this.batcher.enqueue(event);\n return event;\n }\n\n /**\n * Flush pending events to Stripe (vital for Serverless & Edge environments)\n */\n public async flush(): Promise<void> {\n await this.batcher.flush();\n }\n\n /**\n * Get in-memory aggregated usage statistics\n */\n public getUsageSummary(): UsageSummary {\n return this.batcher.getSummary();\n }\n\n /**\n * Reset in-memory ledger\n */\n public resetSummary(): void {\n this.batcher.resetLedger();\n }\n}\n\n/**\n * Factory function to create a VibezMeter instance\n */\nexport function createMeter(options: MeterOptions = {}): VibezMeter {\n return new VibezMeter(options);\n}\n","import type Stripe from 'stripe';\nimport type { UsageEvent, UsageSummary, MeterOptions } from '../types';\n\nexport class MeterBatcher {\n private queue: UsageEvent[] = [];\n private timer: NodeJS.Timeout | null = null;\n private isFlushing: boolean = false;\n private readonly maxBatchSize: number;\n private readonly flushIntervalMs: number;\n private readonly stripeClient?: Stripe;\n private readonly eventName: string;\n private readonly onUsageCallback?: (event: UsageEvent) => void | Promise<void>;\n private readonly onErrorCallback?: (error: Error, events: UsageEvent[]) => void;\n private readonly debug: boolean;\n\n // In-memory ledger for local stats\n private totalRequests = 0;\n private totalTokens = 0;\n private totalInputTokens = 0;\n private totalOutputTokens = 0;\n private totalReasoningTokens = 0;\n private totalCostUSD = 0;\n private byModel: Record<string, { requests: number; tokens: number; costUSD: number }> = {};\n\n constructor(options: MeterOptions = {}) {\n this.stripeClient = options.stripe;\n this.eventName = options.eventName || 'token-billing-tokens';\n this.maxBatchSize = options.batching?.maxBatchSize ?? 50;\n this.flushIntervalMs = options.batching?.flushIntervalMs ?? 50;\n this.onUsageCallback = options.onUsage;\n this.onErrorCallback = options.onError;\n this.debug = options.debug ?? false;\n }\n\n /**\n * Enqueue a usage event for batch dispatching\n */\n public enqueue(event: UsageEvent): void {\n // 1. Update in-memory local ledger\n this.recordInLedger(event);\n\n // 2. Fire onUsage hook immediately\n if (this.onUsageCallback) {\n try {\n const res = this.onUsageCallback(event);\n if (res instanceof Promise) {\n res.catch((err) => {\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\n });\n }\n } catch (err) {\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\n }\n }\n\n // 3. If no Stripe client is configured, we're done (local mode)\n if (!this.stripeClient) {\n if (this.debug) {\n console.log(\n `[vibezcheck:local] 📊 ${event.model} | Tokens: ${event.usage.totalTokens} | Cost: $${event.cost.totalUSD.toFixed(6)}`\n );\n }\n return;\n }\n\n // 4. Queue for Stripe dispatch\n this.queue.push(event);\n\n if (this.queue.length >= this.maxBatchSize) {\n this.flush().catch((err) => {\n if (this.debug) console.error('[vibezcheck] Batch flush error:', err);\n });\n } else if (!this.timer) {\n this.timer = setTimeout(() => {\n this.timer = null;\n this.flush().catch((err) => {\n if (this.debug) console.error('[vibezcheck] Debounce flush error:', err);\n });\n }, this.flushIntervalMs);\n }\n }\n\n /**\n * Immediately flush all queued events to Stripe\n */\n public async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n if (this.queue.length === 0 || !this.stripeClient || this.isFlushing) {\n return;\n }\n\n this.isFlushing = true;\n const eventsToSend = [...this.queue];\n this.queue = [];\n\n try {\n await this.sendEventsToStripe(eventsToSend);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n if (this.debug) {\n console.error('[vibezcheck] Failed to send meter events to Stripe:', err);\n }\n if (this.onErrorCallback) {\n this.onErrorCallback(err, eventsToSend);\n }\n } finally {\n this.isFlushing = false;\n // If new items were queued while flushing, trigger another flush\n if (this.queue.length > 0) {\n this.flush().catch(() => {});\n }\n }\n }\n\n /**\n * Sends events to Stripe Billing Meter Events API\n */\n private async sendEventsToStripe(events: UsageEvent[]): Promise<void> {\n if (!this.stripeClient) return;\n\n for (const event of events) {\n const customerId = event.customerId;\n if (!customerId) {\n // Skip events without customer attribution for Stripe billing\n continue;\n }\n\n const timestamp = event.timestamp || new Date().toISOString();\n const model = `${event.provider}/${event.model}`;\n\n // 1. Send Input Tokens Meter Event\n if (event.usage.inputTokens > 0) {\n try {\n await this.stripeClient.v2.billing.meterEvents.create({\n event_name: this.eventName,\n timestamp,\n payload: {\n stripe_customer_id: customerId,\n value: event.usage.inputTokens.toString(),\n model,\n token_type: 'input',\n cached_tokens: (event.usage.cachedTokens ?? 0).toString(),\n ...(event.metadata ? (event.metadata as any) : {}),\n },\n });\n } catch (e) {\n if (this.debug) console.warn('[vibezcheck] Input meter event error:', e);\n }\n }\n\n // 2. Send Output Tokens Meter Event\n if (event.usage.outputTokens > 0) {\n try {\n await this.stripeClient.v2.billing.meterEvents.create({\n event_name: this.eventName,\n timestamp,\n payload: {\n stripe_customer_id: customerId,\n value: event.usage.outputTokens.toString(),\n model,\n token_type: 'output',\n reasoning_tokens: (event.usage.reasoningTokens ?? 0).toString(),\n visible_tokens: (event.usage.visibleOutputTokens ?? event.usage.outputTokens).toString(),\n ...(event.metadata ? (event.metadata as any) : {}),\n },\n });\n } catch (e) {\n if (this.debug) console.warn('[vibezcheck] Output meter event error:', e);\n }\n }\n }\n }\n\n /**\n * Updates internal in-memory ledger\n */\n private recordInLedger(event: UsageEvent): void {\n this.totalRequests += 1;\n this.totalTokens += event.usage.totalTokens;\n this.totalInputTokens += event.usage.inputTokens;\n this.totalOutputTokens += event.usage.outputTokens;\n this.totalReasoningTokens += event.usage.reasoningTokens ?? 0;\n this.totalCostUSD += event.cost.totalUSD;\n\n const modelKey = event.model;\n if (!this.byModel[modelKey]) {\n this.byModel[modelKey] = { requests: 0, tokens: 0, costUSD: 0 };\n }\n this.byModel[modelKey].requests += 1;\n this.byModel[modelKey].tokens += event.usage.totalTokens;\n this.byModel[modelKey].costUSD += event.cost.totalUSD;\n }\n\n /**\n * Get in-memory usage summary\n */\n public getSummary(): UsageSummary {\n return {\n totalRequests: this.totalRequests,\n totalTokens: this.totalTokens,\n totalInputTokens: this.totalInputTokens,\n totalOutputTokens: this.totalOutputTokens,\n totalReasoningTokens: this.totalReasoningTokens,\n totalCostUSD: Number(this.totalCostUSD.toFixed(6)),\n byModel: { ...this.byModel },\n };\n }\n\n /**\n * Reset in-memory ledger\n */\n public resetLedger(): void {\n this.totalRequests = 0;\n this.totalTokens = 0;\n this.totalInputTokens = 0;\n this.totalOutputTokens = 0;\n this.totalReasoningTokens = 0;\n this.totalCostUSD = 0;\n this.byModel = {};\n }\n}\n","import type { TokenUsage } from '../../types';\n\nexport interface ExtractedUsage {\n model: string;\n provider: string;\n usage: TokenUsage;\n}\n\n/**\n * Extracts token usage from OpenAI synchronous responses (ChatCompletion, Responses, Embeddings)\n */\nexport function extractOpenAIResponseUsage(response: any): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // 1. Standard OpenAI ChatCompletion\n if ('choices' in response && 'usage' in response && response.usage) {\n const rawUsage = response.usage;\n const model = response.model || 'gpt-4o';\n\n const inputTokens = rawUsage.prompt_tokens ?? 0;\n const outputTokens = rawUsage.completion_tokens ?? 0;\n const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens ?? 0;\n const cachedTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? 0;\n\n return {\n model,\n provider: 'openai',\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n // 2. OpenAI Embeddings Response\n if ('data' in response && 'usage' in response && response.usage && 'model' in response) {\n const rawUsage = response.usage;\n const inputTokens = rawUsage.prompt_tokens ?? 0;\n\n return {\n model: response.model || 'text-embedding-3-small',\n provider: 'openai',\n usage: {\n inputTokens,\n outputTokens: 0,\n totalTokens: inputTokens,\n },\n };\n }\n\n // 3. OpenAI Responses API (New standard)\n if ('status' in response && 'usage' in response && response.usage) {\n const rawUsage = response.usage;\n const model = response.model || 'gpt-5.6-sol';\n\n const inputTokens = rawUsage.input_tokens ?? rawUsage.prompt_tokens ?? 0;\n const outputTokens = rawUsage.output_tokens ?? rawUsage.completion_tokens ?? 0;\n const reasoningTokens =\n rawUsage.output_token_details?.reasoning_tokens ??\n rawUsage.completion_tokens_details?.reasoning_tokens ??\n 0;\n const cachedTokens =\n rawUsage.input_token_details?.cached_tokens ??\n rawUsage.prompt_tokens_details?.cached_tokens ??\n 0;\n\n return {\n model,\n provider: 'openai',\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n return null;\n}\n\n/**\n * Extracts token usage from an individual OpenAI stream chunk or stream accumulator\n */\nexport function inspectOpenAIStreamChunk(chunk: any): {\n model?: string;\n usage?: TokenUsage;\n} {\n if (!chunk || typeof chunk !== 'object') return {};\n\n const model = chunk.model;\n\n // Final chunk with usage object (when stream_options: { include_usage: true })\n if (chunk.usage) {\n const rawUsage = chunk.usage;\n const inputTokens = rawUsage.prompt_tokens ?? rawUsage.input_tokens ?? 0;\n const outputTokens = rawUsage.completion_tokens ?? rawUsage.output_tokens ?? 0;\n const reasoningTokens =\n rawUsage.completion_tokens_details?.reasoning_tokens ??\n rawUsage.output_token_details?.reasoning_tokens ??\n 0;\n const cachedTokens =\n rawUsage.prompt_tokens_details?.cached_tokens ??\n rawUsage.input_token_details?.cached_tokens ??\n 0;\n\n return {\n model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n // Response API stream event (response.completed or response.done)\n if (chunk.type === 'response.completed' || chunk.type === 'response.done') {\n if (chunk.response?.usage) {\n const rawUsage = chunk.response.usage;\n const inputTokens = rawUsage.input_tokens ?? 0;\n const outputTokens = rawUsage.output_tokens ?? 0;\n const reasoningTokens = rawUsage.output_token_details?.reasoning_tokens ?? 0;\n const cachedTokens = rawUsage.input_token_details?.cached_tokens ?? 0;\n\n return {\n model: chunk.response.model || model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n }\n\n return { model };\n}\n","import type { TokenUsage } from '../../types';\nimport type { ExtractedUsage } from './openai';\n\n/**\n * Extracts token usage from Anthropic synchronous responses\n */\nexport function extractAnthropicResponseUsage(response: any): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // Anthropic Message response has type: 'message' or role: 'assistant' with usage\n if (response.type === 'message' || ('content' in response && 'usage' in response)) {\n const rawUsage = response.usage || {};\n const model = response.model || 'claude-3-7-sonnet';\n\n const inputTokens = rawUsage.input_tokens ?? 0;\n const outputTokens = rawUsage.output_tokens ?? 0;\n const cachedTokens = rawUsage.cache_read_input_tokens ?? 0;\n const cacheWriteTokens = rawUsage.cache_creation_input_tokens ?? 0;\n\n // Check content blocks for thinking/reasoning tokens count or thinking blocks\n let reasoningTokens: number | undefined = undefined;\n if (Array.isArray(response.content)) {\n const thinkingBlocks = response.content.filter((b: any) => b.type === 'thinking');\n if (thinkingBlocks.length > 0) {\n // Approximate or extract explicit thinking tokens if present in metadata\n reasoningTokens = (rawUsage as any).thinking_tokens ?? undefined;\n }\n }\n\n return {\n model,\n provider: 'anthropic',\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens,\n visibleOutputTokens:\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n cacheWriteTokens: cacheWriteTokens > 0 ? cacheWriteTokens : undefined,\n },\n };\n }\n\n return null;\n}\n\n/**\n * Accumulates stream events across an Anthropic raw message stream\n */\nexport class AnthropicStreamAccumulator {\n private model: string = 'claude-3-7-sonnet';\n private inputTokens: number = 0;\n private outputTokens: number = 0;\n private cachedTokens: number = 0;\n private cacheWriteTokens: number = 0;\n private reasoningTokens: number = 0;\n\n processEvent(event: any): void {\n if (!event || typeof event !== 'object') return;\n\n // 1. message_start (contains model and initial input usage)\n if (event.type === 'message_start' && event.message) {\n if (event.message.model) {\n this.model = event.message.model;\n }\n if (event.message.usage) {\n this.inputTokens = event.message.usage.input_tokens ?? 0;\n this.cachedTokens = event.message.usage.cache_read_input_tokens ?? 0;\n this.cacheWriteTokens = event.message.usage.cache_creation_input_tokens ?? 0;\n }\n }\n\n // 2. message_delta (contains final output usage)\n if (event.type === 'message_delta' && event.usage) {\n this.outputTokens = event.usage.output_tokens ?? 0;\n if (event.usage.thinking_tokens) {\n this.reasoningTokens = event.usage.thinking_tokens;\n }\n }\n\n // 3. content_block_start / content_block_delta for thinking blocks\n if (event.type === 'content_block_start' && event.content_block?.type === 'thinking') {\n // thinking block detected\n }\n }\n\n getUsage(): ExtractedUsage {\n return {\n model: this.model,\n provider: 'anthropic',\n usage: {\n inputTokens: this.inputTokens,\n outputTokens: this.outputTokens,\n totalTokens: this.inputTokens + this.outputTokens,\n reasoningTokens: this.reasoningTokens > 0 ? this.reasoningTokens : undefined,\n visibleOutputTokens:\n this.reasoningTokens > 0\n ? Math.max(0, this.outputTokens - this.reasoningTokens)\n : this.outputTokens,\n cachedTokens: this.cachedTokens > 0 ? this.cachedTokens : undefined,\n cacheWriteTokens: this.cacheWriteTokens > 0 ? this.cacheWriteTokens : undefined,\n },\n };\n }\n}\n","import type { TokenUsage } from '../../types';\nimport type { ExtractedUsage } from './openai';\n\n/**\n * Extracts token usage from Google Gemini API response or chunk\n */\nexport function extractGeminiResponseUsage(\n response: any,\n fallbackModel: string = 'gemini-3.7-flash'\n): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // Gemini returns usageMetadata on response or GenerateContentResult\n const usageMetadata = response.usageMetadata || response.response?.usageMetadata;\n\n if (usageMetadata) {\n const inputTokens = usageMetadata.promptTokenCount ?? 0;\n const baseOutputTokens = usageMetadata.candidatesTokenCount ?? 0;\n const thoughtsTokenCount =\n usageMetadata.thoughtsTokenCount ?? (usageMetadata as any).reasoningTokenCount ?? 0;\n const cachedTokens = usageMetadata.cachedContentTokenCount ?? 0;\n\n const totalOutput = baseOutputTokens + thoughtsTokenCount;\n const model = response.model || response.response?.model || fallbackModel;\n\n return {\n model,\n provider: 'google',\n usage: {\n inputTokens,\n outputTokens: totalOutput,\n totalTokens: inputTokens + totalOutput,\n reasoningTokens: thoughtsTokenCount > 0 ? thoughtsTokenCount : undefined,\n visibleOutputTokens: baseOutputTokens,\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n return null;\n}\n","import type { TokenUsage } from '../../types';\nimport type { ExtractedUsage } from './openai';\n\n/**\n * Extracts token usage from generic LLM provider objects (DeepSeek, Groq, Mistral, Ollama, Cohere, Together)\n */\nexport function extractGenericResponseUsage(\n response: any,\n fallbackModel: string = 'generic-llm',\n fallbackProvider: string = 'generic'\n): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // Check common usage property locations\n const usage = response.usage || response.token_usage || response.usageMetadata;\n\n if (usage) {\n const inputTokens =\n usage.prompt_tokens ??\n usage.input_tokens ??\n usage.promptTokenCount ??\n usage.prompt_eval_count ??\n 0;\n const outputTokens =\n usage.completion_tokens ??\n usage.output_tokens ??\n usage.candidatesTokenCount ??\n usage.eval_count ??\n 0;\n const reasoningTokens =\n usage.reasoning_tokens ??\n usage.thoughtsTokenCount ??\n usage.completion_tokens_details?.reasoning_tokens ??\n 0;\n const cachedTokens =\n usage.prompt_tokens_details?.cached_tokens ??\n usage.cached_tokens ??\n usage.cachedContentTokenCount ??\n 0;\n\n const model = response.model || fallbackModel;\n const provider = response.provider || fallbackProvider;\n\n return {\n model,\n provider,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n return null;\n}\n","import type { ExtractedUsage } from './openai';\nimport { extractOpenAIResponseUsage } from './openai';\nimport { extractAnthropicResponseUsage } from './anthropic';\nimport { extractGeminiResponseUsage } from './gemini';\nimport { extractGenericResponseUsage } from './generic';\n\nexport * from './openai';\nexport * from './anthropic';\nexport * from './gemini';\nexport * from './generic';\n\n/**\n * Universal polymorphic response detector\n */\nexport function detectAndExtractUsage(\n response: any,\n fallbackModel?: string,\n fallbackProvider?: string\n): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // 1. Try OpenAI\n const openaiResult = extractOpenAIResponseUsage(response);\n if (openaiResult) return openaiResult;\n\n // 2. Try Anthropic\n const anthropicResult = extractAnthropicResponseUsage(response);\n if (anthropicResult) return anthropicResult;\n\n // 3. Try Gemini\n const geminiResult = extractGeminiResponseUsage(response, fallbackModel);\n if (geminiResult) return geminiResult;\n\n // 4. Try Generic\n const genericResult = extractGenericResponseUsage(response, fallbackModel, fallbackProvider);\n if (genericResult) return genericResult;\n\n return null;\n}\n","import type { ModelPricingRates } from '../types';\n\n/**\n * Built-in Registry of Model Pricing (USD per 1 Million Tokens)\n * Sourced from official 2026 provider pricing tables.\n */\nexport const MODEL_PRICING_TABLE: Record<string, ModelPricingRates> = {\n // --- OpenAI ---\n 'gpt-5.6-sol': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\n 'gpt-5.6-terra': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.2 },\n 'gpt-5.6-luna': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\n 'gpt-5': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\n 'gpt-5-mini': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\n 'o1': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\n 'o1-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\n 'o3': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\n 'o3-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10.0, cachedInputPer1M: 1.25 },\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.075 },\n 'gpt-4.1': { inputPer1M: 2.0, outputPer1M: 8.0, cachedInputPer1M: 1.0 },\n 'gpt-4.1-nano': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.05 },\n 'text-embedding-3-small': { inputPer1M: 0.02, outputPer1M: 0.0 },\n 'text-embedding-3-large': { inputPer1M: 0.13, outputPer1M: 0.0 },\n\n // --- Anthropic ---\n 'claude-3-7-sonnet': { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },\n 'claude-sonnet-5': { inputPer1M: 2.0, outputPer1M: 10.0, cachedInputPer1M: 0.3 },\n 'claude-3-5-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\n 'claude-3-5-haiku': { inputPer1M: 0.8, outputPer1M: 4.0, cachedInputPer1M: 0.08 },\n 'haiku-4.5': { inputPer1M: 1.0, outputPer1M: 5.0, cachedInputPer1M: 0.1 },\n 'claude-opus-5': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 1.5 },\n 'claude-3-opus': { inputPer1M: 15.0, outputPer1M: 75.0, cachedInputPer1M: 1.5 },\n\n // --- Google Gemini ---\n 'gemini-3.7-flash': { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },\n 'gemini-3.1-pro': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.5 },\n 'gemini-3.5-flash': { inputPer1M: 1.5, outputPer1M: 9.0, cachedInputPer1M: 0.38 },\n 'gemini-3.1-flash-lite': { inputPer1M: 0.25, outputPer1M: 1.5, cachedInputPer1M: 0.06 },\n 'gemini-2.0-flash': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.025 },\n 'gemini-1.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\n 'gemini-1.5-flash': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\n\n // --- xAI Grok ---\n 'grok-4.6': { inputPer1M: 3.0, outputPer1M: 15.0 },\n 'grok-2': { inputPer1M: 2.0, outputPer1M: 10.0 },\n 'grok-2-vision': { inputPer1M: 2.0, outputPer1M: 10.0 },\n 'grok-beta': { inputPer1M: 5.0, outputPer1M: 15.0 },\n\n // --- Mistral ---\n 'mistral-large-3': { inputPer1M: 2.0, outputPer1M: 6.0 },\n 'mistral-large-latest': { inputPer1M: 2.0, outputPer1M: 6.0 },\n 'codestral-latest': { inputPer1M: 0.3, outputPer1M: 0.9 },\n 'mistral-small-latest': { inputPer1M: 0.2, outputPer1M: 0.6 },\n 'ministral-8b-latest': { inputPer1M: 0.1, outputPer1M: 0.1 },\n\n // --- Groq LPUs ---\n 'llama-3.3-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\n 'llama-3.1-8b-instant': { inputPer1M: 0.05, outputPer1M: 0.08 },\n 'deepseek-r1-distill-llama-70b': { inputPer1M: 0.75, outputPer1M: 0.99 },\n 'qwen-2.5-32b': { inputPer1M: 0.29, outputPer1M: 0.39 },\n\n // --- DeepSeek ---\n 'deepseek-v4-pro': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\n 'deepseek-v4-flash': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\n 'deepseek-chat': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\n 'deepseek-reasoner': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\n\n // --- Cohere ---\n 'command-r-plus': { inputPer1M: 2.5, outputPer1M: 10.0 },\n 'command-r': { inputPer1M: 0.15, outputPer1M: 0.6 },\n};\n\n/**\n * Dynamic in-memory registry allowing runtime custom price registration\n */\nconst customPricingRegistry: Record<string, ModelPricingRates> = {};\n\n/**\n * Normalize model identifier to match pricing table keys\n */\nexport function normalizeModelKey(rawModel: string): string {\n if (!rawModel) return 'unknown';\n\n let model = rawModel.toLowerCase().trim();\n\n // Strip provider prefix if present (e.g. 'openai/gpt-4o' -> 'gpt-4o')\n if (model.includes('/')) {\n model = model.split('/')[1] || model;\n }\n\n // Remove date suffixes like -20240307 or -20250219\n model = model.replace(/-\\d{8}$/, '');\n model = model.replace(/-\\d{4}-\\d{2}-\\d{2}$/, '');\n\n return model;\n}\n\n/**\n * Retrieve pricing rates for a given model\n */\nexport function getModelPricing(modelName: string): ModelPricingRates {\n const normalized = normalizeModelKey(modelName);\n\n // Check custom registry first\n if (customPricingRegistry[normalized]) {\n return customPricingRegistry[normalized];\n }\n if (customPricingRegistry[modelName]) {\n return customPricingRegistry[modelName];\n }\n\n // Check built-in table\n if (MODEL_PRICING_TABLE[normalized]) {\n return MODEL_PRICING_TABLE[normalized];\n }\n if (MODEL_PRICING_TABLE[modelName]) {\n return MODEL_PRICING_TABLE[modelName];\n }\n\n // Fallback defaults for unknown models (conservative estimates: $1.00 in, $3.00 out)\n return {\n inputPer1M: 1.0,\n outputPer1M: 3.0,\n cachedInputPer1M: 0.5,\n };\n}\n\n/**\n * Register or override pricing rates for a custom model\n */\nexport function registerModelPricing(modelName: string, rates: ModelPricingRates): void {\n const normalized = normalizeModelKey(modelName);\n customPricingRegistry[normalized] = rates;\n customPricingRegistry[modelName] = rates;\n}\n","import type { InferenceCost, TokenUsage } from '../types';\nimport { getModelPricing } from './table';\n\nexport interface CalculateCostParams {\n model: string;\n inputTokens?: number;\n outputTokens?: number;\n reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n markupMultiplier?: number;\n}\n\n/**\n * Calculates exact inference cost for an LLM call or usage breakdown in USD.\n */\nexport function calculateCost(params: CalculateCostParams): InferenceCost {\n const rates = getModelPricing(params.model);\n\n const inputTokens = params.inputTokens ?? 0;\n const outputTokens = params.outputTokens ?? 0;\n const reasoningTokens = params.reasoningTokens ?? 0;\n const cachedTokens = params.cachedTokens ?? 0;\n\n // Regular input tokens (minus any cached tokens)\n const regularInputTokens = Math.max(0, inputTokens - cachedTokens);\n\n // Input costs\n const regularInputCost = (regularInputTokens / 1_000_000) * rates.inputPer1M;\n const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.5;\n const cachedInputCost = (cachedTokens / 1_000_000) * cachedRate;\n const inputCostUSD = regularInputCost + cachedInputCost;\n\n // Output costs (reasoning tokens are billed as output tokens in standard APIs)\n const outputCostUSD = (outputTokens / 1_000_000) * rates.outputPer1M;\n\n // Reasoning breakdown cost\n const reasoningRate = rates.reasoningPer1M ?? rates.outputPer1M;\n const reasoningCostUSD = (reasoningTokens / 1_000_000) * reasoningRate;\n\n // Cache savings discount\n const standardCacheCost = (cachedTokens / 1_000_000) * rates.inputPer1M;\n const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);\n\n // Total base cost\n const totalUSD = inputCostUSD + outputCostUSD;\n\n // Retail price calculation (if markup multiplier provided)\n const markup = params.markupMultiplier ?? 1.0;\n const retailUSD = markup !== 1.0 ? totalUSD * markup : undefined;\n\n return {\n inputCostUSD: Number(inputCostUSD.toFixed(8)),\n outputCostUSD: Number(outputCostUSD.toFixed(8)),\n reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : undefined,\n cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n totalUSD: Number(totalUSD.toFixed(8)),\n retailUSD: retailUSD ? 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 markupMultiplier?: number\n): InferenceCost {\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,\n });\n}\n","import type { UsageEvent, StreamWrapOptions } from '../types';\nimport { inspectOpenAIStreamChunk } from './extractors/openai';\nimport { AnthropicStreamAccumulator } from './extractors/anthropic';\nimport { extractGeminiResponseUsage } from './extractors/gemini';\nimport { calculateUsageCost } from '../pricing/calculator';\n\nexport type UsageDispatchedCallback = (event: UsageEvent) => void;\n\n/**\n * Wraps an OpenAI async iterable stream to capture usage at stream conclusion\n */\nexport function wrapOpenAIStream<T extends AsyncIterable<any>>(\n stream: T,\n options: StreamWrapOptions,\n onComplete: UsageDispatchedCallback\n): T {\n let detectedModel = options.model || 'gpt-4o';\n let finalUsage: any = null;\n\n const wrappedAsyncIterable = {\n async *[Symbol.asyncIterator]() {\n try {\n for await (const chunk of stream) {\n const inspected = inspectOpenAIStreamChunk(chunk);\n if (inspected.model) {\n detectedModel = inspected.model;\n }\n if (inspected.usage) {\n finalUsage = inspected.usage;\n }\n yield chunk;\n }\n } finally {\n if (finalUsage) {\n const cost = calculateUsageCost(detectedModel, finalUsage);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const event: UsageEvent = {\n timestamp: new Date().toISOString(),\n model: detectedModel,\n provider: 'openai',\n usage: finalUsage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n onComplete(event);\n if (options.onUsage) {\n options.onUsage(event);\n }\n }\n }\n },\n };\n\n return wrappedAsyncIterable as unknown as T;\n}\n\n/**\n * Wraps an Anthropic message stream to accumulate message_start and message_delta usage\n */\nexport function wrapAnthropicStream<T extends AsyncIterable<any>>(\n stream: T,\n options: StreamWrapOptions,\n onComplete: UsageDispatchedCallback\n): T {\n const accumulator = new AnthropicStreamAccumulator();\n\n const wrappedAsyncIterable = {\n async *[Symbol.asyncIterator]() {\n try {\n for await (const event of stream) {\n accumulator.processEvent(event);\n yield event;\n }\n } finally {\n const extracted = accumulator.getUsage();\n const model = options.model || extracted.model;\n const cost = calculateUsageCost(model, extracted.usage);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const usageEvent: UsageEvent = {\n timestamp: new Date().toISOString(),\n model,\n provider: 'anthropic',\n usage: extracted.usage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n onComplete(usageEvent);\n if (options.onUsage) {\n options.onUsage(usageEvent);\n }\n }\n },\n };\n\n return wrappedAsyncIterable as unknown as T;\n}\n\n/**\n * Wraps a Google Gemini GenerateContentStreamResult\n */\nexport function wrapGeminiStream(\n result: any,\n options: StreamWrapOptions,\n onComplete: UsageDispatchedCallback\n): any {\n if (!result || !result.stream) return result;\n\n const originalStream = result.stream;\n const model = options.model || 'gemini-3.7-flash';\n let lastChunkWithUsage: any = null;\n\n const wrappedStream = (async function* () {\n try {\n for await (const chunk of originalStream) {\n if (chunk.usageMetadata) {\n lastChunkWithUsage = chunk;\n }\n yield chunk;\n }\n } finally {\n if (lastChunkWithUsage) {\n const extracted = extractGeminiResponseUsage(lastChunkWithUsage, model);\n if (extracted) {\n const cost = calculateUsageCost(extracted.model, extracted.usage);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const event: UsageEvent = {\n timestamp: new Date().toISOString(),\n model: extracted.model,\n provider: 'google',\n usage: extracted.usage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n onComplete(event);\n if (options.onUsage) {\n options.onUsage(event);\n }\n }\n }\n }\n })();\n\n return {\n ...result,\n stream: wrappedStream,\n };\n}\n\n/**\n * Universal Stream Wrapper\n */\nexport function wrapUniversalStream<T>(\n stream: T,\n options: StreamWrapOptions = {},\n onComplete: UsageDispatchedCallback\n): T {\n if (!stream || typeof stream !== 'object') return stream;\n\n // 1. Check Gemini stream\n if ('stream' in stream && 'response' in stream) {\n return wrapGeminiStream(stream, options, onComplete);\n }\n\n // 2. Check if stream is an AsyncIterable\n if (Symbol.asyncIterator in stream) {\n // If provider is explicitly anthropic or stream looks like anthropic events\n if (options.provider === 'anthropic') {\n return wrapAnthropicStream(stream as any, options, onComplete);\n }\n // Default to OpenAI stream wrapper which detects usage chunks polymorphically\n return wrapOpenAIStream(stream as any, options, onComplete);\n }\n\n return stream;\n}\n","export * from './client';\nexport * from './batcher';\nexport * from './stream';\nexport * from './extractors';\n\nimport { createMeter } from './client';\nimport type { StreamWrapOptions, CustomerParam } from '../types';\n\n// Default singleton instance\nconst defaultMeter = createMeter();\n\n/**\n * Convenient standalone stream wrapper\n */\nexport function wrapStream<T>(stream: T, options?: StreamWrapOptions): T {\n return defaultMeter.wrapStream(stream, options);\n}\n\n/**\n * Convenient standalone usage tracker\n */\nexport function trackTokens(\n response: any,\n options?: { customer?: CustomerParam; customerId?: string; model?: string }\n) {\n return defaultMeter.trackUsage(response, options);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/meter/client.ts","../../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/table.ts","../../src/pricing/calculator.ts","../../src/meter/stream.ts","../../src/meter/index.ts"],"sourcesContent":["import Stripe from 'stripe';\nimport type {\n MeterOptions,\n StreamWrapOptions,\n RecordUsageOptions,\n UsageEvent,\n UsageSummary,\n CustomerParam,\n} from '../types';\nimport { MeterBatcher } from './batcher';\nimport { detectAndExtractUsage } from './extractors';\nimport { calculateUsageCost } from '../pricing/calculator';\nimport { wrapUniversalStream } from './stream';\n\nexport class VibezMeter {\n private batcher: MeterBatcher;\n private stripeClient?: Stripe;\n private markupMultiplier?: number;\n\n constructor(options: MeterOptions = {}) {\n this.markupMultiplier = options.markupMultiplier;\n\n // Initialize Stripe client if apiKey or stripe instance is provided\n if (options.stripe) {\n this.stripeClient = options.stripe;\n } else if (options.apiKey || process.env.STRIPE_SECRET_KEY) {\n const key = options.apiKey || process.env.STRIPE_SECRET_KEY!;\n this.stripeClient = new Stripe(key, {\n appInfo: {\n name: 'vibezcheck',\n version: '0.1.0',\n url: 'https://vibezcheck.xyz',\n },\n });\n }\n\n this.batcher = new MeterBatcher({\n ...options,\n stripe: this.stripeClient,\n });\n }\n\n /**\n * Track token usage from a non-streaming response object (OpenAI, Anthropic, Gemini, etc.)\n */\n public trackUsage(\n response: any,\n options: {\n customer?: CustomerParam;\n customerId?: string;\n model?: string;\n provider?: string;\n metadata?: Record<string, string | number | boolean>;\n } = {}\n ): UsageEvent | null {\n const extracted = detectAndExtractUsage(response, options.model, options.provider);\n if (!extracted) {\n return null;\n }\n\n const model = options.model || extracted.model;\n const cost = calculateUsageCost(model, extracted.usage, this.markupMultiplier);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const event: UsageEvent = {\n timestamp: new Date().toISOString(),\n model,\n provider: extracted.provider,\n usage: extracted.usage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n this.batcher.enqueue(event);\n return event;\n }\n\n /**\n * Wrap any LLM stream (OpenAI, Anthropic, Gemini) with zero added latency\n */\n public wrapStream<T>(stream: T, options: StreamWrapOptions = {}): T {\n return wrapUniversalStream(stream, options, (event) => {\n this.batcher.enqueue(event);\n });\n }\n\n /**\n * Directly record token usage manually\n */\n public recordUsage(options: RecordUsageOptions): UsageEvent {\n const inputTokens = options.inputTokens ?? 0;\n const outputTokens = options.outputTokens ?? 0;\n const reasoningTokens = options.reasoningTokens;\n const cachedTokens = options.cachedTokens;\n\n const usage = {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens,\n visibleOutputTokens:\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\n cachedTokens,\n };\n\n const cost = calculateUsageCost(options.model, usage, this.markupMultiplier);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const event: UsageEvent = {\n timestamp: new Date().toISOString(),\n model: options.model,\n provider: options.provider || 'custom',\n usage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n this.batcher.enqueue(event);\n return event;\n }\n\n /**\n * Flush pending events to Stripe (vital for Serverless & Edge environments)\n */\n public async flush(): Promise<void> {\n await this.batcher.flush();\n }\n\n /**\n * Get in-memory aggregated usage statistics\n */\n public getUsageSummary(): UsageSummary {\n return this.batcher.getSummary();\n }\n\n /**\n * Reset in-memory ledger\n */\n public resetSummary(): void {\n this.batcher.resetLedger();\n }\n}\n\n/**\n * Factory function to create a VibezMeter instance\n */\nexport function createMeter(options: MeterOptions = {}): VibezMeter {\n return new VibezMeter(options);\n}\n","import type Stripe from 'stripe';\nimport type { UsageEvent, UsageSummary, MeterOptions } from '../types';\n\nexport class MeterBatcher {\n private queue: UsageEvent[] = [];\n private timer: NodeJS.Timeout | null = null;\n private isFlushing: boolean = false;\n private readonly maxBatchSize: number;\n private readonly flushIntervalMs: number;\n private readonly stripeClient?: Stripe;\n private readonly eventName: string;\n private readonly onUsageCallback?: (event: UsageEvent) => void | Promise<void>;\n private readonly onErrorCallback?: (error: Error, events: UsageEvent[]) => void;\n private readonly debug: boolean;\n\n // In-memory ledger for local stats\n private totalRequests = 0;\n private totalTokens = 0;\n private totalInputTokens = 0;\n private totalOutputTokens = 0;\n private totalReasoningTokens = 0;\n private totalCostUSD = 0;\n private byModel: Record<string, { requests: number; tokens: number; costUSD: number }> = {};\n\n constructor(options: MeterOptions = {}) {\n this.stripeClient = options.stripe;\n this.eventName = options.eventName || 'token-billing-tokens';\n this.maxBatchSize = options.batching?.maxBatchSize ?? 50;\n this.flushIntervalMs = options.batching?.flushIntervalMs ?? 50;\n this.onUsageCallback = options.onUsage;\n this.onErrorCallback = options.onError;\n this.debug = options.debug ?? false;\n }\n\n /**\n * Enqueue a usage event for batch dispatching\n */\n public enqueue(event: UsageEvent): void {\n // 1. Update in-memory local ledger\n this.recordInLedger(event);\n\n // 2. Fire onUsage hook immediately\n if (this.onUsageCallback) {\n try {\n const res = this.onUsageCallback(event);\n if (res instanceof Promise) {\n res.catch((err) => {\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\n });\n }\n } catch (err) {\n if (this.debug) console.error('[vibezcheck] Error in onUsage callback:', err);\n }\n }\n\n // 3. If no Stripe client is configured, we're done (local mode)\n if (!this.stripeClient) {\n if (this.debug) {\n console.log(\n `[vibezcheck:local] 📊 ${event.model} | Tokens: ${event.usage.totalTokens} | Cost: $${event.cost.totalUSD.toFixed(6)}`\n );\n }\n return;\n }\n\n // 4. Queue for Stripe dispatch\n this.queue.push(event);\n\n if (this.queue.length >= this.maxBatchSize) {\n this.flush().catch((err) => {\n if (this.debug) console.error('[vibezcheck] Batch flush error:', err);\n });\n } else if (!this.timer) {\n this.timer = setTimeout(() => {\n this.timer = null;\n this.flush().catch((err) => {\n if (this.debug) console.error('[vibezcheck] Debounce flush error:', err);\n });\n }, this.flushIntervalMs);\n }\n }\n\n /**\n * Immediately flush all queued events to Stripe\n */\n public async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n if (this.queue.length === 0 || !this.stripeClient || this.isFlushing) {\n return;\n }\n\n this.isFlushing = true;\n const eventsToSend = [...this.queue];\n this.queue = [];\n\n try {\n await this.sendEventsToStripe(eventsToSend);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n if (this.debug) {\n console.error('[vibezcheck] Failed to send meter events to Stripe:', err);\n }\n if (this.onErrorCallback) {\n this.onErrorCallback(err, eventsToSend);\n }\n } finally {\n this.isFlushing = false;\n // If new items were queued while flushing, trigger another flush\n if (this.queue.length > 0) {\n this.flush().catch(() => {});\n }\n }\n }\n\n /**\n * Sends events to Stripe Billing Meter Events API\n */\n private async sendEventsToStripe(events: UsageEvent[]): Promise<void> {\n if (!this.stripeClient) return;\n\n for (const event of events) {\n const customerId = event.customerId;\n if (!customerId) {\n // Skip events without customer attribution for Stripe billing\n continue;\n }\n\n const timestamp = event.timestamp || new Date().toISOString();\n const model = `${event.provider}/${event.model}`;\n\n // 1. Send Input Tokens Meter Event\n if (event.usage.inputTokens > 0) {\n try {\n await this.stripeClient.v2.billing.meterEvents.create({\n event_name: this.eventName,\n timestamp,\n payload: {\n stripe_customer_id: customerId,\n value: event.usage.inputTokens.toString(),\n model,\n token_type: 'input',\n cached_tokens: (event.usage.cachedTokens ?? 0).toString(),\n ...(event.metadata ? (event.metadata as any) : {}),\n },\n });\n } catch (e) {\n if (this.debug) console.warn('[vibezcheck] Input meter event error:', e);\n }\n }\n\n // 2. Send Output Tokens Meter Event\n if (event.usage.outputTokens > 0) {\n try {\n await this.stripeClient.v2.billing.meterEvents.create({\n event_name: this.eventName,\n timestamp,\n payload: {\n stripe_customer_id: customerId,\n value: event.usage.outputTokens.toString(),\n model,\n token_type: 'output',\n reasoning_tokens: (event.usage.reasoningTokens ?? 0).toString(),\n visible_tokens: (event.usage.visibleOutputTokens ?? event.usage.outputTokens).toString(),\n ...(event.metadata ? (event.metadata as any) : {}),\n },\n });\n } catch (e) {\n if (this.debug) console.warn('[vibezcheck] Output meter event error:', e);\n }\n }\n }\n }\n\n /**\n * Updates internal in-memory ledger\n */\n private recordInLedger(event: UsageEvent): void {\n this.totalRequests += 1;\n this.totalTokens += event.usage.totalTokens;\n this.totalInputTokens += event.usage.inputTokens;\n this.totalOutputTokens += event.usage.outputTokens;\n this.totalReasoningTokens += event.usage.reasoningTokens ?? 0;\n this.totalCostUSD += event.cost.totalUSD;\n\n const modelKey = event.model;\n if (!this.byModel[modelKey]) {\n this.byModel[modelKey] = { requests: 0, tokens: 0, costUSD: 0 };\n }\n this.byModel[modelKey].requests += 1;\n this.byModel[modelKey].tokens += event.usage.totalTokens;\n this.byModel[modelKey].costUSD += event.cost.totalUSD;\n }\n\n /**\n * Get in-memory usage summary\n */\n public getSummary(): UsageSummary {\n return {\n totalRequests: this.totalRequests,\n totalTokens: this.totalTokens,\n totalInputTokens: this.totalInputTokens,\n totalOutputTokens: this.totalOutputTokens,\n totalReasoningTokens: this.totalReasoningTokens,\n totalCostUSD: Number(this.totalCostUSD.toFixed(6)),\n byModel: { ...this.byModel },\n };\n }\n\n /**\n * Reset in-memory ledger\n */\n public resetLedger(): void {\n this.totalRequests = 0;\n this.totalTokens = 0;\n this.totalInputTokens = 0;\n this.totalOutputTokens = 0;\n this.totalReasoningTokens = 0;\n this.totalCostUSD = 0;\n this.byModel = {};\n }\n}\n","import type { TokenUsage } from '../../types';\n\nexport interface ExtractedUsage {\n model: string;\n provider: string;\n usage: TokenUsage;\n}\n\n/**\n * Extracts token usage from OpenAI synchronous responses (ChatCompletion, Responses, Embeddings)\n */\nexport function extractOpenAIResponseUsage(response: any): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // 1. Standard OpenAI ChatCompletion\n if ('choices' in response && 'usage' in response && response.usage) {\n const rawUsage = response.usage;\n const model = response.model || 'gpt-4o';\n\n const inputTokens = rawUsage.prompt_tokens ?? 0;\n const outputTokens = rawUsage.completion_tokens ?? 0;\n const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens ?? 0;\n const cachedTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? 0;\n\n return {\n model,\n provider: 'openai',\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n // 2. OpenAI Embeddings Response\n if ('data' in response && 'usage' in response && response.usage && 'model' in response) {\n const rawUsage = response.usage;\n const inputTokens = rawUsage.prompt_tokens ?? 0;\n\n return {\n model: response.model || 'text-embedding-3-small',\n provider: 'openai',\n usage: {\n inputTokens,\n outputTokens: 0,\n totalTokens: inputTokens,\n },\n };\n }\n\n // 3. OpenAI Responses API (New standard)\n if ('status' in response && 'usage' in response && response.usage) {\n const rawUsage = response.usage;\n const model = response.model || 'gpt-5.6-sol';\n\n const inputTokens = rawUsage.input_tokens ?? rawUsage.prompt_tokens ?? 0;\n const outputTokens = rawUsage.output_tokens ?? rawUsage.completion_tokens ?? 0;\n const reasoningTokens =\n rawUsage.output_token_details?.reasoning_tokens ??\n rawUsage.completion_tokens_details?.reasoning_tokens ??\n 0;\n const cachedTokens =\n rawUsage.input_token_details?.cached_tokens ??\n rawUsage.prompt_tokens_details?.cached_tokens ??\n 0;\n\n return {\n model,\n provider: 'openai',\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n return null;\n}\n\n/**\n * Extracts token usage from an individual OpenAI stream chunk or stream accumulator\n */\nexport function inspectOpenAIStreamChunk(chunk: any): {\n model?: string;\n usage?: TokenUsage;\n} {\n if (!chunk || typeof chunk !== 'object') return {};\n\n const model = chunk.model;\n\n // Final chunk with usage object (when stream_options: { include_usage: true })\n if (chunk.usage) {\n const rawUsage = chunk.usage;\n const inputTokens = rawUsage.prompt_tokens ?? rawUsage.input_tokens ?? 0;\n const outputTokens = rawUsage.completion_tokens ?? rawUsage.output_tokens ?? 0;\n const reasoningTokens =\n rawUsage.completion_tokens_details?.reasoning_tokens ??\n rawUsage.output_token_details?.reasoning_tokens ??\n 0;\n const cachedTokens =\n rawUsage.prompt_tokens_details?.cached_tokens ??\n rawUsage.input_token_details?.cached_tokens ??\n 0;\n\n return {\n model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n // Response API stream event (response.completed or response.done)\n if (chunk.type === 'response.completed' || chunk.type === 'response.done') {\n if (chunk.response?.usage) {\n const rawUsage = chunk.response.usage;\n const inputTokens = rawUsage.input_tokens ?? 0;\n const outputTokens = rawUsage.output_tokens ?? 0;\n const reasoningTokens = rawUsage.output_token_details?.reasoning_tokens ?? 0;\n const cachedTokens = rawUsage.input_token_details?.cached_tokens ?? 0;\n\n return {\n model: chunk.response.model || model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n }\n\n return { model };\n}\n","import type { TokenUsage } from '../../types';\nimport type { ExtractedUsage } from './openai';\n\n/**\n * Extracts token usage from Anthropic synchronous responses\n */\nexport function extractAnthropicResponseUsage(response: any): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // Anthropic Message response has type: 'message' or role: 'assistant' with usage\n if (response.type === 'message' || ('content' in response && 'usage' in response)) {\n const rawUsage = response.usage || {};\n const model = response.model || 'claude-3-7-sonnet';\n\n const inputTokens = rawUsage.input_tokens ?? 0;\n const outputTokens = rawUsage.output_tokens ?? 0;\n const cachedTokens = rawUsage.cache_read_input_tokens ?? 0;\n const cacheWriteTokens = rawUsage.cache_creation_input_tokens ?? 0;\n\n // Check content blocks for thinking/reasoning tokens count or thinking blocks\n let reasoningTokens: number | undefined = undefined;\n if (Array.isArray(response.content)) {\n const thinkingBlocks = response.content.filter((b: any) => b.type === 'thinking');\n if (thinkingBlocks.length > 0) {\n // Approximate or extract explicit thinking tokens if present in metadata\n reasoningTokens = (rawUsage as any).thinking_tokens ?? undefined;\n }\n }\n\n return {\n model,\n provider: 'anthropic',\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens,\n visibleOutputTokens:\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n cacheWriteTokens: cacheWriteTokens > 0 ? cacheWriteTokens : undefined,\n },\n };\n }\n\n return null;\n}\n\n/**\n * Accumulates stream events across an Anthropic raw message stream\n */\nexport class AnthropicStreamAccumulator {\n private model: string = 'claude-3-7-sonnet';\n private inputTokens: number = 0;\n private outputTokens: number = 0;\n private cachedTokens: number = 0;\n private cacheWriteTokens: number = 0;\n private reasoningTokens: number = 0;\n\n processEvent(event: any): void {\n if (!event || typeof event !== 'object') return;\n\n // 1. message_start (contains model and initial input usage)\n if (event.type === 'message_start' && event.message) {\n if (event.message.model) {\n this.model = event.message.model;\n }\n if (event.message.usage) {\n this.inputTokens = event.message.usage.input_tokens ?? 0;\n this.cachedTokens = event.message.usage.cache_read_input_tokens ?? 0;\n this.cacheWriteTokens = event.message.usage.cache_creation_input_tokens ?? 0;\n }\n }\n\n // 2. message_delta (contains final output usage)\n if (event.type === 'message_delta' && event.usage) {\n this.outputTokens = event.usage.output_tokens ?? 0;\n if (event.usage.thinking_tokens) {\n this.reasoningTokens = event.usage.thinking_tokens;\n }\n }\n\n // 3. content_block_start / content_block_delta for thinking blocks\n if (event.type === 'content_block_start' && event.content_block?.type === 'thinking') {\n // thinking block detected\n }\n }\n\n getUsage(): ExtractedUsage {\n return {\n model: this.model,\n provider: 'anthropic',\n usage: {\n inputTokens: this.inputTokens,\n outputTokens: this.outputTokens,\n totalTokens: this.inputTokens + this.outputTokens,\n reasoningTokens: this.reasoningTokens > 0 ? this.reasoningTokens : undefined,\n visibleOutputTokens:\n this.reasoningTokens > 0\n ? Math.max(0, this.outputTokens - this.reasoningTokens)\n : this.outputTokens,\n cachedTokens: this.cachedTokens > 0 ? this.cachedTokens : undefined,\n cacheWriteTokens: this.cacheWriteTokens > 0 ? this.cacheWriteTokens : undefined,\n },\n };\n }\n}\n","import type { TokenUsage } from '../../types';\nimport type { ExtractedUsage } from './openai';\n\n/**\n * Extracts token usage from Google Gemini API response or chunk\n */\nexport function extractGeminiResponseUsage(\n response: any,\n fallbackModel: string = 'gemini-3.7-flash'\n): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // Gemini returns usageMetadata on response or GenerateContentResult\n const usageMetadata = response.usageMetadata || response.response?.usageMetadata;\n\n if (usageMetadata) {\n const inputTokens = usageMetadata.promptTokenCount ?? 0;\n const baseOutputTokens = usageMetadata.candidatesTokenCount ?? 0;\n const thoughtsTokenCount =\n usageMetadata.thoughtsTokenCount ?? (usageMetadata as any).reasoningTokenCount ?? 0;\n const cachedTokens = usageMetadata.cachedContentTokenCount ?? 0;\n\n const totalOutput = baseOutputTokens + thoughtsTokenCount;\n const model = response.model || response.response?.model || fallbackModel;\n\n return {\n model,\n provider: 'google',\n usage: {\n inputTokens,\n outputTokens: totalOutput,\n totalTokens: inputTokens + totalOutput,\n reasoningTokens: thoughtsTokenCount > 0 ? thoughtsTokenCount : undefined,\n visibleOutputTokens: baseOutputTokens,\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n return null;\n}\n","import type { TokenUsage } from '../../types';\nimport type { ExtractedUsage } from './openai';\n\n/**\n * Extracts token usage from generic LLM provider objects (DeepSeek, Groq, Mistral, Ollama, Cohere, Together)\n */\nexport function extractGenericResponseUsage(\n response: any,\n fallbackModel: string = 'generic-llm',\n fallbackProvider: string = 'generic'\n): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // Check common usage property locations\n const usage = response.usage || response.token_usage || response.usageMetadata;\n\n if (usage) {\n const inputTokens =\n usage.prompt_tokens ??\n usage.input_tokens ??\n usage.promptTokenCount ??\n usage.prompt_eval_count ??\n 0;\n const outputTokens =\n usage.completion_tokens ??\n usage.output_tokens ??\n usage.candidatesTokenCount ??\n usage.eval_count ??\n 0;\n const reasoningTokens =\n usage.reasoning_tokens ??\n usage.thoughtsTokenCount ??\n usage.completion_tokens_details?.reasoning_tokens ??\n 0;\n const cachedTokens =\n usage.prompt_tokens_details?.cached_tokens ??\n usage.cached_tokens ??\n usage.cachedContentTokenCount ??\n 0;\n\n const model = response.model || fallbackModel;\n const provider = response.provider || fallbackProvider;\n\n return {\n model,\n provider,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n reasoningTokens: reasoningTokens > 0 ? reasoningTokens : undefined,\n visibleOutputTokens: Math.max(0, outputTokens - reasoningTokens),\n cachedTokens: cachedTokens > 0 ? cachedTokens : undefined,\n },\n };\n }\n\n return null;\n}\n","import type { ExtractedUsage } from './openai';\nimport { extractOpenAIResponseUsage } from './openai';\nimport { extractAnthropicResponseUsage } from './anthropic';\nimport { extractGeminiResponseUsage } from './gemini';\nimport { extractGenericResponseUsage } from './generic';\n\nexport * from './openai';\nexport * from './anthropic';\nexport * from './gemini';\nexport * from './generic';\n\n/**\n * Universal polymorphic response detector\n */\nexport function detectAndExtractUsage(\n response: any,\n fallbackModel?: string,\n fallbackProvider?: string\n): ExtractedUsage | null {\n if (!response || typeof response !== 'object') return null;\n\n // 1. Try OpenAI\n const openaiResult = extractOpenAIResponseUsage(response);\n if (openaiResult) return openaiResult;\n\n // 2. Try Anthropic\n const anthropicResult = extractAnthropicResponseUsage(response);\n if (anthropicResult) return anthropicResult;\n\n // 3. Try Gemini\n const geminiResult = extractGeminiResponseUsage(response, fallbackModel);\n if (geminiResult) return geminiResult;\n\n // 4. Try Generic\n const genericResult = extractGenericResponseUsage(response, fallbackModel, fallbackProvider);\n if (genericResult) return genericResult;\n\n return null;\n}\n","import type { ModelPricingRates } from '../types';\n\n/**\n * Built-in Registry of Model Pricing (USD per 1 Million Tokens)\n * Sourced from official 2026 provider pricing tables.\n */\nexport const MODEL_PRICING_TABLE: Record<string, ModelPricingRates> = {\n // --- OpenAI ---\n 'gpt-5.6-sol': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\n 'gpt-5.6-terra': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.2 },\n 'gpt-5.6-luna': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\n 'gpt-5': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\n 'gpt-5-mini': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\n 'o1': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\n 'o1-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\n 'o3': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\n 'o3-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10.0, cachedInputPer1M: 1.25 },\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.075 },\n 'gpt-4.1': { inputPer1M: 2.0, outputPer1M: 8.0, cachedInputPer1M: 1.0 },\n 'gpt-4.1-nano': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.05 },\n 'text-embedding-3-small': { inputPer1M: 0.02, outputPer1M: 0.0 },\n 'text-embedding-3-large': { inputPer1M: 0.13, outputPer1M: 0.0 },\n\n // --- Anthropic ---\n 'claude-3-7-sonnet': { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },\n 'claude-sonnet-5': { inputPer1M: 2.0, outputPer1M: 10.0, cachedInputPer1M: 0.3 },\n 'claude-3-5-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\n 'claude-3-5-haiku': { inputPer1M: 0.8, outputPer1M: 4.0, cachedInputPer1M: 0.08 },\n 'haiku-4.5': { inputPer1M: 1.0, outputPer1M: 5.0, cachedInputPer1M: 0.1 },\n 'claude-opus-5': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 1.5 },\n 'claude-3-opus': { inputPer1M: 15.0, outputPer1M: 75.0, cachedInputPer1M: 1.5 },\n\n // --- Google Gemini ---\n 'gemini-3.7-flash': { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },\n 'gemini-3.1-pro': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.5 },\n 'gemini-3.5-flash': { inputPer1M: 1.5, outputPer1M: 9.0, cachedInputPer1M: 0.38 },\n 'gemini-3.1-flash-lite': { inputPer1M: 0.25, outputPer1M: 1.5, cachedInputPer1M: 0.06 },\n 'gemini-2.0-flash': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.025 },\n 'gemini-1.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\n 'gemini-1.5-flash': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\n\n // --- xAI Grok ---\n 'grok-4.6': { inputPer1M: 3.0, outputPer1M: 15.0 },\n 'grok-2': { inputPer1M: 2.0, outputPer1M: 10.0 },\n 'grok-2-vision': { inputPer1M: 2.0, outputPer1M: 10.0 },\n 'grok-beta': { inputPer1M: 5.0, outputPer1M: 15.0 },\n\n // --- Mistral ---\n 'mistral-large-3': { inputPer1M: 2.0, outputPer1M: 6.0 },\n 'mistral-large-latest': { inputPer1M: 2.0, outputPer1M: 6.0 },\n 'codestral-latest': { inputPer1M: 0.3, outputPer1M: 0.9 },\n 'mistral-small-latest': { inputPer1M: 0.2, outputPer1M: 0.6 },\n 'ministral-8b-latest': { inputPer1M: 0.1, outputPer1M: 0.1 },\n\n // --- Groq LPUs ---\n 'llama-3.3-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\n 'llama-3.1-8b-instant': { inputPer1M: 0.05, outputPer1M: 0.08 },\n 'deepseek-r1-distill-llama-70b': { inputPer1M: 0.75, outputPer1M: 0.99 },\n 'qwen-2.5-32b': { inputPer1M: 0.29, outputPer1M: 0.39 },\n\n // --- DeepSeek ---\n 'deepseek-v4-pro': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\n 'deepseek-v4-flash': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\n 'deepseek-chat': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\n 'deepseek-reasoner': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\n\n // --- Cohere ---\n 'command-r-plus': { inputPer1M: 2.5, outputPer1M: 10.0 },\n 'command-r': { inputPer1M: 0.15, outputPer1M: 0.6 },\n};\n\n/**\n * Dynamic in-memory registry allowing runtime custom price registration\n */\nconst customPricingRegistry: Record<string, ModelPricingRates> = {};\n\n/**\n * Normalize model identifier to match pricing table keys\n */\nexport function normalizeModelKey(rawModel: string): string {\n if (!rawModel) return 'unknown';\n\n let model = rawModel.toLowerCase().trim();\n\n // Strip provider prefix if present (e.g. 'openai/gpt-4o' -> 'gpt-4o')\n if (model.includes('/')) {\n model = model.split('/')[1] || model;\n }\n\n // Remove date suffixes like -20240307 or -20250219\n model = model.replace(/-\\d{8}$/, '');\n model = model.replace(/-\\d{4}-\\d{2}-\\d{2}$/, '');\n\n return model;\n}\n\n/**\n * Retrieve pricing rates for a given model\n */\nexport function getModelPricing(modelName: string): ModelPricingRates {\n const normalized = normalizeModelKey(modelName);\n\n // Check custom registry first\n if (customPricingRegistry[normalized]) {\n return customPricingRegistry[normalized];\n }\n if (customPricingRegistry[modelName]) {\n return customPricingRegistry[modelName];\n }\n\n // Check built-in table\n if (MODEL_PRICING_TABLE[normalized]) {\n return MODEL_PRICING_TABLE[normalized];\n }\n if (MODEL_PRICING_TABLE[modelName]) {\n return MODEL_PRICING_TABLE[modelName];\n }\n\n // Fallback defaults for unknown models (conservative estimates: $1.00 in, $3.00 out)\n return {\n inputPer1M: 1.0,\n outputPer1M: 3.0,\n cachedInputPer1M: 0.5,\n };\n}\n\n/**\n * Register or override pricing rates for a custom model\n */\nexport function registerModelPricing(modelName: string, rates: ModelPricingRates): void {\n const normalized = normalizeModelKey(modelName);\n customPricingRegistry[normalized] = rates;\n customPricingRegistry[modelName] = rates;\n}\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 reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n markupMultiplier?: number;\n minimumChargeUSD?: number;\n customRate?: InlineRateConfig;\n}\n\n/**\n * Calculates exact inference cost for an LLM call or usage breakdown in USD.\n */\nexport function calculateCost(params: CalculateCostParams): InferenceCost {\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 = params.inputTokens ?? 0;\n const outputTokens = params.outputTokens ?? 0;\n const reasoningTokens = params.reasoningTokens ?? 0;\n const cachedTokens = params.cachedTokens ?? 0;\n\n // Regular input tokens (minus any cached tokens)\n const regularInputTokens = Math.max(0, inputTokens - cachedTokens);\n\n // Input costs\n const regularInputCost = (regularInputTokens / 1_000_000) * rates.inputPer1M;\n const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15; // 85% discount default for cached\n const cachedInputCost = (cachedTokens / 1_000_000) * cachedRate;\n const inputCostUSD = regularInputCost + cachedInputCost;\n\n // Output costs (reasoning tokens are billed as output tokens in standard APIs)\n const outputCostUSD = (outputTokens / 1_000_000) * rates.outputPer1M;\n\n // Reasoning breakdown cost\n const reasoningRate = rates.reasoningPer1M ?? rates.outputPer1M;\n const reasoningCostUSD = (reasoningTokens / 1_000_000) * reasoningRate;\n\n // Cache savings discount\n const standardCacheCost = (cachedTokens / 1_000_000) * rates.inputPer1M;\n const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);\n\n // Total base cost\n let totalUSD = inputCostUSD + outputCostUSD;\n\n // Retail price calculation (if markup multiplier provided)\n const markup = params.markupMultiplier ?? 1.0;\n let retailUSD: number | undefined = undefined;\n\n if (markup !== 1.0 || params.minimumChargeUSD !== undefined) {\n retailUSD = totalUSD * markup;\n if (params.minimumChargeUSD !== undefined && retailUSD < params.minimumChargeUSD) {\n retailUSD = params.minimumChargeUSD;\n }\n }\n\n return {\n inputCostUSD: Number(inputCostUSD.toFixed(8)),\n outputCostUSD: Number(outputCostUSD.toFixed(8)),\n reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : undefined,\n cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n totalUSD: Number(totalUSD.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 { UsageEvent, StreamWrapOptions } from '../types';\nimport { inspectOpenAIStreamChunk } from './extractors/openai';\nimport { AnthropicStreamAccumulator } from './extractors/anthropic';\nimport { extractGeminiResponseUsage } from './extractors/gemini';\nimport { calculateUsageCost } from '../pricing/calculator';\n\nexport type UsageDispatchedCallback = (event: UsageEvent) => void;\n\n/**\n * Wraps an OpenAI async iterable stream to capture usage at stream conclusion\n */\nexport function wrapOpenAIStream<T extends AsyncIterable<any>>(\n stream: T,\n options: StreamWrapOptions,\n onComplete: UsageDispatchedCallback\n): T {\n let detectedModel = options.model || 'gpt-4o';\n let finalUsage: any = null;\n\n const wrappedAsyncIterable = {\n async *[Symbol.asyncIterator]() {\n try {\n for await (const chunk of stream) {\n const inspected = inspectOpenAIStreamChunk(chunk);\n if (inspected.model) {\n detectedModel = inspected.model;\n }\n if (inspected.usage) {\n finalUsage = inspected.usage;\n }\n yield chunk;\n }\n } finally {\n if (finalUsage) {\n const cost = calculateUsageCost(detectedModel, finalUsage);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const event: UsageEvent = {\n timestamp: new Date().toISOString(),\n model: detectedModel,\n provider: 'openai',\n usage: finalUsage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n onComplete(event);\n if (options.onUsage) {\n options.onUsage(event);\n }\n }\n }\n },\n };\n\n return wrappedAsyncIterable as unknown as T;\n}\n\n/**\n * Wraps an Anthropic message stream to accumulate message_start and message_delta usage\n */\nexport function wrapAnthropicStream<T extends AsyncIterable<any>>(\n stream: T,\n options: StreamWrapOptions,\n onComplete: UsageDispatchedCallback\n): T {\n const accumulator = new AnthropicStreamAccumulator();\n\n const wrappedAsyncIterable = {\n async *[Symbol.asyncIterator]() {\n try {\n for await (const event of stream) {\n accumulator.processEvent(event);\n yield event;\n }\n } finally {\n const extracted = accumulator.getUsage();\n const model = options.model || extracted.model;\n const cost = calculateUsageCost(model, extracted.usage);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const usageEvent: UsageEvent = {\n timestamp: new Date().toISOString(),\n model,\n provider: 'anthropic',\n usage: extracted.usage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n onComplete(usageEvent);\n if (options.onUsage) {\n options.onUsage(usageEvent);\n }\n }\n },\n };\n\n return wrappedAsyncIterable as unknown as T;\n}\n\n/**\n * Wraps a Google Gemini GenerateContentStreamResult\n */\nexport function wrapGeminiStream(\n result: any,\n options: StreamWrapOptions,\n onComplete: UsageDispatchedCallback\n): any {\n if (!result || !result.stream) return result;\n\n const originalStream = result.stream;\n const model = options.model || 'gemini-3.7-flash';\n let lastChunkWithUsage: any = null;\n\n const wrappedStream = (async function* () {\n try {\n for await (const chunk of originalStream) {\n if (chunk.usageMetadata) {\n lastChunkWithUsage = chunk;\n }\n yield chunk;\n }\n } finally {\n if (lastChunkWithUsage) {\n const extracted = extractGeminiResponseUsage(lastChunkWithUsage, model);\n if (extracted) {\n const cost = calculateUsageCost(extracted.model, extracted.usage);\n const customerId =\n typeof options.customer === 'string'\n ? options.customer\n : options.customer?.id || options.customerId;\n\n const event: UsageEvent = {\n timestamp: new Date().toISOString(),\n model: extracted.model,\n provider: 'google',\n usage: extracted.usage,\n cost,\n customerId,\n metadata: options.metadata,\n };\n\n onComplete(event);\n if (options.onUsage) {\n options.onUsage(event);\n }\n }\n }\n }\n })();\n\n return {\n ...result,\n stream: wrappedStream,\n };\n}\n\n/**\n * Universal Stream Wrapper\n */\nexport function wrapUniversalStream<T>(\n stream: T,\n options: StreamWrapOptions = {},\n onComplete: UsageDispatchedCallback\n): T {\n if (!stream || typeof stream !== 'object') return stream;\n\n // 1. Check Gemini stream\n if ('stream' in stream && 'response' in stream) {\n return wrapGeminiStream(stream, options, onComplete);\n }\n\n // 2. Check if stream is an AsyncIterable\n if (Symbol.asyncIterator in stream) {\n // If provider is explicitly anthropic or stream looks like anthropic events\n if (options.provider === 'anthropic') {\n return wrapAnthropicStream(stream as any, options, onComplete);\n }\n // Default to OpenAI stream wrapper which detects usage chunks polymorphically\n return wrapOpenAIStream(stream as any, options, onComplete);\n }\n\n return stream;\n}\n","export * from './client';\nexport * from './batcher';\nexport * from './stream';\nexport * from './extractors';\n\nimport { createMeter } from './client';\nimport type { StreamWrapOptions, CustomerParam } from '../types';\n\n// Default singleton instance\nconst defaultMeter = createMeter();\n\n/**\n * Convenient standalone stream wrapper\n */\nexport function wrapStream<T>(stream: T, options?: StreamWrapOptions): T {\n return defaultMeter.wrapStream(stream, options);\n}\n\n/**\n * Convenient standalone usage tracker\n */\nexport function trackTokens(\n response: any,\n options?: { customer?: CustomerParam; customerId?: string; model?: string }\n) {\n return defaultMeter.trackUsage(response, options);\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- import { b as ModelPricingRates, I as InferenceCost, T as TokenUsage } from '../types-CSrSmsd1.mjs';
1
+ import { e as ModelPricingRates, d as InlineRateConfig, I as InferenceCost, T as TokenUsage } from '../types-Zbzxg-Ka.mjs';
2
2
  import 'stripe';
3
3
 
4
4
  /**
@@ -27,6 +27,8 @@ interface CalculateCostParams {
27
27
  cachedTokens?: number;
28
28
  cacheWriteTokens?: number;
29
29
  markupMultiplier?: number;
30
+ minimumChargeUSD?: number;
31
+ customRate?: InlineRateConfig;
30
32
  }
31
33
  /**
32
34
  * Calculates exact inference cost for an LLM call or usage breakdown in USD.
@@ -35,6 +37,10 @@ declare function calculateCost(params: CalculateCostParams): InferenceCost;
35
37
  /**
36
38
  * Calculates cost directly from a TokenUsage object
37
39
  */
38
- declare function calculateUsageCost(model: string, usage: TokenUsage, markupMultiplier?: number): InferenceCost;
40
+ declare function calculateUsageCost(model: string, usage: TokenUsage, optionsOrMarkup?: number | {
41
+ markupMultiplier?: number;
42
+ minimumChargeUSD?: number;
43
+ customRate?: InlineRateConfig;
44
+ }): InferenceCost;
39
45
 
40
46
  export { type CalculateCostParams, MODEL_PRICING_TABLE, calculateCost, calculateUsageCost, getModelPricing, normalizeModelKey, registerModelPricing };
@@ -1,4 +1,4 @@
1
- import { b as ModelPricingRates, I as InferenceCost, T as TokenUsage } from '../types-CSrSmsd1.js';
1
+ import { e as ModelPricingRates, d as InlineRateConfig, I as InferenceCost, T as TokenUsage } from '../types-Zbzxg-Ka.js';
2
2
  import 'stripe';
3
3
 
4
4
  /**
@@ -27,6 +27,8 @@ interface CalculateCostParams {
27
27
  cachedTokens?: number;
28
28
  cacheWriteTokens?: number;
29
29
  markupMultiplier?: number;
30
+ minimumChargeUSD?: number;
31
+ customRate?: InlineRateConfig;
30
32
  }
31
33
  /**
32
34
  * Calculates exact inference cost for an LLM call or usage breakdown in USD.
@@ -35,6 +37,10 @@ declare function calculateCost(params: CalculateCostParams): InferenceCost;
35
37
  /**
36
38
  * Calculates cost directly from a TokenUsage object
37
39
  */
38
- declare function calculateUsageCost(model: string, usage: TokenUsage, markupMultiplier?: number): InferenceCost;
40
+ declare function calculateUsageCost(model: string, usage: TokenUsage, optionsOrMarkup?: number | {
41
+ markupMultiplier?: number;
42
+ minimumChargeUSD?: number;
43
+ customRate?: InlineRateConfig;
44
+ }): InferenceCost;
39
45
 
40
46
  export { type CalculateCostParams, MODEL_PRICING_TABLE, calculateCost, calculateUsageCost, getModelPricing, normalizeModelKey, registerModelPricing };
@@ -127,14 +127,26 @@ function registerModelPricing(modelName, rates) {
127
127
 
128
128
  // src/pricing/calculator.ts
129
129
  function calculateCost(params) {
130
- const rates = getModelPricing(params.model);
130
+ let rates;
131
+ if (params.customRate) {
132
+ const outRate = params.customRate.out ?? params.customRate.output ?? 0;
133
+ rates = {
134
+ inputPer1M: params.customRate.in,
135
+ outputPer1M: outRate,
136
+ reasoningPer1M: params.customRate.reasoning ?? outRate,
137
+ cachedInputPer1M: params.customRate.cached ?? params.customRate.in * 0.15,
138
+ currency: "USD"
139
+ };
140
+ } else {
141
+ rates = getModelPricing(params.model);
142
+ }
131
143
  const inputTokens = params.inputTokens ?? 0;
132
144
  const outputTokens = params.outputTokens ?? 0;
133
145
  const reasoningTokens = params.reasoningTokens ?? 0;
134
146
  const cachedTokens = params.cachedTokens ?? 0;
135
147
  const regularInputTokens = Math.max(0, inputTokens - cachedTokens);
136
148
  const regularInputCost = regularInputTokens / 1e6 * rates.inputPer1M;
137
- const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.5;
149
+ const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15;
138
150
  const cachedInputCost = cachedTokens / 1e6 * cachedRate;
139
151
  const inputCostUSD = regularInputCost + cachedInputCost;
140
152
  const outputCostUSD = outputTokens / 1e6 * rates.outputPer1M;
@@ -142,20 +154,27 @@ function calculateCost(params) {
142
154
  const reasoningCostUSD = reasoningTokens / 1e6 * reasoningRate;
143
155
  const standardCacheCost = cachedTokens / 1e6 * rates.inputPer1M;
144
156
  const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);
145
- const totalUSD = inputCostUSD + outputCostUSD;
157
+ let totalUSD = inputCostUSD + outputCostUSD;
146
158
  const markup = params.markupMultiplier ?? 1;
147
- const retailUSD = markup !== 1 ? totalUSD * markup : void 0;
159
+ let retailUSD = void 0;
160
+ if (markup !== 1 || params.minimumChargeUSD !== void 0) {
161
+ retailUSD = totalUSD * markup;
162
+ if (params.minimumChargeUSD !== void 0 && retailUSD < params.minimumChargeUSD) {
163
+ retailUSD = params.minimumChargeUSD;
164
+ }
165
+ }
148
166
  return {
149
167
  inputCostUSD: Number(inputCostUSD.toFixed(8)),
150
168
  outputCostUSD: Number(outputCostUSD.toFixed(8)),
151
169
  reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : void 0,
152
170
  cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : void 0,
153
171
  totalUSD: Number(totalUSD.toFixed(8)),
154
- retailUSD: retailUSD ? Number(retailUSD.toFixed(8)) : void 0,
172
+ retailUSD: retailUSD !== void 0 ? Number(retailUSD.toFixed(8)) : void 0,
155
173
  currency: rates.currency || "USD"
156
174
  };
157
175
  }
158
- function calculateUsageCost(model, usage, markupMultiplier) {
176
+ function calculateUsageCost(model, usage, optionsOrMarkup) {
177
+ const options = typeof optionsOrMarkup === "number" ? { markupMultiplier: optionsOrMarkup } : optionsOrMarkup || {};
159
178
  return calculateCost({
160
179
  model,
161
180
  inputTokens: usage.inputTokens,
@@ -163,7 +182,9 @@ function calculateUsageCost(model, usage, markupMultiplier) {
163
182
  reasoningTokens: usage.reasoningTokens,
164
183
  cachedTokens: usage.cachedTokens,
165
184
  cacheWriteTokens: usage.cacheWriteTokens,
166
- markupMultiplier
185
+ markupMultiplier: options.markupMultiplier,
186
+ minimumChargeUSD: options.minimumChargeUSD,
187
+ customRate: options.customRate
167
188
  });
168
189
  }
169
190
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/pricing/index.ts","../../src/pricing/table.ts","../../src/pricing/calculator.ts"],"sourcesContent":["export * from './table';\nexport * from './calculator';\n","import type { ModelPricingRates } from '../types';\n\n/**\n * Built-in Registry of Model Pricing (USD per 1 Million Tokens)\n * Sourced from official 2026 provider pricing tables.\n */\nexport const MODEL_PRICING_TABLE: Record<string, ModelPricingRates> = {\n // --- OpenAI ---\n 'gpt-5.6-sol': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\n 'gpt-5.6-terra': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.2 },\n 'gpt-5.6-luna': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\n 'gpt-5': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\n 'gpt-5-mini': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\n 'o1': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\n 'o1-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\n 'o3': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\n 'o3-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10.0, cachedInputPer1M: 1.25 },\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.075 },\n 'gpt-4.1': { inputPer1M: 2.0, outputPer1M: 8.0, cachedInputPer1M: 1.0 },\n 'gpt-4.1-nano': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.05 },\n 'text-embedding-3-small': { inputPer1M: 0.02, outputPer1M: 0.0 },\n 'text-embedding-3-large': { inputPer1M: 0.13, outputPer1M: 0.0 },\n\n // --- Anthropic ---\n 'claude-3-7-sonnet': { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },\n 'claude-sonnet-5': { inputPer1M: 2.0, outputPer1M: 10.0, cachedInputPer1M: 0.3 },\n 'claude-3-5-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\n 'claude-3-5-haiku': { inputPer1M: 0.8, outputPer1M: 4.0, cachedInputPer1M: 0.08 },\n 'haiku-4.5': { inputPer1M: 1.0, outputPer1M: 5.0, cachedInputPer1M: 0.1 },\n 'claude-opus-5': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 1.5 },\n 'claude-3-opus': { inputPer1M: 15.0, outputPer1M: 75.0, cachedInputPer1M: 1.5 },\n\n // --- Google Gemini ---\n 'gemini-3.7-flash': { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },\n 'gemini-3.1-pro': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.5 },\n 'gemini-3.5-flash': { inputPer1M: 1.5, outputPer1M: 9.0, cachedInputPer1M: 0.38 },\n 'gemini-3.1-flash-lite': { inputPer1M: 0.25, outputPer1M: 1.5, cachedInputPer1M: 0.06 },\n 'gemini-2.0-flash': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.025 },\n 'gemini-1.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\n 'gemini-1.5-flash': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\n\n // --- xAI Grok ---\n 'grok-4.6': { inputPer1M: 3.0, outputPer1M: 15.0 },\n 'grok-2': { inputPer1M: 2.0, outputPer1M: 10.0 },\n 'grok-2-vision': { inputPer1M: 2.0, outputPer1M: 10.0 },\n 'grok-beta': { inputPer1M: 5.0, outputPer1M: 15.0 },\n\n // --- Mistral ---\n 'mistral-large-3': { inputPer1M: 2.0, outputPer1M: 6.0 },\n 'mistral-large-latest': { inputPer1M: 2.0, outputPer1M: 6.0 },\n 'codestral-latest': { inputPer1M: 0.3, outputPer1M: 0.9 },\n 'mistral-small-latest': { inputPer1M: 0.2, outputPer1M: 0.6 },\n 'ministral-8b-latest': { inputPer1M: 0.1, outputPer1M: 0.1 },\n\n // --- Groq LPUs ---\n 'llama-3.3-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\n 'llama-3.1-8b-instant': { inputPer1M: 0.05, outputPer1M: 0.08 },\n 'deepseek-r1-distill-llama-70b': { inputPer1M: 0.75, outputPer1M: 0.99 },\n 'qwen-2.5-32b': { inputPer1M: 0.29, outputPer1M: 0.39 },\n\n // --- DeepSeek ---\n 'deepseek-v4-pro': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\n 'deepseek-v4-flash': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\n 'deepseek-chat': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\n 'deepseek-reasoner': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\n\n // --- Cohere ---\n 'command-r-plus': { inputPer1M: 2.5, outputPer1M: 10.0 },\n 'command-r': { inputPer1M: 0.15, outputPer1M: 0.6 },\n};\n\n/**\n * Dynamic in-memory registry allowing runtime custom price registration\n */\nconst customPricingRegistry: Record<string, ModelPricingRates> = {};\n\n/**\n * Normalize model identifier to match pricing table keys\n */\nexport function normalizeModelKey(rawModel: string): string {\n if (!rawModel) return 'unknown';\n\n let model = rawModel.toLowerCase().trim();\n\n // Strip provider prefix if present (e.g. 'openai/gpt-4o' -> 'gpt-4o')\n if (model.includes('/')) {\n model = model.split('/')[1] || model;\n }\n\n // Remove date suffixes like -20240307 or -20250219\n model = model.replace(/-\\d{8}$/, '');\n model = model.replace(/-\\d{4}-\\d{2}-\\d{2}$/, '');\n\n return model;\n}\n\n/**\n * Retrieve pricing rates for a given model\n */\nexport function getModelPricing(modelName: string): ModelPricingRates {\n const normalized = normalizeModelKey(modelName);\n\n // Check custom registry first\n if (customPricingRegistry[normalized]) {\n return customPricingRegistry[normalized];\n }\n if (customPricingRegistry[modelName]) {\n return customPricingRegistry[modelName];\n }\n\n // Check built-in table\n if (MODEL_PRICING_TABLE[normalized]) {\n return MODEL_PRICING_TABLE[normalized];\n }\n if (MODEL_PRICING_TABLE[modelName]) {\n return MODEL_PRICING_TABLE[modelName];\n }\n\n // Fallback defaults for unknown models (conservative estimates: $1.00 in, $3.00 out)\n return {\n inputPer1M: 1.0,\n outputPer1M: 3.0,\n cachedInputPer1M: 0.5,\n };\n}\n\n/**\n * Register or override pricing rates for a custom model\n */\nexport function registerModelPricing(modelName: string, rates: ModelPricingRates): void {\n const normalized = normalizeModelKey(modelName);\n customPricingRegistry[normalized] = rates;\n customPricingRegistry[modelName] = rates;\n}\n","import type { InferenceCost, TokenUsage } from '../types';\nimport { getModelPricing } from './table';\n\nexport interface CalculateCostParams {\n model: string;\n inputTokens?: number;\n outputTokens?: number;\n reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n markupMultiplier?: number;\n}\n\n/**\n * Calculates exact inference cost for an LLM call or usage breakdown in USD.\n */\nexport function calculateCost(params: CalculateCostParams): InferenceCost {\n const rates = getModelPricing(params.model);\n\n const inputTokens = params.inputTokens ?? 0;\n const outputTokens = params.outputTokens ?? 0;\n const reasoningTokens = params.reasoningTokens ?? 0;\n const cachedTokens = params.cachedTokens ?? 0;\n\n // Regular input tokens (minus any cached tokens)\n const regularInputTokens = Math.max(0, inputTokens - cachedTokens);\n\n // Input costs\n const regularInputCost = (regularInputTokens / 1_000_000) * rates.inputPer1M;\n const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.5;\n const cachedInputCost = (cachedTokens / 1_000_000) * cachedRate;\n const inputCostUSD = regularInputCost + cachedInputCost;\n\n // Output costs (reasoning tokens are billed as output tokens in standard APIs)\n const outputCostUSD = (outputTokens / 1_000_000) * rates.outputPer1M;\n\n // Reasoning breakdown cost\n const reasoningRate = rates.reasoningPer1M ?? rates.outputPer1M;\n const reasoningCostUSD = (reasoningTokens / 1_000_000) * reasoningRate;\n\n // Cache savings discount\n const standardCacheCost = (cachedTokens / 1_000_000) * rates.inputPer1M;\n const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);\n\n // Total base cost\n const totalUSD = inputCostUSD + outputCostUSD;\n\n // Retail price calculation (if markup multiplier provided)\n const markup = params.markupMultiplier ?? 1.0;\n const retailUSD = markup !== 1.0 ? totalUSD * markup : undefined;\n\n return {\n inputCostUSD: Number(inputCostUSD.toFixed(8)),\n outputCostUSD: Number(outputCostUSD.toFixed(8)),\n reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : undefined,\n cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n totalUSD: Number(totalUSD.toFixed(8)),\n retailUSD: retailUSD ? 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 markupMultiplier?: number\n): InferenceCost {\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,\n });\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/pricing/index.ts","../../src/pricing/table.ts","../../src/pricing/calculator.ts"],"sourcesContent":["export * from './table';\nexport * from './calculator';\n","import type { ModelPricingRates } from '../types';\n\n/**\n * Built-in Registry of Model Pricing (USD per 1 Million Tokens)\n * Sourced from official 2026 provider pricing tables.\n */\nexport const MODEL_PRICING_TABLE: Record<string, ModelPricingRates> = {\n // --- OpenAI ---\n 'gpt-5.6-sol': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\n 'gpt-5.6-terra': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.2 },\n 'gpt-5.6-luna': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\n 'gpt-5': { inputPer1M: 4.0, outputPer1M: 20.0, cachedInputPer1M: 0.4 },\n 'gpt-5-mini': { inputPer1M: 0.2, outputPer1M: 1.2, cachedInputPer1M: 0.02 },\n 'o1': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\n 'o1-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\n 'o3': { inputPer1M: 15.0, outputPer1M: 60.0, cachedInputPer1M: 7.5 },\n 'o3-mini': { inputPer1M: 1.1, outputPer1M: 4.4, cachedInputPer1M: 0.55 },\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10.0, cachedInputPer1M: 1.25 },\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6, cachedInputPer1M: 0.075 },\n 'gpt-4.1': { inputPer1M: 2.0, outputPer1M: 8.0, cachedInputPer1M: 1.0 },\n 'gpt-4.1-nano': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.05 },\n 'text-embedding-3-small': { inputPer1M: 0.02, outputPer1M: 0.0 },\n 'text-embedding-3-large': { inputPer1M: 0.13, outputPer1M: 0.0 },\n\n // --- Anthropic ---\n 'claude-3-7-sonnet': { inputPer1M: 0.59, outputPer1M: 2.93, cachedInputPer1M: 0.3 },\n 'claude-sonnet-5': { inputPer1M: 2.0, outputPer1M: 10.0, cachedInputPer1M: 0.3 },\n 'claude-3-5-sonnet': { inputPer1M: 3.0, outputPer1M: 15.0, cachedInputPer1M: 0.3 },\n 'claude-3-5-haiku': { inputPer1M: 0.8, outputPer1M: 4.0, cachedInputPer1M: 0.08 },\n 'haiku-4.5': { inputPer1M: 1.0, outputPer1M: 5.0, cachedInputPer1M: 0.1 },\n 'claude-opus-5': { inputPer1M: 5.0, outputPer1M: 25.0, cachedInputPer1M: 1.5 },\n 'claude-3-opus': { inputPer1M: 15.0, outputPer1M: 75.0, cachedInputPer1M: 1.5 },\n\n // --- Google Gemini ---\n 'gemini-3.7-flash': { inputPer1M: 0.75, outputPer1M: 3.75, cachedInputPer1M: 0.18 },\n 'gemini-3.1-pro': { inputPer1M: 2.0, outputPer1M: 12.0, cachedInputPer1M: 0.5 },\n 'gemini-3.5-flash': { inputPer1M: 1.5, outputPer1M: 9.0, cachedInputPer1M: 0.38 },\n 'gemini-3.1-flash-lite': { inputPer1M: 0.25, outputPer1M: 1.5, cachedInputPer1M: 0.06 },\n 'gemini-2.0-flash': { inputPer1M: 0.1, outputPer1M: 0.4, cachedInputPer1M: 0.025 },\n 'gemini-1.5-pro': { inputPer1M: 1.25, outputPer1M: 5.0, cachedInputPer1M: 0.3125 },\n 'gemini-1.5-flash': { inputPer1M: 0.075, outputPer1M: 0.3, cachedInputPer1M: 0.01875 },\n\n // --- xAI Grok ---\n 'grok-4.6': { inputPer1M: 3.0, outputPer1M: 15.0 },\n 'grok-2': { inputPer1M: 2.0, outputPer1M: 10.0 },\n 'grok-2-vision': { inputPer1M: 2.0, outputPer1M: 10.0 },\n 'grok-beta': { inputPer1M: 5.0, outputPer1M: 15.0 },\n\n // --- Mistral ---\n 'mistral-large-3': { inputPer1M: 2.0, outputPer1M: 6.0 },\n 'mistral-large-latest': { inputPer1M: 2.0, outputPer1M: 6.0 },\n 'codestral-latest': { inputPer1M: 0.3, outputPer1M: 0.9 },\n 'mistral-small-latest': { inputPer1M: 0.2, outputPer1M: 0.6 },\n 'ministral-8b-latest': { inputPer1M: 0.1, outputPer1M: 0.1 },\n\n // --- Groq LPUs ---\n 'llama-3.3-70b-versatile': { inputPer1M: 0.59, outputPer1M: 0.79 },\n 'llama-3.1-8b-instant': { inputPer1M: 0.05, outputPer1M: 0.08 },\n 'deepseek-r1-distill-llama-70b': { inputPer1M: 0.75, outputPer1M: 0.99 },\n 'qwen-2.5-32b': { inputPer1M: 0.29, outputPer1M: 0.39 },\n\n // --- DeepSeek ---\n 'deepseek-v4-pro': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\n 'deepseek-v4-flash': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\n 'deepseek-chat': { inputPer1M: 0.22, outputPer1M: 0.66, cachedInputPer1M: 0.05 },\n 'deepseek-reasoner': { inputPer1M: 0.66, outputPer1M: 1.98, cachedInputPer1M: 0.15 },\n\n // --- Cohere ---\n 'command-r-plus': { inputPer1M: 2.5, outputPer1M: 10.0 },\n 'command-r': { inputPer1M: 0.15, outputPer1M: 0.6 },\n};\n\n/**\n * Dynamic in-memory registry allowing runtime custom price registration\n */\nconst customPricingRegistry: Record<string, ModelPricingRates> = {};\n\n/**\n * Normalize model identifier to match pricing table keys\n */\nexport function normalizeModelKey(rawModel: string): string {\n if (!rawModel) return 'unknown';\n\n let model = rawModel.toLowerCase().trim();\n\n // Strip provider prefix if present (e.g. 'openai/gpt-4o' -> 'gpt-4o')\n if (model.includes('/')) {\n model = model.split('/')[1] || model;\n }\n\n // Remove date suffixes like -20240307 or -20250219\n model = model.replace(/-\\d{8}$/, '');\n model = model.replace(/-\\d{4}-\\d{2}-\\d{2}$/, '');\n\n return model;\n}\n\n/**\n * Retrieve pricing rates for a given model\n */\nexport function getModelPricing(modelName: string): ModelPricingRates {\n const normalized = normalizeModelKey(modelName);\n\n // Check custom registry first\n if (customPricingRegistry[normalized]) {\n return customPricingRegistry[normalized];\n }\n if (customPricingRegistry[modelName]) {\n return customPricingRegistry[modelName];\n }\n\n // Check built-in table\n if (MODEL_PRICING_TABLE[normalized]) {\n return MODEL_PRICING_TABLE[normalized];\n }\n if (MODEL_PRICING_TABLE[modelName]) {\n return MODEL_PRICING_TABLE[modelName];\n }\n\n // Fallback defaults for unknown models (conservative estimates: $1.00 in, $3.00 out)\n return {\n inputPer1M: 1.0,\n outputPer1M: 3.0,\n cachedInputPer1M: 0.5,\n };\n}\n\n/**\n * Register or override pricing rates for a custom model\n */\nexport function registerModelPricing(modelName: string, rates: ModelPricingRates): void {\n const normalized = normalizeModelKey(modelName);\n customPricingRegistry[normalized] = rates;\n customPricingRegistry[modelName] = rates;\n}\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 reasoningTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n markupMultiplier?: number;\n minimumChargeUSD?: number;\n customRate?: InlineRateConfig;\n}\n\n/**\n * Calculates exact inference cost for an LLM call or usage breakdown in USD.\n */\nexport function calculateCost(params: CalculateCostParams): InferenceCost {\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 = params.inputTokens ?? 0;\n const outputTokens = params.outputTokens ?? 0;\n const reasoningTokens = params.reasoningTokens ?? 0;\n const cachedTokens = params.cachedTokens ?? 0;\n\n // Regular input tokens (minus any cached tokens)\n const regularInputTokens = Math.max(0, inputTokens - cachedTokens);\n\n // Input costs\n const regularInputCost = (regularInputTokens / 1_000_000) * rates.inputPer1M;\n const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15; // 85% discount default for cached\n const cachedInputCost = (cachedTokens / 1_000_000) * cachedRate;\n const inputCostUSD = regularInputCost + cachedInputCost;\n\n // Output costs (reasoning tokens are billed as output tokens in standard APIs)\n const outputCostUSD = (outputTokens / 1_000_000) * rates.outputPer1M;\n\n // Reasoning breakdown cost\n const reasoningRate = rates.reasoningPer1M ?? rates.outputPer1M;\n const reasoningCostUSD = (reasoningTokens / 1_000_000) * reasoningRate;\n\n // Cache savings discount\n const standardCacheCost = (cachedTokens / 1_000_000) * rates.inputPer1M;\n const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);\n\n // Total base cost\n let totalUSD = inputCostUSD + outputCostUSD;\n\n // Retail price calculation (if markup multiplier provided)\n const markup = params.markupMultiplier ?? 1.0;\n let retailUSD: number | undefined = undefined;\n\n if (markup !== 1.0 || params.minimumChargeUSD !== undefined) {\n retailUSD = totalUSD * markup;\n if (params.minimumChargeUSD !== undefined && retailUSD < params.minimumChargeUSD) {\n retailUSD = params.minimumChargeUSD;\n }\n }\n\n return {\n inputCostUSD: Number(inputCostUSD.toFixed(8)),\n outputCostUSD: Number(outputCostUSD.toFixed(8)),\n reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : undefined,\n cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : undefined,\n totalUSD: Number(totalUSD.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"],"mappings":"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","names":[]}
@@ -96,14 +96,26 @@ function registerModelPricing(modelName, rates) {
96
96
 
97
97
  // src/pricing/calculator.ts
98
98
  function calculateCost(params) {
99
- const rates = getModelPricing(params.model);
99
+ let rates;
100
+ if (params.customRate) {
101
+ const outRate = params.customRate.out ?? params.customRate.output ?? 0;
102
+ rates = {
103
+ inputPer1M: params.customRate.in,
104
+ outputPer1M: outRate,
105
+ reasoningPer1M: params.customRate.reasoning ?? outRate,
106
+ cachedInputPer1M: params.customRate.cached ?? params.customRate.in * 0.15,
107
+ currency: "USD"
108
+ };
109
+ } else {
110
+ rates = getModelPricing(params.model);
111
+ }
100
112
  const inputTokens = params.inputTokens ?? 0;
101
113
  const outputTokens = params.outputTokens ?? 0;
102
114
  const reasoningTokens = params.reasoningTokens ?? 0;
103
115
  const cachedTokens = params.cachedTokens ?? 0;
104
116
  const regularInputTokens = Math.max(0, inputTokens - cachedTokens);
105
117
  const regularInputCost = regularInputTokens / 1e6 * rates.inputPer1M;
106
- const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.5;
118
+ const cachedRate = rates.cachedInputPer1M ?? rates.inputPer1M * 0.15;
107
119
  const cachedInputCost = cachedTokens / 1e6 * cachedRate;
108
120
  const inputCostUSD = regularInputCost + cachedInputCost;
109
121
  const outputCostUSD = outputTokens / 1e6 * rates.outputPer1M;
@@ -111,20 +123,27 @@ function calculateCost(params) {
111
123
  const reasoningCostUSD = reasoningTokens / 1e6 * reasoningRate;
112
124
  const standardCacheCost = cachedTokens / 1e6 * rates.inputPer1M;
113
125
  const cachedDiscountUSD = Math.max(0, standardCacheCost - cachedInputCost);
114
- const totalUSD = inputCostUSD + outputCostUSD;
126
+ let totalUSD = inputCostUSD + outputCostUSD;
115
127
  const markup = params.markupMultiplier ?? 1;
116
- const retailUSD = markup !== 1 ? totalUSD * markup : void 0;
128
+ let retailUSD = void 0;
129
+ if (markup !== 1 || params.minimumChargeUSD !== void 0) {
130
+ retailUSD = totalUSD * markup;
131
+ if (params.minimumChargeUSD !== void 0 && retailUSD < params.minimumChargeUSD) {
132
+ retailUSD = params.minimumChargeUSD;
133
+ }
134
+ }
117
135
  return {
118
136
  inputCostUSD: Number(inputCostUSD.toFixed(8)),
119
137
  outputCostUSD: Number(outputCostUSD.toFixed(8)),
120
138
  reasoningCostUSD: reasoningTokens > 0 ? Number(reasoningCostUSD.toFixed(8)) : void 0,
121
139
  cachedDiscountUSD: cachedTokens > 0 ? Number(cachedDiscountUSD.toFixed(8)) : void 0,
122
140
  totalUSD: Number(totalUSD.toFixed(8)),
123
- retailUSD: retailUSD ? Number(retailUSD.toFixed(8)) : void 0,
141
+ retailUSD: retailUSD !== void 0 ? Number(retailUSD.toFixed(8)) : void 0,
124
142
  currency: rates.currency || "USD"
125
143
  };
126
144
  }
127
- function calculateUsageCost(model, usage, markupMultiplier) {
145
+ function calculateUsageCost(model, usage, optionsOrMarkup) {
146
+ const options = typeof optionsOrMarkup === "number" ? { markupMultiplier: optionsOrMarkup } : optionsOrMarkup || {};
128
147
  return calculateCost({
129
148
  model,
130
149
  inputTokens: usage.inputTokens,
@@ -132,7 +151,9 @@ function calculateUsageCost(model, usage, markupMultiplier) {
132
151
  reasoningTokens: usage.reasoningTokens,
133
152
  cachedTokens: usage.cachedTokens,
134
153
  cacheWriteTokens: usage.cacheWriteTokens,
135
- markupMultiplier
154
+ markupMultiplier: options.markupMultiplier,
155
+ minimumChargeUSD: options.minimumChargeUSD,
156
+ customRate: options.customRate
136
157
  });
137
158
  }
138
159
  export {