@ai-billing/core 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -31,6 +31,7 @@ __export(index_exports, {
31
31
  costToNumber: () => costToNumber,
32
32
  createBasePriceResolver: () => createBasePriceResolver,
33
33
  createDestination: () => createDestination,
34
+ createNarevPriceResolver: () => createNarevPriceResolver,
34
35
  createObjectPriceResolver: () => createObjectPriceResolver,
35
36
  createV3BillingMiddleware: () => createV3BillingMiddleware,
36
37
  multiplyCost: () => multiplyCost,
@@ -66,7 +67,7 @@ function createV3BillingMiddleware(options) {
66
67
  providerMetadata,
67
68
  tags
68
69
  });
69
- if (event && destinations.length > 0) {
70
+ if (event && destinations && destinations?.length > 0) {
70
71
  const dispatchDestinationsPromise = Promise.allSettled(
71
72
  destinations.map((d) => Promise.resolve(d(event)))
72
73
  );
@@ -331,6 +332,60 @@ function createBasePriceResolver(handler) {
331
332
  };
332
333
  }
333
334
 
335
+ // src/pricing/narev-price-resolver.ts
336
+ function rowToModelPricing(row) {
337
+ return {
338
+ promptTokens: row["price_prompt"],
339
+ completionTokens: row["price_completion"],
340
+ ...row["price_request"] != null && {
341
+ request: row["price_request"]
342
+ },
343
+ ...row["price_input_cache_read"] != null && {
344
+ inputCacheReadTokens: row["price_input_cache_read"]
345
+ },
346
+ ...row["price_input_cache_write"] != null && {
347
+ inputCacheWriteTokens: row["price_input_cache_write"]
348
+ },
349
+ ...row["price_internal_reasoning"] != null && {
350
+ internalReasoningTokens: row["price_internal_reasoning"]
351
+ },
352
+ ...row["pricing_discount"] != null && {
353
+ discount: row["pricing_discount"]
354
+ }
355
+ };
356
+ }
357
+ function createNarevPriceResolver({
358
+ apiKey,
359
+ apiUrl = "https://narev.ai"
360
+ }) {
361
+ return createBasePriceResolver(
362
+ async ({
363
+ modelId,
364
+ providerId,
365
+ subProviderId
366
+ }) => {
367
+ const params = new URLSearchParams({ model_id: modelId });
368
+ if (providerId) params.set("gateway", providerId);
369
+ if (subProviderId) params.set("provider", subProviderId);
370
+ const url = `${apiUrl}/api/models/pricing?${params}`;
371
+ const headers = apiKey ? { Authorization: `Bearer ${apiKey}` } : {};
372
+ let data;
373
+ try {
374
+ const res = await fetch(url, { headers });
375
+ if (!res.ok) return void 0;
376
+ data = await res.json();
377
+ } catch {
378
+ return void 0;
379
+ }
380
+ if (!data) return void 0;
381
+ const rows = data[modelId];
382
+ const row = rows?.[0];
383
+ if (!row) return void 0;
384
+ return rowToModelPricing(row);
385
+ }
386
+ );
387
+ }
388
+
334
389
  // src/pricing/object-price-resolver.ts
335
390
  function createObjectPriceResolver(pricingMap) {
336
391
  return createBasePriceResolver(({ modelId }) => {
@@ -350,6 +405,7 @@ function createObjectPriceResolver(pricingMap) {
350
405
  costToNumber,
351
406
  createBasePriceResolver,
352
407
  createDestination,
408
+ createNarevPriceResolver,
353
409
  createObjectPriceResolver,
354
410
  createV3BillingMiddleware,
355
411
  multiplyCost,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/event/to-json-object.ts","../src/ai-sdk/language-model-middleware/v3/language-model-v3-base-billing-middleware.ts","../src/error/ai-billing-error.ts","../src/error/extractor-error.ts","../src/error/destination-error.ts","../src/error/cost-error.ts","../src/destination/base-destination.ts","../src/destination/console-destination.ts","../src/cost/convert-cost.ts","../src/cost/op-cost.ts","../src/pricing/base-price-resolver.ts","../src/pricing/object-price-resolver.ts"],"sourcesContent":["export * from './types/index.js';\nexport * from './ai-sdk/index.js';\nexport * from './destination/index.js';\nexport * from './error/index.js';\nexport * from './cost/index.js';\nexport * from './pricing/index.js';\n","import { DefaultTags, BillingEvent } from '../types/index.js';\nimport type { JSONObject } from '@ai-sdk/provider';\n\nexport function toJSONObject(event: BillingEvent<DefaultTags>): JSONObject {\n return event as unknown as JSONObject;\n}\n","import type {\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3Usage,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamPart,\n LanguageModelV3Middleware,\n SharedV3ProviderMetadata,\n} from '@ai-sdk/provider';\nimport type {\n BaseBillingMiddlewareOptions,\n EventBuilder,\n BillingEvent,\n DefaultTags,\n} from '../../../types/index.js';\nimport { toJSONObject } from '../../../event/index.js';\n\nexport interface BuildV3EventPayload<TTags extends DefaultTags = DefaultTags> {\n responseId: string | undefined;\n model: LanguageModelV3;\n usage: LanguageModelV3Usage | undefined;\n providerMetadata: SharedV3ProviderMetadata | undefined;\n tags: TTags;\n}\n\nexport interface BillingMiddlewareV3Options<\n TTags extends DefaultTags = DefaultTags,\n> extends BaseBillingMiddlewareOptions<TTags> {\n buildEvent: EventBuilder<BuildV3EventPayload<TTags>, TTags>;\n}\n\nexport function createV3BillingMiddleware<\n TTags extends DefaultTags = DefaultTags,\n>(options: BillingMiddlewareV3Options<TTags>): LanguageModelV3Middleware {\n const { buildEvent, destinations, defaultTags, waitUntil, onError } = options;\n\n const processEvent = async ({\n model,\n params,\n usage,\n providerMetadata,\n responseId,\n }: {\n model: LanguageModelV3;\n params: LanguageModelV3CallOptions;\n usage: LanguageModelV3Usage | undefined;\n providerMetadata: SharedV3ProviderMetadata | undefined;\n responseId: string | undefined;\n }): Promise<BillingEvent<TTags> | null> => {\n try {\n const requestTags = params.providerOptions?.['ai-billing-tags'];\n\n const tags = {\n ...(defaultTags ?? {}),\n ...(requestTags ?? {}),\n } as TTags;\n\n const event = await buildEvent({\n responseId,\n model,\n usage,\n providerMetadata,\n tags,\n });\n\n if (event && destinations.length > 0) {\n const dispatchDestinationsPromise = Promise.allSettled(\n destinations.map(d => Promise.resolve(d(event))),\n );\n if (waitUntil) waitUntil(dispatchDestinationsPromise);\n }\n return event;\n } catch (err) {\n if (onError) onError(err);\n else console.error('[ai-billing] Core Error:', err);\n return null;\n }\n };\n\n return {\n specificationVersion: 'v3',\n\n wrapGenerate: async ({ doGenerate, model, params }) => {\n const result: LanguageModelV3GenerateResult = await doGenerate();\n\n const event = await processEvent({\n model,\n params,\n usage: result.usage,\n providerMetadata: result.providerMetadata,\n responseId: result.response?.id,\n });\n\n const providerMetadataWithBilling = {\n ...result.providerMetadata,\n } as SharedV3ProviderMetadata;\n\n if (event) {\n providerMetadataWithBilling['ai-billing'] = toJSONObject(event);\n }\n\n return {\n ...result,\n providerMetadata: providerMetadataWithBilling,\n };\n },\n\n wrapStream: async ({ doStream, model, params }) => {\n const { stream, ...rest } = await doStream();\n\n let responseId: string | undefined;\n let usage: LanguageModelV3Usage | undefined;\n let providerMetadata: SharedV3ProviderMetadata | undefined;\n let finishChunk:\n | Extract<LanguageModelV3StreamPart, { type: 'finish' }>\n | undefined;\n\n const billedStream = stream.pipeThrough(\n new TransformStream<\n LanguageModelV3StreamPart,\n LanguageModelV3StreamPart\n >({\n transform(chunk, controller) {\n if (chunk.type === 'text-start') responseId = chunk.id;\n if (chunk.type === 'response-metadata' && !responseId) {\n responseId = chunk.id;\n }\n if (chunk.type === 'finish') {\n usage = chunk.usage;\n providerMetadata = chunk.providerMetadata;\n finishChunk = chunk;\n return; // held until flush\n }\n controller.enqueue(chunk);\n },\n async flush(controller) {\n const event = await processEvent({\n model,\n params,\n usage,\n providerMetadata,\n responseId,\n });\n\n const providerMetadataWithBilling = {\n ...providerMetadata,\n } as SharedV3ProviderMetadata;\n\n if (event) {\n providerMetadataWithBilling['ai-billing'] = toJSONObject(event);\n }\n\n if (finishChunk) {\n controller.enqueue({\n ...finishChunk,\n providerMetadata: providerMetadataWithBilling,\n });\n }\n },\n }),\n );\n\n return { ...rest, stream: billedStream };\n },\n };\n}\n","const marker = 'ai-billing.error';\nconst symbol = Symbol.for(marker);\n\nexport class AIBillingError extends Error {\n private readonly [symbol] = true;\n\n readonly cause?: unknown;\n\n constructor({\n name,\n message,\n cause,\n }: {\n name: string;\n message: string;\n cause?: unknown;\n }) {\n super(message);\n this.name = name;\n this.cause = cause;\n }\n\n static isInstance(error: unknown): error is AIBillingError {\n return AIBillingError.hasMarker(error, marker);\n }\n\n protected static hasMarker(error: unknown, markerString: string): boolean {\n const markerSymbol = Symbol.for(markerString);\n return (\n error != null &&\n typeof error === 'object' &&\n markerSymbol in error &&\n typeof error[markerSymbol] === 'boolean' &&\n error[markerSymbol] === true\n );\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingExtractorError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingExtractorError extends AIBillingError {\n private readonly [symbol] = true;\n\n constructor({\n message = `Failed to extract billing data.`,\n cause,\n }: {\n message?: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is AiBillingExtractorError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingDestinationError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingDestinationError extends AIBillingError {\n private readonly [symbol] = true;\n\n readonly destinationId?: string;\n\n constructor({\n destinationId,\n message = `Failed to process billing data for destination: '${destinationId}'.`,\n cause,\n }: {\n destinationId?: string;\n message?: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n this.destinationId = destinationId;\n }\n\n static isInstance(error: unknown): error is AiBillingDestinationError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingCostError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingCostError extends AIBillingError {\n private readonly [symbol] = true;\n\n constructor({ message, cause }: { message: string; cause?: unknown }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is AiBillingCostError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import type { Destination, BillingEvent, DefaultTags } from '../types/index.js';\nimport { AiBillingDestinationError } from '../error/index.js';\n\nexport function createDestination<TTags extends DefaultTags = DefaultTags>(\n destinationId: string,\n handler: (event: BillingEvent<TTags>) => Promise<void> | void,\n): Destination<TTags> {\n return async (event: BillingEvent<TTags>) => {\n try {\n await handler(event);\n } catch (error) {\n throw new AiBillingDestinationError({\n destinationId,\n cause: error,\n });\n }\n };\n}\n","import { createDestination } from './base-destination.js';\nimport type { DefaultTags, Destination } from '../types/index.js';\nimport { JSONObject } from '@ai-sdk/provider';\n\nexport function consoleDestination<\n TTags extends DefaultTags = DefaultTags,\n>(): Destination<TTags> {\n return createDestination<TTags>('console-logger', event => {\n console.dir(event, {\n depth: null,\n colors: true,\n compact: false,\n });\n });\n}\n","import { AiBillingCostError } from '../index.js';\nimport type { Cost, CostUnit } from '../index.js';\n\nconst getNanos = (cost: Cost): number => {\n switch (cost.unit) {\n case 'base':\n return Math.round(cost.amount * 1_000_000_000);\n case 'cents':\n return Math.round(cost.amount * 10_000_000);\n case 'micros':\n return Math.round(cost.amount * 1_000);\n case 'nanos':\n return Math.round(cost.amount);\n default:\n throw new AiBillingCostError({\n message: `Failed to process cost. Unknown CostUnit: '${String(cost.unit)}'.`,\n });\n }\n};\n\nexport const costToNumber = (cost: Cost, targetUnit: CostUnit): number => {\n const nanos = getNanos(cost);\n\n if (targetUnit === 'nanos') return nanos;\n if (targetUnit === 'micros') return nanos / 1_000;\n if (targetUnit === 'cents') return nanos / 10_000_000;\n return nanos / 1_000_000_000; // base\n};\n\nexport const convertCostUnit = (cost: Cost, targetUnit: CostUnit): Cost => {\n return {\n amount: costToNumber(cost, targetUnit),\n currency: cost.currency,\n unit: targetUnit,\n };\n};\n\nexport const rateToCost = (amount: number = 0): Cost => ({\n amount,\n unit: 'base',\n currency: 'USD',\n});\n","import { Cost } from '../types/index.js';\nimport { AiBillingCostError } from '../index.js';\nimport { convertCostUnit } from './convert-cost.js';\n\nexport const multiplyCost = (cost: Cost, multiplier: number): Cost => {\n const nanosCost = convertCostUnit(cost, 'nanos');\n return {\n ...nanosCost,\n amount: Math.round(nanosCost.amount * multiplier),\n };\n};\n\nexport const addCosts = (...costs: Cost[]): Cost => {\n if (costs.length === 0) {\n return { amount: 0, unit: 'nanos', currency: 'USD' };\n }\n\n const firstCost = costs[0];\n\n if (!firstCost) {\n return { amount: 0, unit: 'nanos', currency: 'USD' };\n }\n\n const baseCurrency = firstCost.currency;\n\n const totalNanos = costs.reduce((sum, currentCost) => {\n if (currentCost.currency !== baseCurrency) {\n throw new AiBillingCostError({\n message: `Currency mismatch: Cannot add ${baseCurrency} to ${currentCost.currency}`,\n });\n }\n return sum + convertCostUnit(currentCost, 'nanos').amount;\n }, 0);\n\n return { amount: totalNanos, unit: 'nanos', currency: baseCurrency };\n};\n\nexport const applyDiscount = (cost: Cost, discount: number): Cost => {\n if (!discount || discount <= 0) return cost;\n\n const nanosCost = convertCostUnit(cost, 'nanos');\n const discountAmount = Math.round(nanosCost.amount * discount);\n\n return {\n ...nanosCost,\n amount: Math.max(0, nanosCost.amount - discountAmount),\n };\n};\n","import type {\n ModelPricing,\n PriceResolver,\n PriceResolverContext,\n} from '../types/index.js';\n\nexport function createBasePriceResolver(\n handler: (\n context: PriceResolverContext,\n ) => ModelPricing | undefined | Promise<ModelPricing | undefined>,\n): PriceResolver {\n return async (context: PriceResolverContext) => {\n return handler(context);\n };\n}\n","import { createBasePriceResolver } from './base-price-resolver.js';\nimport type {\n ModelPricing,\n PriceResolver,\n PriceResolverContext,\n} from '../types/index.js';\n\nexport function createObjectPriceResolver(\n pricingMap: Record<string, ModelPricing>,\n): PriceResolver {\n return createBasePriceResolver(({ modelId }: PriceResolverContext) => {\n return pricingMap[modelId];\n });\n}\n"],"mappings":"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","names":["name","marker","symbol","name","marker","symbol","name","marker","symbol"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/event/to-json-object.ts","../src/ai-sdk/language-model-middleware/v3/language-model-v3-base-billing-middleware.ts","../src/error/ai-billing-error.ts","../src/error/extractor-error.ts","../src/error/destination-error.ts","../src/error/cost-error.ts","../src/destination/base-destination.ts","../src/destination/console-destination.ts","../src/cost/convert-cost.ts","../src/cost/op-cost.ts","../src/pricing/base-price-resolver.ts","../src/pricing/narev-price-resolver.ts","../src/pricing/object-price-resolver.ts"],"sourcesContent":["export * from './types/index.js';\nexport * from './ai-sdk/index.js';\nexport * from './destination/index.js';\nexport * from './error/index.js';\nexport * from './cost/index.js';\nexport * from './pricing/index.js';\n","import { DefaultTags, BillingEvent } from '../types/index.js';\nimport type { JSONObject } from '@ai-sdk/provider';\n\nexport function toJSONObject(event: BillingEvent<DefaultTags>): JSONObject {\n return event as unknown as JSONObject;\n}\n","import type {\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3Usage,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamPart,\n LanguageModelV3Middleware,\n SharedV3ProviderMetadata,\n} from '@ai-sdk/provider';\nimport type {\n BaseBillingMiddlewareOptions,\n EventBuilder,\n BillingEvent,\n DefaultTags,\n} from '../../../types/index.js';\nimport { toJSONObject } from '../../../event/index.js';\n\nexport interface BuildV3EventPayload<TTags extends DefaultTags = DefaultTags> {\n responseId: string | undefined;\n model: LanguageModelV3;\n usage: LanguageModelV3Usage | undefined;\n providerMetadata: SharedV3ProviderMetadata | undefined;\n tags: TTags;\n}\n\nexport interface BillingMiddlewareV3Options<\n TTags extends DefaultTags = DefaultTags,\n> extends BaseBillingMiddlewareOptions<TTags> {\n buildEvent: EventBuilder<BuildV3EventPayload<TTags>, TTags>;\n}\n\nexport function createV3BillingMiddleware<\n TTags extends DefaultTags = DefaultTags,\n>(options: BillingMiddlewareV3Options<TTags>): LanguageModelV3Middleware {\n const { buildEvent, destinations, defaultTags, waitUntil, onError } = options;\n\n const processEvent = async ({\n model,\n params,\n usage,\n providerMetadata,\n responseId,\n }: {\n model: LanguageModelV3;\n params: LanguageModelV3CallOptions;\n usage: LanguageModelV3Usage | undefined;\n providerMetadata: SharedV3ProviderMetadata | undefined;\n responseId: string | undefined;\n }): Promise<BillingEvent<TTags> | null> => {\n try {\n const requestTags = params.providerOptions?.['ai-billing-tags'];\n\n const tags = {\n ...(defaultTags ?? {}),\n ...(requestTags ?? {}),\n } as TTags;\n\n const event = await buildEvent({\n responseId,\n model,\n usage,\n providerMetadata,\n tags,\n });\n\n if (event && destinations && destinations?.length > 0) {\n const dispatchDestinationsPromise = Promise.allSettled(\n destinations.map(d => Promise.resolve(d(event))),\n );\n if (waitUntil) waitUntil(dispatchDestinationsPromise);\n }\n return event;\n } catch (err) {\n if (onError) onError(err);\n else console.error('[ai-billing] Core Error:', err);\n return null;\n }\n };\n\n return {\n specificationVersion: 'v3',\n\n wrapGenerate: async ({ doGenerate, model, params }) => {\n const result: LanguageModelV3GenerateResult = await doGenerate();\n\n const event = await processEvent({\n model,\n params,\n usage: result.usage,\n providerMetadata: result.providerMetadata,\n responseId: result.response?.id,\n });\n\n const providerMetadataWithBilling = {\n ...result.providerMetadata,\n } as SharedV3ProviderMetadata;\n\n if (event) {\n providerMetadataWithBilling['ai-billing'] = toJSONObject(event);\n }\n\n return {\n ...result,\n providerMetadata: providerMetadataWithBilling,\n };\n },\n\n wrapStream: async ({ doStream, model, params }) => {\n const { stream, ...rest } = await doStream();\n\n let responseId: string | undefined;\n let usage: LanguageModelV3Usage | undefined;\n let providerMetadata: SharedV3ProviderMetadata | undefined;\n let finishChunk:\n | Extract<LanguageModelV3StreamPart, { type: 'finish' }>\n | undefined;\n\n const billedStream = stream.pipeThrough(\n new TransformStream<\n LanguageModelV3StreamPart,\n LanguageModelV3StreamPart\n >({\n transform(chunk, controller) {\n if (chunk.type === 'text-start') responseId = chunk.id;\n if (chunk.type === 'response-metadata' && !responseId) {\n responseId = chunk.id;\n }\n if (chunk.type === 'finish') {\n usage = chunk.usage;\n providerMetadata = chunk.providerMetadata;\n finishChunk = chunk;\n return; // held until flush\n }\n controller.enqueue(chunk);\n },\n async flush(controller) {\n const event = await processEvent({\n model,\n params,\n usage,\n providerMetadata,\n responseId,\n });\n\n const providerMetadataWithBilling = {\n ...providerMetadata,\n } as SharedV3ProviderMetadata;\n\n if (event) {\n providerMetadataWithBilling['ai-billing'] = toJSONObject(event);\n }\n\n if (finishChunk) {\n controller.enqueue({\n ...finishChunk,\n providerMetadata: providerMetadataWithBilling,\n });\n }\n },\n }),\n );\n\n return { ...rest, stream: billedStream };\n },\n };\n}\n","const marker = 'ai-billing.error';\nconst symbol = Symbol.for(marker);\n\nexport class AIBillingError extends Error {\n private readonly [symbol] = true;\n\n readonly cause?: unknown;\n\n constructor({\n name,\n message,\n cause,\n }: {\n name: string;\n message: string;\n cause?: unknown;\n }) {\n super(message);\n this.name = name;\n this.cause = cause;\n }\n\n static isInstance(error: unknown): error is AIBillingError {\n return AIBillingError.hasMarker(error, marker);\n }\n\n protected static hasMarker(error: unknown, markerString: string): boolean {\n const markerSymbol = Symbol.for(markerString);\n return (\n error != null &&\n typeof error === 'object' &&\n markerSymbol in error &&\n typeof error[markerSymbol] === 'boolean' &&\n error[markerSymbol] === true\n );\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingExtractorError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingExtractorError extends AIBillingError {\n private readonly [symbol] = true;\n\n constructor({\n message = `Failed to extract billing data.`,\n cause,\n }: {\n message?: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is AiBillingExtractorError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingDestinationError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingDestinationError extends AIBillingError {\n private readonly [symbol] = true;\n\n readonly destinationId?: string;\n\n constructor({\n destinationId,\n message = `Failed to process billing data for destination: '${destinationId}'.`,\n cause,\n }: {\n destinationId?: string;\n message?: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n this.destinationId = destinationId;\n }\n\n static isInstance(error: unknown): error is AiBillingDestinationError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingCostError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingCostError extends AIBillingError {\n private readonly [symbol] = true;\n\n constructor({ message, cause }: { message: string; cause?: unknown }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is AiBillingCostError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import type { Destination, BillingEvent, DefaultTags } from '../types/index.js';\nimport { AiBillingDestinationError } from '../error/index.js';\n\nexport function createDestination<TTags extends DefaultTags = DefaultTags>(\n destinationId: string,\n handler: (event: BillingEvent<TTags>) => Promise<void> | void,\n): Destination<TTags> {\n return async (event: BillingEvent<TTags>) => {\n try {\n await handler(event);\n } catch (error) {\n throw new AiBillingDestinationError({\n destinationId,\n cause: error,\n });\n }\n };\n}\n","import { createDestination } from './base-destination.js';\nimport type { DefaultTags, Destination } from '../types/index.js';\nimport { JSONObject } from '@ai-sdk/provider';\n\nexport function consoleDestination<\n TTags extends DefaultTags = DefaultTags,\n>(): Destination<TTags> {\n return createDestination<TTags>('console-logger', event => {\n console.dir(event, {\n depth: null,\n colors: true,\n compact: false,\n });\n });\n}\n","import { AiBillingCostError } from '../index.js';\nimport type { Cost, CostUnit } from '../index.js';\n\nconst getNanos = (cost: Cost): number => {\n switch (cost.unit) {\n case 'base':\n return Math.round(cost.amount * 1_000_000_000);\n case 'cents':\n return Math.round(cost.amount * 10_000_000);\n case 'micros':\n return Math.round(cost.amount * 1_000);\n case 'nanos':\n return Math.round(cost.amount);\n default:\n throw new AiBillingCostError({\n message: `Failed to process cost. Unknown CostUnit: '${String(cost.unit)}'.`,\n });\n }\n};\n\nexport const costToNumber = (cost: Cost, targetUnit: CostUnit): number => {\n const nanos = getNanos(cost);\n\n if (targetUnit === 'nanos') return nanos;\n if (targetUnit === 'micros') return nanos / 1_000;\n if (targetUnit === 'cents') return nanos / 10_000_000;\n return nanos / 1_000_000_000; // base\n};\n\nexport const convertCostUnit = (cost: Cost, targetUnit: CostUnit): Cost => {\n return {\n amount: costToNumber(cost, targetUnit),\n currency: cost.currency,\n unit: targetUnit,\n };\n};\n\nexport const rateToCost = (amount: number = 0): Cost => ({\n amount,\n unit: 'base',\n currency: 'USD',\n});\n","import { Cost } from '../types/index.js';\nimport { AiBillingCostError } from '../index.js';\nimport { convertCostUnit } from './convert-cost.js';\n\nexport const multiplyCost = (cost: Cost, multiplier: number): Cost => {\n const nanosCost = convertCostUnit(cost, 'nanos');\n return {\n ...nanosCost,\n amount: Math.round(nanosCost.amount * multiplier),\n };\n};\n\nexport const addCosts = (...costs: Cost[]): Cost => {\n if (costs.length === 0) {\n return { amount: 0, unit: 'nanos', currency: 'USD' };\n }\n\n const firstCost = costs[0];\n\n if (!firstCost) {\n return { amount: 0, unit: 'nanos', currency: 'USD' };\n }\n\n const baseCurrency = firstCost.currency;\n\n const totalNanos = costs.reduce((sum, currentCost) => {\n if (currentCost.currency !== baseCurrency) {\n throw new AiBillingCostError({\n message: `Currency mismatch: Cannot add ${baseCurrency} to ${currentCost.currency}`,\n });\n }\n return sum + convertCostUnit(currentCost, 'nanos').amount;\n }, 0);\n\n return { amount: totalNanos, unit: 'nanos', currency: baseCurrency };\n};\n\nexport const applyDiscount = (cost: Cost, discount: number): Cost => {\n if (!discount || discount <= 0) return cost;\n\n const nanosCost = convertCostUnit(cost, 'nanos');\n const discountAmount = Math.round(nanosCost.amount * discount);\n\n return {\n ...nanosCost,\n amount: Math.max(0, nanosCost.amount - discountAmount),\n };\n};\n","import type {\n ModelPricing,\n PriceResolver,\n PriceResolverContext,\n} from '../types/index.js';\n\nexport function createBasePriceResolver(\n handler: (\n context: PriceResolverContext,\n ) => ModelPricing | undefined | Promise<ModelPricing | undefined>,\n): PriceResolver {\n return async (context: PriceResolverContext) => {\n return handler(context);\n };\n}\n","import { createBasePriceResolver } from './base-price-resolver.js';\nimport type { ModelPricing, PriceResolverContext } from '../types/index.js';\n\ntype PricingRow = Record<string, number | string>;\ntype PricingMap = Record<string, PricingRow[]>;\n\nfunction rowToModelPricing(row: PricingRow): ModelPricing {\n return {\n promptTokens: row['price_prompt'] as number,\n completionTokens: row['price_completion'] as number,\n ...(row['price_request'] != null && {\n request: row['price_request'] as number,\n }),\n ...(row['price_input_cache_read'] != null && {\n inputCacheReadTokens: row['price_input_cache_read'] as number,\n }),\n ...(row['price_input_cache_write'] != null && {\n inputCacheWriteTokens: row['price_input_cache_write'] as number,\n }),\n ...(row['price_internal_reasoning'] != null && {\n internalReasoningTokens: row['price_internal_reasoning'] as number,\n }),\n ...(row['pricing_discount'] != null && {\n discount: row['pricing_discount'] as number,\n }),\n };\n}\n\nexport type NarevPriceResolverOptions = {\n apiKey: string;\n apiUrl?: string;\n};\n\nexport function createNarevPriceResolver({\n apiKey,\n apiUrl = 'https://narev.ai',\n}: NarevPriceResolverOptions): ReturnType<typeof createBasePriceResolver> {\n return createBasePriceResolver(\n async ({\n modelId,\n providerId,\n subProviderId,\n }: PriceResolverContext): Promise<ModelPricing | undefined> => {\n const params = new URLSearchParams({ model_id: modelId });\n if (providerId) params.set('gateway', providerId);\n if (subProviderId) params.set('provider', subProviderId);\n\n const url = `${apiUrl}/api/models/pricing?${params}`;\n const headers: Record<string, string> = apiKey\n ? { Authorization: `Bearer ${apiKey}` }\n : {};\n\n let data: PricingMap | null;\n try {\n const res = await fetch(url, { headers });\n if (!res.ok) return undefined;\n data = (await res.json()) as PricingMap | null;\n } catch {\n return undefined;\n }\n\n if (!data) return undefined;\n\n const rows = data[modelId];\n const row = rows?.[0];\n if (!row) return undefined;\n\n return rowToModelPricing(row);\n },\n );\n}\n","import { createBasePriceResolver } from './base-price-resolver.js';\nimport type {\n ModelPricing,\n PriceResolver,\n PriceResolverContext,\n} from '../types/index.js';\n\nexport function createObjectPriceResolver(\n pricingMap: Record<string, ModelPricing>,\n): PriceResolver {\n return createBasePriceResolver(({ modelId }: PriceResolverContext) => {\n return pricingMap[modelId];\n });\n}\n"],"mappings":"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","names":["name","marker","symbol","name","marker","symbol","name","marker","symbol"]}
package/dist/index.d.cts CHANGED
@@ -12,6 +12,7 @@ interface Usage {
12
12
  readonly cacheWriteTokens?: number;
13
13
  readonly requestCount?: number;
14
14
  readonly rawProviderCost?: number;
15
+ readonly rawUpstreamInferenceCost?: number;
15
16
  }
16
17
  interface BillingEvent<TTags extends DefaultTags = DefaultTags> {
17
18
  readonly generationId: string;
@@ -25,7 +26,7 @@ type EventBuilder<TPayload, TTags extends DefaultTags = DefaultTags> = (payload:
25
26
 
26
27
  type DefaultTags = JSONObject;
27
28
  interface BaseBillingMiddlewareOptions<TTags extends JSONObject = DefaultTags> {
28
- destinations: Destination<TTags>[];
29
+ destinations?: Destination<TTags>[];
29
30
  defaultTags?: TTags;
30
31
  waitUntil?: (promise: Promise<unknown>) => void;
31
32
  onError?: (error: unknown) => void;
@@ -126,6 +127,12 @@ declare const applyDiscount: (cost: Cost, discount: number) => Cost;
126
127
 
127
128
  declare function createBasePriceResolver(handler: (context: PriceResolverContext) => ModelPricing | undefined | Promise<ModelPricing | undefined>): PriceResolver;
128
129
 
130
+ type NarevPriceResolverOptions = {
131
+ apiKey: string;
132
+ apiUrl?: string;
133
+ };
134
+ declare function createNarevPriceResolver({ apiKey, apiUrl, }: NarevPriceResolverOptions): ReturnType<typeof createBasePriceResolver>;
135
+
129
136
  declare function createObjectPriceResolver(pricingMap: Record<string, ModelPricing>): PriceResolver;
130
137
 
131
- export { AIBillingError, AiBillingCostError, AiBillingDestinationError, AiBillingExtractorError, type BaseBillingMiddlewareOptions, type BillingEvent, type BillingMiddlewareV3Options, type BuildV3EventPayload, type Cost, type CostUnit, type DefaultTags, type Destination, type EventBuilder, type ModelPricing, type PriceResolver, type PriceResolverContext, type Usage, addCosts, applyDiscount, consoleDestination, convertCostUnit, costToNumber, createBasePriceResolver, createDestination, createObjectPriceResolver, createV3BillingMiddleware, multiplyCost, rateToCost };
138
+ export { AIBillingError, AiBillingCostError, AiBillingDestinationError, AiBillingExtractorError, type BaseBillingMiddlewareOptions, type BillingEvent, type BillingMiddlewareV3Options, type BuildV3EventPayload, type Cost, type CostUnit, type DefaultTags, type Destination, type EventBuilder, type ModelPricing, type NarevPriceResolverOptions, type PriceResolver, type PriceResolverContext, type Usage, addCosts, applyDiscount, consoleDestination, convertCostUnit, costToNumber, createBasePriceResolver, createDestination, createNarevPriceResolver, createObjectPriceResolver, createV3BillingMiddleware, multiplyCost, rateToCost };
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ interface Usage {
12
12
  readonly cacheWriteTokens?: number;
13
13
  readonly requestCount?: number;
14
14
  readonly rawProviderCost?: number;
15
+ readonly rawUpstreamInferenceCost?: number;
15
16
  }
16
17
  interface BillingEvent<TTags extends DefaultTags = DefaultTags> {
17
18
  readonly generationId: string;
@@ -25,7 +26,7 @@ type EventBuilder<TPayload, TTags extends DefaultTags = DefaultTags> = (payload:
25
26
 
26
27
  type DefaultTags = JSONObject;
27
28
  interface BaseBillingMiddlewareOptions<TTags extends JSONObject = DefaultTags> {
28
- destinations: Destination<TTags>[];
29
+ destinations?: Destination<TTags>[];
29
30
  defaultTags?: TTags;
30
31
  waitUntil?: (promise: Promise<unknown>) => void;
31
32
  onError?: (error: unknown) => void;
@@ -126,6 +127,12 @@ declare const applyDiscount: (cost: Cost, discount: number) => Cost;
126
127
 
127
128
  declare function createBasePriceResolver(handler: (context: PriceResolverContext) => ModelPricing | undefined | Promise<ModelPricing | undefined>): PriceResolver;
128
129
 
130
+ type NarevPriceResolverOptions = {
131
+ apiKey: string;
132
+ apiUrl?: string;
133
+ };
134
+ declare function createNarevPriceResolver({ apiKey, apiUrl, }: NarevPriceResolverOptions): ReturnType<typeof createBasePriceResolver>;
135
+
129
136
  declare function createObjectPriceResolver(pricingMap: Record<string, ModelPricing>): PriceResolver;
130
137
 
131
- export { AIBillingError, AiBillingCostError, AiBillingDestinationError, AiBillingExtractorError, type BaseBillingMiddlewareOptions, type BillingEvent, type BillingMiddlewareV3Options, type BuildV3EventPayload, type Cost, type CostUnit, type DefaultTags, type Destination, type EventBuilder, type ModelPricing, type PriceResolver, type PriceResolverContext, type Usage, addCosts, applyDiscount, consoleDestination, convertCostUnit, costToNumber, createBasePriceResolver, createDestination, createObjectPriceResolver, createV3BillingMiddleware, multiplyCost, rateToCost };
138
+ export { AIBillingError, AiBillingCostError, AiBillingDestinationError, AiBillingExtractorError, type BaseBillingMiddlewareOptions, type BillingEvent, type BillingMiddlewareV3Options, type BuildV3EventPayload, type Cost, type CostUnit, type DefaultTags, type Destination, type EventBuilder, type ModelPricing, type NarevPriceResolverOptions, type PriceResolver, type PriceResolverContext, type Usage, addCosts, applyDiscount, consoleDestination, convertCostUnit, costToNumber, createBasePriceResolver, createDestination, createNarevPriceResolver, createObjectPriceResolver, createV3BillingMiddleware, multiplyCost, rateToCost };
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ function createV3BillingMiddleware(options) {
26
26
  providerMetadata,
27
27
  tags
28
28
  });
29
- if (event && destinations.length > 0) {
29
+ if (event && destinations && destinations?.length > 0) {
30
30
  const dispatchDestinationsPromise = Promise.allSettled(
31
31
  destinations.map((d) => Promise.resolve(d(event)))
32
32
  );
@@ -291,6 +291,60 @@ function createBasePriceResolver(handler) {
291
291
  };
292
292
  }
293
293
 
294
+ // src/pricing/narev-price-resolver.ts
295
+ function rowToModelPricing(row) {
296
+ return {
297
+ promptTokens: row["price_prompt"],
298
+ completionTokens: row["price_completion"],
299
+ ...row["price_request"] != null && {
300
+ request: row["price_request"]
301
+ },
302
+ ...row["price_input_cache_read"] != null && {
303
+ inputCacheReadTokens: row["price_input_cache_read"]
304
+ },
305
+ ...row["price_input_cache_write"] != null && {
306
+ inputCacheWriteTokens: row["price_input_cache_write"]
307
+ },
308
+ ...row["price_internal_reasoning"] != null && {
309
+ internalReasoningTokens: row["price_internal_reasoning"]
310
+ },
311
+ ...row["pricing_discount"] != null && {
312
+ discount: row["pricing_discount"]
313
+ }
314
+ };
315
+ }
316
+ function createNarevPriceResolver({
317
+ apiKey,
318
+ apiUrl = "https://narev.ai"
319
+ }) {
320
+ return createBasePriceResolver(
321
+ async ({
322
+ modelId,
323
+ providerId,
324
+ subProviderId
325
+ }) => {
326
+ const params = new URLSearchParams({ model_id: modelId });
327
+ if (providerId) params.set("gateway", providerId);
328
+ if (subProviderId) params.set("provider", subProviderId);
329
+ const url = `${apiUrl}/api/models/pricing?${params}`;
330
+ const headers = apiKey ? { Authorization: `Bearer ${apiKey}` } : {};
331
+ let data;
332
+ try {
333
+ const res = await fetch(url, { headers });
334
+ if (!res.ok) return void 0;
335
+ data = await res.json();
336
+ } catch {
337
+ return void 0;
338
+ }
339
+ if (!data) return void 0;
340
+ const rows = data[modelId];
341
+ const row = rows?.[0];
342
+ if (!row) return void 0;
343
+ return rowToModelPricing(row);
344
+ }
345
+ );
346
+ }
347
+
294
348
  // src/pricing/object-price-resolver.ts
295
349
  function createObjectPriceResolver(pricingMap) {
296
350
  return createBasePriceResolver(({ modelId }) => {
@@ -309,6 +363,7 @@ export {
309
363
  costToNumber,
310
364
  createBasePriceResolver,
311
365
  createDestination,
366
+ createNarevPriceResolver,
312
367
  createObjectPriceResolver,
313
368
  createV3BillingMiddleware,
314
369
  multiplyCost,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/event/to-json-object.ts","../src/ai-sdk/language-model-middleware/v3/language-model-v3-base-billing-middleware.ts","../src/error/ai-billing-error.ts","../src/error/extractor-error.ts","../src/error/destination-error.ts","../src/error/cost-error.ts","../src/destination/base-destination.ts","../src/destination/console-destination.ts","../src/cost/convert-cost.ts","../src/cost/op-cost.ts","../src/pricing/base-price-resolver.ts","../src/pricing/object-price-resolver.ts"],"sourcesContent":["import { DefaultTags, BillingEvent } from '../types/index.js';\nimport type { JSONObject } from '@ai-sdk/provider';\n\nexport function toJSONObject(event: BillingEvent<DefaultTags>): JSONObject {\n return event as unknown as JSONObject;\n}\n","import type {\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3Usage,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamPart,\n LanguageModelV3Middleware,\n SharedV3ProviderMetadata,\n} from '@ai-sdk/provider';\nimport type {\n BaseBillingMiddlewareOptions,\n EventBuilder,\n BillingEvent,\n DefaultTags,\n} from '../../../types/index.js';\nimport { toJSONObject } from '../../../event/index.js';\n\nexport interface BuildV3EventPayload<TTags extends DefaultTags = DefaultTags> {\n responseId: string | undefined;\n model: LanguageModelV3;\n usage: LanguageModelV3Usage | undefined;\n providerMetadata: SharedV3ProviderMetadata | undefined;\n tags: TTags;\n}\n\nexport interface BillingMiddlewareV3Options<\n TTags extends DefaultTags = DefaultTags,\n> extends BaseBillingMiddlewareOptions<TTags> {\n buildEvent: EventBuilder<BuildV3EventPayload<TTags>, TTags>;\n}\n\nexport function createV3BillingMiddleware<\n TTags extends DefaultTags = DefaultTags,\n>(options: BillingMiddlewareV3Options<TTags>): LanguageModelV3Middleware {\n const { buildEvent, destinations, defaultTags, waitUntil, onError } = options;\n\n const processEvent = async ({\n model,\n params,\n usage,\n providerMetadata,\n responseId,\n }: {\n model: LanguageModelV3;\n params: LanguageModelV3CallOptions;\n usage: LanguageModelV3Usage | undefined;\n providerMetadata: SharedV3ProviderMetadata | undefined;\n responseId: string | undefined;\n }): Promise<BillingEvent<TTags> | null> => {\n try {\n const requestTags = params.providerOptions?.['ai-billing-tags'];\n\n const tags = {\n ...(defaultTags ?? {}),\n ...(requestTags ?? {}),\n } as TTags;\n\n const event = await buildEvent({\n responseId,\n model,\n usage,\n providerMetadata,\n tags,\n });\n\n if (event && destinations.length > 0) {\n const dispatchDestinationsPromise = Promise.allSettled(\n destinations.map(d => Promise.resolve(d(event))),\n );\n if (waitUntil) waitUntil(dispatchDestinationsPromise);\n }\n return event;\n } catch (err) {\n if (onError) onError(err);\n else console.error('[ai-billing] Core Error:', err);\n return null;\n }\n };\n\n return {\n specificationVersion: 'v3',\n\n wrapGenerate: async ({ doGenerate, model, params }) => {\n const result: LanguageModelV3GenerateResult = await doGenerate();\n\n const event = await processEvent({\n model,\n params,\n usage: result.usage,\n providerMetadata: result.providerMetadata,\n responseId: result.response?.id,\n });\n\n const providerMetadataWithBilling = {\n ...result.providerMetadata,\n } as SharedV3ProviderMetadata;\n\n if (event) {\n providerMetadataWithBilling['ai-billing'] = toJSONObject(event);\n }\n\n return {\n ...result,\n providerMetadata: providerMetadataWithBilling,\n };\n },\n\n wrapStream: async ({ doStream, model, params }) => {\n const { stream, ...rest } = await doStream();\n\n let responseId: string | undefined;\n let usage: LanguageModelV3Usage | undefined;\n let providerMetadata: SharedV3ProviderMetadata | undefined;\n let finishChunk:\n | Extract<LanguageModelV3StreamPart, { type: 'finish' }>\n | undefined;\n\n const billedStream = stream.pipeThrough(\n new TransformStream<\n LanguageModelV3StreamPart,\n LanguageModelV3StreamPart\n >({\n transform(chunk, controller) {\n if (chunk.type === 'text-start') responseId = chunk.id;\n if (chunk.type === 'response-metadata' && !responseId) {\n responseId = chunk.id;\n }\n if (chunk.type === 'finish') {\n usage = chunk.usage;\n providerMetadata = chunk.providerMetadata;\n finishChunk = chunk;\n return; // held until flush\n }\n controller.enqueue(chunk);\n },\n async flush(controller) {\n const event = await processEvent({\n model,\n params,\n usage,\n providerMetadata,\n responseId,\n });\n\n const providerMetadataWithBilling = {\n ...providerMetadata,\n } as SharedV3ProviderMetadata;\n\n if (event) {\n providerMetadataWithBilling['ai-billing'] = toJSONObject(event);\n }\n\n if (finishChunk) {\n controller.enqueue({\n ...finishChunk,\n providerMetadata: providerMetadataWithBilling,\n });\n }\n },\n }),\n );\n\n return { ...rest, stream: billedStream };\n },\n };\n}\n","const marker = 'ai-billing.error';\nconst symbol = Symbol.for(marker);\n\nexport class AIBillingError extends Error {\n private readonly [symbol] = true;\n\n readonly cause?: unknown;\n\n constructor({\n name,\n message,\n cause,\n }: {\n name: string;\n message: string;\n cause?: unknown;\n }) {\n super(message);\n this.name = name;\n this.cause = cause;\n }\n\n static isInstance(error: unknown): error is AIBillingError {\n return AIBillingError.hasMarker(error, marker);\n }\n\n protected static hasMarker(error: unknown, markerString: string): boolean {\n const markerSymbol = Symbol.for(markerString);\n return (\n error != null &&\n typeof error === 'object' &&\n markerSymbol in error &&\n typeof error[markerSymbol] === 'boolean' &&\n error[markerSymbol] === true\n );\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingExtractorError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingExtractorError extends AIBillingError {\n private readonly [symbol] = true;\n\n constructor({\n message = `Failed to extract billing data.`,\n cause,\n }: {\n message?: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is AiBillingExtractorError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingDestinationError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingDestinationError extends AIBillingError {\n private readonly [symbol] = true;\n\n readonly destinationId?: string;\n\n constructor({\n destinationId,\n message = `Failed to process billing data for destination: '${destinationId}'.`,\n cause,\n }: {\n destinationId?: string;\n message?: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n this.destinationId = destinationId;\n }\n\n static isInstance(error: unknown): error is AiBillingDestinationError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingCostError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingCostError extends AIBillingError {\n private readonly [symbol] = true;\n\n constructor({ message, cause }: { message: string; cause?: unknown }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is AiBillingCostError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import type { Destination, BillingEvent, DefaultTags } from '../types/index.js';\nimport { AiBillingDestinationError } from '../error/index.js';\n\nexport function createDestination<TTags extends DefaultTags = DefaultTags>(\n destinationId: string,\n handler: (event: BillingEvent<TTags>) => Promise<void> | void,\n): Destination<TTags> {\n return async (event: BillingEvent<TTags>) => {\n try {\n await handler(event);\n } catch (error) {\n throw new AiBillingDestinationError({\n destinationId,\n cause: error,\n });\n }\n };\n}\n","import { createDestination } from './base-destination.js';\nimport type { DefaultTags, Destination } from '../types/index.js';\nimport { JSONObject } from '@ai-sdk/provider';\n\nexport function consoleDestination<\n TTags extends DefaultTags = DefaultTags,\n>(): Destination<TTags> {\n return createDestination<TTags>('console-logger', event => {\n console.dir(event, {\n depth: null,\n colors: true,\n compact: false,\n });\n });\n}\n","import { AiBillingCostError } from '../index.js';\nimport type { Cost, CostUnit } from '../index.js';\n\nconst getNanos = (cost: Cost): number => {\n switch (cost.unit) {\n case 'base':\n return Math.round(cost.amount * 1_000_000_000);\n case 'cents':\n return Math.round(cost.amount * 10_000_000);\n case 'micros':\n return Math.round(cost.amount * 1_000);\n case 'nanos':\n return Math.round(cost.amount);\n default:\n throw new AiBillingCostError({\n message: `Failed to process cost. Unknown CostUnit: '${String(cost.unit)}'.`,\n });\n }\n};\n\nexport const costToNumber = (cost: Cost, targetUnit: CostUnit): number => {\n const nanos = getNanos(cost);\n\n if (targetUnit === 'nanos') return nanos;\n if (targetUnit === 'micros') return nanos / 1_000;\n if (targetUnit === 'cents') return nanos / 10_000_000;\n return nanos / 1_000_000_000; // base\n};\n\nexport const convertCostUnit = (cost: Cost, targetUnit: CostUnit): Cost => {\n return {\n amount: costToNumber(cost, targetUnit),\n currency: cost.currency,\n unit: targetUnit,\n };\n};\n\nexport const rateToCost = (amount: number = 0): Cost => ({\n amount,\n unit: 'base',\n currency: 'USD',\n});\n","import { Cost } from '../types/index.js';\nimport { AiBillingCostError } from '../index.js';\nimport { convertCostUnit } from './convert-cost.js';\n\nexport const multiplyCost = (cost: Cost, multiplier: number): Cost => {\n const nanosCost = convertCostUnit(cost, 'nanos');\n return {\n ...nanosCost,\n amount: Math.round(nanosCost.amount * multiplier),\n };\n};\n\nexport const addCosts = (...costs: Cost[]): Cost => {\n if (costs.length === 0) {\n return { amount: 0, unit: 'nanos', currency: 'USD' };\n }\n\n const firstCost = costs[0];\n\n if (!firstCost) {\n return { amount: 0, unit: 'nanos', currency: 'USD' };\n }\n\n const baseCurrency = firstCost.currency;\n\n const totalNanos = costs.reduce((sum, currentCost) => {\n if (currentCost.currency !== baseCurrency) {\n throw new AiBillingCostError({\n message: `Currency mismatch: Cannot add ${baseCurrency} to ${currentCost.currency}`,\n });\n }\n return sum + convertCostUnit(currentCost, 'nanos').amount;\n }, 0);\n\n return { amount: totalNanos, unit: 'nanos', currency: baseCurrency };\n};\n\nexport const applyDiscount = (cost: Cost, discount: number): Cost => {\n if (!discount || discount <= 0) return cost;\n\n const nanosCost = convertCostUnit(cost, 'nanos');\n const discountAmount = Math.round(nanosCost.amount * discount);\n\n return {\n ...nanosCost,\n amount: Math.max(0, nanosCost.amount - discountAmount),\n };\n};\n","import type {\n ModelPricing,\n PriceResolver,\n PriceResolverContext,\n} from '../types/index.js';\n\nexport function createBasePriceResolver(\n handler: (\n context: PriceResolverContext,\n ) => ModelPricing | undefined | Promise<ModelPricing | undefined>,\n): PriceResolver {\n return async (context: PriceResolverContext) => {\n return handler(context);\n };\n}\n","import { createBasePriceResolver } from './base-price-resolver.js';\nimport type {\n ModelPricing,\n PriceResolver,\n PriceResolverContext,\n} from '../types/index.js';\n\nexport function createObjectPriceResolver(\n pricingMap: Record<string, ModelPricing>,\n): PriceResolver {\n return createBasePriceResolver(({ modelId }: PriceResolverContext) => {\n return pricingMap[modelId];\n });\n}\n"],"mappings":"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","names":["name","marker","symbol","name","marker","symbol","name","marker","symbol"]}
1
+ {"version":3,"sources":["../src/event/to-json-object.ts","../src/ai-sdk/language-model-middleware/v3/language-model-v3-base-billing-middleware.ts","../src/error/ai-billing-error.ts","../src/error/extractor-error.ts","../src/error/destination-error.ts","../src/error/cost-error.ts","../src/destination/base-destination.ts","../src/destination/console-destination.ts","../src/cost/convert-cost.ts","../src/cost/op-cost.ts","../src/pricing/base-price-resolver.ts","../src/pricing/narev-price-resolver.ts","../src/pricing/object-price-resolver.ts"],"sourcesContent":["import { DefaultTags, BillingEvent } from '../types/index.js';\nimport type { JSONObject } from '@ai-sdk/provider';\n\nexport function toJSONObject(event: BillingEvent<DefaultTags>): JSONObject {\n return event as unknown as JSONObject;\n}\n","import type {\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3Usage,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamPart,\n LanguageModelV3Middleware,\n SharedV3ProviderMetadata,\n} from '@ai-sdk/provider';\nimport type {\n BaseBillingMiddlewareOptions,\n EventBuilder,\n BillingEvent,\n DefaultTags,\n} from '../../../types/index.js';\nimport { toJSONObject } from '../../../event/index.js';\n\nexport interface BuildV3EventPayload<TTags extends DefaultTags = DefaultTags> {\n responseId: string | undefined;\n model: LanguageModelV3;\n usage: LanguageModelV3Usage | undefined;\n providerMetadata: SharedV3ProviderMetadata | undefined;\n tags: TTags;\n}\n\nexport interface BillingMiddlewareV3Options<\n TTags extends DefaultTags = DefaultTags,\n> extends BaseBillingMiddlewareOptions<TTags> {\n buildEvent: EventBuilder<BuildV3EventPayload<TTags>, TTags>;\n}\n\nexport function createV3BillingMiddleware<\n TTags extends DefaultTags = DefaultTags,\n>(options: BillingMiddlewareV3Options<TTags>): LanguageModelV3Middleware {\n const { buildEvent, destinations, defaultTags, waitUntil, onError } = options;\n\n const processEvent = async ({\n model,\n params,\n usage,\n providerMetadata,\n responseId,\n }: {\n model: LanguageModelV3;\n params: LanguageModelV3CallOptions;\n usage: LanguageModelV3Usage | undefined;\n providerMetadata: SharedV3ProviderMetadata | undefined;\n responseId: string | undefined;\n }): Promise<BillingEvent<TTags> | null> => {\n try {\n const requestTags = params.providerOptions?.['ai-billing-tags'];\n\n const tags = {\n ...(defaultTags ?? {}),\n ...(requestTags ?? {}),\n } as TTags;\n\n const event = await buildEvent({\n responseId,\n model,\n usage,\n providerMetadata,\n tags,\n });\n\n if (event && destinations && destinations?.length > 0) {\n const dispatchDestinationsPromise = Promise.allSettled(\n destinations.map(d => Promise.resolve(d(event))),\n );\n if (waitUntil) waitUntil(dispatchDestinationsPromise);\n }\n return event;\n } catch (err) {\n if (onError) onError(err);\n else console.error('[ai-billing] Core Error:', err);\n return null;\n }\n };\n\n return {\n specificationVersion: 'v3',\n\n wrapGenerate: async ({ doGenerate, model, params }) => {\n const result: LanguageModelV3GenerateResult = await doGenerate();\n\n const event = await processEvent({\n model,\n params,\n usage: result.usage,\n providerMetadata: result.providerMetadata,\n responseId: result.response?.id,\n });\n\n const providerMetadataWithBilling = {\n ...result.providerMetadata,\n } as SharedV3ProviderMetadata;\n\n if (event) {\n providerMetadataWithBilling['ai-billing'] = toJSONObject(event);\n }\n\n return {\n ...result,\n providerMetadata: providerMetadataWithBilling,\n };\n },\n\n wrapStream: async ({ doStream, model, params }) => {\n const { stream, ...rest } = await doStream();\n\n let responseId: string | undefined;\n let usage: LanguageModelV3Usage | undefined;\n let providerMetadata: SharedV3ProviderMetadata | undefined;\n let finishChunk:\n | Extract<LanguageModelV3StreamPart, { type: 'finish' }>\n | undefined;\n\n const billedStream = stream.pipeThrough(\n new TransformStream<\n LanguageModelV3StreamPart,\n LanguageModelV3StreamPart\n >({\n transform(chunk, controller) {\n if (chunk.type === 'text-start') responseId = chunk.id;\n if (chunk.type === 'response-metadata' && !responseId) {\n responseId = chunk.id;\n }\n if (chunk.type === 'finish') {\n usage = chunk.usage;\n providerMetadata = chunk.providerMetadata;\n finishChunk = chunk;\n return; // held until flush\n }\n controller.enqueue(chunk);\n },\n async flush(controller) {\n const event = await processEvent({\n model,\n params,\n usage,\n providerMetadata,\n responseId,\n });\n\n const providerMetadataWithBilling = {\n ...providerMetadata,\n } as SharedV3ProviderMetadata;\n\n if (event) {\n providerMetadataWithBilling['ai-billing'] = toJSONObject(event);\n }\n\n if (finishChunk) {\n controller.enqueue({\n ...finishChunk,\n providerMetadata: providerMetadataWithBilling,\n });\n }\n },\n }),\n );\n\n return { ...rest, stream: billedStream };\n },\n };\n}\n","const marker = 'ai-billing.error';\nconst symbol = Symbol.for(marker);\n\nexport class AIBillingError extends Error {\n private readonly [symbol] = true;\n\n readonly cause?: unknown;\n\n constructor({\n name,\n message,\n cause,\n }: {\n name: string;\n message: string;\n cause?: unknown;\n }) {\n super(message);\n this.name = name;\n this.cause = cause;\n }\n\n static isInstance(error: unknown): error is AIBillingError {\n return AIBillingError.hasMarker(error, marker);\n }\n\n protected static hasMarker(error: unknown, markerString: string): boolean {\n const markerSymbol = Symbol.for(markerString);\n return (\n error != null &&\n typeof error === 'object' &&\n markerSymbol in error &&\n typeof error[markerSymbol] === 'boolean' &&\n error[markerSymbol] === true\n );\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingExtractorError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingExtractorError extends AIBillingError {\n private readonly [symbol] = true;\n\n constructor({\n message = `Failed to extract billing data.`,\n cause,\n }: {\n message?: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is AiBillingExtractorError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingDestinationError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingDestinationError extends AIBillingError {\n private readonly [symbol] = true;\n\n readonly destinationId?: string;\n\n constructor({\n destinationId,\n message = `Failed to process billing data for destination: '${destinationId}'.`,\n cause,\n }: {\n destinationId?: string;\n message?: string;\n cause?: unknown;\n }) {\n super({ name, message, cause });\n this.destinationId = destinationId;\n }\n\n static isInstance(error: unknown): error is AiBillingDestinationError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import { AIBillingError } from './ai-billing-error.js';\n\nconst name = 'AiBillingCostError';\nconst marker = `ai-billing.error.${name}`;\nconst symbol = Symbol.for(marker);\n\nexport class AiBillingCostError extends AIBillingError {\n private readonly [symbol] = true;\n\n constructor({ message, cause }: { message: string; cause?: unknown }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is AiBillingCostError {\n return AIBillingError.hasMarker(error, marker);\n }\n}\n","import type { Destination, BillingEvent, DefaultTags } from '../types/index.js';\nimport { AiBillingDestinationError } from '../error/index.js';\n\nexport function createDestination<TTags extends DefaultTags = DefaultTags>(\n destinationId: string,\n handler: (event: BillingEvent<TTags>) => Promise<void> | void,\n): Destination<TTags> {\n return async (event: BillingEvent<TTags>) => {\n try {\n await handler(event);\n } catch (error) {\n throw new AiBillingDestinationError({\n destinationId,\n cause: error,\n });\n }\n };\n}\n","import { createDestination } from './base-destination.js';\nimport type { DefaultTags, Destination } from '../types/index.js';\nimport { JSONObject } from '@ai-sdk/provider';\n\nexport function consoleDestination<\n TTags extends DefaultTags = DefaultTags,\n>(): Destination<TTags> {\n return createDestination<TTags>('console-logger', event => {\n console.dir(event, {\n depth: null,\n colors: true,\n compact: false,\n });\n });\n}\n","import { AiBillingCostError } from '../index.js';\nimport type { Cost, CostUnit } from '../index.js';\n\nconst getNanos = (cost: Cost): number => {\n switch (cost.unit) {\n case 'base':\n return Math.round(cost.amount * 1_000_000_000);\n case 'cents':\n return Math.round(cost.amount * 10_000_000);\n case 'micros':\n return Math.round(cost.amount * 1_000);\n case 'nanos':\n return Math.round(cost.amount);\n default:\n throw new AiBillingCostError({\n message: `Failed to process cost. Unknown CostUnit: '${String(cost.unit)}'.`,\n });\n }\n};\n\nexport const costToNumber = (cost: Cost, targetUnit: CostUnit): number => {\n const nanos = getNanos(cost);\n\n if (targetUnit === 'nanos') return nanos;\n if (targetUnit === 'micros') return nanos / 1_000;\n if (targetUnit === 'cents') return nanos / 10_000_000;\n return nanos / 1_000_000_000; // base\n};\n\nexport const convertCostUnit = (cost: Cost, targetUnit: CostUnit): Cost => {\n return {\n amount: costToNumber(cost, targetUnit),\n currency: cost.currency,\n unit: targetUnit,\n };\n};\n\nexport const rateToCost = (amount: number = 0): Cost => ({\n amount,\n unit: 'base',\n currency: 'USD',\n});\n","import { Cost } from '../types/index.js';\nimport { AiBillingCostError } from '../index.js';\nimport { convertCostUnit } from './convert-cost.js';\n\nexport const multiplyCost = (cost: Cost, multiplier: number): Cost => {\n const nanosCost = convertCostUnit(cost, 'nanos');\n return {\n ...nanosCost,\n amount: Math.round(nanosCost.amount * multiplier),\n };\n};\n\nexport const addCosts = (...costs: Cost[]): Cost => {\n if (costs.length === 0) {\n return { amount: 0, unit: 'nanos', currency: 'USD' };\n }\n\n const firstCost = costs[0];\n\n if (!firstCost) {\n return { amount: 0, unit: 'nanos', currency: 'USD' };\n }\n\n const baseCurrency = firstCost.currency;\n\n const totalNanos = costs.reduce((sum, currentCost) => {\n if (currentCost.currency !== baseCurrency) {\n throw new AiBillingCostError({\n message: `Currency mismatch: Cannot add ${baseCurrency} to ${currentCost.currency}`,\n });\n }\n return sum + convertCostUnit(currentCost, 'nanos').amount;\n }, 0);\n\n return { amount: totalNanos, unit: 'nanos', currency: baseCurrency };\n};\n\nexport const applyDiscount = (cost: Cost, discount: number): Cost => {\n if (!discount || discount <= 0) return cost;\n\n const nanosCost = convertCostUnit(cost, 'nanos');\n const discountAmount = Math.round(nanosCost.amount * discount);\n\n return {\n ...nanosCost,\n amount: Math.max(0, nanosCost.amount - discountAmount),\n };\n};\n","import type {\n ModelPricing,\n PriceResolver,\n PriceResolverContext,\n} from '../types/index.js';\n\nexport function createBasePriceResolver(\n handler: (\n context: PriceResolverContext,\n ) => ModelPricing | undefined | Promise<ModelPricing | undefined>,\n): PriceResolver {\n return async (context: PriceResolverContext) => {\n return handler(context);\n };\n}\n","import { createBasePriceResolver } from './base-price-resolver.js';\nimport type { ModelPricing, PriceResolverContext } from '../types/index.js';\n\ntype PricingRow = Record<string, number | string>;\ntype PricingMap = Record<string, PricingRow[]>;\n\nfunction rowToModelPricing(row: PricingRow): ModelPricing {\n return {\n promptTokens: row['price_prompt'] as number,\n completionTokens: row['price_completion'] as number,\n ...(row['price_request'] != null && {\n request: row['price_request'] as number,\n }),\n ...(row['price_input_cache_read'] != null && {\n inputCacheReadTokens: row['price_input_cache_read'] as number,\n }),\n ...(row['price_input_cache_write'] != null && {\n inputCacheWriteTokens: row['price_input_cache_write'] as number,\n }),\n ...(row['price_internal_reasoning'] != null && {\n internalReasoningTokens: row['price_internal_reasoning'] as number,\n }),\n ...(row['pricing_discount'] != null && {\n discount: row['pricing_discount'] as number,\n }),\n };\n}\n\nexport type NarevPriceResolverOptions = {\n apiKey: string;\n apiUrl?: string;\n};\n\nexport function createNarevPriceResolver({\n apiKey,\n apiUrl = 'https://narev.ai',\n}: NarevPriceResolverOptions): ReturnType<typeof createBasePriceResolver> {\n return createBasePriceResolver(\n async ({\n modelId,\n providerId,\n subProviderId,\n }: PriceResolverContext): Promise<ModelPricing | undefined> => {\n const params = new URLSearchParams({ model_id: modelId });\n if (providerId) params.set('gateway', providerId);\n if (subProviderId) params.set('provider', subProviderId);\n\n const url = `${apiUrl}/api/models/pricing?${params}`;\n const headers: Record<string, string> = apiKey\n ? { Authorization: `Bearer ${apiKey}` }\n : {};\n\n let data: PricingMap | null;\n try {\n const res = await fetch(url, { headers });\n if (!res.ok) return undefined;\n data = (await res.json()) as PricingMap | null;\n } catch {\n return undefined;\n }\n\n if (!data) return undefined;\n\n const rows = data[modelId];\n const row = rows?.[0];\n if (!row) return undefined;\n\n return rowToModelPricing(row);\n },\n );\n}\n","import { createBasePriceResolver } from './base-price-resolver.js';\nimport type {\n ModelPricing,\n PriceResolver,\n PriceResolverContext,\n} from '../types/index.js';\n\nexport function createObjectPriceResolver(\n pricingMap: Record<string, ModelPricing>,\n): PriceResolver {\n return createBasePriceResolver(({ modelId }: PriceResolverContext) => {\n return pricingMap[modelId];\n });\n}\n"],"mappings":"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","names":["name","marker","symbol","name","marker","symbol","name","marker","symbol"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-billing/core",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "repository": {
@@ -35,7 +35,8 @@
35
35
  "typescript": "5.9.2",
36
36
  "vitest": "4.1.1",
37
37
  "@edge-runtime/vm": "^5.0.0",
38
- "@ai-billing/testing": "0.0.1",
38
+ "zod": "^4.3.6",
39
+ "@ai-billing/testing": "0.0.2",
39
40
  "@ai-billing/typescript-config": "0.0.1"
40
41
  },
41
42
  "peerDependencies": {