@ai-sdk/google 3.0.98 → 3.0.100

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.
@@ -377,6 +377,7 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
377
377
  }
378
378
  case "assistant": {
379
379
  systemMessagesAllowed = false;
380
+ let modelResponseHasSignedFunctionCall = false;
380
381
  contents.push({
381
382
  role: "model",
382
383
  parts: content.map((part) => {
@@ -417,8 +418,19 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
417
418
  case "tool-call": {
418
419
  const serverToolCallId = (providerOpts == null ? void 0 : providerOpts.serverToolCallId) != null ? String(providerOpts.serverToolCallId) : void 0;
419
420
  const serverToolType = (providerOpts == null ? void 0 : providerOpts.serverToolType) != null ? String(providerOpts.serverToolType) : void 0;
420
- const effectiveThoughtSignature = thoughtSignature != null ? thoughtSignature : isGemini3Model ? injectSkipSignature(part.toolName) : void 0;
421
- if (serverToolCallId && serverToolType) {
421
+ const isServerToolCall = serverToolCallId != null && serverToolType != null;
422
+ const shouldSkipMissingSignatureMitigation = (
423
+ // Gemini 3 returns a single signature for a parallel
424
+ // function-call response on the first standard function
425
+ // call. Subsequent standard function calls in the same
426
+ // model response legitimately have no signature.
427
+ !isServerToolCall && thoughtSignature == null && modelResponseHasSignedFunctionCall
428
+ );
429
+ const effectiveThoughtSignature = thoughtSignature != null ? thoughtSignature : isGemini3Model && !shouldSkipMissingSignatureMitigation ? injectSkipSignature(part.toolName) : void 0;
430
+ if (!isServerToolCall && thoughtSignature != null) {
431
+ modelResponseHasSignedFunctionCall = true;
432
+ }
433
+ if (isServerToolCall) {
422
434
  return {
423
435
  toolCall: {
424
436
  toolType: serverToolType,
@@ -754,6 +766,27 @@ var googleLanguageModelOptions = (0, import_provider_utils3.lazySchema)(
754
766
  )
755
767
  );
756
768
 
769
+ // src/google-model-capabilities.ts
770
+ var gemini1ModelPattern = /(^|\/)gemini-1(?:[.-]|$)/i;
771
+ var gemini2ModelPattern = /(^|\/)gemini-2(?:[.-]|$)/i;
772
+ var gemini25ModelPattern = /(^|\/)gemini-2\.5(?:[.-]|$)/i;
773
+ var geminiModelPattern = /(^|\/)gemini-/i;
774
+ function isKnownPreGemini2Model(modelId) {
775
+ return gemini1ModelPattern.test(modelId) || /(^|\/)gemini-pro(?:-vision)?$/i.test(modelId) || /(^|\/)gemini-robotics-er-1\.5(?:[.-]|$)/i.test(modelId);
776
+ }
777
+ function getGoogleModelCapabilities(modelId) {
778
+ const isGeminiModel = geminiModelPattern.test(modelId);
779
+ const isGemini2Model = gemini2ModelPattern.test(modelId);
780
+ const isKnownPreGemini2 = isKnownPreGemini2Model(modelId);
781
+ const isKnownOlderModel = isKnownPreGemini2 || isGemini2Model;
782
+ const usesGemini3Features = isGeminiModel && !isKnownOlderModel;
783
+ return {
784
+ supportsGemini2Tools: isGeminiModel && !isKnownPreGemini2 || modelId.toLowerCase().includes("nano-banana"),
785
+ supportsFileSearch: gemini25ModelPattern.test(modelId) || usesGemini3Features,
786
+ usesGemini3Features
787
+ };
788
+ }
789
+
757
790
  // src/google-prepare-tools.ts
758
791
  var import_provider2 = require("@ai-sdk/provider");
759
792
  function prepareTools({
@@ -765,20 +798,13 @@ function prepareTools({
765
798
  var _a, _b;
766
799
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
767
800
  const toolWarnings = [];
768
- const isLatest = [
769
- "gemini-flash-latest",
770
- "gemini-flash-lite-latest",
771
- "gemini-pro-latest"
772
- ].some((id) => id === modelId);
773
- const isGemini2orNewer = modelId.includes("gemini-2") || modelId.includes("gemini-3") || modelId.includes("nano-banana") || isLatest;
774
- const isGemini3orNewer = modelId.includes("gemini-3");
775
- const supportsFileSearch = modelId.includes("gemini-2.5") || modelId.includes("gemini-3");
801
+ const { supportsGemini2Tools, supportsFileSearch, usesGemini3Features } = getGoogleModelCapabilities(modelId);
776
802
  if (tools == null) {
777
803
  return { tools: void 0, toolConfig: void 0, toolWarnings };
778
804
  }
779
805
  const hasFunctionTools = tools.some((tool) => tool.type === "function");
780
806
  const hasProviderTools = tools.some((tool) => tool.type === "provider");
781
- if (hasFunctionTools && hasProviderTools && !isGemini3orNewer) {
807
+ if (hasFunctionTools && hasProviderTools && !usesGemini3Features) {
782
808
  toolWarnings.push({
783
809
  type: "unsupported",
784
810
  feature: `combination of function and provider-defined tools`
@@ -790,7 +816,7 @@ function prepareTools({
790
816
  ProviderTools.forEach((tool) => {
791
817
  switch (tool.id) {
792
818
  case "google.google_search":
793
- if (isGemini2orNewer) {
819
+ if (supportsGemini2Tools) {
794
820
  googleTools2.push({ googleSearch: { ...tool.args } });
795
821
  } else {
796
822
  toolWarnings.push({
@@ -801,7 +827,7 @@ function prepareTools({
801
827
  }
802
828
  break;
803
829
  case "google.enterprise_web_search":
804
- if (isGemini2orNewer) {
830
+ if (supportsGemini2Tools) {
805
831
  googleTools2.push({ enterpriseWebSearch: {} });
806
832
  } else {
807
833
  toolWarnings.push({
@@ -812,7 +838,7 @@ function prepareTools({
812
838
  }
813
839
  break;
814
840
  case "google.url_context":
815
- if (isGemini2orNewer) {
841
+ if (supportsGemini2Tools) {
816
842
  googleTools2.push({ urlContext: {} });
817
843
  } else {
818
844
  toolWarnings.push({
@@ -823,7 +849,7 @@ function prepareTools({
823
849
  }
824
850
  break;
825
851
  case "google.code_execution":
826
- if (isGemini2orNewer) {
852
+ if (supportsGemini2Tools) {
827
853
  googleTools2.push({ codeExecution: {} });
828
854
  } else {
829
855
  toolWarnings.push({
@@ -845,7 +871,7 @@ function prepareTools({
845
871
  }
846
872
  break;
847
873
  case "google.vertex_rag_store":
848
- if (isGemini2orNewer) {
874
+ if (supportsGemini2Tools) {
849
875
  googleTools2.push({
850
876
  retrieval: {
851
877
  vertex_rag_store: {
@@ -865,7 +891,7 @@ function prepareTools({
865
891
  }
866
892
  break;
867
893
  case "google.google_maps":
868
- if (isGemini2orNewer) {
894
+ if (supportsGemini2Tools) {
869
895
  googleTools2.push({ googleMaps: {} });
870
896
  } else {
871
897
  toolWarnings.push({
@@ -883,7 +909,7 @@ function prepareTools({
883
909
  break;
884
910
  }
885
911
  });
886
- if (hasFunctionTools && isGemini3orNewer && googleTools2.length > 0) {
912
+ if (hasFunctionTools && usesGemini3Features && googleTools2.length > 0) {
887
913
  const functionDeclarations2 = [];
888
914
  for (const tool of tools) {
889
915
  if (tool.type === "function") {
@@ -1380,15 +1406,14 @@ var GoogleGenerativeAILanguageModel = class {
1380
1406
  }
1381
1407
  }
1382
1408
  const isGemmaModel = this.modelId.toLowerCase().startsWith("gemma-");
1383
- const isGemini3Model = /^gemini-3[.-]/.test(this.modelId);
1384
- const supportsFunctionResponseParts = isGemini3Model;
1409
+ const { usesGemini3Features } = getGoogleModelCapabilities(this.modelId);
1385
1410
  const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(
1386
1411
  prompt,
1387
1412
  {
1388
1413
  isGemmaModel,
1389
- isGemini3Model,
1414
+ isGemini3Model: usesGemini3Features,
1390
1415
  providerOptionsName,
1391
- supportsFunctionResponseParts,
1416
+ supportsFunctionResponseParts: usesGemini3Features,
1392
1417
  onWarning: (warning) => warnings.push(warning)
1393
1418
  }
1394
1419
  );