ai-sdk-cost-calculator 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -35
- package/dist/calculator.d.ts +1 -2
- package/dist/calculator.d.ts.map +1 -1
- package/dist/calculator.js +40 -23
- package/dist/index.d.mts +3 -6
- package/dist/index.d.ts +3 -6
- package/dist/index.js +75 -26
- package/dist/index.mjs +75 -26
- package/dist/prices/index.d.ts +1 -16
- package/dist/prices/index.d.ts.map +1 -1
- package/dist/prices/index.js +1 -26
- package/dist/streaming.d.ts +2 -4
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +28 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,8 +37,7 @@ const result = await generateText({
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
const cost = calculateCost({
|
|
40
|
-
|
|
41
|
-
modelId: "gpt-4o",
|
|
40
|
+
model: "gpt-4o",
|
|
42
41
|
usage: result.usage,
|
|
43
42
|
});
|
|
44
43
|
|
|
@@ -56,16 +55,17 @@ Calculate the cost for a single API request.
|
|
|
56
55
|
import { calculateCost } from "ai-sdk-cost-calculator";
|
|
57
56
|
|
|
58
57
|
const cost = calculateCost({
|
|
59
|
-
|
|
60
|
-
modelId: "claude-sonnet-4-5",
|
|
58
|
+
model: "claude-sonnet-4-5",
|
|
61
59
|
usage: {
|
|
62
60
|
inputTokens: 1000,
|
|
63
61
|
outputTokens: 500,
|
|
64
62
|
inputTokenDetails: {
|
|
63
|
+
noCacheTokens: 700,
|
|
65
64
|
cacheReadTokens: 200,
|
|
66
65
|
cacheWriteTokens: 100,
|
|
67
66
|
},
|
|
68
67
|
outputTokenDetails: {
|
|
68
|
+
textTokens: 500,
|
|
69
69
|
reasoningTokens: 0,
|
|
70
70
|
},
|
|
71
71
|
},
|
|
@@ -86,25 +86,24 @@ console.log(cost);
|
|
|
86
86
|
|
|
87
87
|
#### Options
|
|
88
88
|
|
|
89
|
-
| Property
|
|
90
|
-
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `customPricing` | `ModelPricing` | No | Override default pricing |
|
|
89
|
+
| Property | Type | Required | Description |
|
|
90
|
+
| --------------- | -------------------- | -------- | ---------------------------------------------------------- |
|
|
91
|
+
| `model` | `string` | Yes | Model identifier (e.g., `"gpt-4o"`, `"claude-sonnet-4-5"`) |
|
|
92
|
+
| `usage` | `LanguageModelUsage` | Yes | Token usage from AI SDK |
|
|
93
|
+
| `customPricing` | `ModelPricing` | No | Override default pricing |
|
|
95
94
|
|
|
96
95
|
#### Return Value: `CostBreakdown`
|
|
97
96
|
|
|
98
|
-
| Property
|
|
99
|
-
|
|
100
|
-
| `inputCost`
|
|
101
|
-
| `outputCost`
|
|
102
|
-
| `cacheReadCost`
|
|
103
|
-
| `cacheWriteCost` | `number`
|
|
104
|
-
| `reasoningCost`
|
|
105
|
-
| `totalCost`
|
|
106
|
-
| `currency`
|
|
107
|
-
| `isLongContext`
|
|
97
|
+
| Property | Type | Description |
|
|
98
|
+
| ---------------- | --------- | -------------------------------------------- |
|
|
99
|
+
| `inputCost` | `number` | Cost for input tokens (excluding cache) |
|
|
100
|
+
| `outputCost` | `number` | Cost for output tokens (excluding reasoning) |
|
|
101
|
+
| `cacheReadCost` | `number` | Cost for cached input tokens |
|
|
102
|
+
| `cacheWriteCost` | `number` | Cost for writing to cache |
|
|
103
|
+
| `reasoningCost` | `number` | Cost for reasoning tokens |
|
|
104
|
+
| `totalCost` | `number` | Sum of all costs |
|
|
105
|
+
| `currency` | `"USD"` | Always USD |
|
|
106
|
+
| `isLongContext` | `boolean` | Whether long context pricing was applied |
|
|
108
107
|
|
|
109
108
|
### `formatCost(cost, decimals?)`
|
|
110
109
|
|
|
@@ -113,8 +112,8 @@ Format a cost value as a currency string.
|
|
|
113
112
|
```typescript
|
|
114
113
|
import { formatCost } from "ai-sdk-cost-calculator";
|
|
115
114
|
|
|
116
|
-
formatCost(0.0015);
|
|
117
|
-
formatCost(0.0015, 4);
|
|
115
|
+
formatCost(0.0015); // "$0.001500"
|
|
116
|
+
formatCost(0.0015, 4); // "$0.0015"
|
|
118
117
|
```
|
|
119
118
|
|
|
120
119
|
### `formatCostBreakdown(breakdown, decimals?)`
|
|
@@ -140,8 +139,7 @@ Track cumulative costs across multiple requests.
|
|
|
140
139
|
import { createCostTracker } from "ai-sdk-cost-calculator";
|
|
141
140
|
|
|
142
141
|
const tracker = createCostTracker({
|
|
143
|
-
|
|
144
|
-
modelId: "gpt-4o",
|
|
142
|
+
model: "gpt-4o",
|
|
145
143
|
});
|
|
146
144
|
|
|
147
145
|
// Add usage from multiple requests
|
|
@@ -171,8 +169,7 @@ const stream = await streamText({
|
|
|
171
169
|
});
|
|
172
170
|
|
|
173
171
|
const cost = await calculateStreamCost(stream, {
|
|
174
|
-
|
|
175
|
-
modelId: "gpt-4o",
|
|
172
|
+
model: "gpt-4o",
|
|
176
173
|
onCost: (cost, usage) => {
|
|
177
174
|
console.log(`Stream completed: ${formatCost(cost.totalCost)}`);
|
|
178
175
|
},
|
|
@@ -220,6 +217,7 @@ const models = getAllSupportedModels();
|
|
|
220
217
|
## Supported Models
|
|
221
218
|
|
|
222
219
|
### OpenAI (23 models)
|
|
220
|
+
|
|
223
221
|
- GPT-4o, GPT-4o-mini
|
|
224
222
|
- GPT-4.1, GPT-4.1-mini, GPT-4.1-nano
|
|
225
223
|
- GPT-4 Turbo, GPT-4, GPT-4-32k
|
|
@@ -229,6 +227,7 @@ const models = getAllSupportedModels();
|
|
|
229
227
|
- o4-mini
|
|
230
228
|
|
|
231
229
|
### Anthropic (23 models)
|
|
230
|
+
|
|
232
231
|
- Claude Opus 4.5, Sonnet 4.5, Haiku 4.5
|
|
233
232
|
- Claude Opus 4.1, Sonnet 4, Opus 4
|
|
234
233
|
- Claude 3.5 Sonnet, 3.5 Haiku
|
|
@@ -236,12 +235,14 @@ const models = getAllSupportedModels();
|
|
|
236
235
|
- All dated variants (e.g., `claude-3-5-sonnet-20241022`)
|
|
237
236
|
|
|
238
237
|
### Google Gemini (17 models)
|
|
238
|
+
|
|
239
239
|
- Gemini 3 Pro, 3 Flash
|
|
240
240
|
- Gemini 2.5 Pro, 2.5 Flash, 2.5 Flash-Lite
|
|
241
241
|
- Gemini 2.0 Flash, 2.0 Flash-Lite
|
|
242
242
|
- Gemini 1.5 Pro, 1.5 Flash, 1.5 Flash-8B
|
|
243
243
|
|
|
244
244
|
### xAI Grok (12 models)
|
|
245
|
+
|
|
245
246
|
- Grok 4, Grok 4-0709
|
|
246
247
|
- Grok 4 Fast (reasoning/non-reasoning)
|
|
247
248
|
- Grok 4.1 Fast (reasoning/non-reasoning)
|
|
@@ -250,6 +251,7 @@ const models = getAllSupportedModels();
|
|
|
250
251
|
- Grok 2, Grok 2 Vision
|
|
251
252
|
|
|
252
253
|
### DeepSeek (10 models)
|
|
254
|
+
|
|
253
255
|
- DeepSeek Chat (V3, V3.2)
|
|
254
256
|
- DeepSeek Reasoner (R1)
|
|
255
257
|
- DeepSeek R1 Distill variants
|
|
@@ -259,12 +261,12 @@ const models = getAllSupportedModels();
|
|
|
259
261
|
|
|
260
262
|
Some models have tiered pricing based on input token count:
|
|
261
263
|
|
|
262
|
-
| Model
|
|
263
|
-
|
|
264
|
-
| Claude Sonnet 4.5 | 200K
|
|
265
|
-
| Gemini 2.5 Pro
|
|
266
|
-
| Gemini 1.5 Pro
|
|
267
|
-
| Grok 4 Fast
|
|
264
|
+
| Model | Threshold | Standard | Long Context |
|
|
265
|
+
| ----------------- | --------- | ----------- | ------------ |
|
|
266
|
+
| Claude Sonnet 4.5 | 200K | $3/$15 | $6/$22.50 |
|
|
267
|
+
| Gemini 2.5 Pro | 200K | $1.25/$10 | $2.50/$15 |
|
|
268
|
+
| Gemini 1.5 Pro | 128K | $1.25/$5 | $2.50/$10 |
|
|
269
|
+
| Grok 4 Fast | 128K | $0.20/$0.50 | $0.40/$1.00 |
|
|
268
270
|
|
|
269
271
|
The calculator automatically applies the correct pricing tier based on input token count.
|
|
270
272
|
|
|
@@ -274,11 +276,10 @@ Override default pricing for any model:
|
|
|
274
276
|
|
|
275
277
|
```typescript
|
|
276
278
|
const cost = calculateCost({
|
|
277
|
-
|
|
278
|
-
modelId: "gpt-4o",
|
|
279
|
+
model: "gpt-4o",
|
|
279
280
|
usage: result.usage,
|
|
280
281
|
customPricing: {
|
|
281
|
-
inputPer1MTokens: 2.0,
|
|
282
|
+
inputPer1MTokens: 2.0, // Custom rate
|
|
282
283
|
outputPer1MTokens: 8.0,
|
|
283
284
|
cacheReadPer1MTokens: 1.0,
|
|
284
285
|
},
|
package/dist/calculator.d.ts
CHANGED
package/dist/calculator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calculator.d.ts","sourceRoot":"","sources":["../src/calculator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,
|
|
1
|
+
{"version":3,"file":"calculator.d.ts","sourceRoot":"","sources":["../src/calculator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAIvE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,CAAC;IAC1B,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAkGD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAyD1E;AAMD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG,MAAM,CAErE;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,QAAQ,GAAE,MAAU,GACnB,MAAM,CAwBR"}
|
package/dist/calculator.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getModelPricingByModelId } from "./prices";
|
|
2
|
+
const TOKENS_PER_MILLION = 1_000_000;
|
|
2
3
|
function getEffectivePricing(pricing, inputTokens) {
|
|
3
4
|
const threshold = pricing.longContextThreshold ?? 200000;
|
|
4
5
|
const isLongContext = inputTokens > threshold &&
|
|
@@ -28,32 +29,48 @@ function getEffectivePricing(pricing, inputTokens) {
|
|
|
28
29
|
isLongContext: false,
|
|
29
30
|
};
|
|
30
31
|
}
|
|
32
|
+
function getUsageTokenDetails(usage) {
|
|
33
|
+
const inputDetails = usage.inputTokenDetails;
|
|
34
|
+
const outputDetails = usage.outputTokenDetails;
|
|
35
|
+
let noCacheTokens = inputDetails?.noCacheTokens ?? 0;
|
|
36
|
+
let cacheReadTokens = inputDetails?.cacheReadTokens ?? 0;
|
|
37
|
+
let cacheWriteTokens = inputDetails?.cacheWriteTokens ?? 0;
|
|
38
|
+
let textTokens = outputDetails?.textTokens ?? 0;
|
|
39
|
+
let reasoningTokens = outputDetails?.reasoningTokens ?? 0;
|
|
40
|
+
if (!inputDetails && usage.inputTokens !== undefined) {
|
|
41
|
+
noCacheTokens = usage.inputTokens;
|
|
42
|
+
}
|
|
43
|
+
if (!outputDetails && usage.outputTokens !== undefined) {
|
|
44
|
+
textTokens = usage.outputTokens;
|
|
45
|
+
}
|
|
46
|
+
const totalInputTokens = usage.inputTokens ?? noCacheTokens + cacheReadTokens + cacheWriteTokens;
|
|
47
|
+
return {
|
|
48
|
+
noCacheTokens,
|
|
49
|
+
cacheReadTokens,
|
|
50
|
+
cacheWriteTokens,
|
|
51
|
+
textTokens,
|
|
52
|
+
reasoningTokens,
|
|
53
|
+
totalInputTokens,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function costFromTokens(tokens, per1MTokens) {
|
|
57
|
+
return (tokens / TOKENS_PER_MILLION) * per1MTokens;
|
|
58
|
+
}
|
|
31
59
|
export function calculateCost(options) {
|
|
32
|
-
const {
|
|
33
|
-
const pricing = customPricing ??
|
|
60
|
+
const { model, usage, customPricing } = options;
|
|
61
|
+
const pricing = customPricing ?? getModelPricingByModelId(model);
|
|
34
62
|
if (!pricing) {
|
|
35
|
-
throw new Error(`Unknown model: ${
|
|
63
|
+
throw new Error(`Unknown model: ${model}. Use customPricing option or add the model to prices.ts`);
|
|
36
64
|
}
|
|
37
|
-
|
|
38
|
-
const noCacheTokens = usage.inputTokenDetails?.noCacheTokens ?? 0;
|
|
39
|
-
const cacheReadTokens = usage.inputTokenDetails?.cacheReadTokens ?? 0;
|
|
40
|
-
const cacheWriteTokens = usage.inputTokenDetails?.cacheWriteTokens ?? 0;
|
|
41
|
-
const textTokens = usage.outputTokenDetails?.textTokens ?? 0;
|
|
42
|
-
const reasoningTokens = usage.outputTokenDetails?.reasoningTokens ?? 0;
|
|
43
|
-
// Total input tokens for long context threshold check
|
|
44
|
-
const totalInputTokens = usage.inputTokens ?? (noCacheTokens + cacheReadTokens);
|
|
65
|
+
const usageDetails = getUsageTokenDetails(usage);
|
|
45
66
|
// Get effective pricing based on input token count
|
|
46
|
-
const effectivePricing = getEffectivePricing(pricing, totalInputTokens);
|
|
47
|
-
const inputCost = (noCacheTokens
|
|
48
|
-
const outputCost = (textTokens
|
|
49
|
-
const cacheReadCost = (cacheReadTokens
|
|
50
|
-
const cacheWriteCost = (cacheWriteTokens
|
|
51
|
-
const reasoningCost = (reasoningTokens
|
|
52
|
-
const totalCost = inputCost +
|
|
53
|
-
outputCost +
|
|
54
|
-
cacheReadCost +
|
|
55
|
-
cacheWriteCost +
|
|
56
|
-
reasoningCost;
|
|
67
|
+
const effectivePricing = getEffectivePricing(pricing, usageDetails.totalInputTokens);
|
|
68
|
+
const inputCost = costFromTokens(usageDetails.noCacheTokens, effectivePricing.inputPer1MTokens);
|
|
69
|
+
const outputCost = costFromTokens(usageDetails.textTokens, effectivePricing.outputPer1MTokens);
|
|
70
|
+
const cacheReadCost = costFromTokens(usageDetails.cacheReadTokens, effectivePricing.cacheReadPer1MTokens);
|
|
71
|
+
const cacheWriteCost = costFromTokens(usageDetails.cacheWriteTokens, effectivePricing.cacheWritePer1MTokens);
|
|
72
|
+
const reasoningCost = costFromTokens(usageDetails.reasoningTokens, effectivePricing.reasoningPer1MTokens);
|
|
73
|
+
const totalCost = inputCost + outputCost + cacheReadCost + cacheWriteCost + reasoningCost;
|
|
57
74
|
return {
|
|
58
75
|
inputCost: roundToMicroDollars(inputCost),
|
|
59
76
|
outputCost: roundToMicroDollars(outputCost),
|
package/dist/index.d.mts
CHANGED
|
@@ -47,8 +47,7 @@ interface CostBreakdown {
|
|
|
47
47
|
isLongContext: boolean;
|
|
48
48
|
}
|
|
49
49
|
interface CalculateCostOptions {
|
|
50
|
-
|
|
51
|
-
modelId: string;
|
|
50
|
+
model: string;
|
|
52
51
|
usage: LanguageModelUsage;
|
|
53
52
|
customPricing?: ModelPricing;
|
|
54
53
|
}
|
|
@@ -64,14 +63,12 @@ interface CostTracker {
|
|
|
64
63
|
reset(): void;
|
|
65
64
|
}
|
|
66
65
|
interface CreateCostTrackerOptions {
|
|
67
|
-
|
|
68
|
-
modelId: string;
|
|
66
|
+
model: string;
|
|
69
67
|
customPricing?: ModelPricing;
|
|
70
68
|
}
|
|
71
69
|
declare function createCostTracker(options: CreateCostTrackerOptions): CostTracker;
|
|
72
70
|
interface StreamCostOptions {
|
|
73
|
-
|
|
74
|
-
modelId: string;
|
|
71
|
+
model: string;
|
|
75
72
|
customPricing?: ModelPricing;
|
|
76
73
|
onCost?: (cost: CostBreakdown, usage: LanguageModelUsage) => void;
|
|
77
74
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -47,8 +47,7 @@ interface CostBreakdown {
|
|
|
47
47
|
isLongContext: boolean;
|
|
48
48
|
}
|
|
49
49
|
interface CalculateCostOptions {
|
|
50
|
-
|
|
51
|
-
modelId: string;
|
|
50
|
+
model: string;
|
|
52
51
|
usage: LanguageModelUsage;
|
|
53
52
|
customPricing?: ModelPricing;
|
|
54
53
|
}
|
|
@@ -64,14 +63,12 @@ interface CostTracker {
|
|
|
64
63
|
reset(): void;
|
|
65
64
|
}
|
|
66
65
|
interface CreateCostTrackerOptions {
|
|
67
|
-
|
|
68
|
-
modelId: string;
|
|
66
|
+
model: string;
|
|
69
67
|
customPricing?: ModelPricing;
|
|
70
68
|
}
|
|
71
69
|
declare function createCostTracker(options: CreateCostTrackerOptions): CostTracker;
|
|
72
70
|
interface StreamCostOptions {
|
|
73
|
-
|
|
74
|
-
modelId: string;
|
|
71
|
+
model: string;
|
|
75
72
|
customPricing?: ModelPricing;
|
|
76
73
|
onCost?: (cost: CostBreakdown, usage: LanguageModelUsage) => void;
|
|
77
74
|
}
|
package/dist/index.js
CHANGED
|
@@ -629,6 +629,7 @@ function getAllSupportedModels() {
|
|
|
629
629
|
}
|
|
630
630
|
|
|
631
631
|
// src/calculator.ts
|
|
632
|
+
var TOKENS_PER_MILLION = 1e6;
|
|
632
633
|
function getEffectivePricing(pricing, inputTokens) {
|
|
633
634
|
const threshold = pricing.longContextThreshold ?? 2e5;
|
|
634
635
|
const isLongContext = inputTokens > threshold && pricing.longContextInputPer1MTokens !== void 0;
|
|
@@ -651,26 +652,66 @@ function getEffectivePricing(pricing, inputTokens) {
|
|
|
651
652
|
isLongContext: false
|
|
652
653
|
};
|
|
653
654
|
}
|
|
655
|
+
function getUsageTokenDetails(usage) {
|
|
656
|
+
const inputDetails = usage.inputTokenDetails;
|
|
657
|
+
const outputDetails = usage.outputTokenDetails;
|
|
658
|
+
let noCacheTokens = inputDetails?.noCacheTokens ?? 0;
|
|
659
|
+
let cacheReadTokens = inputDetails?.cacheReadTokens ?? 0;
|
|
660
|
+
let cacheWriteTokens = inputDetails?.cacheWriteTokens ?? 0;
|
|
661
|
+
let textTokens = outputDetails?.textTokens ?? 0;
|
|
662
|
+
let reasoningTokens = outputDetails?.reasoningTokens ?? 0;
|
|
663
|
+
if (!inputDetails && usage.inputTokens !== void 0) {
|
|
664
|
+
noCacheTokens = usage.inputTokens;
|
|
665
|
+
}
|
|
666
|
+
if (!outputDetails && usage.outputTokens !== void 0) {
|
|
667
|
+
textTokens = usage.outputTokens;
|
|
668
|
+
}
|
|
669
|
+
const totalInputTokens = usage.inputTokens ?? noCacheTokens + cacheReadTokens + cacheWriteTokens;
|
|
670
|
+
return {
|
|
671
|
+
noCacheTokens,
|
|
672
|
+
cacheReadTokens,
|
|
673
|
+
cacheWriteTokens,
|
|
674
|
+
textTokens,
|
|
675
|
+
reasoningTokens,
|
|
676
|
+
totalInputTokens
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
function costFromTokens(tokens, per1MTokens) {
|
|
680
|
+
return tokens / TOKENS_PER_MILLION * per1MTokens;
|
|
681
|
+
}
|
|
654
682
|
function calculateCost(options) {
|
|
655
|
-
const {
|
|
656
|
-
const pricing = customPricing ??
|
|
683
|
+
const { model, usage, customPricing } = options;
|
|
684
|
+
const pricing = customPricing ?? getModelPricingByModelId(model);
|
|
657
685
|
if (!pricing) {
|
|
658
686
|
throw new Error(
|
|
659
|
-
`Unknown model: ${
|
|
687
|
+
`Unknown model: ${model}. Use customPricing option or add the model to prices.ts`
|
|
660
688
|
);
|
|
661
689
|
}
|
|
662
|
-
const
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
690
|
+
const usageDetails = getUsageTokenDetails(usage);
|
|
691
|
+
const effectivePricing = getEffectivePricing(
|
|
692
|
+
pricing,
|
|
693
|
+
usageDetails.totalInputTokens
|
|
694
|
+
);
|
|
695
|
+
const inputCost = costFromTokens(
|
|
696
|
+
usageDetails.noCacheTokens,
|
|
697
|
+
effectivePricing.inputPer1MTokens
|
|
698
|
+
);
|
|
699
|
+
const outputCost = costFromTokens(
|
|
700
|
+
usageDetails.textTokens,
|
|
701
|
+
effectivePricing.outputPer1MTokens
|
|
702
|
+
);
|
|
703
|
+
const cacheReadCost = costFromTokens(
|
|
704
|
+
usageDetails.cacheReadTokens,
|
|
705
|
+
effectivePricing.cacheReadPer1MTokens
|
|
706
|
+
);
|
|
707
|
+
const cacheWriteCost = costFromTokens(
|
|
708
|
+
usageDetails.cacheWriteTokens,
|
|
709
|
+
effectivePricing.cacheWritePer1MTokens
|
|
710
|
+
);
|
|
711
|
+
const reasoningCost = costFromTokens(
|
|
712
|
+
usageDetails.reasoningTokens,
|
|
713
|
+
effectivePricing.reasoningPer1MTokens
|
|
714
|
+
);
|
|
674
715
|
const totalCost = inputCost + outputCost + cacheReadCost + cacheWriteCost + reasoningCost;
|
|
675
716
|
return {
|
|
676
717
|
inputCost: roundToMicroDollars(inputCost),
|
|
@@ -715,7 +756,7 @@ function formatCostBreakdown(result, decimals = 6) {
|
|
|
715
756
|
|
|
716
757
|
// src/streaming.ts
|
|
717
758
|
function createCostTracker(options) {
|
|
718
|
-
const {
|
|
759
|
+
const { model, customPricing } = options;
|
|
719
760
|
let totalNoCacheTokens = 0;
|
|
720
761
|
let totalCacheReadTokens = 0;
|
|
721
762
|
let totalCacheWriteTokens = 0;
|
|
@@ -724,15 +765,25 @@ function createCostTracker(options) {
|
|
|
724
765
|
let requestCount = 0;
|
|
725
766
|
return {
|
|
726
767
|
addUsage(usage) {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
768
|
+
const inputDetails = usage.inputTokenDetails;
|
|
769
|
+
if (inputDetails) {
|
|
770
|
+
totalNoCacheTokens += inputDetails.noCacheTokens ?? 0;
|
|
771
|
+
totalCacheReadTokens += inputDetails.cacheReadTokens ?? 0;
|
|
772
|
+
totalCacheWriteTokens += inputDetails.cacheWriteTokens ?? 0;
|
|
773
|
+
} else if (usage.inputTokens !== void 0) {
|
|
774
|
+
totalNoCacheTokens += usage.inputTokens;
|
|
775
|
+
}
|
|
776
|
+
const outputDetails = usage.outputTokenDetails;
|
|
777
|
+
if (outputDetails) {
|
|
778
|
+
totalTextTokens += outputDetails.textTokens ?? 0;
|
|
779
|
+
totalReasoningTokens += outputDetails.reasoningTokens ?? 0;
|
|
780
|
+
} else if (usage.outputTokens !== void 0) {
|
|
781
|
+
totalTextTokens += usage.outputTokens;
|
|
782
|
+
}
|
|
732
783
|
requestCount++;
|
|
733
784
|
},
|
|
734
785
|
getTotalUsage() {
|
|
735
|
-
const inputTokens = totalNoCacheTokens + totalCacheReadTokens;
|
|
786
|
+
const inputTokens = totalNoCacheTokens + totalCacheReadTokens + totalCacheWriteTokens;
|
|
736
787
|
const outputTokens = totalTextTokens + totalReasoningTokens;
|
|
737
788
|
return {
|
|
738
789
|
inputTokens,
|
|
@@ -751,8 +802,7 @@ function createCostTracker(options) {
|
|
|
751
802
|
},
|
|
752
803
|
getTotalCost() {
|
|
753
804
|
return calculateCost({
|
|
754
|
-
|
|
755
|
-
modelId,
|
|
805
|
+
model,
|
|
756
806
|
usage: this.getTotalUsage(),
|
|
757
807
|
customPricing
|
|
758
808
|
});
|
|
@@ -774,8 +824,7 @@ async function calculateStreamCost(streamResult, options) {
|
|
|
774
824
|
const result = await streamResult;
|
|
775
825
|
const usage = result.usage;
|
|
776
826
|
const cost = calculateCost({
|
|
777
|
-
|
|
778
|
-
modelId: options.modelId,
|
|
827
|
+
model: options.model,
|
|
779
828
|
usage,
|
|
780
829
|
customPricing: options.customPricing
|
|
781
830
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -589,6 +589,7 @@ function getAllSupportedModels() {
|
|
|
589
589
|
}
|
|
590
590
|
|
|
591
591
|
// src/calculator.ts
|
|
592
|
+
var TOKENS_PER_MILLION = 1e6;
|
|
592
593
|
function getEffectivePricing(pricing, inputTokens) {
|
|
593
594
|
const threshold = pricing.longContextThreshold ?? 2e5;
|
|
594
595
|
const isLongContext = inputTokens > threshold && pricing.longContextInputPer1MTokens !== void 0;
|
|
@@ -611,26 +612,66 @@ function getEffectivePricing(pricing, inputTokens) {
|
|
|
611
612
|
isLongContext: false
|
|
612
613
|
};
|
|
613
614
|
}
|
|
615
|
+
function getUsageTokenDetails(usage) {
|
|
616
|
+
const inputDetails = usage.inputTokenDetails;
|
|
617
|
+
const outputDetails = usage.outputTokenDetails;
|
|
618
|
+
let noCacheTokens = inputDetails?.noCacheTokens ?? 0;
|
|
619
|
+
let cacheReadTokens = inputDetails?.cacheReadTokens ?? 0;
|
|
620
|
+
let cacheWriteTokens = inputDetails?.cacheWriteTokens ?? 0;
|
|
621
|
+
let textTokens = outputDetails?.textTokens ?? 0;
|
|
622
|
+
let reasoningTokens = outputDetails?.reasoningTokens ?? 0;
|
|
623
|
+
if (!inputDetails && usage.inputTokens !== void 0) {
|
|
624
|
+
noCacheTokens = usage.inputTokens;
|
|
625
|
+
}
|
|
626
|
+
if (!outputDetails && usage.outputTokens !== void 0) {
|
|
627
|
+
textTokens = usage.outputTokens;
|
|
628
|
+
}
|
|
629
|
+
const totalInputTokens = usage.inputTokens ?? noCacheTokens + cacheReadTokens + cacheWriteTokens;
|
|
630
|
+
return {
|
|
631
|
+
noCacheTokens,
|
|
632
|
+
cacheReadTokens,
|
|
633
|
+
cacheWriteTokens,
|
|
634
|
+
textTokens,
|
|
635
|
+
reasoningTokens,
|
|
636
|
+
totalInputTokens
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
function costFromTokens(tokens, per1MTokens) {
|
|
640
|
+
return tokens / TOKENS_PER_MILLION * per1MTokens;
|
|
641
|
+
}
|
|
614
642
|
function calculateCost(options) {
|
|
615
|
-
const {
|
|
616
|
-
const pricing = customPricing ??
|
|
643
|
+
const { model, usage, customPricing } = options;
|
|
644
|
+
const pricing = customPricing ?? getModelPricingByModelId(model);
|
|
617
645
|
if (!pricing) {
|
|
618
646
|
throw new Error(
|
|
619
|
-
`Unknown model: ${
|
|
647
|
+
`Unknown model: ${model}. Use customPricing option or add the model to prices.ts`
|
|
620
648
|
);
|
|
621
649
|
}
|
|
622
|
-
const
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
650
|
+
const usageDetails = getUsageTokenDetails(usage);
|
|
651
|
+
const effectivePricing = getEffectivePricing(
|
|
652
|
+
pricing,
|
|
653
|
+
usageDetails.totalInputTokens
|
|
654
|
+
);
|
|
655
|
+
const inputCost = costFromTokens(
|
|
656
|
+
usageDetails.noCacheTokens,
|
|
657
|
+
effectivePricing.inputPer1MTokens
|
|
658
|
+
);
|
|
659
|
+
const outputCost = costFromTokens(
|
|
660
|
+
usageDetails.textTokens,
|
|
661
|
+
effectivePricing.outputPer1MTokens
|
|
662
|
+
);
|
|
663
|
+
const cacheReadCost = costFromTokens(
|
|
664
|
+
usageDetails.cacheReadTokens,
|
|
665
|
+
effectivePricing.cacheReadPer1MTokens
|
|
666
|
+
);
|
|
667
|
+
const cacheWriteCost = costFromTokens(
|
|
668
|
+
usageDetails.cacheWriteTokens,
|
|
669
|
+
effectivePricing.cacheWritePer1MTokens
|
|
670
|
+
);
|
|
671
|
+
const reasoningCost = costFromTokens(
|
|
672
|
+
usageDetails.reasoningTokens,
|
|
673
|
+
effectivePricing.reasoningPer1MTokens
|
|
674
|
+
);
|
|
634
675
|
const totalCost = inputCost + outputCost + cacheReadCost + cacheWriteCost + reasoningCost;
|
|
635
676
|
return {
|
|
636
677
|
inputCost: roundToMicroDollars(inputCost),
|
|
@@ -675,7 +716,7 @@ function formatCostBreakdown(result, decimals = 6) {
|
|
|
675
716
|
|
|
676
717
|
// src/streaming.ts
|
|
677
718
|
function createCostTracker(options) {
|
|
678
|
-
const {
|
|
719
|
+
const { model, customPricing } = options;
|
|
679
720
|
let totalNoCacheTokens = 0;
|
|
680
721
|
let totalCacheReadTokens = 0;
|
|
681
722
|
let totalCacheWriteTokens = 0;
|
|
@@ -684,15 +725,25 @@ function createCostTracker(options) {
|
|
|
684
725
|
let requestCount = 0;
|
|
685
726
|
return {
|
|
686
727
|
addUsage(usage) {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
728
|
+
const inputDetails = usage.inputTokenDetails;
|
|
729
|
+
if (inputDetails) {
|
|
730
|
+
totalNoCacheTokens += inputDetails.noCacheTokens ?? 0;
|
|
731
|
+
totalCacheReadTokens += inputDetails.cacheReadTokens ?? 0;
|
|
732
|
+
totalCacheWriteTokens += inputDetails.cacheWriteTokens ?? 0;
|
|
733
|
+
} else if (usage.inputTokens !== void 0) {
|
|
734
|
+
totalNoCacheTokens += usage.inputTokens;
|
|
735
|
+
}
|
|
736
|
+
const outputDetails = usage.outputTokenDetails;
|
|
737
|
+
if (outputDetails) {
|
|
738
|
+
totalTextTokens += outputDetails.textTokens ?? 0;
|
|
739
|
+
totalReasoningTokens += outputDetails.reasoningTokens ?? 0;
|
|
740
|
+
} else if (usage.outputTokens !== void 0) {
|
|
741
|
+
totalTextTokens += usage.outputTokens;
|
|
742
|
+
}
|
|
692
743
|
requestCount++;
|
|
693
744
|
},
|
|
694
745
|
getTotalUsage() {
|
|
695
|
-
const inputTokens = totalNoCacheTokens + totalCacheReadTokens;
|
|
746
|
+
const inputTokens = totalNoCacheTokens + totalCacheReadTokens + totalCacheWriteTokens;
|
|
696
747
|
const outputTokens = totalTextTokens + totalReasoningTokens;
|
|
697
748
|
return {
|
|
698
749
|
inputTokens,
|
|
@@ -711,8 +762,7 @@ function createCostTracker(options) {
|
|
|
711
762
|
},
|
|
712
763
|
getTotalCost() {
|
|
713
764
|
return calculateCost({
|
|
714
|
-
|
|
715
|
-
modelId,
|
|
765
|
+
model,
|
|
716
766
|
usage: this.getTotalUsage(),
|
|
717
767
|
customPricing
|
|
718
768
|
});
|
|
@@ -734,8 +784,7 @@ async function calculateStreamCost(streamResult, options) {
|
|
|
734
784
|
const result = await streamResult;
|
|
735
785
|
const usage = result.usage;
|
|
736
786
|
const cost = calculateCost({
|
|
737
|
-
|
|
738
|
-
modelId: options.modelId,
|
|
787
|
+
model: options.model,
|
|
739
788
|
usage,
|
|
740
789
|
customPricing: options.customPricing
|
|
741
790
|
});
|
package/dist/prices/index.d.ts
CHANGED
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { openaiPricing } from "./openai";
|
|
3
|
-
export { anthropicPricing } from "./anthropic";
|
|
4
|
-
export { googlePricing } from "./google";
|
|
5
|
-
export { xaiPricing } from "./xai";
|
|
6
|
-
export { deepseekPricing } from "./deepseek";
|
|
7
|
-
import type { ProviderPricing } from "./types";
|
|
8
|
-
export declare const allPricing: ProviderPricing;
|
|
9
|
-
export declare const pricingByProvider: {
|
|
10
|
-
readonly openai: ProviderPricing;
|
|
11
|
-
readonly anthropic: ProviderPricing;
|
|
12
|
-
readonly google: ProviderPricing;
|
|
13
|
-
readonly xai: ProviderPricing;
|
|
14
|
-
readonly deepseek: ProviderPricing;
|
|
15
|
-
};
|
|
16
|
-
export type Provider = keyof typeof pricingByProvider;
|
|
1
|
+
export * from "../prices";
|
|
17
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prices/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prices/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
|
package/dist/prices/index.js
CHANGED
|
@@ -1,26 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { anthropicPricing } from "./anthropic";
|
|
3
|
-
export { googlePricing } from "./google";
|
|
4
|
-
export { xaiPricing } from "./xai";
|
|
5
|
-
export { deepseekPricing } from "./deepseek";
|
|
6
|
-
import { openaiPricing } from "./openai";
|
|
7
|
-
import { anthropicPricing } from "./anthropic";
|
|
8
|
-
import { googlePricing } from "./google";
|
|
9
|
-
import { xaiPricing } from "./xai";
|
|
10
|
-
import { deepseekPricing } from "./deepseek";
|
|
11
|
-
// Combined pricing for all providers
|
|
12
|
-
export const allPricing = {
|
|
13
|
-
...openaiPricing,
|
|
14
|
-
...anthropicPricing,
|
|
15
|
-
...googlePricing,
|
|
16
|
-
...xaiPricing,
|
|
17
|
-
...deepseekPricing,
|
|
18
|
-
};
|
|
19
|
-
// Provider name to pricing map
|
|
20
|
-
export const pricingByProvider = {
|
|
21
|
-
openai: openaiPricing,
|
|
22
|
-
anthropic: anthropicPricing,
|
|
23
|
-
google: googlePricing,
|
|
24
|
-
xai: xaiPricing,
|
|
25
|
-
deepseek: deepseekPricing,
|
|
26
|
-
};
|
|
1
|
+
export * from "../prices";
|
package/dist/streaming.d.ts
CHANGED
|
@@ -9,14 +9,12 @@ export interface CostTracker {
|
|
|
9
9
|
reset(): void;
|
|
10
10
|
}
|
|
11
11
|
export interface CreateCostTrackerOptions {
|
|
12
|
-
|
|
13
|
-
modelId: string;
|
|
12
|
+
model: string;
|
|
14
13
|
customPricing?: ModelPricing;
|
|
15
14
|
}
|
|
16
15
|
export declare function createCostTracker(options: CreateCostTrackerOptions): CostTracker;
|
|
17
16
|
export interface StreamCostOptions {
|
|
18
|
-
|
|
19
|
-
modelId: string;
|
|
17
|
+
model: string;
|
|
20
18
|
customPricing?: ModelPricing;
|
|
21
19
|
onCost?: (cost: CostBreakdown, usage: LanguageModelUsage) => void;
|
|
22
20
|
}
|
package/dist/streaming.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,aAAa,IAAI,kBAAkB,CAAC;IACpC,YAAY,IAAI,aAAa,CAAC;IAC9B,eAAe,IAAI,MAAM,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,
|
|
1
|
+
{"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,aAAa,IAAI,kBAAkB,CAAC;IACpC,YAAY,IAAI,aAAa,CAAC;IAC9B,eAAe,IAAI,MAAM,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CA2EhF;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACnE;AAED,wBAAsB,mBAAmB,CAAC,CAAC,SAAS;IAAE,KAAK,EAAE,kBAAkB,CAAA;CAAE,EAC/E,YAAY,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC5B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,aAAa,GAAG;IAAE,KAAK,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAkBxD"}
|
package/dist/streaming.js
CHANGED
|
@@ -1,51 +1,55 @@
|
|
|
1
1
|
import { calculateCost } from "./calculator";
|
|
2
2
|
export function createCostTracker(options) {
|
|
3
|
-
const {
|
|
4
|
-
|
|
5
|
-
let
|
|
3
|
+
const { model, customPricing } = options;
|
|
4
|
+
// Track detail fields directly
|
|
5
|
+
let totalNoCacheTokens = 0;
|
|
6
6
|
let totalCacheReadTokens = 0;
|
|
7
7
|
let totalCacheWriteTokens = 0;
|
|
8
|
+
let totalTextTokens = 0;
|
|
8
9
|
let totalReasoningTokens = 0;
|
|
9
10
|
let requestCount = 0;
|
|
10
11
|
return {
|
|
11
12
|
addUsage(usage) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
totalCacheReadTokens +=
|
|
16
|
-
totalCacheWriteTokens +=
|
|
13
|
+
const inputDetails = usage.inputTokenDetails;
|
|
14
|
+
if (inputDetails) {
|
|
15
|
+
totalNoCacheTokens += inputDetails.noCacheTokens ?? 0;
|
|
16
|
+
totalCacheReadTokens += inputDetails.cacheReadTokens ?? 0;
|
|
17
|
+
totalCacheWriteTokens += inputDetails.cacheWriteTokens ?? 0;
|
|
17
18
|
}
|
|
18
|
-
else if (usage.
|
|
19
|
-
|
|
19
|
+
else if (usage.inputTokens !== undefined) {
|
|
20
|
+
totalNoCacheTokens += usage.inputTokens;
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
const outputDetails = usage.outputTokenDetails;
|
|
23
|
+
if (outputDetails) {
|
|
24
|
+
totalTextTokens += outputDetails.textTokens ?? 0;
|
|
25
|
+
totalReasoningTokens += outputDetails.reasoningTokens ?? 0;
|
|
23
26
|
}
|
|
24
|
-
else if (usage.
|
|
25
|
-
|
|
27
|
+
else if (usage.outputTokens !== undefined) {
|
|
28
|
+
totalTextTokens += usage.outputTokens;
|
|
26
29
|
}
|
|
27
30
|
requestCount++;
|
|
28
31
|
},
|
|
29
32
|
getTotalUsage() {
|
|
33
|
+
const inputTokens = totalNoCacheTokens + totalCacheReadTokens + totalCacheWriteTokens;
|
|
34
|
+
const outputTokens = totalTextTokens + totalReasoningTokens;
|
|
30
35
|
return {
|
|
31
|
-
inputTokens
|
|
32
|
-
outputTokens
|
|
33
|
-
totalTokens:
|
|
36
|
+
inputTokens,
|
|
37
|
+
outputTokens,
|
|
38
|
+
totalTokens: inputTokens + outputTokens,
|
|
34
39
|
inputTokenDetails: {
|
|
40
|
+
noCacheTokens: totalNoCacheTokens,
|
|
35
41
|
cacheReadTokens: totalCacheReadTokens,
|
|
36
42
|
cacheWriteTokens: totalCacheWriteTokens,
|
|
37
|
-
noCacheTokens: totalInputTokens - totalCacheReadTokens,
|
|
38
43
|
},
|
|
39
44
|
outputTokenDetails: {
|
|
45
|
+
textTokens: totalTextTokens,
|
|
40
46
|
reasoningTokens: totalReasoningTokens,
|
|
41
|
-
textTokens: totalOutputTokens - totalReasoningTokens,
|
|
42
47
|
},
|
|
43
48
|
};
|
|
44
49
|
},
|
|
45
50
|
getTotalCost() {
|
|
46
51
|
return calculateCost({
|
|
47
|
-
|
|
48
|
-
modelId,
|
|
52
|
+
model,
|
|
49
53
|
usage: this.getTotalUsage(),
|
|
50
54
|
customPricing,
|
|
51
55
|
});
|
|
@@ -54,10 +58,10 @@ export function createCostTracker(options) {
|
|
|
54
58
|
return requestCount;
|
|
55
59
|
},
|
|
56
60
|
reset() {
|
|
57
|
-
|
|
58
|
-
totalOutputTokens = 0;
|
|
61
|
+
totalNoCacheTokens = 0;
|
|
59
62
|
totalCacheReadTokens = 0;
|
|
60
63
|
totalCacheWriteTokens = 0;
|
|
64
|
+
totalTextTokens = 0;
|
|
61
65
|
totalReasoningTokens = 0;
|
|
62
66
|
requestCount = 0;
|
|
63
67
|
},
|
|
@@ -67,8 +71,7 @@ export async function calculateStreamCost(streamResult, options) {
|
|
|
67
71
|
const result = await streamResult;
|
|
68
72
|
const usage = result.usage;
|
|
69
73
|
const cost = calculateCost({
|
|
70
|
-
|
|
71
|
-
modelId: options.modelId,
|
|
74
|
+
model: options.model,
|
|
72
75
|
usage,
|
|
73
76
|
customPricing: options.customPricing,
|
|
74
77
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-sdk-cost-calculator",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Cost calculator for Vercel AI SDK token usage. Supports OpenAI, Anthropic, Google, xAI (Grok), and DeepSeek with long context pricing, prompt caching, and reasoning tokens.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|