@ai-sdk/google 3.0.37 → 3.0.39

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @ai-sdk/google
2
2
 
3
+ ## 3.0.39
4
+
5
+ ### Patch Changes
6
+
7
+ - 2565e70: feat(google): add support for image search, replace obsolete google_search_retrieval implementation
8
+
9
+ ## 3.0.38
10
+
11
+ ### Patch Changes
12
+
13
+ - 2291047: fix(ai): fix missing support for image thought signatures (e.g. for Gemini image models)
14
+
3
15
  ## 3.0.37
4
16
 
5
17
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -82,6 +82,7 @@ declare const responseSchema: _ai_sdk_provider_utils.LazySchema<{
82
82
  }[] | null | undefined;
83
83
  groundingMetadata?: {
84
84
  webSearchQueries?: string[] | null | undefined;
85
+ imageSearchQueries?: string[] | null | undefined;
85
86
  retrievalQueries?: string[] | null | undefined;
86
87
  searchEntryPoint?: {
87
88
  renderedContent: string;
@@ -91,6 +92,12 @@ declare const responseSchema: _ai_sdk_provider_utils.LazySchema<{
91
92
  uri: string;
92
93
  title?: string | null | undefined;
93
94
  } | null | undefined;
95
+ image?: {
96
+ sourceUri: string;
97
+ imageUri: string;
98
+ title?: string | null | undefined;
99
+ domain?: string | null | undefined;
100
+ } | null | undefined;
94
101
  retrievedContext?: {
95
102
  uri?: string | null | undefined;
96
103
  title?: string | null | undefined;
@@ -201,8 +208,15 @@ declare const googleTools: {
201
208
  * Must have name "google_search".
202
209
  */
203
210
  googleSearch: _ai_sdk_provider_utils.ProviderToolFactory<{}, {
204
- mode?: "MODE_DYNAMIC" | "MODE_UNSPECIFIED";
205
- dynamicThreshold?: number;
211
+ [x: string]: unknown;
212
+ searchTypes?: {
213
+ webSearch?: Record<string, never> | undefined;
214
+ imageSearch?: Record<string, never> | undefined;
215
+ } | undefined;
216
+ timeRangeFilter?: {
217
+ startTime: string;
218
+ endTime: string;
219
+ } | undefined;
206
220
  }>;
207
221
  /**
208
222
  * Creates an Enterprise Web Search tool for grounding responses using a compliance-focused web index.
package/dist/index.d.ts CHANGED
@@ -82,6 +82,7 @@ declare const responseSchema: _ai_sdk_provider_utils.LazySchema<{
82
82
  }[] | null | undefined;
83
83
  groundingMetadata?: {
84
84
  webSearchQueries?: string[] | null | undefined;
85
+ imageSearchQueries?: string[] | null | undefined;
85
86
  retrievalQueries?: string[] | null | undefined;
86
87
  searchEntryPoint?: {
87
88
  renderedContent: string;
@@ -91,6 +92,12 @@ declare const responseSchema: _ai_sdk_provider_utils.LazySchema<{
91
92
  uri: string;
92
93
  title?: string | null | undefined;
93
94
  } | null | undefined;
95
+ image?: {
96
+ sourceUri: string;
97
+ imageUri: string;
98
+ title?: string | null | undefined;
99
+ domain?: string | null | undefined;
100
+ } | null | undefined;
94
101
  retrievedContext?: {
95
102
  uri?: string | null | undefined;
96
103
  title?: string | null | undefined;
@@ -201,8 +208,15 @@ declare const googleTools: {
201
208
  * Must have name "google_search".
202
209
  */
203
210
  googleSearch: _ai_sdk_provider_utils.ProviderToolFactory<{}, {
204
- mode?: "MODE_DYNAMIC" | "MODE_UNSPECIFIED";
205
- dynamicThreshold?: number;
211
+ [x: string]: unknown;
212
+ searchTypes?: {
213
+ webSearch?: Record<string, never> | undefined;
214
+ imageSearch?: Record<string, never> | undefined;
215
+ } | undefined;
216
+ timeRangeFilter?: {
217
+ startTime: string;
218
+ endTime: string;
219
+ } | undefined;
206
220
  }>;
207
221
  /**
208
222
  * Creates an Enterprise Web Search tool for grounding responses using a compliance-focused web index.
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ module.exports = __toCommonJS(src_exports);
30
30
  var import_provider_utils16 = require("@ai-sdk/provider-utils");
31
31
 
32
32
  // src/version.ts
33
- var VERSION = true ? "3.0.37" : "0.0.0-test";
33
+ var VERSION = true ? "3.0.39" : "0.0.0-test";
34
34
 
35
35
  // src/google-generative-ai-embedding-model.ts
36
36
  var import_provider = require("@ai-sdk/provider");
@@ -676,8 +676,7 @@ function prepareTools({
676
676
  "gemini-flash-lite-latest",
677
677
  "gemini-pro-latest"
678
678
  ].some((id) => id === modelId);
679
- const isGemini2orNewer = modelId.includes("gemini-2") || modelId.includes("gemini-3") || isLatest;
680
- const supportsDynamicRetrieval = modelId.includes("gemini-1.5-flash") && !modelId.includes("-8b");
679
+ const isGemini2orNewer = modelId.includes("gemini-2") || modelId.includes("gemini-3") || modelId.includes("nano-banana") || isLatest;
681
680
  const supportsFileSearch = modelId.includes("gemini-2.5") || modelId.includes("gemini-3");
682
681
  if (tools == null) {
683
682
  return { tools: void 0, toolConfig: void 0, toolWarnings };
@@ -697,18 +696,13 @@ function prepareTools({
697
696
  switch (tool.id) {
698
697
  case "google.google_search":
699
698
  if (isGemini2orNewer) {
700
- googleTools2.push({ googleSearch: {} });
701
- } else if (supportsDynamicRetrieval) {
702
- googleTools2.push({
703
- googleSearchRetrieval: {
704
- dynamicRetrievalConfig: {
705
- mode: tool.args.mode,
706
- dynamicThreshold: tool.args.dynamicThreshold
707
- }
708
- }
709
- });
699
+ googleTools2.push({ googleSearch: { ...tool.args } });
710
700
  } else {
711
- googleTools2.push({ googleSearchRetrieval: {} });
701
+ toolWarnings.push({
702
+ type: "unsupported",
703
+ feature: `provider-defined tool ${tool.id}`,
704
+ details: "Google Search requires Gemini 2.0 or newer."
705
+ });
712
706
  }
713
707
  break;
714
708
  case "google.enterprise_web_search":
@@ -1291,10 +1285,30 @@ var GoogleGenerativeAILanguageModel = class {
1291
1285
  });
1292
1286
  }
1293
1287
  } else if ("inlineData" in part) {
1288
+ if (currentTextBlockId !== null) {
1289
+ controller.enqueue({
1290
+ type: "text-end",
1291
+ id: currentTextBlockId
1292
+ });
1293
+ currentTextBlockId = null;
1294
+ }
1295
+ if (currentReasoningBlockId !== null) {
1296
+ controller.enqueue({
1297
+ type: "reasoning-end",
1298
+ id: currentReasoningBlockId
1299
+ });
1300
+ currentReasoningBlockId = null;
1301
+ }
1302
+ const thoughtSignatureMetadata = part.thoughtSignature ? {
1303
+ [providerOptionsName]: {
1304
+ thoughtSignature: part.thoughtSignature
1305
+ }
1306
+ } : void 0;
1294
1307
  controller.enqueue({
1295
1308
  type: "file",
1296
1309
  mediaType: part.inlineData.mimeType,
1297
- data: part.inlineData.data
1310
+ data: part.inlineData.data,
1311
+ providerMetadata: thoughtSignatureMetadata
1298
1312
  });
1299
1313
  }
1300
1314
  }
@@ -1405,7 +1419,7 @@ function extractSources({
1405
1419
  groundingMetadata,
1406
1420
  generateId: generateId3
1407
1421
  }) {
1408
- var _a, _b, _c, _d, _e;
1422
+ var _a, _b, _c, _d, _e, _f;
1409
1423
  if (!(groundingMetadata == null ? void 0 : groundingMetadata.groundingChunks)) {
1410
1424
  return void 0;
1411
1425
  }
@@ -1419,6 +1433,16 @@ function extractSources({
1419
1433
  url: chunk.web.uri,
1420
1434
  title: (_a = chunk.web.title) != null ? _a : void 0
1421
1435
  });
1436
+ } else if (chunk.image != null) {
1437
+ sources.push({
1438
+ type: "source",
1439
+ sourceType: "url",
1440
+ id: generateId3(),
1441
+ // Google requires attribution to the source URI, not the actual image URI.
1442
+ // TODO: add another type in v7 to allow both the image and source URL to be included separately
1443
+ url: chunk.image.sourceUri,
1444
+ title: (_b = chunk.image.title) != null ? _b : void 0
1445
+ });
1422
1446
  } else if (chunk.retrievedContext != null) {
1423
1447
  const uri = chunk.retrievedContext.uri;
1424
1448
  const fileSearchStore = chunk.retrievedContext.fileSearchStore;
@@ -1428,10 +1452,10 @@ function extractSources({
1428
1452
  sourceType: "url",
1429
1453
  id: generateId3(),
1430
1454
  url: uri,
1431
- title: (_b = chunk.retrievedContext.title) != null ? _b : void 0
1455
+ title: (_c = chunk.retrievedContext.title) != null ? _c : void 0
1432
1456
  });
1433
1457
  } else if (uri) {
1434
- const title = (_c = chunk.retrievedContext.title) != null ? _c : "Unknown Document";
1458
+ const title = (_d = chunk.retrievedContext.title) != null ? _d : "Unknown Document";
1435
1459
  let mediaType = "application/octet-stream";
1436
1460
  let filename = void 0;
1437
1461
  if (uri.endsWith(".pdf")) {
@@ -1461,7 +1485,7 @@ function extractSources({
1461
1485
  filename
1462
1486
  });
1463
1487
  } else if (fileSearchStore) {
1464
- const title = (_d = chunk.retrievedContext.title) != null ? _d : "Unknown Document";
1488
+ const title = (_e = chunk.retrievedContext.title) != null ? _e : "Unknown Document";
1465
1489
  sources.push({
1466
1490
  type: "source",
1467
1491
  sourceType: "document",
@@ -1478,7 +1502,7 @@ function extractSources({
1478
1502
  sourceType: "url",
1479
1503
  id: generateId3(),
1480
1504
  url: chunk.maps.uri,
1481
- title: (_e = chunk.maps.title) != null ? _e : void 0
1505
+ title: (_f = chunk.maps.title) != null ? _f : void 0
1482
1506
  });
1483
1507
  }
1484
1508
  }
@@ -1487,11 +1511,18 @@ function extractSources({
1487
1511
  }
1488
1512
  var getGroundingMetadataSchema = () => import_v45.z.object({
1489
1513
  webSearchQueries: import_v45.z.array(import_v45.z.string()).nullish(),
1514
+ imageSearchQueries: import_v45.z.array(import_v45.z.string()).nullish(),
1490
1515
  retrievalQueries: import_v45.z.array(import_v45.z.string()).nullish(),
1491
1516
  searchEntryPoint: import_v45.z.object({ renderedContent: import_v45.z.string() }).nullish(),
1492
1517
  groundingChunks: import_v45.z.array(
1493
1518
  import_v45.z.object({
1494
1519
  web: import_v45.z.object({ uri: import_v45.z.string(), title: import_v45.z.string().nullish() }).nullish(),
1520
+ image: import_v45.z.object({
1521
+ sourceUri: import_v45.z.string(),
1522
+ imageUri: import_v45.z.string(),
1523
+ title: import_v45.z.string().nullish(),
1524
+ domain: import_v45.z.string().nullish()
1525
+ }).nullish(),
1495
1526
  retrievedContext: import_v45.z.object({
1496
1527
  uri: import_v45.z.string().nullish(),
1497
1528
  title: import_v45.z.string().nullish(),
@@ -1688,17 +1719,25 @@ var googleMaps = (0, import_provider_utils10.createProviderToolFactory)({
1688
1719
  // src/tool/google-search.ts
1689
1720
  var import_provider_utils11 = require("@ai-sdk/provider-utils");
1690
1721
  var import_v410 = require("zod/v4");
1691
- var googleSearch = (0, import_provider_utils11.createProviderToolFactory)({
1692
- id: "google.google_search",
1693
- inputSchema: (0, import_provider_utils11.lazySchema)(
1694
- () => (0, import_provider_utils11.zodSchema)(
1695
- import_v410.z.object({
1696
- mode: import_v410.z.enum(["MODE_DYNAMIC", "MODE_UNSPECIFIED"]).default("MODE_UNSPECIFIED"),
1697
- dynamicThreshold: import_v410.z.number().default(1)
1698
- })
1699
- )
1700
- )
1701
- });
1722
+ var googleSearchToolArgsBaseSchema = import_v410.z.object({
1723
+ searchTypes: import_v410.z.object({
1724
+ webSearch: import_v410.z.object({}).optional(),
1725
+ imageSearch: import_v410.z.object({}).optional()
1726
+ }).optional(),
1727
+ timeRangeFilter: import_v410.z.object({
1728
+ startTime: import_v410.z.string(),
1729
+ endTime: import_v410.z.string()
1730
+ }).optional()
1731
+ }).passthrough();
1732
+ var googleSearchToolArgsSchema = (0, import_provider_utils11.lazySchema)(
1733
+ () => (0, import_provider_utils11.zodSchema)(googleSearchToolArgsBaseSchema)
1734
+ );
1735
+ var googleSearch = (0, import_provider_utils11.createProviderToolFactory)(
1736
+ {
1737
+ id: "google.google_search",
1738
+ inputSchema: googleSearchToolArgsSchema
1739
+ }
1740
+ );
1702
1741
 
1703
1742
  // src/tool/url-context.ts
1704
1743
  var import_provider_utils12 = require("@ai-sdk/provider-utils");