@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 +57 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +56 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
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
|
|
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,
|
package/dist/index.cjs.map
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
"
|
|
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": {
|