@ai-billing/openai 0.0.0 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -90,8 +90,9 @@ function createOpenAIV3Middleware(options) {
90
90
  cacheWriteTokens: usage?.inputTokens?.cacheWrite ?? 0,
91
91
  reasoningTokens: usage?.outputTokens?.reasoning ?? 0
92
92
  };
93
- const pricing = await options.prices({
94
- modelId: model.modelId
93
+ const pricing = await options.priceResolver({
94
+ modelId: model.modelId,
95
+ providerId: "openai"
95
96
  });
96
97
  let calculatedCost = calculateOpenAICost({
97
98
  pricing,
@@ -100,8 +101,7 @@ function createOpenAIV3Middleware(options) {
100
101
  return {
101
102
  generationId: responseId ?? crypto.randomUUID(),
102
103
  modelId: model.modelId,
103
- provider: model.provider || "openai",
104
- timestamp: Date.now(),
104
+ provider: "openai",
105
105
  tags,
106
106
  usage: {
107
107
  inputTokens: inputTokensTotal,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/cost/calculate-openai-cost.ts","../src/ai-sdk/language-model-middleware/v3/language-model-v3-openai-billing-middleware.ts"],"sourcesContent":["export * from './ai-sdk/index.js';\n","import {\n addCosts,\n applyDiscount,\n multiplyCost,\n rateToCost,\n} from '@ai-billing/core';\nimport type { ModelPricing, Cost } from '@ai-billing/core';\n\nexport interface OpenAICostInputs {\n promptTokens: number;\n completionTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n reasoningTokens: number;\n}\n\nexport const calculateOpenAICost = ({\n pricing,\n usage,\n}: {\n pricing: ModelPricing | undefined;\n usage: OpenAICostInputs;\n}): Cost | undefined => {\n if (!pricing) {\n return undefined;\n }\n\n const promptCost = multiplyCost(\n rateToCost(pricing.promptTokens),\n usage.promptTokens,\n );\n\n const completionCost = multiplyCost(\n rateToCost(pricing.completionTokens),\n usage.completionTokens,\n );\n\n const cacheReadCost = multiplyCost(\n rateToCost(pricing.inputCacheReadTokens),\n usage.cacheReadTokens,\n );\n\n const cacheWriteCost = multiplyCost(\n rateToCost(pricing.inputCacheWriteTokens),\n usage.cacheWriteTokens,\n );\n\n const reasoningCost = multiplyCost(\n rateToCost(pricing.internalReasoningTokens ?? pricing.completionTokens),\n usage.reasoningTokens,\n );\n\n const requestCost = rateToCost(pricing.request);\n\n const grossCost = addCosts(\n promptCost,\n completionCost,\n cacheReadCost,\n cacheWriteCost,\n reasoningCost,\n requestCost,\n );\n\n return applyDiscount(grossCost, pricing.discount ?? 0);\n};\n","import { calculateOpenAICost } from '../../../cost/index.js';\nimport type { OpenAICostInputs as OpenAIUsageInputs } from '../../../cost/calculate-openai-cost.js';\nimport { createV3BillingMiddleware } from '@ai-billing/core';\nimport type {\n BaseBillingMiddlewareOptions,\n PriceResolver,\n Cost,\n DefaultTags,\n} from '@ai-billing/core';\nimport { JSONObject, SharedV3ProviderMetadata } from '@ai-sdk/provider';\n\ninterface OpenAIUsageAccounting extends JSONObject {\n acceptedPredictionTokens?: number;\n rejectedPredictionTokens?: number;\n logprobs?: number | boolean;\n serviceTier?: string;\n}\n\ntype OpenAIProviderMetadata = SharedV3ProviderMetadata & {\n openai?: OpenAIUsageAccounting;\n};\n\nexport interface OpenAIV3MiddlewareOptions<\n TTags extends DefaultTags,\n> extends BaseBillingMiddlewareOptions<TTags> {\n prices: PriceResolver;\n}\n\nexport function createOpenAIV3Middleware<TTags extends DefaultTags>(\n options: OpenAIV3MiddlewareOptions<TTags>,\n) {\n return createV3BillingMiddleware<TTags>({\n ...options,\n\n buildEvent: async ({\n model,\n usage,\n providerMetadata,\n responseId,\n tags,\n }) => {\n const _openaiMetadata = providerMetadata as\n | OpenAIProviderMetadata\n | undefined;\n\n const inputTokensTotal = usage?.inputTokens?.total ?? 0;\n const inputTokensCacheRead = usage?.inputTokens?.cacheRead ?? 0;\n const outputTokensTotal = usage?.outputTokens?.text ?? 0;\n const outputTokensReasoning = usage?.outputTokens?.reasoning ?? 0;\n\n const openAIUsage: OpenAIUsageInputs = {\n promptTokens: inputTokensTotal,\n completionTokens: usage?.outputTokens?.text ?? 0,\n cacheReadTokens: usage?.inputTokens?.cacheRead ?? 0,\n cacheWriteTokens: usage?.inputTokens?.cacheWrite ?? 0,\n reasoningTokens: usage?.outputTokens?.reasoning ?? 0,\n };\n\n const pricing = await options.prices({\n modelId: model.modelId,\n });\n\n let calculatedCost: Cost | undefined = calculateOpenAICost({\n pricing,\n usage: openAIUsage,\n });\n\n return {\n generationId: responseId ?? crypto.randomUUID(),\n modelId: model.modelId,\n provider: model.provider || 'openai',\n timestamp: Date.now(),\n tags: tags,\n usage: {\n inputTokens: inputTokensTotal,\n outputTokens: outputTokensTotal,\n cacheReadTokens: inputTokensCacheRead,\n reasoningTokens: outputTokensReasoning,\n totalTokens: inputTokensTotal + outputTokensTotal,\n },\n ...(calculatedCost !== undefined && {\n cost: calculatedCost,\n }),\n };\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAKO;AAWA,IAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AACF,MAGwB;AACtB,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,iBAAa;AAAA,QACjB,wBAAW,QAAQ,YAAY;AAAA,IAC/B,MAAM;AAAA,EACR;AAEA,QAAM,qBAAiB;AAAA,QACrB,wBAAW,QAAQ,gBAAgB;AAAA,IACnC,MAAM;AAAA,EACR;AAEA,QAAM,oBAAgB;AAAA,QACpB,wBAAW,QAAQ,oBAAoB;AAAA,IACvC,MAAM;AAAA,EACR;AAEA,QAAM,qBAAiB;AAAA,QACrB,wBAAW,QAAQ,qBAAqB;AAAA,IACxC,MAAM;AAAA,EACR;AAEA,QAAM,oBAAgB;AAAA,QACpB,wBAAW,QAAQ,2BAA2B,QAAQ,gBAAgB;AAAA,IACtE,MAAM;AAAA,EACR;AAEA,QAAM,kBAAc,wBAAW,QAAQ,OAAO;AAE9C,QAAM,gBAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAO,2BAAc,WAAW,QAAQ,YAAY,CAAC;AACvD;;;AC9DA,IAAAA,eAA0C;AA0BnC,SAAS,yBACd,SACA;AACA,aAAO,wCAAiC;AAAA,IACtC,GAAG;AAAA,IAEH,YAAY,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAAM;AACJ,YAAM,kBAAkB;AAIxB,YAAM,mBAAmB,OAAO,aAAa,SAAS;AACtD,YAAM,uBAAuB,OAAO,aAAa,aAAa;AAC9D,YAAM,oBAAoB,OAAO,cAAc,QAAQ;AACvD,YAAM,wBAAwB,OAAO,cAAc,aAAa;AAEhE,YAAM,cAAiC;AAAA,QACrC,cAAc;AAAA,QACd,kBAAkB,OAAO,cAAc,QAAQ;AAAA,QAC/C,iBAAiB,OAAO,aAAa,aAAa;AAAA,QAClD,kBAAkB,OAAO,aAAa,cAAc;AAAA,QACpD,iBAAiB,OAAO,cAAc,aAAa;AAAA,MACrD;AAEA,YAAM,UAAU,MAAM,QAAQ,OAAO;AAAA,QACnC,SAAS,MAAM;AAAA,MACjB,CAAC;AAED,UAAI,iBAAmC,oBAAoB;AAAA,QACzD;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAED,aAAO;AAAA,QACL,cAAc,cAAc,OAAO,WAAW;AAAA,QAC9C,SAAS,MAAM;AAAA,QACf,UAAU,MAAM,YAAY;AAAA,QAC5B,WAAW,KAAK,IAAI;AAAA,QACpB;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,iBAAiB;AAAA,UACjB,aAAa,mBAAmB;AAAA,QAClC;AAAA,QACA,GAAI,mBAAmB,UAAa;AAAA,UAClC,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":["import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/cost/calculate-openai-cost.ts","../src/ai-sdk/language-model-middleware/v3/language-model-v3-openai-billing-middleware.ts"],"sourcesContent":["export * from './ai-sdk/index.js';\n","import {\n addCosts,\n applyDiscount,\n multiplyCost,\n rateToCost,\n} from '@ai-billing/core';\nimport type { ModelPricing, Cost } from '@ai-billing/core';\n\nexport interface OpenAICostInputs {\n promptTokens: number;\n completionTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n reasoningTokens: number;\n}\n\nexport const calculateOpenAICost = ({\n pricing,\n usage,\n}: {\n pricing: ModelPricing | undefined;\n usage: OpenAICostInputs;\n}): Cost | undefined => {\n if (!pricing) {\n return undefined;\n }\n\n const promptCost = multiplyCost(\n rateToCost(pricing.promptTokens),\n usage.promptTokens,\n );\n\n const completionCost = multiplyCost(\n rateToCost(pricing.completionTokens),\n usage.completionTokens,\n );\n\n const cacheReadCost = multiplyCost(\n rateToCost(pricing.inputCacheReadTokens),\n usage.cacheReadTokens,\n );\n\n const cacheWriteCost = multiplyCost(\n rateToCost(pricing.inputCacheWriteTokens),\n usage.cacheWriteTokens,\n );\n\n const reasoningCost = multiplyCost(\n rateToCost(pricing.internalReasoningTokens ?? pricing.completionTokens),\n usage.reasoningTokens,\n );\n\n const requestCost = rateToCost(pricing.request);\n\n const grossCost = addCosts(\n promptCost,\n completionCost,\n cacheReadCost,\n cacheWriteCost,\n reasoningCost,\n requestCost,\n );\n\n return applyDiscount(grossCost, pricing.discount ?? 0);\n};\n","import { calculateOpenAICost } from '../../../cost/index.js';\nimport type { OpenAICostInputs as OpenAIUsageInputs } from '../../../cost/calculate-openai-cost.js';\nimport { createV3BillingMiddleware } from '@ai-billing/core';\nimport type {\n BaseBillingMiddlewareOptions,\n PriceResolver,\n Cost,\n DefaultTags,\n PriceResolverContext,\n ModelPricing,\n BillingEvent,\n} from '@ai-billing/core';\nimport { JSONObject, SharedV3ProviderMetadata } from '@ai-sdk/provider';\n\ninterface OpenAIUsageAccounting extends JSONObject {\n acceptedPredictionTokens?: number;\n rejectedPredictionTokens?: number;\n logprobs?: number | boolean;\n serviceTier?: string;\n}\n\ntype OpenAIProviderMetadata = SharedV3ProviderMetadata & {\n openai?: OpenAIUsageAccounting;\n};\n\nexport interface OpenAIV3MiddlewareOptions<\n TTags extends DefaultTags,\n> extends BaseBillingMiddlewareOptions<TTags> {\n priceResolver: PriceResolver;\n}\n\nexport function createOpenAIV3Middleware<TTags extends DefaultTags>(\n options: OpenAIV3MiddlewareOptions<TTags>,\n) {\n return createV3BillingMiddleware<TTags>({\n ...options,\n\n buildEvent: async ({\n model,\n usage,\n providerMetadata,\n responseId,\n tags,\n }) => {\n const _openaiMetadata = providerMetadata as\n | OpenAIProviderMetadata\n | undefined;\n\n const inputTokensTotal = usage?.inputTokens?.total ?? 0;\n const inputTokensCacheRead = usage?.inputTokens?.cacheRead ?? 0;\n const outputTokensTotal = usage?.outputTokens?.text ?? 0;\n const outputTokensReasoning = usage?.outputTokens?.reasoning ?? 0;\n\n const openAIUsage: OpenAIUsageInputs = {\n promptTokens: inputTokensTotal,\n completionTokens: usage?.outputTokens?.text ?? 0,\n cacheReadTokens: usage?.inputTokens?.cacheRead ?? 0,\n cacheWriteTokens: usage?.inputTokens?.cacheWrite ?? 0,\n reasoningTokens: usage?.outputTokens?.reasoning ?? 0,\n };\n\n const pricing: ModelPricing | undefined = await options.priceResolver({\n modelId: model.modelId,\n providerId: 'openai',\n } as PriceResolverContext);\n\n let calculatedCost: Cost | undefined = calculateOpenAICost({\n pricing,\n usage: openAIUsage,\n });\n\n return {\n generationId: responseId ?? crypto.randomUUID(),\n modelId: model.modelId,\n provider: 'openai',\n tags: tags,\n usage: {\n inputTokens: inputTokensTotal,\n outputTokens: outputTokensTotal,\n cacheReadTokens: inputTokensCacheRead,\n reasoningTokens: outputTokensReasoning,\n totalTokens: inputTokensTotal + outputTokensTotal,\n },\n ...(calculatedCost !== undefined && {\n cost: calculatedCost,\n }),\n } satisfies BillingEvent<TTags>;\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAKO;AAWA,IAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AACF,MAGwB;AACtB,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,iBAAa;AAAA,QACjB,wBAAW,QAAQ,YAAY;AAAA,IAC/B,MAAM;AAAA,EACR;AAEA,QAAM,qBAAiB;AAAA,QACrB,wBAAW,QAAQ,gBAAgB;AAAA,IACnC,MAAM;AAAA,EACR;AAEA,QAAM,oBAAgB;AAAA,QACpB,wBAAW,QAAQ,oBAAoB;AAAA,IACvC,MAAM;AAAA,EACR;AAEA,QAAM,qBAAiB;AAAA,QACrB,wBAAW,QAAQ,qBAAqB;AAAA,IACxC,MAAM;AAAA,EACR;AAEA,QAAM,oBAAgB;AAAA,QACpB,wBAAW,QAAQ,2BAA2B,QAAQ,gBAAgB;AAAA,IACtE,MAAM;AAAA,EACR;AAEA,QAAM,kBAAc,wBAAW,QAAQ,OAAO;AAE9C,QAAM,gBAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAO,2BAAc,WAAW,QAAQ,YAAY,CAAC;AACvD;;;AC9DA,IAAAA,eAA0C;AA6BnC,SAAS,yBACd,SACA;AACA,aAAO,wCAAiC;AAAA,IACtC,GAAG;AAAA,IAEH,YAAY,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAAM;AACJ,YAAM,kBAAkB;AAIxB,YAAM,mBAAmB,OAAO,aAAa,SAAS;AACtD,YAAM,uBAAuB,OAAO,aAAa,aAAa;AAC9D,YAAM,oBAAoB,OAAO,cAAc,QAAQ;AACvD,YAAM,wBAAwB,OAAO,cAAc,aAAa;AAEhE,YAAM,cAAiC;AAAA,QACrC,cAAc;AAAA,QACd,kBAAkB,OAAO,cAAc,QAAQ;AAAA,QAC/C,iBAAiB,OAAO,aAAa,aAAa;AAAA,QAClD,kBAAkB,OAAO,aAAa,cAAc;AAAA,QACpD,iBAAiB,OAAO,cAAc,aAAa;AAAA,MACrD;AAEA,YAAM,UAAoC,MAAM,QAAQ,cAAc;AAAA,QACpE,SAAS,MAAM;AAAA,QACf,YAAY;AAAA,MACd,CAAyB;AAEzB,UAAI,iBAAmC,oBAAoB;AAAA,QACzD;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAED,aAAO;AAAA,QACL,cAAc,cAAc,OAAO,WAAW;AAAA,QAC9C,SAAS,MAAM;AAAA,QACf,UAAU;AAAA,QACV;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,iBAAiB;AAAA,UACjB,aAAa,mBAAmB;AAAA,QAClC;AAAA,QACA,GAAI,mBAAmB,UAAa;AAAA,UAClC,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":["import_core"]}
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@ import * as _ai_sdk_provider from '@ai-sdk/provider';
2
2
  import { DefaultTags, BaseBillingMiddlewareOptions, PriceResolver } from '@ai-billing/core';
3
3
 
4
4
  interface OpenAIV3MiddlewareOptions<TTags extends DefaultTags> extends BaseBillingMiddlewareOptions<TTags> {
5
- prices: PriceResolver;
5
+ priceResolver: PriceResolver;
6
6
  }
7
7
  declare function createOpenAIV3Middleware<TTags extends DefaultTags>(options: OpenAIV3MiddlewareOptions<TTags>): _ai_sdk_provider.LanguageModelV3Middleware;
8
8
 
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as _ai_sdk_provider from '@ai-sdk/provider';
2
2
  import { DefaultTags, BaseBillingMiddlewareOptions, PriceResolver } from '@ai-billing/core';
3
3
 
4
4
  interface OpenAIV3MiddlewareOptions<TTags extends DefaultTags> extends BaseBillingMiddlewareOptions<TTags> {
5
- prices: PriceResolver;
5
+ priceResolver: PriceResolver;
6
6
  }
7
7
  declare function createOpenAIV3Middleware<TTags extends DefaultTags>(options: OpenAIV3MiddlewareOptions<TTags>): _ai_sdk_provider.LanguageModelV3Middleware;
8
8
 
package/dist/index.js CHANGED
@@ -68,8 +68,9 @@ function createOpenAIV3Middleware(options) {
68
68
  cacheWriteTokens: usage?.inputTokens?.cacheWrite ?? 0,
69
69
  reasoningTokens: usage?.outputTokens?.reasoning ?? 0
70
70
  };
71
- const pricing = await options.prices({
72
- modelId: model.modelId
71
+ const pricing = await options.priceResolver({
72
+ modelId: model.modelId,
73
+ providerId: "openai"
73
74
  });
74
75
  let calculatedCost = calculateOpenAICost({
75
76
  pricing,
@@ -78,8 +79,7 @@ function createOpenAIV3Middleware(options) {
78
79
  return {
79
80
  generationId: responseId ?? crypto.randomUUID(),
80
81
  modelId: model.modelId,
81
- provider: model.provider || "openai",
82
- timestamp: Date.now(),
82
+ provider: "openai",
83
83
  tags,
84
84
  usage: {
85
85
  inputTokens: inputTokensTotal,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cost/calculate-openai-cost.ts","../src/ai-sdk/language-model-middleware/v3/language-model-v3-openai-billing-middleware.ts"],"sourcesContent":["import {\n addCosts,\n applyDiscount,\n multiplyCost,\n rateToCost,\n} from '@ai-billing/core';\nimport type { ModelPricing, Cost } from '@ai-billing/core';\n\nexport interface OpenAICostInputs {\n promptTokens: number;\n completionTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n reasoningTokens: number;\n}\n\nexport const calculateOpenAICost = ({\n pricing,\n usage,\n}: {\n pricing: ModelPricing | undefined;\n usage: OpenAICostInputs;\n}): Cost | undefined => {\n if (!pricing) {\n return undefined;\n }\n\n const promptCost = multiplyCost(\n rateToCost(pricing.promptTokens),\n usage.promptTokens,\n );\n\n const completionCost = multiplyCost(\n rateToCost(pricing.completionTokens),\n usage.completionTokens,\n );\n\n const cacheReadCost = multiplyCost(\n rateToCost(pricing.inputCacheReadTokens),\n usage.cacheReadTokens,\n );\n\n const cacheWriteCost = multiplyCost(\n rateToCost(pricing.inputCacheWriteTokens),\n usage.cacheWriteTokens,\n );\n\n const reasoningCost = multiplyCost(\n rateToCost(pricing.internalReasoningTokens ?? pricing.completionTokens),\n usage.reasoningTokens,\n );\n\n const requestCost = rateToCost(pricing.request);\n\n const grossCost = addCosts(\n promptCost,\n completionCost,\n cacheReadCost,\n cacheWriteCost,\n reasoningCost,\n requestCost,\n );\n\n return applyDiscount(grossCost, pricing.discount ?? 0);\n};\n","import { calculateOpenAICost } from '../../../cost/index.js';\nimport type { OpenAICostInputs as OpenAIUsageInputs } from '../../../cost/calculate-openai-cost.js';\nimport { createV3BillingMiddleware } from '@ai-billing/core';\nimport type {\n BaseBillingMiddlewareOptions,\n PriceResolver,\n Cost,\n DefaultTags,\n} from '@ai-billing/core';\nimport { JSONObject, SharedV3ProviderMetadata } from '@ai-sdk/provider';\n\ninterface OpenAIUsageAccounting extends JSONObject {\n acceptedPredictionTokens?: number;\n rejectedPredictionTokens?: number;\n logprobs?: number | boolean;\n serviceTier?: string;\n}\n\ntype OpenAIProviderMetadata = SharedV3ProviderMetadata & {\n openai?: OpenAIUsageAccounting;\n};\n\nexport interface OpenAIV3MiddlewareOptions<\n TTags extends DefaultTags,\n> extends BaseBillingMiddlewareOptions<TTags> {\n prices: PriceResolver;\n}\n\nexport function createOpenAIV3Middleware<TTags extends DefaultTags>(\n options: OpenAIV3MiddlewareOptions<TTags>,\n) {\n return createV3BillingMiddleware<TTags>({\n ...options,\n\n buildEvent: async ({\n model,\n usage,\n providerMetadata,\n responseId,\n tags,\n }) => {\n const _openaiMetadata = providerMetadata as\n | OpenAIProviderMetadata\n | undefined;\n\n const inputTokensTotal = usage?.inputTokens?.total ?? 0;\n const inputTokensCacheRead = usage?.inputTokens?.cacheRead ?? 0;\n const outputTokensTotal = usage?.outputTokens?.text ?? 0;\n const outputTokensReasoning = usage?.outputTokens?.reasoning ?? 0;\n\n const openAIUsage: OpenAIUsageInputs = {\n promptTokens: inputTokensTotal,\n completionTokens: usage?.outputTokens?.text ?? 0,\n cacheReadTokens: usage?.inputTokens?.cacheRead ?? 0,\n cacheWriteTokens: usage?.inputTokens?.cacheWrite ?? 0,\n reasoningTokens: usage?.outputTokens?.reasoning ?? 0,\n };\n\n const pricing = await options.prices({\n modelId: model.modelId,\n });\n\n let calculatedCost: Cost | undefined = calculateOpenAICost({\n pricing,\n usage: openAIUsage,\n });\n\n return {\n generationId: responseId ?? crypto.randomUUID(),\n modelId: model.modelId,\n provider: model.provider || 'openai',\n timestamp: Date.now(),\n tags: tags,\n usage: {\n inputTokens: inputTokensTotal,\n outputTokens: outputTokensTotal,\n cacheReadTokens: inputTokensCacheRead,\n reasoningTokens: outputTokensReasoning,\n totalTokens: inputTokensTotal + outputTokensTotal,\n },\n ...(calculatedCost !== undefined && {\n cost: calculatedCost,\n }),\n };\n },\n });\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAWA,IAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AACF,MAGwB;AACtB,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,aAAa;AAAA,IACjB,WAAW,QAAQ,YAAY;AAAA,IAC/B,MAAM;AAAA,EACR;AAEA,QAAM,iBAAiB;AAAA,IACrB,WAAW,QAAQ,gBAAgB;AAAA,IACnC,MAAM;AAAA,EACR;AAEA,QAAM,gBAAgB;AAAA,IACpB,WAAW,QAAQ,oBAAoB;AAAA,IACvC,MAAM;AAAA,EACR;AAEA,QAAM,iBAAiB;AAAA,IACrB,WAAW,QAAQ,qBAAqB;AAAA,IACxC,MAAM;AAAA,EACR;AAEA,QAAM,gBAAgB;AAAA,IACpB,WAAW,QAAQ,2BAA2B,QAAQ,gBAAgB;AAAA,IACtE,MAAM;AAAA,EACR;AAEA,QAAM,cAAc,WAAW,QAAQ,OAAO;AAE9C,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,cAAc,WAAW,QAAQ,YAAY,CAAC;AACvD;;;AC9DA,SAAS,iCAAiC;AA0BnC,SAAS,yBACd,SACA;AACA,SAAO,0BAAiC;AAAA,IACtC,GAAG;AAAA,IAEH,YAAY,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAAM;AACJ,YAAM,kBAAkB;AAIxB,YAAM,mBAAmB,OAAO,aAAa,SAAS;AACtD,YAAM,uBAAuB,OAAO,aAAa,aAAa;AAC9D,YAAM,oBAAoB,OAAO,cAAc,QAAQ;AACvD,YAAM,wBAAwB,OAAO,cAAc,aAAa;AAEhE,YAAM,cAAiC;AAAA,QACrC,cAAc;AAAA,QACd,kBAAkB,OAAO,cAAc,QAAQ;AAAA,QAC/C,iBAAiB,OAAO,aAAa,aAAa;AAAA,QAClD,kBAAkB,OAAO,aAAa,cAAc;AAAA,QACpD,iBAAiB,OAAO,cAAc,aAAa;AAAA,MACrD;AAEA,YAAM,UAAU,MAAM,QAAQ,OAAO;AAAA,QACnC,SAAS,MAAM;AAAA,MACjB,CAAC;AAED,UAAI,iBAAmC,oBAAoB;AAAA,QACzD;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAED,aAAO;AAAA,QACL,cAAc,cAAc,OAAO,WAAW;AAAA,QAC9C,SAAS,MAAM;AAAA,QACf,UAAU,MAAM,YAAY;AAAA,QAC5B,WAAW,KAAK,IAAI;AAAA,QACpB;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,iBAAiB;AAAA,UACjB,aAAa,mBAAmB;AAAA,QAClC;AAAA,QACA,GAAI,mBAAmB,UAAa;AAAA,UAClC,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../src/cost/calculate-openai-cost.ts","../src/ai-sdk/language-model-middleware/v3/language-model-v3-openai-billing-middleware.ts"],"sourcesContent":["import {\n addCosts,\n applyDiscount,\n multiplyCost,\n rateToCost,\n} from '@ai-billing/core';\nimport type { ModelPricing, Cost } from '@ai-billing/core';\n\nexport interface OpenAICostInputs {\n promptTokens: number;\n completionTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n reasoningTokens: number;\n}\n\nexport const calculateOpenAICost = ({\n pricing,\n usage,\n}: {\n pricing: ModelPricing | undefined;\n usage: OpenAICostInputs;\n}): Cost | undefined => {\n if (!pricing) {\n return undefined;\n }\n\n const promptCost = multiplyCost(\n rateToCost(pricing.promptTokens),\n usage.promptTokens,\n );\n\n const completionCost = multiplyCost(\n rateToCost(pricing.completionTokens),\n usage.completionTokens,\n );\n\n const cacheReadCost = multiplyCost(\n rateToCost(pricing.inputCacheReadTokens),\n usage.cacheReadTokens,\n );\n\n const cacheWriteCost = multiplyCost(\n rateToCost(pricing.inputCacheWriteTokens),\n usage.cacheWriteTokens,\n );\n\n const reasoningCost = multiplyCost(\n rateToCost(pricing.internalReasoningTokens ?? pricing.completionTokens),\n usage.reasoningTokens,\n );\n\n const requestCost = rateToCost(pricing.request);\n\n const grossCost = addCosts(\n promptCost,\n completionCost,\n cacheReadCost,\n cacheWriteCost,\n reasoningCost,\n requestCost,\n );\n\n return applyDiscount(grossCost, pricing.discount ?? 0);\n};\n","import { calculateOpenAICost } from '../../../cost/index.js';\nimport type { OpenAICostInputs as OpenAIUsageInputs } from '../../../cost/calculate-openai-cost.js';\nimport { createV3BillingMiddleware } from '@ai-billing/core';\nimport type {\n BaseBillingMiddlewareOptions,\n PriceResolver,\n Cost,\n DefaultTags,\n PriceResolverContext,\n ModelPricing,\n BillingEvent,\n} from '@ai-billing/core';\nimport { JSONObject, SharedV3ProviderMetadata } from '@ai-sdk/provider';\n\ninterface OpenAIUsageAccounting extends JSONObject {\n acceptedPredictionTokens?: number;\n rejectedPredictionTokens?: number;\n logprobs?: number | boolean;\n serviceTier?: string;\n}\n\ntype OpenAIProviderMetadata = SharedV3ProviderMetadata & {\n openai?: OpenAIUsageAccounting;\n};\n\nexport interface OpenAIV3MiddlewareOptions<\n TTags extends DefaultTags,\n> extends BaseBillingMiddlewareOptions<TTags> {\n priceResolver: PriceResolver;\n}\n\nexport function createOpenAIV3Middleware<TTags extends DefaultTags>(\n options: OpenAIV3MiddlewareOptions<TTags>,\n) {\n return createV3BillingMiddleware<TTags>({\n ...options,\n\n buildEvent: async ({\n model,\n usage,\n providerMetadata,\n responseId,\n tags,\n }) => {\n const _openaiMetadata = providerMetadata as\n | OpenAIProviderMetadata\n | undefined;\n\n const inputTokensTotal = usage?.inputTokens?.total ?? 0;\n const inputTokensCacheRead = usage?.inputTokens?.cacheRead ?? 0;\n const outputTokensTotal = usage?.outputTokens?.text ?? 0;\n const outputTokensReasoning = usage?.outputTokens?.reasoning ?? 0;\n\n const openAIUsage: OpenAIUsageInputs = {\n promptTokens: inputTokensTotal,\n completionTokens: usage?.outputTokens?.text ?? 0,\n cacheReadTokens: usage?.inputTokens?.cacheRead ?? 0,\n cacheWriteTokens: usage?.inputTokens?.cacheWrite ?? 0,\n reasoningTokens: usage?.outputTokens?.reasoning ?? 0,\n };\n\n const pricing: ModelPricing | undefined = await options.priceResolver({\n modelId: model.modelId,\n providerId: 'openai',\n } as PriceResolverContext);\n\n let calculatedCost: Cost | undefined = calculateOpenAICost({\n pricing,\n usage: openAIUsage,\n });\n\n return {\n generationId: responseId ?? crypto.randomUUID(),\n modelId: model.modelId,\n provider: 'openai',\n tags: tags,\n usage: {\n inputTokens: inputTokensTotal,\n outputTokens: outputTokensTotal,\n cacheReadTokens: inputTokensCacheRead,\n reasoningTokens: outputTokensReasoning,\n totalTokens: inputTokensTotal + outputTokensTotal,\n },\n ...(calculatedCost !== undefined && {\n cost: calculatedCost,\n }),\n } satisfies BillingEvent<TTags>;\n },\n });\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAWA,IAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AACF,MAGwB;AACtB,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,aAAa;AAAA,IACjB,WAAW,QAAQ,YAAY;AAAA,IAC/B,MAAM;AAAA,EACR;AAEA,QAAM,iBAAiB;AAAA,IACrB,WAAW,QAAQ,gBAAgB;AAAA,IACnC,MAAM;AAAA,EACR;AAEA,QAAM,gBAAgB;AAAA,IACpB,WAAW,QAAQ,oBAAoB;AAAA,IACvC,MAAM;AAAA,EACR;AAEA,QAAM,iBAAiB;AAAA,IACrB,WAAW,QAAQ,qBAAqB;AAAA,IACxC,MAAM;AAAA,EACR;AAEA,QAAM,gBAAgB;AAAA,IACpB,WAAW,QAAQ,2BAA2B,QAAQ,gBAAgB;AAAA,IACtE,MAAM;AAAA,EACR;AAEA,QAAM,cAAc,WAAW,QAAQ,OAAO;AAE9C,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,cAAc,WAAW,QAAQ,YAAY,CAAC;AACvD;;;AC9DA,SAAS,iCAAiC;AA6BnC,SAAS,yBACd,SACA;AACA,SAAO,0BAAiC;AAAA,IACtC,GAAG;AAAA,IAEH,YAAY,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAAM;AACJ,YAAM,kBAAkB;AAIxB,YAAM,mBAAmB,OAAO,aAAa,SAAS;AACtD,YAAM,uBAAuB,OAAO,aAAa,aAAa;AAC9D,YAAM,oBAAoB,OAAO,cAAc,QAAQ;AACvD,YAAM,wBAAwB,OAAO,cAAc,aAAa;AAEhE,YAAM,cAAiC;AAAA,QACrC,cAAc;AAAA,QACd,kBAAkB,OAAO,cAAc,QAAQ;AAAA,QAC/C,iBAAiB,OAAO,aAAa,aAAa;AAAA,QAClD,kBAAkB,OAAO,aAAa,cAAc;AAAA,QACpD,iBAAiB,OAAO,cAAc,aAAa;AAAA,MACrD;AAEA,YAAM,UAAoC,MAAM,QAAQ,cAAc;AAAA,QACpE,SAAS,MAAM;AAAA,QACf,YAAY;AAAA,MACd,CAAyB;AAEzB,UAAI,iBAAmC,oBAAoB;AAAA,QACzD;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAED,aAAO;AAAA,QACL,cAAc,cAAc,OAAO,WAAW;AAAA,QAC9C,SAAS,MAAM;AAAA,QACf,UAAU;AAAA,QACV;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,cAAc;AAAA,UACd,iBAAiB;AAAA,UACjB,iBAAiB;AAAA,UACjB,aAAa,mBAAmB;AAAA,QAClC;AAAA,QACA,GAAI,mBAAmB,UAAa;AAAA,UAClC,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;","names":[]}
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@ai-billing/openai",
3
- "version": "0.0.0",
3
+ "version": "0.0.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/narevai/ai-billing.git",
9
- "directory": "packages/core"
9
+ "directory": "packages/openai"
10
10
  },
11
11
  "main": "./dist/index.js",
12
12
  "types": "./dist/index.d.ts",
@@ -23,39 +23,39 @@
23
23
  }
24
24
  },
25
25
  "publishConfig": {
26
- "access": "public"
26
+ "access": "public",
27
+ "provenance": true
27
28
  },
28
29
  "files": [
29
30
  "dist"
30
31
  ],
31
- "scripts": {
32
- "build": "tsup",
33
- "check-types": "tsc --noEmit",
34
- "lint": "oxlint",
35
- "dev": "tsup --watch",
36
- "test": "vitest run",
37
- "test:coverage": "vitest run --coverage",
38
- "test:watch": "vitest",
39
- "prepack": "node -e \"require('fs').copyFileSync('../../LICENSE', 'LICENSE')\"",
40
- "postpack": "node -e \"require('fs').rmSync('LICENSE', { force: true })\""
41
- },
42
32
  "dependencies": {
43
- "@ai-billing/core": "workspace:*"
33
+ "@ai-billing/core": "0.0.3"
44
34
  },
45
35
  "devDependencies": {
46
- "@ai-billing/typescript-config": "workspace:*",
47
- "@ai-billing/testing": "workspace:*",
48
- "tsup": "catalog:",
49
- "typescript": "catalog:",
50
- "vitest": "catalog:",
51
- "ai": "catalog:",
52
- "@ai-sdk/provider": "catalog:",
53
- "@edge-runtime/vm": "catalog:"
36
+ "tsup": "^8.5.1",
37
+ "typescript": "5.9.2",
38
+ "vitest": "4.1.1",
39
+ "ai": "^6.0.138",
40
+ "@ai-sdk/provider": "^3.0.8",
41
+ "@edge-runtime/vm": "^5.0.0",
42
+ "zod": "^4.3.6",
43
+ "@ai-billing/typescript-config": "0.0.1",
44
+ "@ai-billing/testing": "0.0.2"
54
45
  },
55
46
  "peerDependencies": {
56
47
  "@ai-sdk/openai": "^3.0.0"
57
48
  },
58
49
  "engines": {
59
50
  "node": ">=20.0.0"
51
+ },
52
+ "scripts": {
53
+ "build": "tsup",
54
+ "check-types": "tsc --noEmit",
55
+ "lint": "oxlint",
56
+ "dev": "tsup --watch",
57
+ "test": "vitest run",
58
+ "test:coverage": "vitest run --coverage",
59
+ "test:watch": "vitest"
60
60
  }
61
- }
61
+ }