@ai-sdk/google 3.0.79 → 3.0.80
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 +10 -0
- package/dist/index.js +54 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +54 -12
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +53 -11
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +53 -11
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/convert-to-google-generative-ai-messages.ts +104 -12
- package/src/google-generative-ai-language-model.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @ai-sdk/google
|
|
2
2
|
|
|
3
|
+
## 3.0.80
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f62ffe0: fix(google): auto-inject `skip_thought_signature_validator` for Gemini 3 tool-call replays without a signature
|
|
8
|
+
|
|
9
|
+
Gemini 3 models reject requests when an assistant `functionCall` part lacks a `thoughtSignature` with HTTP 400 `"Function call is missing a thought_signature in functionCall parts."` This is easy to hit when application code persists/serializes messages and drops `providerOptions.google.thoughtSignature` (custom DB schemas, `useChat` server routes that rebuild messages, synthetic tool-call injection).
|
|
10
|
+
|
|
11
|
+
The provider now detects this case (Gemini 3 model + missing signature under `google`, `googleVertex`, and `vertex` namespaces) and injects the documented `skip_thought_signature_validator` sentinel into the outbound `functionCall`, plus surfaces a one-shot warning per request listing the affected tool names so the developer can find and fix the upstream serialization. Non-Gemini-3 models are unaffected, and real signatures take precedence when present.
|
|
12
|
+
|
|
3
13
|
## 3.0.79
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
30
30
|
var import_provider_utils23 = require("@ai-sdk/provider-utils");
|
|
31
31
|
|
|
32
32
|
// src/version.ts
|
|
33
|
-
var VERSION = true ? "3.0.
|
|
33
|
+
var VERSION = true ? "3.0.80" : "0.0.0-test";
|
|
34
34
|
|
|
35
35
|
// src/google-generative-ai-embedding-model.ts
|
|
36
36
|
var import_provider = require("@ai-sdk/provider");
|
|
@@ -406,6 +406,23 @@ function isEmptyObjectSchema(jsonSchema) {
|
|
|
406
406
|
// src/convert-to-google-generative-ai-messages.ts
|
|
407
407
|
var import_provider2 = require("@ai-sdk/provider");
|
|
408
408
|
var import_provider_utils4 = require("@ai-sdk/provider-utils");
|
|
409
|
+
var SKIP_THOUGHT_SIGNATURE_VALIDATOR = "skip_thought_signature_validator";
|
|
410
|
+
function getGoogleProviderOptions(providerOptions, providerOptionsName) {
|
|
411
|
+
const namespaces = [
|
|
412
|
+
providerOptionsName,
|
|
413
|
+
"google",
|
|
414
|
+
"googleVertex",
|
|
415
|
+
"vertex"
|
|
416
|
+
].filter((namespace, index, allNamespaces) => {
|
|
417
|
+
return allNamespaces.indexOf(namespace) === index;
|
|
418
|
+
});
|
|
419
|
+
for (const namespace of namespaces) {
|
|
420
|
+
const options = providerOptions == null ? void 0 : providerOptions[namespace];
|
|
421
|
+
if (options != null) {
|
|
422
|
+
return options;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
409
426
|
var dataUrlRegex = /^data:([^;,]+);base64,(.+)$/s;
|
|
410
427
|
function parseBase64DataUrl(value) {
|
|
411
428
|
const match = dataUrlRegex.exec(value);
|
|
@@ -513,13 +530,22 @@ function appendLegacyToolResultParts(parts, toolName, outputValue, toolCallId) {
|
|
|
513
530
|
}
|
|
514
531
|
}
|
|
515
532
|
function convertToGoogleGenerativeAIMessages(prompt, options) {
|
|
516
|
-
var _a, _b, _c, _d, _e
|
|
533
|
+
var _a, _b, _c, _d, _e;
|
|
517
534
|
const systemInstructionParts = [];
|
|
518
535
|
const contents = [];
|
|
519
536
|
let systemMessagesAllowed = true;
|
|
520
537
|
const isGemmaModel = (_a = options == null ? void 0 : options.isGemmaModel) != null ? _a : false;
|
|
521
|
-
const
|
|
522
|
-
const
|
|
538
|
+
const isGemini3Model = (_b = options == null ? void 0 : options.isGemini3Model) != null ? _b : false;
|
|
539
|
+
const providerOptionsName = (_c = options == null ? void 0 : options.providerOptionsName) != null ? _c : "google";
|
|
540
|
+
const supportsFunctionResponseParts = (_d = options == null ? void 0 : options.supportsFunctionResponseParts) != null ? _d : true;
|
|
541
|
+
const onWarning = options == null ? void 0 : options.onWarning;
|
|
542
|
+
let sentinelInjected = false;
|
|
543
|
+
const missingSignatureToolNames = [];
|
|
544
|
+
const injectSkipSignature = (toolName) => {
|
|
545
|
+
missingSignatureToolNames.push(toolName);
|
|
546
|
+
sentinelInjected = true;
|
|
547
|
+
return SKIP_THOUGHT_SIGNATURE_VALIDATOR;
|
|
548
|
+
};
|
|
523
549
|
for (const { role, content } of prompt) {
|
|
524
550
|
switch (role) {
|
|
525
551
|
case "system": {
|
|
@@ -567,8 +593,10 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
|
|
|
567
593
|
contents.push({
|
|
568
594
|
role: "model",
|
|
569
595
|
parts: content.map((part) => {
|
|
570
|
-
|
|
571
|
-
|
|
596
|
+
const providerOpts = getGoogleProviderOptions(
|
|
597
|
+
part.providerOptions,
|
|
598
|
+
providerOptionsName
|
|
599
|
+
);
|
|
572
600
|
const thoughtSignature = (providerOpts == null ? void 0 : providerOpts.thoughtSignature) != null ? String(providerOpts.thoughtSignature) : void 0;
|
|
573
601
|
switch (part.type) {
|
|
574
602
|
case "text": {
|
|
@@ -602,6 +630,7 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
|
|
|
602
630
|
case "tool-call": {
|
|
603
631
|
const serverToolCallId = (providerOpts == null ? void 0 : providerOpts.serverToolCallId) != null ? String(providerOpts.serverToolCallId) : void 0;
|
|
604
632
|
const serverToolType = (providerOpts == null ? void 0 : providerOpts.serverToolType) != null ? String(providerOpts.serverToolType) : void 0;
|
|
633
|
+
const effectiveThoughtSignature = thoughtSignature != null ? thoughtSignature : isGemini3Model ? injectSkipSignature(part.toolName) : void 0;
|
|
605
634
|
if (serverToolCallId && serverToolType) {
|
|
606
635
|
return {
|
|
607
636
|
toolCall: {
|
|
@@ -609,7 +638,7 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
|
|
|
609
638
|
args: typeof part.input === "string" ? JSON.parse(part.input) : part.input,
|
|
610
639
|
id: serverToolCallId
|
|
611
640
|
},
|
|
612
|
-
thoughtSignature
|
|
641
|
+
thoughtSignature: effectiveThoughtSignature
|
|
613
642
|
};
|
|
614
643
|
}
|
|
615
644
|
return {
|
|
@@ -618,7 +647,7 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
|
|
|
618
647
|
name: part.toolName,
|
|
619
648
|
args: part.input
|
|
620
649
|
},
|
|
621
|
-
thoughtSignature
|
|
650
|
+
thoughtSignature: effectiveThoughtSignature
|
|
622
651
|
};
|
|
623
652
|
}
|
|
624
653
|
case "tool-result": {
|
|
@@ -648,7 +677,10 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
|
|
|
648
677
|
if (part.type === "tool-approval-response") {
|
|
649
678
|
continue;
|
|
650
679
|
}
|
|
651
|
-
const partProviderOpts = (
|
|
680
|
+
const partProviderOpts = getGoogleProviderOptions(
|
|
681
|
+
part.providerOptions,
|
|
682
|
+
providerOptionsName
|
|
683
|
+
);
|
|
652
684
|
const serverToolCallId = (partProviderOpts == null ? void 0 : partProviderOpts.serverToolCallId) != null ? String(partProviderOpts.serverToolCallId) : void 0;
|
|
653
685
|
const serverToolType = (partProviderOpts == null ? void 0 : partProviderOpts.serverToolType) != null ? String(partProviderOpts.serverToolType) : void 0;
|
|
654
686
|
if (serverToolCallId && serverToolType) {
|
|
@@ -692,7 +724,7 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
|
|
|
692
724
|
name: part.toolName,
|
|
693
725
|
response: {
|
|
694
726
|
name: part.toolName,
|
|
695
|
-
content: output.type === "execution-denied" ? (
|
|
727
|
+
content: output.type === "execution-denied" ? (_e = output.reason) != null ? _e : "Tool execution denied." : output.value
|
|
696
728
|
}
|
|
697
729
|
}
|
|
698
730
|
});
|
|
@@ -710,6 +742,13 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
|
|
|
710
742
|
const systemText = systemInstructionParts.map((part) => part.text).join("\n\n");
|
|
711
743
|
contents[0].parts.unshift({ text: systemText + "\n\n" });
|
|
712
744
|
}
|
|
745
|
+
if (sentinelInjected && onWarning != null) {
|
|
746
|
+
const uniqueToolNames = Array.from(new Set(missingSignatureToolNames));
|
|
747
|
+
onWarning({
|
|
748
|
+
type: "other",
|
|
749
|
+
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.`
|
|
750
|
+
});
|
|
751
|
+
}
|
|
713
752
|
return {
|
|
714
753
|
systemInstruction: systemInstructionParts.length > 0 && !isGemmaModel ? { parts: systemInstructionParts } : void 0,
|
|
715
754
|
contents
|
|
@@ -1463,13 +1502,16 @@ var GoogleGenerativeAILanguageModel = class {
|
|
|
1463
1502
|
} : void 0;
|
|
1464
1503
|
const bodyServiceTier = isVertexProvider ? void 0 : googleOptions == null ? void 0 : googleOptions.serviceTier;
|
|
1465
1504
|
const isGemmaModel = this.modelId.toLowerCase().startsWith("gemma-");
|
|
1466
|
-
const
|
|
1505
|
+
const isGemini3Model = /^gemini-3[.-]/.test(this.modelId);
|
|
1506
|
+
const supportsFunctionResponseParts = isGemini3Model;
|
|
1467
1507
|
const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(
|
|
1468
1508
|
prompt,
|
|
1469
1509
|
{
|
|
1470
1510
|
isGemmaModel,
|
|
1511
|
+
isGemini3Model,
|
|
1471
1512
|
providerOptionsName,
|
|
1472
|
-
supportsFunctionResponseParts
|
|
1513
|
+
supportsFunctionResponseParts,
|
|
1514
|
+
onWarning: (warning) => warnings.push(warning)
|
|
1473
1515
|
}
|
|
1474
1516
|
);
|
|
1475
1517
|
const {
|