@warlock.js/ai-google 5.31.0 → 5.32.0

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/llms-full.txt CHANGED
@@ -295,19 +295,30 @@ ignored. `GoogleCallOptions` is exported. `systemInstruction`, `tools`,
295
295
  `abortSignal` and `httpOptions` are protected and throw `InvalidRequestError`;
296
296
  use neutral messages/tools/signal and SDK transport configuration for them.
297
297
 
298
- `model.countTokens(messages, options?)` calls the native counting endpoint with
299
- the same converted contents. In Vertex mode it also counts the same system
300
- instruction and tools as generation and forwards cancellation. In Developer API
301
- mode, the installed Google SDK cannot count system instructions or tools through
302
- its typed count endpoint: requests containing them fail explicitly before a
303
- network call. Cached-content references also fail explicitly, since this SDK
304
- count endpoint cannot reproduce them. The adapter never silently counts only a
305
- subset of a prompt. `sdk.count(text)` remains a separate offline estimate.
298
+ `model.countTokens(messages, options?)` counts the converted contents, system
299
+ instructions and tools on both the Gemini Developer API (API key) and Vertex AI.
300
+ Developer API counting sends the full `generateContentRequest`, including tool
301
+ configuration and generation settings, as documented in the
302
+ [Gemini token-counting reference](https://ai.google.dev/api/tokens). It uses the
303
+ existing SDK transport, preserving API-key auth, custom fetch, base URL/proxy
304
+ settings, headers, retries and cancellation. Vertex retains its typed SDK path.
305
+
306
+ Cached-content references still throw `InvalidRequestError` with
307
+ `reason: "count-unsupported"`. Use `countInputTokens` for budget preflight: it
308
+ returns an estimate for this explicit limitation; authentication, network,
309
+ rate-limit and ordinary validation errors still propagate. `sdk.count(text)`
310
+ remains a separate offline estimate.
306
311
 
307
312
  ```ts
308
- if (model.countTokens) {
309
- const inputTokens = await model.countTokens(messages, options);
310
- }
313
+ import { countInputTokens } from "@warlock.js/ai";
314
+
315
+ const messages = [
316
+ { role: "system" as const, content: "Be concise." },
317
+ { role: "user" as const, content: "Hello" },
318
+ ];
319
+ const tools = [{ name: "lookup", description: "Look up data", execute: async () => "ok" }];
320
+ const { tokens, source } = await countInputTokens(model, messages, { tools });
321
+ // source is "native" for ordinary Developer API and Vertex requests, including tools.
311
322
  ```
312
323
 
313
324
  ## When NOT to use this skill
@@ -321,4 +332,42 @@ if (model.countTokens) {
321
332
  - The `pick-ai-provider` topic of the `warlock-js-ai` skill
322
333
  - The `embed-text` topic of the `warlock-js-ai` skill
323
334
 
335
+ ## Search grounding metadata and fees
336
+
337
+ `response.providerMetadata.google.groundingMetadata` retains the raw grounding
338
+ metadata for each indexed candidate: queries, chunks, supports and search entry
339
+ point. Streaming `done` carries the same metadata. Agent reports retain it per
340
+ trip. Hosted search never produces a local function call.
341
+
342
+ `usage.serverToolUse.webSearchRequests` counts unique nonempty
343
+ `groundingMetadata.webSearchQueries`; `googleWebSearchQueries` records the raw
344
+ array length, including duplicates and empty entries. Stream snapshots replace
345
+ prior metadata per candidate rather than accumulating repeated snapshots.
346
+ The [official schema](https://ai.google.dev/api/generate-content#GroundingMetadata)
347
+ defines the queries array.
348
+
349
+ [Google's pricing guide](https://ai.google.dev/gemini-api/docs/google-search#pricing)
350
+ (verified 2026-10-18) bills Gemini 3 and newer per unique nonempty query: $14 per
351
+ 1,000 queries after the shared monthly free allowance. You can explicitly use
352
+ the exported `GOOGLE_SERVER_TOOL_PRICING` as `pricing.serverTools` for that
353
+ model family. Gemini 2.5 and older bill per grounded prompt; their query count
354
+ is not a billable-prompt count, so leave this fee unpriced or account for it
355
+ outside this per-query table. Free allowances are not subtracted locally.
356
+ No web-fetch/code-execution count is inferred from result parts. See
357
+ [cost tracking](https://warlock.js.org/v/latest/ai/recipes/cost-tracking/#hosted-tool-request-fees).
358
+
359
+ ```ts
360
+ import { GOOGLE_SERVER_TOOL_PRICING } from "@warlock.js/ai-google";
361
+ const model = google.model({
362
+ name: "gemini-3.5-flash-lite",
363
+
364
+ pricing: { ...{ input: 0.3, output: 2.5 }, serverTools: GOOGLE_SERVER_TOOL_PRICING },
365
+ });
366
+ const response = await model.complete(messages, {
367
+ providerTools: [{ provider: "google", definition: { googleSearch: {} } }],
368
+ });
369
+ console.log(response.usage.serverToolUse?.webSearchRequests);
370
+ console.log(response.providerMetadata);
371
+ ```
372
+
324
373
 
package/package.json CHANGED
@@ -15,13 +15,13 @@
15
15
  "directory": "packages/ai-google"
16
16
  },
17
17
  "peerDependencies": {
18
- "@warlock.js/ai": "5.31.0"
18
+ "@warlock.js/ai": "5.32.0"
19
19
  },
20
20
  "dependencies": {
21
21
  "@google/genai": "^2.17.1",
22
- "@warlock.js/logger": "5.31.0"
22
+ "@warlock.js/logger": "5.32.0"
23
23
  },
24
- "version": "5.31.0",
24
+ "version": "5.32.0",
25
25
  "main": "./cjs/index.cjs",
26
26
  "module": "./esm/index.mjs",
27
27
  "types": "./esm/index.d.mts",
@@ -287,19 +287,30 @@ ignored. `GoogleCallOptions` is exported. `systemInstruction`, `tools`,
287
287
  `abortSignal` and `httpOptions` are protected and throw `InvalidRequestError`;
288
288
  use neutral messages/tools/signal and SDK transport configuration for them.
289
289
 
290
- `model.countTokens(messages, options?)` calls the native counting endpoint with
291
- the same converted contents. In Vertex mode it also counts the same system
292
- instruction and tools as generation and forwards cancellation. In Developer API
293
- mode, the installed Google SDK cannot count system instructions or tools through
294
- its typed count endpoint: requests containing them fail explicitly before a
295
- network call. Cached-content references also fail explicitly, since this SDK
296
- count endpoint cannot reproduce them. The adapter never silently counts only a
297
- subset of a prompt. `sdk.count(text)` remains a separate offline estimate.
290
+ `model.countTokens(messages, options?)` counts the converted contents, system
291
+ instructions and tools on both the Gemini Developer API (API key) and Vertex AI.
292
+ Developer API counting sends the full `generateContentRequest`, including tool
293
+ configuration and generation settings, as documented in the
294
+ [Gemini token-counting reference](https://ai.google.dev/api/tokens). It uses the
295
+ existing SDK transport, preserving API-key auth, custom fetch, base URL/proxy
296
+ settings, headers, retries and cancellation. Vertex retains its typed SDK path.
297
+
298
+ Cached-content references still throw `InvalidRequestError` with
299
+ `reason: "count-unsupported"`. Use `countInputTokens` for budget preflight: it
300
+ returns an estimate for this explicit limitation; authentication, network,
301
+ rate-limit and ordinary validation errors still propagate. `sdk.count(text)`
302
+ remains a separate offline estimate.
298
303
 
299
304
  ```ts
300
- if (model.countTokens) {
301
- const inputTokens = await model.countTokens(messages, options);
302
- }
305
+ import { countInputTokens } from "@warlock.js/ai";
306
+
307
+ const messages = [
308
+ { role: "system" as const, content: "Be concise." },
309
+ { role: "user" as const, content: "Hello" },
310
+ ];
311
+ const tools = [{ name: "lookup", description: "Look up data", execute: async () => "ok" }];
312
+ const { tokens, source } = await countInputTokens(model, messages, { tools });
313
+ // source is "native" for ordinary Developer API and Vertex requests, including tools.
303
314
  ```
304
315
 
305
316
  ## When NOT to use this skill
@@ -312,3 +323,41 @@ if (model.countTokens) {
312
323
  - The `run-ai-agent` topic of the `warlock-js-ai` skill
313
324
  - The `pick-ai-provider` topic of the `warlock-js-ai` skill
314
325
  - The `embed-text` topic of the `warlock-js-ai` skill
326
+
327
+ ## Search grounding metadata and fees
328
+
329
+ `response.providerMetadata.google.groundingMetadata` retains the raw grounding
330
+ metadata for each indexed candidate: queries, chunks, supports and search entry
331
+ point. Streaming `done` carries the same metadata. Agent reports retain it per
332
+ trip. Hosted search never produces a local function call.
333
+
334
+ `usage.serverToolUse.webSearchRequests` counts unique nonempty
335
+ `groundingMetadata.webSearchQueries`; `googleWebSearchQueries` records the raw
336
+ array length, including duplicates and empty entries. Stream snapshots replace
337
+ prior metadata per candidate rather than accumulating repeated snapshots.
338
+ The [official schema](https://ai.google.dev/api/generate-content#GroundingMetadata)
339
+ defines the queries array.
340
+
341
+ [Google's pricing guide](https://ai.google.dev/gemini-api/docs/google-search#pricing)
342
+ (verified 2026-10-18) bills Gemini 3 and newer per unique nonempty query: $14 per
343
+ 1,000 queries after the shared monthly free allowance. You can explicitly use
344
+ the exported `GOOGLE_SERVER_TOOL_PRICING` as `pricing.serverTools` for that
345
+ model family. Gemini 2.5 and older bill per grounded prompt; their query count
346
+ is not a billable-prompt count, so leave this fee unpriced or account for it
347
+ outside this per-query table. Free allowances are not subtracted locally.
348
+ No web-fetch/code-execution count is inferred from result parts. See
349
+ [cost tracking](https://warlock.js.org/v/latest/ai/recipes/cost-tracking/#hosted-tool-request-fees).
350
+
351
+ ```ts
352
+ import { GOOGLE_SERVER_TOOL_PRICING } from "@warlock.js/ai-google";
353
+ const model = google.model({
354
+ name: "gemini-3.5-flash-lite",
355
+
356
+ pricing: { ...{ input: 0.3, output: 2.5 }, serverTools: GOOGLE_SERVER_TOOL_PRICING },
357
+ });
358
+ const response = await model.complete(messages, {
359
+ providerTools: [{ provider: "google", definition: { googleSearch: {} } }],
360
+ });
361
+ console.log(response.usage.serverToolUse?.webSearchRequests);
362
+ console.log(response.providerMetadata);
363
+ ```