@core-ai/google-genai 0.18.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 +17 -12
- package/dist/index.js +136 -36
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
import { GoogleGenAI } from '@google/genai';
|
|
2
|
-
import { ChatModel, EmbeddingModel, ImageModel
|
|
2
|
+
import { ModelCapabilities, ChatModel, EmbeddingModel, ImageModel } from '@core-ai/core-ai';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
|
+
type GoogleModelCapabilities = Omit<ModelCapabilities, 'reasoning'> & {
|
|
6
|
+
reasoning: ModelCapabilities['reasoning'] & {
|
|
7
|
+
thinkingParam: 'thinkingLevel' | 'thinkingBudget';
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
declare function getGoogleModelCapabilities(modelId: string): GoogleModelCapabilities;
|
|
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
|
+
*/
|
|
17
|
+
type GoogleReasoningMetadata = {
|
|
18
|
+
thoughtSignature?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
5
21
|
type GoogleGenAIClient = {
|
|
6
22
|
models: GoogleGenAI['models'];
|
|
7
23
|
};
|
|
@@ -23,17 +39,6 @@ type GoogleGenAIProvider = {
|
|
|
23
39
|
declare function createGoogleGenAIProvider(options?: GoogleGenAIProviderBaseOptions, factoryOptions?: GoogleGenAIProviderFactoryOptions): GoogleGenAIProvider;
|
|
24
40
|
declare function createGoogleGenAI(options?: GoogleGenAIProviderOptions): GoogleGenAIProvider;
|
|
25
41
|
|
|
26
|
-
type GoogleReasoningMetadata = {
|
|
27
|
-
thoughtSignature?: string;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
type GoogleModelCapabilities = {
|
|
31
|
-
reasoning: ModelCapabilities['reasoning'] & {
|
|
32
|
-
thinkingParam: 'thinkingLevel' | 'thinkingBudget';
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
declare function getGoogleModelCapabilities(modelId: string): GoogleModelCapabilities;
|
|
36
|
-
|
|
37
42
|
declare const googleGenerateProviderOptionsSchema: z.ZodObject<{
|
|
38
43
|
stopSequences: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
39
44
|
frequencyPenalty: z.ZodOptional<z.ZodNumber>;
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
// src/provider.ts
|
|
2
2
|
import { GoogleGenAI } from "@google/genai";
|
|
3
3
|
|
|
4
|
-
// src/chat-model.ts
|
|
5
|
-
import {
|
|
6
|
-
StructuredOutputNoObjectGeneratedError,
|
|
7
|
-
StructuredOutputParseError,
|
|
8
|
-
StructuredOutputValidationError,
|
|
9
|
-
createObjectStream,
|
|
10
|
-
createChatStream
|
|
11
|
-
} from "@core-ai/core-ai";
|
|
12
|
-
|
|
13
4
|
// src/chat-adapter.ts
|
|
14
5
|
import {
|
|
15
6
|
FunctionCallingConfigMode
|
|
16
7
|
} from "@google/genai";
|
|
17
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getProviderMetadata,
|
|
10
|
+
validateInputModalities,
|
|
11
|
+
zodSchemaToJsonSchema
|
|
12
|
+
} from "@core-ai/core-ai";
|
|
18
13
|
|
|
19
14
|
// src/model-capabilities.ts
|
|
20
15
|
import {
|
|
@@ -27,6 +22,10 @@ var ALL_EFFORTS = [
|
|
|
27
22
|
"high",
|
|
28
23
|
"max"
|
|
29
24
|
];
|
|
25
|
+
var GOOGLE_INPUT_MODALITIES = {
|
|
26
|
+
input: ["text", "image", "file", "audio"],
|
|
27
|
+
output: ["text"]
|
|
28
|
+
};
|
|
30
29
|
function createCapabilities(config) {
|
|
31
30
|
return {
|
|
32
31
|
reasoning: {
|
|
@@ -35,7 +34,8 @@ function createCapabilities(config) {
|
|
|
35
34
|
restrictsSamplingParams: false,
|
|
36
35
|
supportedToolChoices: ["auto", "none", "required", "tool"],
|
|
37
36
|
thinkingParam: config.thinkingParam
|
|
38
|
-
}
|
|
37
|
+
},
|
|
38
|
+
modalities: GOOGLE_INPUT_MODALITIES
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
var DEFAULT_CAPABILITIES = createCapabilities({
|
|
@@ -151,6 +151,7 @@ function parseGoogleImageProviderOptions(providerOptions) {
|
|
|
151
151
|
var googleProviderOptionsSchema = googleGenerateProviderOptionsSchema;
|
|
152
152
|
|
|
153
153
|
// src/chat-adapter.ts
|
|
154
|
+
var DEFAULT_PROVIDER_ID = "google";
|
|
154
155
|
var DEFAULT_STRUCTURED_OUTPUT_TOOL_NAME = "core_ai_generate_object";
|
|
155
156
|
var DEFAULT_STRUCTURED_OUTPUT_TOOL_DESCRIPTION = "Return a JSON object that matches the requested schema.";
|
|
156
157
|
function convertMessages(messages) {
|
|
@@ -179,12 +180,17 @@ function convertMessages(messages) {
|
|
|
179
180
|
}
|
|
180
181
|
if (part.type === "tool-call") {
|
|
181
182
|
toolCallNameById.set(part.toolCall.id, part.toolCall.name);
|
|
183
|
+
const toolCallSignature = getProviderMetadata(
|
|
184
|
+
part.providerMetadata,
|
|
185
|
+
"google"
|
|
186
|
+
)?.thoughtSignature;
|
|
182
187
|
assistantParts.push({
|
|
183
188
|
functionCall: {
|
|
184
189
|
id: part.toolCall.id,
|
|
185
190
|
name: part.toolCall.name,
|
|
186
191
|
args: part.toolCall.arguments
|
|
187
|
-
}
|
|
192
|
+
},
|
|
193
|
+
...typeof toolCallSignature === "string" ? { thoughtSignature: toolCallSignature } : {}
|
|
188
194
|
});
|
|
189
195
|
continue;
|
|
190
196
|
}
|
|
@@ -254,6 +260,14 @@ function convertUserContentPart(part) {
|
|
|
254
260
|
}
|
|
255
261
|
};
|
|
256
262
|
}
|
|
263
|
+
if (part.type === "audio") {
|
|
264
|
+
return {
|
|
265
|
+
inlineData: {
|
|
266
|
+
data: part.source.data,
|
|
267
|
+
mimeType: part.source.mediaType
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}
|
|
257
271
|
return {
|
|
258
272
|
inlineData: {
|
|
259
273
|
data: part.data,
|
|
@@ -361,17 +375,24 @@ function inferMimeTypeFromUrl(url) {
|
|
|
361
375
|
}
|
|
362
376
|
return "application/octet-stream";
|
|
363
377
|
}
|
|
364
|
-
function createGenerateRequest(modelId, options) {
|
|
378
|
+
function createGenerateRequest(modelId, options, provider = DEFAULT_PROVIDER_ID, adapterOptions = {}) {
|
|
365
379
|
const googleOptions = parseGoogleGenerateProviderOptions(
|
|
366
380
|
options.providerOptions
|
|
367
381
|
);
|
|
382
|
+
const capabilities = adapterOptions.capabilities ?? getGoogleModelCapabilities(modelId);
|
|
383
|
+
validateInputModalities({
|
|
384
|
+
messages: options.messages,
|
|
385
|
+
capabilities,
|
|
386
|
+
modelId,
|
|
387
|
+
providerId: provider
|
|
388
|
+
});
|
|
368
389
|
const convertedMessages = convertMessages(options.messages);
|
|
369
390
|
const requestConfig = {
|
|
370
391
|
...convertedMessages.systemInstruction ? { systemInstruction: convertedMessages.systemInstruction } : {},
|
|
371
392
|
...options.tools && Object.keys(options.tools).length > 0 ? { tools: convertTools(options.tools) } : {},
|
|
372
393
|
...options.toolChoice ? { toolConfig: convertToolChoice(options.toolChoice) } : {},
|
|
373
394
|
...mapSamplingToConfig(options),
|
|
374
|
-
...mapReasoningToConfig(
|
|
395
|
+
...mapReasoningToConfig(options, capabilities),
|
|
375
396
|
...mapGoogleProviderOptionsToConfig(googleOptions),
|
|
376
397
|
...options.signal ? { abortSignal: options.signal } : {}
|
|
377
398
|
};
|
|
@@ -437,6 +458,7 @@ function mapFinishReason(reason) {
|
|
|
437
458
|
}
|
|
438
459
|
async function* transformStream(stream) {
|
|
439
460
|
const bufferedToolCalls = /* @__PURE__ */ new Map();
|
|
461
|
+
const toolCallSignatures = /* @__PURE__ */ new Map();
|
|
440
462
|
let finishReason = "unknown";
|
|
441
463
|
let sawToolCalls = false;
|
|
442
464
|
let textOpen = false;
|
|
@@ -492,18 +514,21 @@ async function* transformStream(stream) {
|
|
|
492
514
|
};
|
|
493
515
|
}
|
|
494
516
|
}
|
|
495
|
-
|
|
517
|
+
const textDeltas = extractTextDeltas(chunk);
|
|
518
|
+
if (textDeltas.length > 0) {
|
|
496
519
|
const reasoningEnd2 = closeReasoning();
|
|
497
520
|
if (reasoningEnd2) {
|
|
498
521
|
yield reasoningEnd2;
|
|
499
522
|
}
|
|
500
523
|
yield* startText();
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
524
|
+
for (const text of textDeltas) {
|
|
525
|
+
yield {
|
|
526
|
+
type: "text-delta",
|
|
527
|
+
text
|
|
528
|
+
};
|
|
529
|
+
}
|
|
505
530
|
}
|
|
506
|
-
const functionCalls = chunk
|
|
531
|
+
const functionCalls = extractStreamedFunctionCalls(chunk);
|
|
507
532
|
if (functionCalls.length > 0) {
|
|
508
533
|
yield* closeText();
|
|
509
534
|
const reasoningEnd2 = closeReasoning();
|
|
@@ -511,8 +536,13 @@ async function* transformStream(stream) {
|
|
|
511
536
|
yield reasoningEnd2;
|
|
512
537
|
}
|
|
513
538
|
sawToolCalls = true;
|
|
514
|
-
for (const
|
|
515
|
-
|
|
539
|
+
for (const {
|
|
540
|
+
toolCall: mappedCall,
|
|
541
|
+
thoughtSignature
|
|
542
|
+
} of functionCalls) {
|
|
543
|
+
if (thoughtSignature) {
|
|
544
|
+
toolCallSignatures.set(mappedCall.id, thoughtSignature);
|
|
545
|
+
}
|
|
516
546
|
const existing = bufferedToolCalls.get(mappedCall.id);
|
|
517
547
|
if (!existing) {
|
|
518
548
|
bufferedToolCalls.set(mappedCall.id, mappedCall);
|
|
@@ -558,9 +588,11 @@ async function* transformStream(stream) {
|
|
|
558
588
|
}
|
|
559
589
|
yield* closeText();
|
|
560
590
|
for (const toolCall of bufferedToolCalls.values()) {
|
|
591
|
+
const thoughtSignature = toolCallSignatures.get(toolCall.id);
|
|
561
592
|
yield {
|
|
562
593
|
type: "tool-call-end",
|
|
563
|
-
toolCall
|
|
594
|
+
toolCall,
|
|
595
|
+
...thoughtSignature ? { providerMetadata: { google: { thoughtSignature } } } : {}
|
|
564
596
|
};
|
|
565
597
|
}
|
|
566
598
|
if (sawToolCalls && finishReason !== "content-filter") {
|
|
@@ -572,11 +604,10 @@ async function* transformStream(stream) {
|
|
|
572
604
|
usage
|
|
573
605
|
};
|
|
574
606
|
}
|
|
575
|
-
function mapReasoningToConfig(
|
|
607
|
+
function mapReasoningToConfig(options, capabilities) {
|
|
576
608
|
if (!options.reasoning) {
|
|
577
609
|
return {};
|
|
578
610
|
}
|
|
579
|
-
const capabilities = getGoogleModelCapabilities(modelId);
|
|
580
611
|
if (capabilities.reasoning.thinkingParam === "thinkingLevel") {
|
|
581
612
|
return {
|
|
582
613
|
thinkingConfig: {
|
|
@@ -602,7 +633,7 @@ function extractAssistantParts(response) {
|
|
|
602
633
|
if (thoughtText.length === 0) {
|
|
603
634
|
continue;
|
|
604
635
|
}
|
|
605
|
-
const thoughtSignature =
|
|
636
|
+
const thoughtSignature = readThoughtSignature(part);
|
|
606
637
|
parts.push({
|
|
607
638
|
type: "reasoning",
|
|
608
639
|
text: thoughtText,
|
|
@@ -619,9 +650,15 @@ function extractAssistantParts(response) {
|
|
|
619
650
|
const key = `${toolCall.id}:${toolCall.name}`;
|
|
620
651
|
if (!seenToolCalls.has(key)) {
|
|
621
652
|
seenToolCalls.add(key);
|
|
653
|
+
const thoughtSignature = readThoughtSignature(part);
|
|
622
654
|
parts.push({
|
|
623
655
|
type: "tool-call",
|
|
624
|
-
toolCall
|
|
656
|
+
toolCall,
|
|
657
|
+
...thoughtSignature ? {
|
|
658
|
+
providerMetadata: {
|
|
659
|
+
google: { thoughtSignature }
|
|
660
|
+
}
|
|
661
|
+
} : {}
|
|
625
662
|
});
|
|
626
663
|
}
|
|
627
664
|
continue;
|
|
@@ -645,14 +682,57 @@ function extractAssistantParts(response) {
|
|
|
645
682
|
toolCall
|
|
646
683
|
});
|
|
647
684
|
}
|
|
648
|
-
if (parts.length === 0
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
685
|
+
if (parts.length === 0) {
|
|
686
|
+
for (const text of extractTextDeltas(response)) {
|
|
687
|
+
parts.push({
|
|
688
|
+
type: "text",
|
|
689
|
+
text
|
|
690
|
+
});
|
|
691
|
+
}
|
|
653
692
|
}
|
|
654
693
|
return parts;
|
|
655
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
|
+
}
|
|
656
736
|
function extractReasoningDeltas(response) {
|
|
657
737
|
const candidateParts = response.candidates?.[0]?.content?.parts ?? [];
|
|
658
738
|
return candidateParts.flatMap((part) => {
|
|
@@ -681,6 +761,15 @@ function mapUsage(response, fallback) {
|
|
|
681
761
|
};
|
|
682
762
|
}
|
|
683
763
|
|
|
764
|
+
// src/chat-model.ts
|
|
765
|
+
import {
|
|
766
|
+
StructuredOutputNoObjectGeneratedError,
|
|
767
|
+
StructuredOutputParseError,
|
|
768
|
+
StructuredOutputValidationError,
|
|
769
|
+
createObjectStream,
|
|
770
|
+
createChatStream
|
|
771
|
+
} from "@core-ai/core-ai";
|
|
772
|
+
|
|
684
773
|
// src/google-error.ts
|
|
685
774
|
import { ApiError } from "@google/genai";
|
|
686
775
|
import {
|
|
@@ -814,6 +903,8 @@ function toNumericHttpCode(body) {
|
|
|
814
903
|
|
|
815
904
|
// src/chat-model.ts
|
|
816
905
|
function createGoogleGenAIChatModel(client, modelId, provider = "google") {
|
|
906
|
+
const capabilities = getGoogleModelCapabilities(modelId);
|
|
907
|
+
const adapterOptions = { capabilities };
|
|
817
908
|
async function callGenerateContentApi(request) {
|
|
818
909
|
try {
|
|
819
910
|
return await client.models.generateContent(request);
|
|
@@ -829,12 +920,22 @@ function createGoogleGenAIChatModel(client, modelId, provider = "google") {
|
|
|
829
920
|
}
|
|
830
921
|
}
|
|
831
922
|
async function generateChat(options) {
|
|
832
|
-
const request = createGenerateRequest(
|
|
923
|
+
const request = createGenerateRequest(
|
|
924
|
+
modelId,
|
|
925
|
+
options,
|
|
926
|
+
provider,
|
|
927
|
+
adapterOptions
|
|
928
|
+
);
|
|
833
929
|
const response = await callGenerateContentApi(request);
|
|
834
930
|
return mapGenerateResponse(response);
|
|
835
931
|
}
|
|
836
932
|
async function streamChat(options) {
|
|
837
|
-
const request = createGenerateRequest(
|
|
933
|
+
const request = createGenerateRequest(
|
|
934
|
+
modelId,
|
|
935
|
+
options,
|
|
936
|
+
provider,
|
|
937
|
+
adapterOptions
|
|
938
|
+
);
|
|
838
939
|
return createChatStream(
|
|
839
940
|
async () => transformStream(await callGenerateContentStreamApi(request)),
|
|
840
941
|
{ signal: options.signal }
|
|
@@ -843,7 +944,7 @@ function createGoogleGenAIChatModel(client, modelId, provider = "google") {
|
|
|
843
944
|
return {
|
|
844
945
|
provider,
|
|
845
946
|
modelId,
|
|
846
|
-
capabilities
|
|
947
|
+
capabilities,
|
|
847
948
|
generate: generateChat,
|
|
848
949
|
stream: streamChat,
|
|
849
950
|
async generateObject(options) {
|
|
@@ -1247,7 +1348,6 @@ function greatestCommonDivisor(a, b) {
|
|
|
1247
1348
|
}
|
|
1248
1349
|
|
|
1249
1350
|
// src/provider.ts
|
|
1250
|
-
var DEFAULT_PROVIDER_ID = "google";
|
|
1251
1351
|
function createGoogleGenAIProvider(options = {}, factoryOptions = {}) {
|
|
1252
1352
|
const client = options.client ?? new GoogleGenAI({
|
|
1253
1353
|
apiKey: options.apiKey,
|
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": {
|