vibezcheck 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +273 -203
- package/dist/ai-sdk/index.d.mts +6 -4
- package/dist/ai-sdk/index.d.ts +6 -4
- package/dist/ai-sdk/index.js +184 -22
- package/dist/ai-sdk/index.js.map +1 -1
- package/dist/ai-sdk/index.mjs +184 -22
- package/dist/ai-sdk/index.mjs.map +1 -1
- package/dist/cli/index.js +316 -17
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +316 -17
- package/dist/cli/index.mjs.map +1 -1
- package/dist/{client-kJN_Znan.d.ts → client-w_hWhQ6g.d.mts} +4 -2
- package/dist/{client--iq93FQg.d.mts → client-ynfWcHX6.d.ts} +4 -2
- package/dist/customers/index.d.mts +30 -4
- package/dist/customers/index.d.ts +30 -4
- package/dist/customers/index.js +108 -8
- package/dist/customers/index.js.map +1 -1
- package/dist/customers/index.mjs +106 -7
- package/dist/customers/index.mjs.map +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +238 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +237 -28
- package/dist/index.mjs.map +1 -1
- package/dist/meter/index.d.mts +2 -2
- package/dist/meter/index.d.ts +2 -2
- package/dist/meter/index.js +95 -16
- package/dist/meter/index.js.map +1 -1
- package/dist/meter/index.mjs +95 -16
- package/dist/meter/index.mjs.map +1 -1
- package/dist/pricing/index.d.mts +1 -1
- package/dist/pricing/index.d.ts +1 -1
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/{types-Zbzxg-Ka.d.mts → types-Mozk4-Mr.d.mts} +70 -12
- package/dist/{types-Zbzxg-Ka.d.ts → types-Mozk4-Mr.d.ts} +70 -12
- package/package.json +161 -153
package/dist/meter/index.mjs
CHANGED
|
@@ -600,6 +600,58 @@ function calculateUsageCost(model, usage, optionsOrMarkup) {
|
|
|
600
600
|
});
|
|
601
601
|
}
|
|
602
602
|
|
|
603
|
+
// src/customers/helpers.ts
|
|
604
|
+
function normalizeCustomer(customer, extraCustomerId) {
|
|
605
|
+
if (!customer && !extraCustomerId) {
|
|
606
|
+
return {
|
|
607
|
+
customerId: void 0,
|
|
608
|
+
customerEmail: void 0,
|
|
609
|
+
customerObj: void 0,
|
|
610
|
+
customerMetadata: {}
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
if (typeof customer === "string") {
|
|
614
|
+
const isEmail = customer.includes("@");
|
|
615
|
+
const customerObj2 = {
|
|
616
|
+
id: customer,
|
|
617
|
+
email: isEmail ? customer : void 0
|
|
618
|
+
};
|
|
619
|
+
return {
|
|
620
|
+
customerId: customer,
|
|
621
|
+
customerEmail: isEmail ? customer : void 0,
|
|
622
|
+
customerObj: customerObj2,
|
|
623
|
+
customerMetadata: {}
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : void 0);
|
|
627
|
+
const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;
|
|
628
|
+
const customerEmail = customerObj?.email;
|
|
629
|
+
const customerMetadata = {};
|
|
630
|
+
if (customerObj) {
|
|
631
|
+
const orgId = customerObj.orgId || customerObj.organizationId;
|
|
632
|
+
if (orgId) customerMetadata.org_id = String(orgId);
|
|
633
|
+
const teamId = customerObj.teamId || customerObj.workspaceId;
|
|
634
|
+
if (teamId) customerMetadata.team_id = String(teamId);
|
|
635
|
+
if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);
|
|
636
|
+
if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);
|
|
637
|
+
if (customerObj.role) customerMetadata.role = String(customerObj.role);
|
|
638
|
+
if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);
|
|
639
|
+
if (customerObj.metadata) {
|
|
640
|
+
for (const [key, val] of Object.entries(customerObj.metadata)) {
|
|
641
|
+
if (val !== null && val !== void 0) {
|
|
642
|
+
customerMetadata[key] = val;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return {
|
|
648
|
+
customerId,
|
|
649
|
+
customerEmail,
|
|
650
|
+
customerObj,
|
|
651
|
+
customerMetadata
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
|
|
603
655
|
// src/meter/stream.ts
|
|
604
656
|
function wrapOpenAIStream(stream, options, onComplete) {
|
|
605
657
|
let detectedModel = options.model || "gpt-4o";
|
|
@@ -620,15 +672,20 @@ function wrapOpenAIStream(stream, options, onComplete) {
|
|
|
620
672
|
} finally {
|
|
621
673
|
if (finalUsage) {
|
|
622
674
|
const cost = calculateUsageCost(detectedModel, finalUsage);
|
|
623
|
-
const
|
|
675
|
+
const normalized = normalizeCustomer(options.customer, options.customerId);
|
|
624
676
|
const event = {
|
|
625
677
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
626
678
|
model: detectedModel,
|
|
627
679
|
provider: "openai",
|
|
628
680
|
usage: finalUsage,
|
|
629
681
|
cost,
|
|
630
|
-
customerId,
|
|
631
|
-
|
|
682
|
+
customerId: normalized.customerId,
|
|
683
|
+
customerEmail: normalized.customerEmail,
|
|
684
|
+
customer: normalized.customerObj,
|
|
685
|
+
metadata: {
|
|
686
|
+
...normalized.customerMetadata,
|
|
687
|
+
...options.metadata
|
|
688
|
+
}
|
|
632
689
|
};
|
|
633
690
|
onComplete(event);
|
|
634
691
|
if (options.onUsage) {
|
|
@@ -653,15 +710,20 @@ function wrapAnthropicStream(stream, options, onComplete) {
|
|
|
653
710
|
const extracted = accumulator.getUsage();
|
|
654
711
|
const model = options.model || extracted.model;
|
|
655
712
|
const cost = calculateUsageCost(model, extracted.usage);
|
|
656
|
-
const
|
|
713
|
+
const normalized = normalizeCustomer(options.customer, options.customerId);
|
|
657
714
|
const usageEvent = {
|
|
658
715
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
659
716
|
model,
|
|
660
717
|
provider: "anthropic",
|
|
661
718
|
usage: extracted.usage,
|
|
662
719
|
cost,
|
|
663
|
-
customerId,
|
|
664
|
-
|
|
720
|
+
customerId: normalized.customerId,
|
|
721
|
+
customerEmail: normalized.customerEmail,
|
|
722
|
+
customer: normalized.customerObj,
|
|
723
|
+
metadata: {
|
|
724
|
+
...normalized.customerMetadata,
|
|
725
|
+
...options.metadata
|
|
726
|
+
}
|
|
665
727
|
};
|
|
666
728
|
onComplete(usageEvent);
|
|
667
729
|
if (options.onUsage) {
|
|
@@ -690,15 +752,20 @@ function wrapGeminiStream(result, options, onComplete) {
|
|
|
690
752
|
const extracted = extractGeminiResponseUsage(lastChunkWithUsage, model);
|
|
691
753
|
if (extracted) {
|
|
692
754
|
const cost = calculateUsageCost(extracted.model, extracted.usage);
|
|
693
|
-
const
|
|
755
|
+
const normalized = normalizeCustomer(options.customer, options.customerId);
|
|
694
756
|
const event = {
|
|
695
757
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
696
758
|
model: extracted.model,
|
|
697
759
|
provider: "google",
|
|
698
760
|
usage: extracted.usage,
|
|
699
761
|
cost,
|
|
700
|
-
customerId,
|
|
701
|
-
|
|
762
|
+
customerId: normalized.customerId,
|
|
763
|
+
customerEmail: normalized.customerEmail,
|
|
764
|
+
customer: normalized.customerObj,
|
|
765
|
+
metadata: {
|
|
766
|
+
...normalized.customerMetadata,
|
|
767
|
+
...options.metadata
|
|
768
|
+
}
|
|
702
769
|
};
|
|
703
770
|
onComplete(event);
|
|
704
771
|
if (options.onUsage) {
|
|
@@ -741,7 +808,7 @@ var VibezMeter = class {
|
|
|
741
808
|
this.stripeClient = new Stripe(key, {
|
|
742
809
|
appInfo: {
|
|
743
810
|
name: "vibezcheck",
|
|
744
|
-
version: "0.
|
|
811
|
+
version: "0.4.2",
|
|
745
812
|
url: "https://vibezcheck.xyz"
|
|
746
813
|
}
|
|
747
814
|
});
|
|
@@ -761,15 +828,21 @@ var VibezMeter = class {
|
|
|
761
828
|
}
|
|
762
829
|
const model = options.model || extracted.model;
|
|
763
830
|
const cost = calculateUsageCost(model, extracted.usage, this.markupMultiplier);
|
|
764
|
-
const
|
|
831
|
+
const normalized = normalizeCustomer(options.customer, options.customerId);
|
|
832
|
+
const mergedMeta = {
|
|
833
|
+
...normalized.customerMetadata,
|
|
834
|
+
...options.metadata
|
|
835
|
+
};
|
|
765
836
|
const event = {
|
|
766
837
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
767
838
|
model,
|
|
768
839
|
provider: extracted.provider,
|
|
769
840
|
usage: extracted.usage,
|
|
770
841
|
cost,
|
|
771
|
-
customerId,
|
|
772
|
-
|
|
842
|
+
customerId: normalized.customerId,
|
|
843
|
+
customerEmail: normalized.customerEmail,
|
|
844
|
+
customer: normalized.customerObj,
|
|
845
|
+
metadata: mergedMeta
|
|
773
846
|
};
|
|
774
847
|
this.batcher.enqueue(event);
|
|
775
848
|
return event;
|
|
@@ -799,15 +872,21 @@ var VibezMeter = class {
|
|
|
799
872
|
cachedTokens
|
|
800
873
|
};
|
|
801
874
|
const cost = calculateUsageCost(options.model, usage, this.markupMultiplier);
|
|
802
|
-
const
|
|
875
|
+
const normalized = normalizeCustomer(options.customer, options.customerId);
|
|
876
|
+
const mergedMeta = {
|
|
877
|
+
...normalized.customerMetadata,
|
|
878
|
+
...options.metadata
|
|
879
|
+
};
|
|
803
880
|
const event = {
|
|
804
881
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
805
882
|
model: options.model,
|
|
806
883
|
provider: options.provider || "custom",
|
|
807
884
|
usage,
|
|
808
885
|
cost,
|
|
809
|
-
customerId,
|
|
810
|
-
|
|
886
|
+
customerId: normalized.customerId,
|
|
887
|
+
customerEmail: normalized.customerEmail,
|
|
888
|
+
customer: normalized.customerObj,
|
|
889
|
+
metadata: mergedMeta
|
|
811
890
|
};
|
|
812
891
|
this.batcher.enqueue(event);
|
|
813
892
|
return event;
|
package/dist/meter/index.mjs.map
CHANGED
|
@@ -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, 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
|
+
{"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/customers/helpers.ts","../../src/meter/stream.ts","../../src/meter/index.ts"],"sourcesContent":["import Stripe from 'stripe';\r\nimport type {\r\n MeterOptions,\r\n StreamWrapOptions,\r\n RecordUsageOptions,\r\n UsageEvent,\r\n UsageSummary,\r\n CustomerParam,\r\n} from '../types';\r\nimport { MeterBatcher } from './batcher';\r\nimport { detectAndExtractUsage } from './extractors';\r\nimport { calculateUsageCost } from '../pricing/calculator';\r\nimport { wrapUniversalStream } from './stream';\r\nimport { normalizeCustomer } from '../customers/helpers';\r\n\r\nexport class VibezMeter {\r\n private batcher: MeterBatcher;\r\n private stripeClient?: Stripe;\r\n private markupMultiplier?: number;\r\n\r\n constructor(options: MeterOptions = {}) {\r\n this.markupMultiplier = options.markupMultiplier;\r\n\r\n // Initialize Stripe client if apiKey or stripe instance is provided\r\n if (options.stripe) {\r\n this.stripeClient = options.stripe;\r\n } else if (options.apiKey || process.env.STRIPE_SECRET_KEY) {\r\n const key = options.apiKey || process.env.STRIPE_SECRET_KEY!;\r\n this.stripeClient = new Stripe(key, {\r\n appInfo: {\r\n name: 'vibezcheck',\r\n version: '0.4.2',\r\n url: 'https://vibezcheck.xyz',\r\n },\r\n });\r\n }\r\n\r\n this.batcher = new MeterBatcher({\r\n ...options,\r\n stripe: this.stripeClient,\r\n });\r\n }\r\n\r\n /**\r\n * Track token usage from a non-streaming response object (OpenAI, Anthropic, Gemini, etc.)\r\n */\r\n public trackUsage(\r\n response: any,\r\n options: {\r\n customer?: CustomerParam;\r\n customerId?: string;\r\n model?: string;\r\n provider?: string;\r\n metadata?: Record<string, string | number | boolean>;\r\n } = {}\r\n ): UsageEvent | null {\r\n const extracted = detectAndExtractUsage(response, options.model, options.provider);\r\n if (!extracted) {\r\n return null;\r\n }\r\n\r\n const model = options.model || extracted.model;\r\n const cost = calculateUsageCost(model, extracted.usage, this.markupMultiplier);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const mergedMeta = {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n };\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model,\r\n provider: extracted.provider,\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: mergedMeta,\r\n };\r\n\r\n this.batcher.enqueue(event);\r\n return event;\r\n }\r\n\r\n /**\r\n * Wrap any LLM stream (OpenAI, Anthropic, Gemini) with zero added latency\r\n */\r\n public wrapStream<T>(stream: T, options: StreamWrapOptions = {}): T {\r\n return wrapUniversalStream(stream, options, (event) => {\r\n this.batcher.enqueue(event);\r\n });\r\n }\r\n\r\n /**\r\n * Directly record token usage manually\r\n */\r\n public recordUsage(options: RecordUsageOptions & { customer?: CustomerParam }): UsageEvent {\r\n const inputTokens = options.inputTokens ?? 0;\r\n const outputTokens = options.outputTokens ?? 0;\r\n const reasoningTokens = options.reasoningTokens;\r\n const cachedTokens = options.cachedTokens;\r\n\r\n const usage = {\r\n inputTokens,\r\n outputTokens,\r\n totalTokens: inputTokens + outputTokens,\r\n reasoningTokens,\r\n visibleOutputTokens:\r\n reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens,\r\n cachedTokens,\r\n };\r\n\r\n const cost = calculateUsageCost(options.model, usage, this.markupMultiplier);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const mergedMeta = {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n };\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: options.model,\r\n provider: options.provider || 'custom',\r\n usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: mergedMeta,\r\n };\r\n\r\n this.batcher.enqueue(event);\r\n return event;\r\n }\r\n\r\n /**\r\n * Flush pending events to Stripe (vital for Serverless & Edge environments)\r\n */\r\n public async flush(): Promise<void> {\r\n await this.batcher.flush();\r\n }\r\n\r\n /**\r\n * Get in-memory aggregated usage statistics\r\n */\r\n public getUsageSummary(): UsageSummary {\r\n return this.batcher.getSummary();\r\n }\r\n\r\n /**\r\n * Reset in-memory ledger\r\n */\r\n public resetSummary(): void {\r\n this.batcher.resetLedger();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create a VibezMeter instance\r\n */\r\nexport function createMeter(options: MeterOptions = {}): VibezMeter {\r\n return new VibezMeter(options);\r\n}\r\n","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 { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n","import type { UsageEvent, StreamWrapOptions } from '../types';\r\nimport { inspectOpenAIStreamChunk } from './extractors/openai';\r\nimport { AnthropicStreamAccumulator } from './extractors/anthropic';\r\nimport { extractGeminiResponseUsage } from './extractors/gemini';\r\nimport { calculateUsageCost } from '../pricing/calculator';\r\nimport { normalizeCustomer } from '../customers/helpers';\r\n\r\nexport type UsageDispatchedCallback = (event: UsageEvent) => void;\r\n\r\n/**\r\n * Wraps an OpenAI async iterable stream to capture usage at stream conclusion\r\n */\r\nexport function wrapOpenAIStream<T extends AsyncIterable<any>>(\r\n stream: T,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n let detectedModel = options.model || 'gpt-4o';\r\n let finalUsage: any = null;\r\n\r\n const wrappedAsyncIterable = {\r\n async *[Symbol.asyncIterator]() {\r\n try {\r\n for await (const chunk of stream) {\r\n const inspected = inspectOpenAIStreamChunk(chunk);\r\n if (inspected.model) {\r\n detectedModel = inspected.model;\r\n }\r\n if (inspected.usage) {\r\n finalUsage = inspected.usage;\r\n }\r\n yield chunk;\r\n }\r\n } finally {\r\n if (finalUsage) {\r\n const cost = calculateUsageCost(detectedModel, finalUsage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: detectedModel,\r\n provider: 'openai',\r\n usage: finalUsage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(event);\r\n if (options.onUsage) {\r\n options.onUsage(event);\r\n }\r\n }\r\n }\r\n },\r\n };\r\n\r\n return wrappedAsyncIterable as unknown as T;\r\n}\r\n\r\n/**\r\n * Wraps an Anthropic message stream to accumulate message_start and message_delta usage\r\n */\r\nexport function wrapAnthropicStream<T extends AsyncIterable<any>>(\r\n stream: T,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n const accumulator = new AnthropicStreamAccumulator();\r\n\r\n const wrappedAsyncIterable = {\r\n async *[Symbol.asyncIterator]() {\r\n try {\r\n for await (const event of stream) {\r\n accumulator.processEvent(event);\r\n yield event;\r\n }\r\n } finally {\r\n const extracted = accumulator.getUsage();\r\n const model = options.model || extracted.model;\r\n const cost = calculateUsageCost(model, extracted.usage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const usageEvent: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model,\r\n provider: 'anthropic',\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(usageEvent);\r\n if (options.onUsage) {\r\n options.onUsage(usageEvent);\r\n }\r\n }\r\n },\r\n };\r\n\r\n return wrappedAsyncIterable as unknown as T;\r\n}\r\n\r\n/**\r\n * Wraps a Google Gemini GenerateContentStreamResult\r\n */\r\nexport function wrapGeminiStream(\r\n result: any,\r\n options: StreamWrapOptions,\r\n onComplete: UsageDispatchedCallback\r\n): any {\r\n if (!result || !result.stream) return result;\r\n\r\n const originalStream = result.stream;\r\n const model = options.model || 'gemini-3.7-flash';\r\n let lastChunkWithUsage: any = null;\r\n\r\n const wrappedStream = (async function* () {\r\n try {\r\n for await (const chunk of originalStream) {\r\n if (chunk.usageMetadata) {\r\n lastChunkWithUsage = chunk;\r\n }\r\n yield chunk;\r\n }\r\n } finally {\r\n if (lastChunkWithUsage) {\r\n const extracted = extractGeminiResponseUsage(lastChunkWithUsage, model);\r\n if (extracted) {\r\n const cost = calculateUsageCost(extracted.model, extracted.usage);\r\n const normalized = normalizeCustomer(options.customer, options.customerId);\r\n\r\n const event: UsageEvent = {\r\n timestamp: new Date().toISOString(),\r\n model: extracted.model,\r\n provider: 'google',\r\n usage: extracted.usage,\r\n cost,\r\n customerId: normalized.customerId,\r\n customerEmail: normalized.customerEmail,\r\n customer: normalized.customerObj,\r\n metadata: {\r\n ...normalized.customerMetadata,\r\n ...options.metadata,\r\n },\r\n };\r\n\r\n onComplete(event);\r\n if (options.onUsage) {\r\n options.onUsage(event);\r\n }\r\n }\r\n }\r\n }\r\n })();\r\n\r\n return {\r\n ...result,\r\n stream: wrappedStream,\r\n };\r\n}\r\n\r\n/**\r\n * Universal Stream Wrapper\r\n */\r\nexport function wrapUniversalStream<T>(\r\n stream: T,\r\n options: StreamWrapOptions = {},\r\n onComplete: UsageDispatchedCallback\r\n): T {\r\n if (!stream || typeof stream !== 'object') return stream;\r\n\r\n // 1. Check Gemini stream\r\n if ('stream' in stream && 'response' in stream) {\r\n return wrapGeminiStream(stream, options, onComplete);\r\n }\r\n\r\n // 2. Check if stream is an AsyncIterable\r\n if (Symbol.asyncIterator in stream) {\r\n // If provider is explicitly anthropic or stream looks like anthropic events\r\n if (options.provider === 'anthropic') {\r\n return wrapAnthropicStream(stream as any, options, onComplete);\r\n }\r\n // Default to OpenAI stream wrapper which detects usage chunks polymorphically\r\n return wrapOpenAIStream(stream as any, options, onComplete);\r\n }\r\n\r\n return stream;\r\n}\r\n","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":["customerObj"]}
|
package/dist/pricing/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { f as ModelPricingRates, e as InlineRateConfig, I as InferenceCost, T as TokenUsage } from '../types-Mozk4-Mr.mjs';
|
|
2
2
|
import 'stripe';
|
|
3
3
|
|
|
4
4
|
/**
|
package/dist/pricing/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { f as ModelPricingRates, e as InlineRateConfig, I as InferenceCost, T as TokenUsage } from '../types-Mozk4-Mr.js';
|
|
2
2
|
import 'stripe';
|
|
3
3
|
|
|
4
4
|
/**
|
package/dist/react/index.d.mts
CHANGED
package/dist/react/index.d.ts
CHANGED