@core-ai/google-genai 0.19.0 → 0.20.0
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/dist/index.d.ts +5 -0
- package/dist/index.js +82 -17
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ type GoogleModelCapabilities = Omit<ModelCapabilities, 'reasoning'> & {
|
|
|
9
9
|
};
|
|
10
10
|
declare function getGoogleModelCapabilities(modelId: string): GoogleModelCapabilities;
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Thought signature Google attaches under the `google` provider metadata key.
|
|
14
|
+
* Used on reasoning parts today, and on tool-call parts so Gemini 3 function
|
|
15
|
+
* calls can be replayed without a missing-`thought_signature` 400.
|
|
16
|
+
*/
|
|
12
17
|
type GoogleReasoningMetadata = {
|
|
13
18
|
thoughtSignature?: string;
|
|
14
19
|
};
|
package/dist/index.js
CHANGED
|
@@ -180,12 +180,17 @@ function convertMessages(messages) {
|
|
|
180
180
|
}
|
|
181
181
|
if (part.type === "tool-call") {
|
|
182
182
|
toolCallNameById.set(part.toolCall.id, part.toolCall.name);
|
|
183
|
+
const toolCallSignature = getProviderMetadata(
|
|
184
|
+
part.providerMetadata,
|
|
185
|
+
"google"
|
|
186
|
+
)?.thoughtSignature;
|
|
183
187
|
assistantParts.push({
|
|
184
188
|
functionCall: {
|
|
185
189
|
id: part.toolCall.id,
|
|
186
190
|
name: part.toolCall.name,
|
|
187
191
|
args: part.toolCall.arguments
|
|
188
|
-
}
|
|
192
|
+
},
|
|
193
|
+
...typeof toolCallSignature === "string" ? { thoughtSignature: toolCallSignature } : {}
|
|
189
194
|
});
|
|
190
195
|
continue;
|
|
191
196
|
}
|
|
@@ -453,6 +458,7 @@ function mapFinishReason(reason) {
|
|
|
453
458
|
}
|
|
454
459
|
async function* transformStream(stream) {
|
|
455
460
|
const bufferedToolCalls = /* @__PURE__ */ new Map();
|
|
461
|
+
const toolCallSignatures = /* @__PURE__ */ new Map();
|
|
456
462
|
let finishReason = "unknown";
|
|
457
463
|
let sawToolCalls = false;
|
|
458
464
|
let textOpen = false;
|
|
@@ -508,18 +514,21 @@ async function* transformStream(stream) {
|
|
|
508
514
|
};
|
|
509
515
|
}
|
|
510
516
|
}
|
|
511
|
-
|
|
517
|
+
const textDeltas = extractTextDeltas(chunk);
|
|
518
|
+
if (textDeltas.length > 0) {
|
|
512
519
|
const reasoningEnd2 = closeReasoning();
|
|
513
520
|
if (reasoningEnd2) {
|
|
514
521
|
yield reasoningEnd2;
|
|
515
522
|
}
|
|
516
523
|
yield* startText();
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
524
|
+
for (const text of textDeltas) {
|
|
525
|
+
yield {
|
|
526
|
+
type: "text-delta",
|
|
527
|
+
text
|
|
528
|
+
};
|
|
529
|
+
}
|
|
521
530
|
}
|
|
522
|
-
const functionCalls = chunk
|
|
531
|
+
const functionCalls = extractStreamedFunctionCalls(chunk);
|
|
523
532
|
if (functionCalls.length > 0) {
|
|
524
533
|
yield* closeText();
|
|
525
534
|
const reasoningEnd2 = closeReasoning();
|
|
@@ -527,8 +536,13 @@ async function* transformStream(stream) {
|
|
|
527
536
|
yield reasoningEnd2;
|
|
528
537
|
}
|
|
529
538
|
sawToolCalls = true;
|
|
530
|
-
for (const
|
|
531
|
-
|
|
539
|
+
for (const {
|
|
540
|
+
toolCall: mappedCall,
|
|
541
|
+
thoughtSignature
|
|
542
|
+
} of functionCalls) {
|
|
543
|
+
if (thoughtSignature) {
|
|
544
|
+
toolCallSignatures.set(mappedCall.id, thoughtSignature);
|
|
545
|
+
}
|
|
532
546
|
const existing = bufferedToolCalls.get(mappedCall.id);
|
|
533
547
|
if (!existing) {
|
|
534
548
|
bufferedToolCalls.set(mappedCall.id, mappedCall);
|
|
@@ -574,9 +588,11 @@ async function* transformStream(stream) {
|
|
|
574
588
|
}
|
|
575
589
|
yield* closeText();
|
|
576
590
|
for (const toolCall of bufferedToolCalls.values()) {
|
|
591
|
+
const thoughtSignature = toolCallSignatures.get(toolCall.id);
|
|
577
592
|
yield {
|
|
578
593
|
type: "tool-call-end",
|
|
579
|
-
toolCall
|
|
594
|
+
toolCall,
|
|
595
|
+
...thoughtSignature ? { providerMetadata: { google: { thoughtSignature } } } : {}
|
|
580
596
|
};
|
|
581
597
|
}
|
|
582
598
|
if (sawToolCalls && finishReason !== "content-filter") {
|
|
@@ -617,7 +633,7 @@ function extractAssistantParts(response) {
|
|
|
617
633
|
if (thoughtText.length === 0) {
|
|
618
634
|
continue;
|
|
619
635
|
}
|
|
620
|
-
const thoughtSignature =
|
|
636
|
+
const thoughtSignature = readThoughtSignature(part);
|
|
621
637
|
parts.push({
|
|
622
638
|
type: "reasoning",
|
|
623
639
|
text: thoughtText,
|
|
@@ -634,9 +650,15 @@ function extractAssistantParts(response) {
|
|
|
634
650
|
const key = `${toolCall.id}:${toolCall.name}`;
|
|
635
651
|
if (!seenToolCalls.has(key)) {
|
|
636
652
|
seenToolCalls.add(key);
|
|
653
|
+
const thoughtSignature = readThoughtSignature(part);
|
|
637
654
|
parts.push({
|
|
638
655
|
type: "tool-call",
|
|
639
|
-
toolCall
|
|
656
|
+
toolCall,
|
|
657
|
+
...thoughtSignature ? {
|
|
658
|
+
providerMetadata: {
|
|
659
|
+
google: { thoughtSignature }
|
|
660
|
+
}
|
|
661
|
+
} : {}
|
|
640
662
|
});
|
|
641
663
|
}
|
|
642
664
|
continue;
|
|
@@ -660,14 +682,57 @@ function extractAssistantParts(response) {
|
|
|
660
682
|
toolCall
|
|
661
683
|
});
|
|
662
684
|
}
|
|
663
|
-
if (parts.length === 0
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
685
|
+
if (parts.length === 0) {
|
|
686
|
+
for (const text of extractTextDeltas(response)) {
|
|
687
|
+
parts.push({
|
|
688
|
+
type: "text",
|
|
689
|
+
text
|
|
690
|
+
});
|
|
691
|
+
}
|
|
668
692
|
}
|
|
669
693
|
return parts;
|
|
670
694
|
}
|
|
695
|
+
function extractTextDeltas(response) {
|
|
696
|
+
const candidateParts = response.candidates?.[0]?.content?.parts ?? [];
|
|
697
|
+
if (candidateParts.length > 0) {
|
|
698
|
+
return candidateParts.flatMap((part) => {
|
|
699
|
+
if (part.thought || part.functionCall) {
|
|
700
|
+
return [];
|
|
701
|
+
}
|
|
702
|
+
if (typeof part.text === "string" && part.text.length > 0) {
|
|
703
|
+
return [part.text];
|
|
704
|
+
}
|
|
705
|
+
return [];
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
return typeof response.text === "string" && response.text.length > 0 ? [response.text] : [];
|
|
709
|
+
}
|
|
710
|
+
function extractStreamedFunctionCalls(chunk) {
|
|
711
|
+
const candidateParts = chunk.candidates?.[0]?.content?.parts ?? [];
|
|
712
|
+
const fromCandidateParts = [];
|
|
713
|
+
for (const part of candidateParts) {
|
|
714
|
+
if (!part.functionCall) {
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
717
|
+
const thoughtSignature = readThoughtSignature(part);
|
|
718
|
+
fromCandidateParts.push({
|
|
719
|
+
toolCall: mapFunctionCall(
|
|
720
|
+
part.functionCall,
|
|
721
|
+
fromCandidateParts.length
|
|
722
|
+
),
|
|
723
|
+
...thoughtSignature ? { thoughtSignature } : {}
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
if (fromCandidateParts.length > 0) {
|
|
727
|
+
return fromCandidateParts;
|
|
728
|
+
}
|
|
729
|
+
return (chunk.functionCalls ?? []).map((functionCall, index) => ({
|
|
730
|
+
toolCall: mapFunctionCall(functionCall, index)
|
|
731
|
+
}));
|
|
732
|
+
}
|
|
733
|
+
function readThoughtSignature(part) {
|
|
734
|
+
return typeof part.thoughtSignature === "string" && part.thoughtSignature.length > 0 ? part.thoughtSignature : void 0;
|
|
735
|
+
}
|
|
671
736
|
function extractReasoningDeltas(response) {
|
|
672
737
|
const candidateParts = response.candidates?.[0]?.content?.parts ?? [];
|
|
673
738
|
return candidateParts.flatMap((part) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@core-ai/google-genai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Google GenAI provider package for @core-ai/core-ai",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Omnifact (https://omnifact.ai)",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"test:watch": "vitest"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@core-ai/core-ai": "^0.
|
|
48
|
+
"@core-ai/core-ai": "^0.20.0",
|
|
49
49
|
"@google/genai": "^1.42.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|