@ai-sdk/google 4.0.21 → 4.0.23

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.
@@ -304,7 +304,7 @@ function convertToGoogleMessages(prompt, options) {
304
304
  const contents = [];
305
305
  let systemMessagesAllowed = true;
306
306
  const isGemmaModel = (_a = options == null ? void 0 : options.isGemmaModel) != null ? _a : false;
307
- const isGemini3Model2 = (_b = options == null ? void 0 : options.isGemini3Model) != null ? _b : false;
307
+ const isGemini3Model = (_b = options == null ? void 0 : options.isGemini3Model) != null ? _b : false;
308
308
  const onWarning = options == null ? void 0 : options.onWarning;
309
309
  const providerOptionsNames = (_c = options == null ? void 0 : options.providerOptionsNames) != null ? _c : ["google"];
310
310
  const isVertexLike = !providerOptionsNames.includes("google");
@@ -405,6 +405,7 @@ function convertToGoogleMessages(prompt, options) {
405
405
  }
406
406
  case "assistant": {
407
407
  systemMessagesAllowed = false;
408
+ let modelResponseHasSignedFunctionCall = false;
408
409
  contents.push({
409
410
  role: "model",
410
411
  parts: content.map((part) => {
@@ -497,8 +498,19 @@ function convertToGoogleMessages(prompt, options) {
497
498
  case "tool-call": {
498
499
  const serverToolCallId = (providerOpts == null ? void 0 : providerOpts.serverToolCallId) != null ? String(providerOpts.serverToolCallId) : void 0;
499
500
  const serverToolType = (providerOpts == null ? void 0 : providerOpts.serverToolType) != null ? String(providerOpts.serverToolType) : void 0;
500
- const effectiveThoughtSignature = thoughtSignature != null ? thoughtSignature : isGemini3Model2 ? injectSkipSignature(part.toolName) : void 0;
501
- if (serverToolCallId && serverToolType) {
501
+ const isServerToolCall = serverToolCallId != null && serverToolType != null;
502
+ const shouldSkipMissingSignatureMitigation = (
503
+ // Gemini 3 returns a single signature for a parallel
504
+ // function-call response on the first standard function
505
+ // call. Subsequent standard function calls in the same
506
+ // model response legitimately have no signature.
507
+ !isServerToolCall && thoughtSignature == null && modelResponseHasSignedFunctionCall
508
+ );
509
+ const effectiveThoughtSignature = thoughtSignature != null ? thoughtSignature : isGemini3Model && !shouldSkipMissingSignatureMitigation ? injectSkipSignature(part.toolName) : void 0;
510
+ if (!isServerToolCall && thoughtSignature != null) {
511
+ modelResponseHasSignedFunctionCall = true;
512
+ }
513
+ if (isServerToolCall) {
502
514
  return {
503
515
  toolCall: {
504
516
  toolType: serverToolType,
@@ -838,6 +850,27 @@ var googleLanguageModelOptions = lazySchema2(
838
850
  )
839
851
  );
840
852
 
853
+ // src/google-model-capabilities.ts
854
+ var gemini1ModelPattern = /(^|\/)gemini-1(?:[.-]|$)/i;
855
+ var gemini2ModelPattern = /(^|\/)gemini-2(?:[.-]|$)/i;
856
+ var gemini25ModelPattern = /(^|\/)gemini-2\.5(?:[.-]|$)/i;
857
+ var geminiModelPattern = /(^|\/)gemini-/i;
858
+ function isKnownPreGemini2Model(modelId) {
859
+ return gemini1ModelPattern.test(modelId) || /(^|\/)gemini-pro(?:-vision)?$/i.test(modelId) || /(^|\/)gemini-robotics-er-1\.5(?:[.-]|$)/i.test(modelId);
860
+ }
861
+ function getGoogleModelCapabilities(modelId) {
862
+ const isGeminiModel = geminiModelPattern.test(modelId);
863
+ const isGemini2Model = gemini2ModelPattern.test(modelId);
864
+ const isKnownPreGemini2 = isKnownPreGemini2Model(modelId);
865
+ const isKnownOlderModel = isKnownPreGemini2 || isGemini2Model;
866
+ const usesGemini3Features = isGeminiModel && !isKnownOlderModel;
867
+ return {
868
+ supportsGemini2Tools: isGeminiModel && !isKnownPreGemini2 || modelId.toLowerCase().includes("nano-banana"),
869
+ supportsFileSearch: gemini25ModelPattern.test(modelId) || usesGemini3Features,
870
+ usesGemini3Features
871
+ };
872
+ }
873
+
841
874
  // src/google-prepare-tools.ts
842
875
  import {
843
876
  UnsupportedFunctionalityError as UnsupportedFunctionalityError2
@@ -851,20 +884,13 @@ function prepareTools({
851
884
  var _a, _b;
852
885
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
853
886
  const toolWarnings = [];
854
- const isLatest = [
855
- "gemini-flash-latest",
856
- "gemini-flash-lite-latest",
857
- "gemini-pro-latest"
858
- ].some((id) => id === modelId);
859
- const isGemini2orNewer = modelId.includes("gemini-2") || modelId.includes("gemini-3") || modelId.includes("nano-banana") || isLatest;
860
- const isGemini3orNewer = modelId.includes("gemini-3");
861
- const supportsFileSearch = modelId.includes("gemini-2.5") || modelId.includes("gemini-3");
887
+ const { supportsGemini2Tools, supportsFileSearch, usesGemini3Features } = getGoogleModelCapabilities(modelId);
862
888
  if (tools == null) {
863
889
  return { tools: void 0, toolConfig: void 0, toolWarnings };
864
890
  }
865
891
  const hasFunctionTools = tools.some((tool) => tool.type === "function");
866
892
  const hasProviderTools = tools.some((tool) => tool.type === "provider");
867
- if (hasFunctionTools && hasProviderTools && !isGemini3orNewer) {
893
+ if (hasFunctionTools && hasProviderTools && !usesGemini3Features) {
868
894
  toolWarnings.push({
869
895
  type: "unsupported",
870
896
  feature: `combination of function and provider-defined tools`
@@ -876,7 +902,7 @@ function prepareTools({
876
902
  ProviderTools.forEach((tool) => {
877
903
  switch (tool.id) {
878
904
  case "google.google_search":
879
- if (isGemini2orNewer) {
905
+ if (supportsGemini2Tools) {
880
906
  googleTools2.push({ googleSearch: { ...tool.args } });
881
907
  } else {
882
908
  toolWarnings.push({
@@ -887,7 +913,7 @@ function prepareTools({
887
913
  }
888
914
  break;
889
915
  case "google.enterprise_web_search":
890
- if (isGemini2orNewer) {
916
+ if (supportsGemini2Tools) {
891
917
  googleTools2.push({ enterpriseWebSearch: {} });
892
918
  } else {
893
919
  toolWarnings.push({
@@ -898,7 +924,7 @@ function prepareTools({
898
924
  }
899
925
  break;
900
926
  case "google.url_context":
901
- if (isGemini2orNewer) {
927
+ if (supportsGemini2Tools) {
902
928
  googleTools2.push({ urlContext: {} });
903
929
  } else {
904
930
  toolWarnings.push({
@@ -909,7 +935,7 @@ function prepareTools({
909
935
  }
910
936
  break;
911
937
  case "google.code_execution":
912
- if (isGemini2orNewer) {
938
+ if (supportsGemini2Tools) {
913
939
  googleTools2.push({ codeExecution: {} });
914
940
  } else {
915
941
  toolWarnings.push({
@@ -931,7 +957,7 @@ function prepareTools({
931
957
  }
932
958
  break;
933
959
  case "google.vertex_rag_store":
934
- if (isGemini2orNewer) {
960
+ if (supportsGemini2Tools) {
935
961
  googleTools2.push({
936
962
  retrieval: {
937
963
  vertex_rag_store: {
@@ -951,7 +977,7 @@ function prepareTools({
951
977
  }
952
978
  break;
953
979
  case "google.google_maps":
954
- if (isGemini2orNewer) {
980
+ if (supportsGemini2Tools) {
955
981
  googleTools2.push({ googleMaps: {} });
956
982
  } else {
957
983
  toolWarnings.push({
@@ -969,7 +995,7 @@ function prepareTools({
969
995
  break;
970
996
  }
971
997
  });
972
- if (hasFunctionTools && isGemini3orNewer && googleTools2.length > 0) {
998
+ if (hasFunctionTools && usesGemini3Features && googleTools2.length > 0) {
973
999
  const functionDeclarations2 = [];
974
1000
  for (const tool of tools) {
975
1001
  if (tool.type === "function") {
@@ -1484,14 +1510,13 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
1484
1510
  }
1485
1511
  }
1486
1512
  const isGemmaModel = this.modelId.toLowerCase().startsWith("gemma-");
1487
- const isGemini3Model2 = /^gemini-3[.-]/.test(this.modelId);
1488
- const supportsFunctionResponseParts = isGemini3Model2;
1513
+ const { usesGemini3Features } = getGoogleModelCapabilities(this.modelId);
1489
1514
  const { contents, systemInstruction } = convertToGoogleMessages(prompt, {
1490
1515
  isGemmaModel,
1491
- isGemini3Model: isGemini3Model2,
1516
+ isGemini3Model: usesGemini3Features,
1492
1517
  onWarning: (warning) => warnings.push(warning),
1493
1518
  providerOptionsNames,
1494
- supportsFunctionResponseParts
1519
+ supportsFunctionResponseParts: usesGemini3Features
1495
1520
  });
1496
1521
  const {
1497
1522
  tools: googleTools2,
@@ -2157,9 +2182,6 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2157
2182
  };
2158
2183
  }
2159
2184
  };
2160
- function isGemini3Model(modelId) {
2161
- return /gemini-3[\.\-]/i.test(modelId) || /gemini-3$/i.test(modelId);
2162
- }
2163
2185
  function getMaxOutputTokensForGemini25Model() {
2164
2186
  return 65536;
2165
2187
  }
@@ -2178,7 +2200,7 @@ function resolveThinkingConfig({
2178
2200
  if (!isCustomReasoning(reasoning)) {
2179
2201
  return void 0;
2180
2202
  }
2181
- if (isGemini3Model(modelId) && !modelId.includes("gemini-3-pro-image")) {
2203
+ if (getGoogleModelCapabilities(modelId).usesGemini3Features && !modelId.includes("gemini-3-pro-image")) {
2182
2204
  return resolveGemini3ThinkingConfig({ reasoning, warnings });
2183
2205
  }
2184
2206
  return resolveGemini25ThinkingConfig({ reasoning, modelId, warnings });