@ai-sdk/google 3.0.60 → 3.0.62
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 +12 -0
- package/dist/index.d.mts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +375 -56
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +375 -56
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +11 -2
- package/dist/internal/index.d.ts +11 -2
- package/dist/internal/index.js +374 -55
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +374 -55
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/google-generative-ai-language-model.ts +216 -45
- package/src/google-generative-ai-options.ts +12 -0
- package/src/google-json-accumulator.ts +336 -0
- package/src/google-prepare-tools.ts +1 -0
package/package.json
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
GoogleGenerativeAIProviderMetadata,
|
|
45
45
|
} from './google-generative-ai-prompt';
|
|
46
46
|
import { prepareTools } from './google-prepare-tools';
|
|
47
|
+
import { GoogleJSONAccumulator, PartialArg } from './google-json-accumulator';
|
|
47
48
|
import { mapGoogleGenerativeAIFinishReason } from './map-google-generative-ai-finish-reason';
|
|
48
49
|
|
|
49
50
|
type GoogleGenerativeAIConfig = {
|
|
@@ -84,21 +85,24 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
84
85
|
return this.config.supportedUrls?.() ?? {};
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
private async getArgs(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
private async getArgs(
|
|
89
|
+
{
|
|
90
|
+
prompt,
|
|
91
|
+
maxOutputTokens,
|
|
92
|
+
temperature,
|
|
93
|
+
topP,
|
|
94
|
+
topK,
|
|
95
|
+
frequencyPenalty,
|
|
96
|
+
presencePenalty,
|
|
97
|
+
stopSequences,
|
|
98
|
+
responseFormat,
|
|
99
|
+
seed,
|
|
100
|
+
tools,
|
|
101
|
+
toolChoice,
|
|
102
|
+
providerOptions,
|
|
103
|
+
}: LanguageModelV3CallOptions,
|
|
104
|
+
{ isStreaming = false }: { isStreaming?: boolean } = {},
|
|
105
|
+
) {
|
|
102
106
|
const warnings: SharedV3Warning[] = [];
|
|
103
107
|
|
|
104
108
|
const providerOptionsName = this.config.provider.includes('vertex')
|
|
@@ -119,12 +123,14 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
119
123
|
}
|
|
120
124
|
|
|
121
125
|
// Add warning if Vertex rag tools are used with a non-Vertex Google provider
|
|
126
|
+
const isVertexProvider = this.config.provider.startsWith('google.vertex.');
|
|
127
|
+
|
|
122
128
|
if (
|
|
123
129
|
tools?.some(
|
|
124
130
|
tool =>
|
|
125
131
|
tool.type === 'provider' && tool.id === 'google.vertex_rag_store',
|
|
126
132
|
) &&
|
|
127
|
-
!
|
|
133
|
+
!isVertexProvider
|
|
128
134
|
) {
|
|
129
135
|
warnings.push({
|
|
130
136
|
type: 'other',
|
|
@@ -135,6 +141,16 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
135
141
|
});
|
|
136
142
|
}
|
|
137
143
|
|
|
144
|
+
if (googleOptions?.streamFunctionCallArguments && !isVertexProvider) {
|
|
145
|
+
warnings.push({
|
|
146
|
+
type: 'other',
|
|
147
|
+
message:
|
|
148
|
+
"'streamFunctionCallArguments' is only supported on the Vertex AI API " +
|
|
149
|
+
'and will be ignored with the current Google provider ' +
|
|
150
|
+
`(${this.config.provider}). See https://docs.cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling#streaming-fc`,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
138
154
|
const isGemmaModel = this.modelId.toLowerCase().startsWith('gemma-');
|
|
139
155
|
const supportsFunctionResponseParts = this.modelId.startsWith('gemini-3');
|
|
140
156
|
|
|
@@ -157,6 +173,29 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
157
173
|
modelId: this.modelId,
|
|
158
174
|
});
|
|
159
175
|
|
|
176
|
+
const streamFunctionCallArguments =
|
|
177
|
+
isStreaming && isVertexProvider
|
|
178
|
+
? (googleOptions?.streamFunctionCallArguments ?? false)
|
|
179
|
+
: undefined;
|
|
180
|
+
|
|
181
|
+
const toolConfig =
|
|
182
|
+
googleToolConfig ||
|
|
183
|
+
streamFunctionCallArguments ||
|
|
184
|
+
googleOptions?.retrievalConfig
|
|
185
|
+
? {
|
|
186
|
+
...googleToolConfig,
|
|
187
|
+
...(streamFunctionCallArguments && {
|
|
188
|
+
functionCallingConfig: {
|
|
189
|
+
...googleToolConfig?.functionCallingConfig,
|
|
190
|
+
streamFunctionCallArguments: true as const,
|
|
191
|
+
},
|
|
192
|
+
}),
|
|
193
|
+
...(googleOptions?.retrievalConfig && {
|
|
194
|
+
retrievalConfig: googleOptions.retrievalConfig,
|
|
195
|
+
}),
|
|
196
|
+
}
|
|
197
|
+
: undefined;
|
|
198
|
+
|
|
160
199
|
return {
|
|
161
200
|
args: {
|
|
162
201
|
generationConfig: {
|
|
@@ -200,12 +239,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
200
239
|
systemInstruction: isGemmaModel ? undefined : systemInstruction,
|
|
201
240
|
safetySettings: googleOptions?.safetySettings,
|
|
202
241
|
tools: googleTools,
|
|
203
|
-
toolConfig
|
|
204
|
-
? {
|
|
205
|
-
...googleToolConfig,
|
|
206
|
-
retrievalConfig: googleOptions.retrievalConfig,
|
|
207
|
-
}
|
|
208
|
-
: googleToolConfig,
|
|
242
|
+
toolConfig,
|
|
209
243
|
cachedContent: googleOptions?.cachedContent,
|
|
210
244
|
labels: googleOptions?.labels,
|
|
211
245
|
serviceTier: googleOptions?.serviceTier,
|
|
@@ -301,7 +335,11 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
301
335
|
providerMetadata: thoughtSignatureMetadata,
|
|
302
336
|
});
|
|
303
337
|
}
|
|
304
|
-
} else if (
|
|
338
|
+
} else if (
|
|
339
|
+
'functionCall' in part &&
|
|
340
|
+
part.functionCall.name != null &&
|
|
341
|
+
part.functionCall.args != null
|
|
342
|
+
) {
|
|
305
343
|
content.push({
|
|
306
344
|
type: 'tool-call' as const,
|
|
307
345
|
toolCallId: this.config.generateId(),
|
|
@@ -434,7 +472,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
434
472
|
async doStream(
|
|
435
473
|
options: LanguageModelV3CallOptions,
|
|
436
474
|
): Promise<LanguageModelV3StreamResult> {
|
|
437
|
-
const { args, warnings, providerOptionsName } = await this.getArgs(
|
|
475
|
+
const { args, warnings, providerOptionsName } = await this.getArgs(
|
|
476
|
+
options,
|
|
477
|
+
{ isStreaming: true },
|
|
478
|
+
);
|
|
438
479
|
|
|
439
480
|
const headers = combineHeaders(
|
|
440
481
|
await resolve(this.config.headers),
|
|
@@ -478,6 +519,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
478
519
|
// Associates a server-side tool response with its preceding call (tool combination).
|
|
479
520
|
let lastServerToolCallId: string | undefined;
|
|
480
521
|
|
|
522
|
+
const activeStreamingToolCalls: Array<{
|
|
523
|
+
toolCallId: string;
|
|
524
|
+
toolName: string;
|
|
525
|
+
accumulator: GoogleJSONAccumulator;
|
|
526
|
+
providerMetadata?: SharedV3ProviderMetadata;
|
|
527
|
+
}> = [];
|
|
528
|
+
|
|
481
529
|
return {
|
|
482
530
|
stream: response.pipeThrough(
|
|
483
531
|
new TransformStream<
|
|
@@ -735,40 +783,152 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
735
783
|
}
|
|
736
784
|
}
|
|
737
785
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
786
|
+
// Handle streaming and complete function calls
|
|
787
|
+
for (const part of parts) {
|
|
788
|
+
if (!('functionCall' in part)) continue;
|
|
789
|
+
|
|
790
|
+
const providerMeta = part.thoughtSignature
|
|
791
|
+
? {
|
|
792
|
+
[providerOptionsName]: {
|
|
793
|
+
thoughtSignature: part.thoughtSignature,
|
|
794
|
+
},
|
|
795
|
+
}
|
|
796
|
+
: undefined;
|
|
797
|
+
|
|
798
|
+
const isStreamingChunk =
|
|
799
|
+
part.functionCall.partialArgs != null ||
|
|
800
|
+
(part.functionCall.name != null &&
|
|
801
|
+
part.functionCall.willContinue === true);
|
|
802
|
+
const isTerminalChunk =
|
|
803
|
+
part.functionCall.name == null &&
|
|
804
|
+
part.functionCall.args == null &&
|
|
805
|
+
part.functionCall.partialArgs == null &&
|
|
806
|
+
part.functionCall.willContinue == null;
|
|
807
|
+
const isCompleteCall =
|
|
808
|
+
part.functionCall.name != null &&
|
|
809
|
+
part.functionCall.args != null &&
|
|
810
|
+
part.functionCall.partialArgs == null;
|
|
811
|
+
|
|
812
|
+
if (isStreamingChunk) {
|
|
813
|
+
if (
|
|
814
|
+
part.functionCall.name != null &&
|
|
815
|
+
part.functionCall.willContinue === true
|
|
816
|
+
) {
|
|
817
|
+
const toolCallId = generateId();
|
|
818
|
+
const accumulator = new GoogleJSONAccumulator();
|
|
819
|
+
activeStreamingToolCalls.push({
|
|
820
|
+
toolCallId,
|
|
821
|
+
toolName: part.functionCall.name,
|
|
822
|
+
accumulator,
|
|
823
|
+
providerMetadata: providerMeta,
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
controller.enqueue({
|
|
827
|
+
type: 'tool-input-start',
|
|
828
|
+
id: toolCallId,
|
|
829
|
+
toolName: part.functionCall.name,
|
|
830
|
+
providerMetadata: providerMeta,
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
if (part.functionCall.partialArgs != null) {
|
|
834
|
+
const { textDelta } = accumulator.processPartialArgs(
|
|
835
|
+
part.functionCall.partialArgs as PartialArg[],
|
|
836
|
+
);
|
|
837
|
+
if (textDelta.length > 0) {
|
|
838
|
+
controller.enqueue({
|
|
839
|
+
type: 'tool-input-delta',
|
|
840
|
+
id: toolCallId,
|
|
841
|
+
delta: textDelta,
|
|
842
|
+
providerMetadata: providerMeta,
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
} else if (
|
|
847
|
+
part.functionCall.partialArgs != null &&
|
|
848
|
+
activeStreamingToolCalls.length > 0
|
|
849
|
+
) {
|
|
850
|
+
const active =
|
|
851
|
+
activeStreamingToolCalls[
|
|
852
|
+
activeStreamingToolCalls.length - 1
|
|
853
|
+
];
|
|
854
|
+
const { textDelta } = active.accumulator.processPartialArgs(
|
|
855
|
+
part.functionCall.partialArgs as PartialArg[],
|
|
856
|
+
);
|
|
857
|
+
if (textDelta.length > 0) {
|
|
858
|
+
controller.enqueue({
|
|
859
|
+
type: 'tool-input-delta',
|
|
860
|
+
id: active.toolCallId,
|
|
861
|
+
delta: textDelta,
|
|
862
|
+
providerMetadata: providerMeta,
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
} else if (
|
|
867
|
+
isTerminalChunk &&
|
|
868
|
+
activeStreamingToolCalls.length > 0
|
|
869
|
+
) {
|
|
870
|
+
const active = activeStreamingToolCalls.pop()!;
|
|
871
|
+
const { finalJSON, closingDelta } =
|
|
872
|
+
active.accumulator.finalize();
|
|
873
|
+
|
|
874
|
+
if (closingDelta.length > 0) {
|
|
875
|
+
controller.enqueue({
|
|
876
|
+
type: 'tool-input-delta',
|
|
877
|
+
id: active.toolCallId,
|
|
878
|
+
delta: closingDelta,
|
|
879
|
+
providerMetadata: active.providerMetadata,
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
controller.enqueue({
|
|
884
|
+
type: 'tool-input-end',
|
|
885
|
+
id: active.toolCallId,
|
|
886
|
+
providerMetadata: active.providerMetadata,
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
controller.enqueue({
|
|
890
|
+
type: 'tool-call',
|
|
891
|
+
toolCallId: active.toolCallId,
|
|
892
|
+
toolName: active.toolName,
|
|
893
|
+
input: finalJSON,
|
|
894
|
+
providerMetadata: active.providerMetadata,
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
hasToolCalls = true;
|
|
898
|
+
} else if (isCompleteCall) {
|
|
899
|
+
const toolCallId = generateId();
|
|
900
|
+
const toolName = part.functionCall.name!;
|
|
901
|
+
const args =
|
|
902
|
+
typeof part.functionCall.args === 'string'
|
|
903
|
+
? part.functionCall.args
|
|
904
|
+
: JSON.stringify(part.functionCall.args ?? {});
|
|
743
905
|
|
|
744
|
-
if (toolCallDeltas != null) {
|
|
745
|
-
for (const toolCall of toolCallDeltas) {
|
|
746
906
|
controller.enqueue({
|
|
747
907
|
type: 'tool-input-start',
|
|
748
|
-
id:
|
|
749
|
-
toolName
|
|
750
|
-
providerMetadata:
|
|
908
|
+
id: toolCallId,
|
|
909
|
+
toolName,
|
|
910
|
+
providerMetadata: providerMeta,
|
|
751
911
|
});
|
|
752
912
|
|
|
753
913
|
controller.enqueue({
|
|
754
914
|
type: 'tool-input-delta',
|
|
755
|
-
id:
|
|
756
|
-
delta:
|
|
757
|
-
providerMetadata:
|
|
915
|
+
id: toolCallId,
|
|
916
|
+
delta: args,
|
|
917
|
+
providerMetadata: providerMeta,
|
|
758
918
|
});
|
|
759
919
|
|
|
760
920
|
controller.enqueue({
|
|
761
921
|
type: 'tool-input-end',
|
|
762
|
-
id:
|
|
763
|
-
providerMetadata:
|
|
922
|
+
id: toolCallId,
|
|
923
|
+
providerMetadata: providerMeta,
|
|
764
924
|
});
|
|
765
925
|
|
|
766
926
|
controller.enqueue({
|
|
767
927
|
type: 'tool-call',
|
|
768
|
-
toolCallId
|
|
769
|
-
toolName
|
|
770
|
-
input:
|
|
771
|
-
providerMetadata:
|
|
928
|
+
toolCallId,
|
|
929
|
+
toolName,
|
|
930
|
+
input: args,
|
|
931
|
+
providerMetadata: providerMeta,
|
|
772
932
|
});
|
|
773
933
|
|
|
774
934
|
hasToolCalls = true;
|
|
@@ -1040,6 +1200,15 @@ export const getGroundingMetadataSchema = () =>
|
|
|
1040
1200
|
.nullish(),
|
|
1041
1201
|
});
|
|
1042
1202
|
|
|
1203
|
+
const partialArgSchema = z.object({
|
|
1204
|
+
jsonPath: z.string(),
|
|
1205
|
+
stringValue: z.string().nullish(),
|
|
1206
|
+
numberValue: z.number().nullish(),
|
|
1207
|
+
boolValue: z.boolean().nullish(),
|
|
1208
|
+
nullValue: z.unknown().nullish(),
|
|
1209
|
+
willContinue: z.boolean().nullish(),
|
|
1210
|
+
});
|
|
1211
|
+
|
|
1043
1212
|
const getContentSchema = () =>
|
|
1044
1213
|
z.object({
|
|
1045
1214
|
parts: z
|
|
@@ -1048,8 +1217,10 @@ const getContentSchema = () =>
|
|
|
1048
1217
|
// note: order matters since text can be fully empty
|
|
1049
1218
|
z.object({
|
|
1050
1219
|
functionCall: z.object({
|
|
1051
|
-
name: z.string(),
|
|
1052
|
-
args: z.unknown(),
|
|
1220
|
+
name: z.string().nullish(),
|
|
1221
|
+
args: z.unknown().nullish(),
|
|
1222
|
+
partialArgs: z.array(partialArgSchema).nullish(),
|
|
1223
|
+
willContinue: z.boolean().nullish(),
|
|
1053
1224
|
}),
|
|
1054
1225
|
thoughtSignature: z.string().nullish(),
|
|
1055
1226
|
}),
|
|
@@ -189,6 +189,18 @@ export const googleLanguageModelOptions = lazySchema(() =>
|
|
|
189
189
|
})
|
|
190
190
|
.optional(),
|
|
191
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Optional. When set to true, function call arguments will be streamed
|
|
194
|
+
* incrementally via partialArgs in streaming responses. Only supported
|
|
195
|
+
* on the Vertex AI API (not the Gemini API) and only for Gemini 3+
|
|
196
|
+
* models.
|
|
197
|
+
*
|
|
198
|
+
* @default false
|
|
199
|
+
*
|
|
200
|
+
* https://docs.cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling#streaming-fc
|
|
201
|
+
*/
|
|
202
|
+
streamFunctionCallArguments: z.boolean().optional(),
|
|
203
|
+
|
|
192
204
|
/**
|
|
193
205
|
* Optional. The service tier to use for the request.
|
|
194
206
|
*/
|