@ai-sdk/google 4.0.0-canary.73 → 4.0.0-canary.74

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,11 @@
1
1
  # @ai-sdk/google
2
2
 
3
+ ## 4.0.0-canary.74
4
+
5
+ ### Patch Changes
6
+
7
+ - a8d70b6: fix(google): auto-inject `skip_thought_signature_validator` for Gemini 3 tool-call replays without a signature
8
+
3
9
  ## 4.0.0-canary.73
4
10
 
5
11
  ### Patch Changes
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  } from "@ai-sdk/provider-utils";
8
8
 
9
9
  // src/version.ts
10
- var VERSION = true ? "4.0.0-canary.73" : "0.0.0-test";
10
+ var VERSION = true ? "4.0.0-canary.74" : "0.0.0-test";
11
11
 
12
12
  // src/google-embedding-model.ts
13
13
  import {
@@ -436,6 +436,7 @@ import {
436
436
  resolveFullMediaType,
437
437
  resolveProviderReference
438
438
  } from "@ai-sdk/provider-utils";
439
+ var SKIP_THOUGHT_SIGNATURE_VALIDATOR = "skip_thought_signature_validator";
439
440
  var dataUrlRegex = /^data:([^;,]+);base64,(.+)$/s;
440
441
  function parseBase64DataUrl(value) {
441
442
  const match = dataUrlRegex.exec(value);
@@ -548,16 +549,25 @@ function appendLegacyToolResultParts(parts, toolName, outputValue, toolCallId) {
548
549
  }
549
550
  }
550
551
  function convertToGoogleMessages(prompt, options) {
551
- var _a, _b, _c, _d;
552
+ var _a, _b, _c, _d, _e;
552
553
  const systemInstructionParts = [];
553
554
  const contents = [];
554
555
  let systemMessagesAllowed = true;
555
556
  const isGemmaModel = (_a = options == null ? void 0 : options.isGemmaModel) != null ? _a : false;
556
- const providerOptionsNames = (_b = options == null ? void 0 : options.providerOptionsNames) != null ? _b : ["google"];
557
+ const isGemini3Model2 = (_b = options == null ? void 0 : options.isGemini3Model) != null ? _b : false;
558
+ const onWarning = options == null ? void 0 : options.onWarning;
559
+ const providerOptionsNames = (_c = options == null ? void 0 : options.providerOptionsNames) != null ? _c : ["google"];
557
560
  const isVertexLike = !providerOptionsNames.includes("google");
558
- const supportsFunctionResponseParts = (_c = options == null ? void 0 : options.supportsFunctionResponseParts) != null ? _c : true;
561
+ const supportsFunctionResponseParts = (_d = options == null ? void 0 : options.supportsFunctionResponseParts) != null ? _d : true;
562
+ let sentinelInjected = false;
563
+ const missingSignatureToolNames = [];
564
+ const injectSkipSignature = (toolName) => {
565
+ missingSignatureToolNames.push(toolName);
566
+ sentinelInjected = true;
567
+ return SKIP_THOUGHT_SIGNATURE_VALIDATOR;
568
+ };
559
569
  const readProviderOpts = (part) => {
560
- var _a2, _b2, _c2, _d2, _e;
570
+ var _a2, _b2, _c2, _d2, _e2;
561
571
  for (const name of providerOptionsNames) {
562
572
  const v = (_a2 = part.providerOptions) == null ? void 0 : _a2[name];
563
573
  if (v != null) return v;
@@ -565,7 +575,7 @@ function convertToGoogleMessages(prompt, options) {
565
575
  if (isVertexLike) {
566
576
  return (_b2 = part.providerOptions) == null ? void 0 : _b2.google;
567
577
  }
568
- return (_e = (_c2 = part.providerOptions) == null ? void 0 : _c2.googleVertex) != null ? _e : (_d2 = part.providerOptions) == null ? void 0 : _d2.vertex;
578
+ return (_e2 = (_c2 = part.providerOptions) == null ? void 0 : _c2.googleVertex) != null ? _e2 : (_d2 = part.providerOptions) == null ? void 0 : _d2.vertex;
569
579
  };
570
580
  for (const { role, content } of prompt) {
571
581
  switch (role) {
@@ -737,6 +747,7 @@ function convertToGoogleMessages(prompt, options) {
737
747
  case "tool-call": {
738
748
  const serverToolCallId = (providerOpts == null ? void 0 : providerOpts.serverToolCallId) != null ? String(providerOpts.serverToolCallId) : void 0;
739
749
  const serverToolType = (providerOpts == null ? void 0 : providerOpts.serverToolType) != null ? String(providerOpts.serverToolType) : void 0;
750
+ const effectiveThoughtSignature = thoughtSignature != null ? thoughtSignature : isGemini3Model2 ? injectSkipSignature(part.toolName) : void 0;
740
751
  if (serverToolCallId && serverToolType) {
741
752
  return {
742
753
  toolCall: {
@@ -744,7 +755,7 @@ function convertToGoogleMessages(prompt, options) {
744
755
  args: typeof part.input === "string" ? JSON.parse(part.input) : part.input,
745
756
  id: serverToolCallId
746
757
  },
747
- thoughtSignature
758
+ thoughtSignature: effectiveThoughtSignature
748
759
  };
749
760
  }
750
761
  return {
@@ -753,7 +764,7 @@ function convertToGoogleMessages(prompt, options) {
753
764
  name: part.toolName,
754
765
  args: part.input
755
766
  },
756
- thoughtSignature
767
+ thoughtSignature: effectiveThoughtSignature
757
768
  };
758
769
  }
759
770
  case "tool-result": {
@@ -827,7 +838,7 @@ function convertToGoogleMessages(prompt, options) {
827
838
  name: part.toolName,
828
839
  response: {
829
840
  name: part.toolName,
830
- content: output.type === "execution-denied" ? (_d = output.reason) != null ? _d : "Tool call execution denied." : output.value
841
+ content: output.type === "execution-denied" ? (_e = output.reason) != null ? _e : "Tool call execution denied." : output.value
831
842
  }
832
843
  }
833
844
  });
@@ -845,6 +856,13 @@ function convertToGoogleMessages(prompt, options) {
845
856
  const systemText = systemInstructionParts.map((part) => part.text).join("\n\n");
846
857
  contents[0].parts.unshift({ text: systemText + "\n\n" });
847
858
  }
859
+ if (sentinelInjected && onWarning != null) {
860
+ const uniqueToolNames = Array.from(new Set(missingSignatureToolNames));
861
+ onWarning({
862
+ type: "other",
863
+ message: `Replayed ${missingSignatureToolNames.length} \`functionCall\` part(s) for a Gemini 3 model without a \`thoughtSignature\` (tools: ${uniqueToolNames.map((name) => `\`${name}\``).join(", ")}). Injected the documented \`skip_thought_signature_validator\` sentinel to keep the request from failing with HTTP 400. The likely cause is application code that drops \`providerOptions.google.thoughtSignature\` when persisting or serializing assistant tool-call messages. See https://ai.google.dev/gemini-api/docs/thought-signatures.`
864
+ });
865
+ }
848
866
  return {
849
867
  systemInstruction: systemInstructionParts.length > 0 && !isGemmaModel ? { parts: systemInstructionParts } : void 0,
850
868
  contents
@@ -1617,9 +1635,12 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
1617
1635
  } : void 0;
1618
1636
  const bodyServiceTier = isVertexProvider ? void 0 : googleOptions == null ? void 0 : googleOptions.serviceTier;
1619
1637
  const isGemmaModel = this.modelId.toLowerCase().startsWith("gemma-");
1620
- const supportsFunctionResponseParts = this.modelId.startsWith("gemini-3");
1638
+ const isGemini3Model2 = /^gemini-3[.-]/.test(this.modelId);
1639
+ const supportsFunctionResponseParts = isGemini3Model2;
1621
1640
  const { contents, systemInstruction } = convertToGoogleMessages(prompt, {
1622
1641
  isGemmaModel,
1642
+ isGemini3Model: isGemini3Model2,
1643
+ onWarning: (warning) => warnings.push(warning),
1623
1644
  providerOptionsNames,
1624
1645
  supportsFunctionResponseParts
1625
1646
  });