ai-sdk-cost-calculator 0.1.2 → 0.1.4

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.
Files changed (66) hide show
  1. package/README.md +157 -33
  2. package/dist/core/calculator.d.ts +2 -0
  3. package/dist/core/calculator.d.ts.map +1 -1
  4. package/dist/core/calculator.js +12 -2
  5. package/dist/core/types.d.ts +1 -0
  6. package/dist/core/types.d.ts.map +1 -1
  7. package/dist/index.d.mts +113 -3
  8. package/dist/index.d.ts +113 -3
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +187 -29
  11. package/dist/index.mjs +183 -29
  12. package/dist/integrations/ai-sdk.d.ts +4 -1
  13. package/dist/integrations/ai-sdk.d.ts.map +1 -1
  14. package/dist/integrations/ai-sdk.js +23 -2
  15. package/dist/pricing/providers/google.d.ts.map +1 -1
  16. package/dist/pricing/providers/google.js +22 -7
  17. package/dist/pricing/types.d.ts +1 -0
  18. package/dist/pricing/types.d.ts.map +1 -1
  19. package/dist/shared/cost.d.ts.map +1 -1
  20. package/dist/shared/cost.js +3 -0
  21. package/dist/shared/detect-requests.d.ts +103 -0
  22. package/dist/shared/detect-requests.d.ts.map +1 -0
  23. package/dist/shared/detect-requests.js +148 -0
  24. package/dist/tracking/tracker.d.ts +4 -1
  25. package/dist/tracking/tracker.d.ts.map +1 -1
  26. package/dist/tracking/tracker.js +16 -1
  27. package/package.json +1 -1
  28. package/dist/ai-sdk.d.ts +0 -151
  29. package/dist/ai-sdk.d.ts.map +0 -1
  30. package/dist/ai-sdk.js +0 -174
  31. package/dist/calculator.d.ts +0 -24
  32. package/dist/calculator.d.ts.map +0 -1
  33. package/dist/calculator.js +0 -133
  34. package/dist/prices/anthropic.d.ts +0 -3
  35. package/dist/prices/anthropic.d.ts.map +0 -1
  36. package/dist/prices/anthropic.js +0 -162
  37. package/dist/prices/deepseek.d.ts +0 -3
  38. package/dist/prices/deepseek.d.ts.map +0 -1
  39. package/dist/prices/deepseek.js +0 -61
  40. package/dist/prices/google.d.ts +0 -3
  41. package/dist/prices/google.d.ts.map +0 -1
  42. package/dist/prices/google.js +0 -136
  43. package/dist/prices/index.d.ts +0 -2
  44. package/dist/prices/index.d.ts.map +0 -1
  45. package/dist/prices/index.js +0 -1
  46. package/dist/prices/openai.d.ts +0 -3
  47. package/dist/prices/openai.d.ts.map +0 -1
  48. package/dist/prices/openai.js +0 -140
  49. package/dist/prices/perplexity.d.ts +0 -3
  50. package/dist/prices/perplexity.d.ts.map +0 -1
  51. package/dist/prices/perplexity.js +0 -43
  52. package/dist/prices/types.d.ts +0 -18
  53. package/dist/prices/types.d.ts.map +0 -1
  54. package/dist/prices/types.js +0 -1
  55. package/dist/prices/xai.d.ts +0 -3
  56. package/dist/prices/xai.d.ts.map +0 -1
  57. package/dist/prices/xai.js +0 -93
  58. package/dist/prices.d.ts +0 -18
  59. package/dist/prices.d.ts.map +0 -1
  60. package/dist/prices.js +0 -48
  61. package/dist/streaming.d.ts +0 -26
  62. package/dist/streaming.d.ts.map +0 -1
  63. package/dist/streaming.js +0 -85
  64. package/dist/tracker.d.ts +0 -96
  65. package/dist/tracker.d.ts.map +0 -1
  66. package/dist/tracker.js +0 -191
package/README.md CHANGED
@@ -9,6 +9,8 @@ Cost calculator for [Vercel AI SDK](https://sdk.vercel.ai/) token usage. Calcula
9
9
  - **Session tracking**: Track costs across multiple calls with `createCostAwareAI()`
10
10
  - **Multi-model tracking**: Track costs across different models in a single tracker
11
11
  - **Web search pricing**: Calculate costs for grounding/search features
12
+ - **Google Maps pricing**: Calculate costs for Google Maps API requests
13
+ - **Auto-detection**: Automatically detect web search/maps tool calls from results
12
14
  - **Long context pricing**: Automatic tier-based pricing (e.g., Claude Sonnet 4.5 >200K tokens)
13
15
  - **Prompt caching**: Separate pricing for cache reads and writes
14
16
  - **Reasoning tokens**: Support for o1/o3/R1 reasoning model costs
@@ -187,31 +189,94 @@ console.log(`Models: ${tracker.getModels().join(", ")}`);
187
189
  tracker.reset();
188
190
  ```
189
191
 
190
- ## Web Search Costs
192
+ ## Web Search & Google Maps Costs
191
193
 
192
- Calculate costs including web search/grounding features.
194
+ Calculate costs including web search/grounding and Google Maps features.
193
195
 
194
196
  ```typescript
195
197
  const cost = calculateCost({
196
- model: "gpt-4o",
198
+ model: "gemini-2.0-flash",
197
199
  usage: result.usage,
198
- webSearchRequests: 10, // Number of web searches
200
+ webSearchRequests: 10, // Number of web searches
201
+ googleMapsRequests: 5, // Number of Google Maps API calls
202
+ });
203
+
204
+ console.log(cost.webSearchCost); // $0.14 for 10 searches
205
+ console.log(cost.googleMapsCost); // $0.035 for 5 maps requests
206
+ ```
207
+
208
+ ### Auto-Detection from Tool Calls
209
+
210
+ Automatically detect web search and Google Maps usage from AI SDK results:
211
+
212
+ ```typescript
213
+ import { createTracker } from "ai-sdk-cost-calculator";
214
+
215
+ const tracker = createTracker();
216
+
217
+ await generateText({
218
+ model: google("gemini-2.0-flash"),
219
+ prompt: "Find coffee shops near Tokyo Station",
220
+ tools: { web_search: mySearchTool, places: myPlacesTool },
221
+ onFinish: tracker.onFinish("gemini-2.0-flash", undefined, {
222
+ webSearchTools: [], // Use default tool names for detection
223
+ }),
224
+ });
225
+
226
+ // Or add custom tool names
227
+ await generateText({
228
+ model: openai("gpt-4o"),
229
+ prompt: "Search the web",
230
+ tools: { my_custom_search: customSearchTool },
231
+ onFinish: tracker.onFinish("gpt-4o", undefined, {
232
+ webSearchTools: ["my_custom_search"], // Add to defaults
233
+ }),
199
234
  });
235
+ ```
200
236
 
201
- console.log(cost.webSearchCost); // $0.10 for 10 searches
237
+ #### Using `detectRequestsFromResult` Directly
238
+
239
+ ```typescript
240
+ import { detectRequestsFromResult, calculateCost } from "ai-sdk-cost-calculator";
241
+
242
+ const result = await generateText({
243
+ model: google("gemini-2.0-flash"),
244
+ prompt: "What's the weather?",
245
+ tools: { web_search: searchTool },
246
+ });
247
+
248
+ // Detect tool usage
249
+ const { webSearchRequests, googleMapsRequests } = detectRequestsFromResult(result, {
250
+ webSearchTools: ["my_search"], // Optional: add custom tool names
251
+ });
252
+
253
+ const cost = calculateCost({
254
+ model: "gemini-2.0-flash",
255
+ usage: result.usage,
256
+ webSearchRequests,
257
+ googleMapsRequests,
258
+ });
202
259
  ```
203
260
 
204
- ### Web Search Pricing by Provider
261
+ #### Default Tool Names
205
262
 
206
- | Provider | Model | Cost per 1k searches | Notes |
207
- | ------------- | ---------------- | -------------------- | -------------------------- |
208
- | **OpenAI** | GPT-4o, GPT-4.1 | $10 | + tokens at model rate |
209
- | **OpenAI** | GPT-4o-mini | $10 | + 8k tokens per search |
210
- | **Google** | Gemini Flash | $14 | Grounding with Google |
211
- | **Google** | Gemini Pro | $35 | Grounding with Google |
212
- | **xAI** | Grok models | $5 | Web Search / X Search |
213
- | **Perplexity** | Sonar | $5 | Search-native |
214
- | **Perplexity** | Sonar Pro | $6 | Search-native |
263
+ The following tool names are detected by default:
264
+
265
+ **Web Search**: `web_search`, `webSearch`, `google_search`, `googleSearch`, `grounding`, `web_search_preview`, `tavily_search`, `brave_search`, `bing_search`, `duckduckgo_search`
266
+
267
+ **Google Maps**: `google_maps`, `googleMaps`, `place_search`, `placeSearch`, `geocode`, `places`
268
+
269
+ ### Pricing by Provider
270
+
271
+ | Provider | Model | Web Search (/1k) | Google Maps (/1k) | Notes |
272
+ | -------------- | ---------------- | ---------------- | ----------------- | ---------------------- |
273
+ | **OpenAI** | GPT-4o, GPT-4.1 | $10 | - | + tokens at model rate |
274
+ | **OpenAI** | GPT-4o-mini | $10 | - | + 8k tokens per search |
275
+ | **Google** | Gemini Flash | $14 | $7 | Grounding with Google |
276
+ | **Google** | Gemini Pro | $35 | $7 | Grounding with Google |
277
+ | **xAI** | Grok models | $5 | - | Web Search / X Search |
278
+ | **Perplexity** | Sonar | $5 | - | Search-native |
279
+ | **Perplexity** | Sonar Pro | $6 | - | Search-native |
215
280
 
216
281
  ## API Reference
217
282
 
@@ -243,26 +308,28 @@ const cost = calculateCost({
243
308
 
244
309
  #### Options
245
310
 
246
- | Property | Type | Required | Description |
247
- | ------------------- | -------------------- | -------- | ---------------------------------------------------------- |
248
- | `model` | `string` | Yes | Model identifier (e.g., `"gpt-4o"`, `"claude-sonnet-4-5"`) |
249
- | `usage` | `LanguageModelUsage` | Yes | Token usage from AI SDK |
250
- | `customPricing` | `ModelPricing` | No | Override default pricing |
251
- | `webSearchRequests` | `number` | No | Number of web search requests |
311
+ | Property | Type | Required | Description |
312
+ | -------------------- | -------------------- | -------- | ---------------------------------------------------------- |
313
+ | `model` | `string` | Yes | Model identifier (e.g., `"gpt-4o"`, `"claude-sonnet-4-5"`) |
314
+ | `usage` | `LanguageModelUsage` | Yes | Token usage from AI SDK |
315
+ | `customPricing` | `ModelPricing` | No | Override default pricing |
316
+ | `webSearchRequests` | `number` | No | Number of web search requests |
317
+ | `googleMapsRequests` | `number` | No | Number of Google Maps API requests |
252
318
 
253
319
  #### Return Value: `CostBreakdown`
254
320
 
255
- | Property | Type | Description |
256
- | --------------- | --------- | -------------------------------------------- |
257
- | `inputCost` | `number` | Cost for input tokens (excluding cache) |
258
- | `outputCost` | `number` | Cost for output tokens (excluding reasoning) |
259
- | `cacheReadCost` | `number` | Cost for cached input tokens |
260
- | `cacheWriteCost`| `number` | Cost for writing to cache |
261
- | `reasoningCost` | `number` | Cost for reasoning tokens |
262
- | `webSearchCost` | `number` | Cost for web search requests |
263
- | `totalCost` | `number` | Sum of all costs |
264
- | `currency` | `"USD"` | Always USD |
265
- | `isLongContext` | `boolean` | Whether long context pricing was applied |
321
+ | Property | Type | Description |
322
+ | ---------------- | --------- | -------------------------------------------- |
323
+ | `inputCost` | `number` | Cost for input tokens (excluding cache) |
324
+ | `outputCost` | `number` | Cost for output tokens (excluding reasoning) |
325
+ | `cacheReadCost` | `number` | Cost for cached input tokens |
326
+ | `cacheWriteCost` | `number` | Cost for writing to cache |
327
+ | `reasoningCost` | `number` | Cost for reasoning tokens |
328
+ | `webSearchCost` | `number` | Cost for web search requests |
329
+ | `googleMapsCost` | `number` | Cost for Google Maps API requests |
330
+ | `totalCost` | `number` | Sum of all costs |
331
+ | `currency` | `"USD"` | Always USD |
332
+ | `isLongContext` | `boolean` | Whether long context pricing was applied |
266
333
 
267
334
  ### `createTracker(options?)`
268
335
 
@@ -408,7 +475,8 @@ const output = formatCostBreakdown(cost);
408
475
  // Cache Read: $0.000060
409
476
  // Output: $0.007500
410
477
  // Web Search: $0.050000
411
- // Total: $0.059960
478
+ // Google Maps: $0.007000
479
+ // Total: $0.066960
412
480
  ```
413
481
 
414
482
  ### `calculateStreamCost(streamResult, options)`
@@ -432,6 +500,57 @@ const cost = await calculateStreamCost(stream, {
432
500
  });
433
501
  ```
434
502
 
503
+ ### `detectRequestsFromResult(result, options?)`
504
+
505
+ Detect web search and Google Maps tool calls from an AI SDK result.
506
+
507
+ ```typescript
508
+ import { detectRequestsFromResult } from "ai-sdk-cost-calculator";
509
+
510
+ const result = await generateText({
511
+ model: google("gemini-2.0-flash"),
512
+ prompt: "Find restaurants",
513
+ tools: { web_search: searchTool, places: placesTool },
514
+ });
515
+
516
+ const { webSearchRequests, googleMapsRequests } = detectRequestsFromResult(result);
517
+
518
+ // With custom tool names (added to defaults)
519
+ const detected = detectRequestsFromResult(result, {
520
+ webSearchTools: ["my_search", "custom_tavily"],
521
+ googleMapsTools: ["location_finder"],
522
+ });
523
+ ```
524
+
525
+ | Parameter | Type | Required | Description |
526
+ | ---------------------- | --------------------- | -------- | ------------------------------------------ |
527
+ | `result` | `ResultWithToolCalls` | Yes | AI SDK result with toolCalls/steps |
528
+ | `options.webSearchTools` | `string[]` | No | Additional tool names to count as search |
529
+ | `options.googleMapsTools` | `string[]` | No | Additional tool names to count as maps |
530
+
531
+ ### `withDetectedRequests(result, options?)`
532
+
533
+ Convenience wrapper that returns detected requests for spreading into `calculateCost`.
534
+
535
+ ```typescript
536
+ import { withDetectedRequests, calculateCost } from "ai-sdk-cost-calculator";
537
+
538
+ const cost = calculateCost({
539
+ model: "gemini-2.0-flash",
540
+ usage: result.usage,
541
+ ...withDetectedRequests(result),
542
+ });
543
+
544
+ // With custom tool names
545
+ const cost2 = calculateCost({
546
+ model: "gemini-2.0-flash",
547
+ usage: result.usage,
548
+ ...withDetectedRequests(result, {
549
+ webSearchTools: ["my_search"],
550
+ }),
551
+ });
552
+ ```
553
+
435
554
  ## Supported Models
436
555
 
437
556
  ### OpenAI (23 models)
@@ -508,6 +627,7 @@ const cost = calculateCost({
508
627
  outputPer1MTokens: 8.0,
509
628
  cacheReadPer1MTokens: 1.0,
510
629
  webSearchPer1kRequests: 15,
630
+ googleMapsPer1kRequests: 10,
511
631
  },
512
632
  });
513
633
  ```
@@ -537,6 +657,10 @@ import type {
537
657
  CostAwareOptions,
538
658
  ResultWithCost,
539
659
  FinishResultWithCost,
660
+ // Auto-detection
661
+ DetectOptions,
662
+ DetectedRequests,
663
+ ResultWithToolCalls,
540
664
  } from "ai-sdk-cost-calculator";
541
665
  ```
542
666
 
@@ -8,6 +8,8 @@ export interface CalculateCostOptions {
8
8
  customPricing?: ModelPricing;
9
9
  /** Number of web search requests made (for grounding/live search) */
10
10
  webSearchRequests?: number;
11
+ /** Number of Google Maps API requests made */
12
+ googleMapsRequests?: number;
11
13
  }
12
14
  export declare function calculateCost(options: CalculateCostOptions): CostBreakdown;
13
15
  export declare function formatCost(cost: number, decimals?: number): string;
@@ -1 +1 @@
1
- {"version":3,"file":"calculator.d.ts","sourceRoot":"","sources":["../../src/core/calculator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM7C,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,CAAC;IAC1B,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAyDD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA+E1E;AAED,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,CA2BR"}
1
+ {"version":3,"file":"calculator.d.ts","sourceRoot":"","sources":["../../src/core/calculator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM7C,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,CAAC;IAC1B,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAyDD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAuF1E;AAED,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,CA8BR"}
@@ -35,7 +35,7 @@ function costFromTokens(tokens, per1MTokens) {
35
35
  return (tokens / TOKENS_PER_MILLION) * per1MTokens;
36
36
  }
37
37
  export function calculateCost(options) {
38
- const { model, usage, customPricing, webSearchRequests = 0 } = options;
38
+ const { model, usage, customPricing, webSearchRequests = 0, googleMapsRequests = 0 } = options;
39
39
  const pricing = customPricing ?? getModelPricingByModelId(model);
40
40
  if (!pricing) {
41
41
  throw new Error(`Unknown model: ${model}. Use customPricing option or add the model to pricing/providers`);
@@ -59,12 +59,18 @@ export function calculateCost(options) {
59
59
  webSearchCost += costFromTokens(searchTokens, effectivePricing.inputPer1MTokens);
60
60
  }
61
61
  }
62
+ // Calculate Google Maps cost
63
+ let googleMapsCost = 0;
64
+ if (googleMapsRequests > 0 && pricing.googleMapsPer1kRequests) {
65
+ googleMapsCost = (googleMapsRequests / 1000) * pricing.googleMapsPer1kRequests;
66
+ }
62
67
  const totalCost = inputCost +
63
68
  outputCost +
64
69
  cacheReadCost +
65
70
  cacheWriteCost +
66
71
  reasoningCost +
67
- webSearchCost;
72
+ webSearchCost +
73
+ googleMapsCost;
68
74
  return {
69
75
  inputCost: roundToMicroDollars(inputCost),
70
76
  outputCost: roundToMicroDollars(outputCost),
@@ -72,6 +78,7 @@ export function calculateCost(options) {
72
78
  cacheWriteCost: roundToMicroDollars(cacheWriteCost),
73
79
  reasoningCost: roundToMicroDollars(reasoningCost),
74
80
  webSearchCost: roundToMicroDollars(webSearchCost),
81
+ googleMapsCost: roundToMicroDollars(googleMapsCost),
75
82
  totalCost: roundToMicroDollars(totalCost),
76
83
  currency: "USD",
77
84
  isLongContext: effectivePricing.isLongContext,
@@ -103,6 +110,9 @@ export function formatCostBreakdown(result, decimals = 6) {
103
110
  if (result.webSearchCost > 0) {
104
111
  lines.push(`Web Search: ${formatCost(result.webSearchCost, decimals)}`);
105
112
  }
113
+ if (result.googleMapsCost > 0) {
114
+ lines.push(`Google Maps: ${formatCost(result.googleMapsCost, decimals)}`);
115
+ }
106
116
  lines.push(`Total: ${formatCost(result.totalCost, decimals)}`);
107
117
  return lines.join("\n");
108
118
  }
@@ -5,6 +5,7 @@ export interface CostBreakdown {
5
5
  cacheWriteCost: number;
6
6
  reasoningCost: number;
7
7
  webSearchCost: number;
8
+ googleMapsCost: number;
8
9
  totalCost: number;
9
10
  currency: "USD";
10
11
  isLongContext: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,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,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;CACxB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,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,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;CACxB"}
package/dist/index.d.mts CHANGED
@@ -13,6 +13,7 @@ interface ModelPricing {
13
13
  longContextCacheWritePer1MTokens?: number;
14
14
  webSearchPer1kRequests?: number;
15
15
  webSearchTokensPerRequest?: number;
16
+ googleMapsPer1kRequests?: number;
16
17
  }
17
18
  interface ProviderPricing {
18
19
  [modelId: string]: ModelPricing;
@@ -47,6 +48,7 @@ interface CostBreakdown {
47
48
  cacheWriteCost: number;
48
49
  reasoningCost: number;
49
50
  webSearchCost: number;
51
+ googleMapsCost: number;
50
52
  totalCost: number;
51
53
  currency: "USD";
52
54
  isLongContext: boolean;
@@ -58,6 +60,8 @@ interface CalculateCostOptions {
58
60
  customPricing?: ModelPricing;
59
61
  /** Number of web search requests made (for grounding/live search) */
60
62
  webSearchRequests?: number;
63
+ /** Number of Google Maps API requests made */
64
+ googleMapsRequests?: number;
61
65
  }
62
66
  declare function calculateCost(options: CalculateCostOptions): CostBreakdown;
63
67
  declare function formatCost(cost: number, decimals?: number): string;
@@ -86,12 +90,116 @@ declare function calculateStreamCost<T extends {
86
90
  usage: LanguageModelUsage;
87
91
  }>;
88
92
 
93
+ /**
94
+ * Utility for auto-detecting web search and Google Maps requests from AI SDK results
95
+ */
96
+ /** Default web search tool names across providers */
97
+ declare const DEFAULT_WEB_SEARCH_TOOLS: string[];
98
+ /** Default Google Maps tool names */
99
+ declare const DEFAULT_GOOGLE_MAPS_TOOLS: string[];
100
+ interface DetectedRequests {
101
+ webSearchRequests: number;
102
+ googleMapsRequests: number;
103
+ }
104
+ interface DetectOptions {
105
+ /** Additional tool names to count as web search (added to defaults) */
106
+ webSearchTools?: string[];
107
+ /** Additional tool names to count as Google Maps (added to defaults) */
108
+ googleMapsTools?: string[];
109
+ }
110
+ interface ToolCall {
111
+ toolName?: string;
112
+ type?: string;
113
+ name?: string;
114
+ }
115
+ interface Step {
116
+ toolCalls?: ToolCall[];
117
+ toolResults?: unknown[];
118
+ }
119
+ interface ProviderMetadata {
120
+ google?: {
121
+ groundingMetadata?: {
122
+ webSearchQueries?: unknown[];
123
+ searchEntryPoint?: unknown;
124
+ groundingChunks?: unknown[];
125
+ groundingSupports?: unknown[];
126
+ };
127
+ };
128
+ [key: string]: unknown;
129
+ }
130
+ interface ResultWithToolCalls {
131
+ toolCalls?: ToolCall[];
132
+ steps?: Step[];
133
+ experimental_providerMetadata?: ProviderMetadata;
134
+ providerMetadata?: ProviderMetadata;
135
+ }
136
+ /**
137
+ * Detects web search and Google Maps requests from an AI SDK result object.
138
+ *
139
+ * Supports:
140
+ * - Tool calls (toolCalls array)
141
+ * - Multi-step generations (steps array)
142
+ * - Google Gemini grounding metadata (experimental_providerMetadata.google.groundingMetadata)
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const result = await generateText({
147
+ * model: google("gemini-2.0-flash"),
148
+ * prompt: "What's the weather today?",
149
+ * tools: { web_search: webSearchTool },
150
+ * });
151
+ *
152
+ * // Use defaults
153
+ * const { webSearchRequests, googleMapsRequests } = detectRequestsFromResult(result);
154
+ *
155
+ * // Or add custom tool names
156
+ * const detected = detectRequestsFromResult(result, {
157
+ * webSearchTools: ["my_search_tool", "custom_search"],
158
+ * googleMapsTools: ["location_finder"],
159
+ * });
160
+ * ```
161
+ */
162
+ declare function detectRequestsFromResult(result: ResultWithToolCalls, options?: DetectOptions): DetectedRequests;
163
+ /**
164
+ * Creates options with auto-detected web search and Google Maps requests.
165
+ * Merges detected counts with any manually specified counts.
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const result = await generateText({
170
+ * model: google("gemini-2.0-flash"),
171
+ * prompt: "Find coffee shops near Tokyo Station",
172
+ * });
173
+ *
174
+ * const cost = calculateCost({
175
+ * model: "gemini-2.0-flash",
176
+ * usage: result.usage,
177
+ * ...withDetectedRequests(result),
178
+ * });
179
+ *
180
+ * // With custom tool names
181
+ * const cost2 = calculateCost({
182
+ * model: "gemini-2.0-flash",
183
+ * usage: result.usage,
184
+ * ...withDetectedRequests(result, {
185
+ * webSearchTools: ["my_search"],
186
+ * }),
187
+ * });
188
+ * ```
189
+ */
190
+ declare function withDetectedRequests(result: ResultWithToolCalls, options?: DetectOptions & {
191
+ webSearchRequests?: number;
192
+ googleMapsRequests?: number;
193
+ }): DetectedRequests;
194
+
89
195
  /**
90
196
  * Options for adding usage to the tracker
91
197
  */
92
- interface AddUsageOptions {
198
+ interface AddUsageOptions extends DetectOptions {
93
199
  /** Number of web search requests made */
94
200
  webSearchRequests?: number;
201
+ /** Number of Google Maps API requests made */
202
+ googleMapsRequests?: number;
95
203
  }
96
204
  /**
97
205
  * Per-model cost summary
@@ -202,11 +310,13 @@ interface FinishResultWithCost {
202
310
  /**
203
311
  * Options for cost-aware wrappers
204
312
  */
205
- interface CostAwareOptions {
313
+ interface CostAwareOptions extends DetectOptions {
206
314
  /** Custom pricing override */
207
315
  customPricing?: ModelPricing;
208
316
  /** Number of web search requests */
209
317
  webSearchRequests?: number;
318
+ /** Number of Google Maps API requests */
319
+ googleMapsRequests?: number;
210
320
  /** Callback when cost is calculated */
211
321
  onCost?: (cost: CostBreakdown, usage: LanguageModelUsage) => void;
212
322
  }
@@ -325,4 +435,4 @@ declare function createCostAwareAI(options?: CreateCostAwareAIOptions): CostAwar
325
435
  */
326
436
  declare function getCost(model: LanguageModel | string, usage: LanguageModelUsage, options?: CostAwareOptions): CostBreakdown;
327
437
 
328
- export { type AddUsageOptions, type CalculateCostOptions, type CostAwareAI, type CostAwareOptions, type CostBreakdown, type CostTracker, type CreateCostAwareAIOptions, type CreateCostTrackerOptions, type CreateMultiModelTrackerOptions, type FinishResultWithCost, type ModelCostSummary, type ModelPricing, type MultiModelCostTracker, type Provider, type ProviderPricing, type ResultWithCost, type StreamCostOptions, allPricing, anthropicPricing, calculateCost, calculateStreamCost, createCostAwareAI, createCostTracker, createTracker, deepseekPricing, flatPricing, formatCost, formatCostBreakdown, getAllSupportedModels, getCost, getModelId, getModelPricing, getModelPricingByModelId, googlePricing, onFinishWithCost, openaiPricing, perplexityPricing, withCost, xaiPricing };
438
+ export { type AddUsageOptions, type CalculateCostOptions, type CostAwareAI, type CostAwareOptions, type CostBreakdown, type CostTracker, type CreateCostAwareAIOptions, type CreateCostTrackerOptions, type CreateMultiModelTrackerOptions, DEFAULT_GOOGLE_MAPS_TOOLS, DEFAULT_WEB_SEARCH_TOOLS, type DetectOptions, type DetectedRequests, type FinishResultWithCost, type ModelCostSummary, type ModelPricing, type MultiModelCostTracker, type Provider, type ProviderPricing, type ResultWithCost, type ResultWithToolCalls, type StreamCostOptions, allPricing, anthropicPricing, calculateCost, calculateStreamCost, createCostAwareAI, createCostTracker, createTracker, deepseekPricing, detectRequestsFromResult, flatPricing, formatCost, formatCostBreakdown, getAllSupportedModels, getCost, getModelId, getModelPricing, getModelPricingByModelId, googlePricing, onFinishWithCost, openaiPricing, perplexityPricing, withCost, withDetectedRequests, xaiPricing };
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ interface ModelPricing {
13
13
  longContextCacheWritePer1MTokens?: number;
14
14
  webSearchPer1kRequests?: number;
15
15
  webSearchTokensPerRequest?: number;
16
+ googleMapsPer1kRequests?: number;
16
17
  }
17
18
  interface ProviderPricing {
18
19
  [modelId: string]: ModelPricing;
@@ -47,6 +48,7 @@ interface CostBreakdown {
47
48
  cacheWriteCost: number;
48
49
  reasoningCost: number;
49
50
  webSearchCost: number;
51
+ googleMapsCost: number;
50
52
  totalCost: number;
51
53
  currency: "USD";
52
54
  isLongContext: boolean;
@@ -58,6 +60,8 @@ interface CalculateCostOptions {
58
60
  customPricing?: ModelPricing;
59
61
  /** Number of web search requests made (for grounding/live search) */
60
62
  webSearchRequests?: number;
63
+ /** Number of Google Maps API requests made */
64
+ googleMapsRequests?: number;
61
65
  }
62
66
  declare function calculateCost(options: CalculateCostOptions): CostBreakdown;
63
67
  declare function formatCost(cost: number, decimals?: number): string;
@@ -86,12 +90,116 @@ declare function calculateStreamCost<T extends {
86
90
  usage: LanguageModelUsage;
87
91
  }>;
88
92
 
93
+ /**
94
+ * Utility for auto-detecting web search and Google Maps requests from AI SDK results
95
+ */
96
+ /** Default web search tool names across providers */
97
+ declare const DEFAULT_WEB_SEARCH_TOOLS: string[];
98
+ /** Default Google Maps tool names */
99
+ declare const DEFAULT_GOOGLE_MAPS_TOOLS: string[];
100
+ interface DetectedRequests {
101
+ webSearchRequests: number;
102
+ googleMapsRequests: number;
103
+ }
104
+ interface DetectOptions {
105
+ /** Additional tool names to count as web search (added to defaults) */
106
+ webSearchTools?: string[];
107
+ /** Additional tool names to count as Google Maps (added to defaults) */
108
+ googleMapsTools?: string[];
109
+ }
110
+ interface ToolCall {
111
+ toolName?: string;
112
+ type?: string;
113
+ name?: string;
114
+ }
115
+ interface Step {
116
+ toolCalls?: ToolCall[];
117
+ toolResults?: unknown[];
118
+ }
119
+ interface ProviderMetadata {
120
+ google?: {
121
+ groundingMetadata?: {
122
+ webSearchQueries?: unknown[];
123
+ searchEntryPoint?: unknown;
124
+ groundingChunks?: unknown[];
125
+ groundingSupports?: unknown[];
126
+ };
127
+ };
128
+ [key: string]: unknown;
129
+ }
130
+ interface ResultWithToolCalls {
131
+ toolCalls?: ToolCall[];
132
+ steps?: Step[];
133
+ experimental_providerMetadata?: ProviderMetadata;
134
+ providerMetadata?: ProviderMetadata;
135
+ }
136
+ /**
137
+ * Detects web search and Google Maps requests from an AI SDK result object.
138
+ *
139
+ * Supports:
140
+ * - Tool calls (toolCalls array)
141
+ * - Multi-step generations (steps array)
142
+ * - Google Gemini grounding metadata (experimental_providerMetadata.google.groundingMetadata)
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const result = await generateText({
147
+ * model: google("gemini-2.0-flash"),
148
+ * prompt: "What's the weather today?",
149
+ * tools: { web_search: webSearchTool },
150
+ * });
151
+ *
152
+ * // Use defaults
153
+ * const { webSearchRequests, googleMapsRequests } = detectRequestsFromResult(result);
154
+ *
155
+ * // Or add custom tool names
156
+ * const detected = detectRequestsFromResult(result, {
157
+ * webSearchTools: ["my_search_tool", "custom_search"],
158
+ * googleMapsTools: ["location_finder"],
159
+ * });
160
+ * ```
161
+ */
162
+ declare function detectRequestsFromResult(result: ResultWithToolCalls, options?: DetectOptions): DetectedRequests;
163
+ /**
164
+ * Creates options with auto-detected web search and Google Maps requests.
165
+ * Merges detected counts with any manually specified counts.
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const result = await generateText({
170
+ * model: google("gemini-2.0-flash"),
171
+ * prompt: "Find coffee shops near Tokyo Station",
172
+ * });
173
+ *
174
+ * const cost = calculateCost({
175
+ * model: "gemini-2.0-flash",
176
+ * usage: result.usage,
177
+ * ...withDetectedRequests(result),
178
+ * });
179
+ *
180
+ * // With custom tool names
181
+ * const cost2 = calculateCost({
182
+ * model: "gemini-2.0-flash",
183
+ * usage: result.usage,
184
+ * ...withDetectedRequests(result, {
185
+ * webSearchTools: ["my_search"],
186
+ * }),
187
+ * });
188
+ * ```
189
+ */
190
+ declare function withDetectedRequests(result: ResultWithToolCalls, options?: DetectOptions & {
191
+ webSearchRequests?: number;
192
+ googleMapsRequests?: number;
193
+ }): DetectedRequests;
194
+
89
195
  /**
90
196
  * Options for adding usage to the tracker
91
197
  */
92
- interface AddUsageOptions {
198
+ interface AddUsageOptions extends DetectOptions {
93
199
  /** Number of web search requests made */
94
200
  webSearchRequests?: number;
201
+ /** Number of Google Maps API requests made */
202
+ googleMapsRequests?: number;
95
203
  }
96
204
  /**
97
205
  * Per-model cost summary
@@ -202,11 +310,13 @@ interface FinishResultWithCost {
202
310
  /**
203
311
  * Options for cost-aware wrappers
204
312
  */
205
- interface CostAwareOptions {
313
+ interface CostAwareOptions extends DetectOptions {
206
314
  /** Custom pricing override */
207
315
  customPricing?: ModelPricing;
208
316
  /** Number of web search requests */
209
317
  webSearchRequests?: number;
318
+ /** Number of Google Maps API requests */
319
+ googleMapsRequests?: number;
210
320
  /** Callback when cost is calculated */
211
321
  onCost?: (cost: CostBreakdown, usage: LanguageModelUsage) => void;
212
322
  }
@@ -325,4 +435,4 @@ declare function createCostAwareAI(options?: CreateCostAwareAIOptions): CostAwar
325
435
  */
326
436
  declare function getCost(model: LanguageModel | string, usage: LanguageModelUsage, options?: CostAwareOptions): CostBreakdown;
327
437
 
328
- export { type AddUsageOptions, type CalculateCostOptions, type CostAwareAI, type CostAwareOptions, type CostBreakdown, type CostTracker, type CreateCostAwareAIOptions, type CreateCostTrackerOptions, type CreateMultiModelTrackerOptions, type FinishResultWithCost, type ModelCostSummary, type ModelPricing, type MultiModelCostTracker, type Provider, type ProviderPricing, type ResultWithCost, type StreamCostOptions, allPricing, anthropicPricing, calculateCost, calculateStreamCost, createCostAwareAI, createCostTracker, createTracker, deepseekPricing, flatPricing, formatCost, formatCostBreakdown, getAllSupportedModels, getCost, getModelId, getModelPricing, getModelPricingByModelId, googlePricing, onFinishWithCost, openaiPricing, perplexityPricing, withCost, xaiPricing };
438
+ export { type AddUsageOptions, type CalculateCostOptions, type CostAwareAI, type CostAwareOptions, type CostBreakdown, type CostTracker, type CreateCostAwareAIOptions, type CreateCostTrackerOptions, type CreateMultiModelTrackerOptions, DEFAULT_GOOGLE_MAPS_TOOLS, DEFAULT_WEB_SEARCH_TOOLS, type DetectOptions, type DetectedRequests, type FinishResultWithCost, type ModelCostSummary, type ModelPricing, type MultiModelCostTracker, type Provider, type ProviderPricing, type ResultWithCost, type ResultWithToolCalls, type StreamCostOptions, allPricing, anthropicPricing, calculateCost, calculateStreamCost, createCostAwareAI, createCostTracker, createTracker, deepseekPricing, detectRequestsFromResult, flatPricing, formatCost, formatCostBreakdown, getAllSupportedModels, getCost, getModelId, getModelPricing, getModelPricingByModelId, googlePricing, onFinishWithCost, openaiPricing, perplexityPricing, withCost, withDetectedRequests, xaiPricing };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,WAAW,EAChB,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,aAAa,EACb,KAAK,qBAAqB,EAC1B,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,OAAO,EACP,UAAU,EACV,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,QAAQ,GACd,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,UAAU,EACV,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,WAAW,EAChB,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,aAAa,EACb,KAAK,qBAAqB,EAC1B,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,OAAO,EACP,UAAU,EACV,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,QAAQ,GACd,MAAM,WAAW,CAAC"}