@ai-sdk/google 3.0.75 → 3.0.77
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 +13 -0
- package/dist/index.d.mts +39 -12
- package/dist/index.d.ts +39 -12
- package/dist/index.js +215 -69
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +215 -69
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +1 -2
- package/dist/internal/index.d.ts +1 -2
- package/dist/internal/index.js +97 -59
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +97 -59
- package/dist/internal/index.mjs.map +1 -1
- package/docs/15-google-generative-ai.mdx +1 -0
- package/package.json +1 -1
- package/src/google-generative-ai-language-model.ts +104 -56
- package/src/google-generative-ai-options.ts +24 -8
- package/src/google-provider.ts +9 -4
- package/src/interactions/google-interactions-agent.ts +6 -7
- package/src/interactions/google-interactions-language-model-options.ts +65 -0
- package/src/interactions/google-interactions-language-model.ts +73 -22
- package/src/interactions/google-interactions-prompt.ts +50 -0
- package/src/interactions/stream-google-interactions.ts +1 -1
|
@@ -1066,6 +1066,7 @@ The following Zod features are known to not work with Google Generative AI:
|
|
|
1066
1066
|
|
|
1067
1067
|
| Model | Image Input | Object Generation | Tool Usage | Tool Streaming | Google Search | URL Context |
|
|
1068
1068
|
| ------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
|
|
1069
|
+
| `gemini-3.5-flash` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
1069
1070
|
| `gemini-3.1-pro-preview` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
1070
1071
|
| `gemini-3.1-flash-image-preview` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
1071
1072
|
| `gemini-3.1-flash-lite-preview` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
package/package.json
CHANGED
|
@@ -37,7 +37,6 @@ import { getModelPath } from './get-model-path';
|
|
|
37
37
|
import { googleFailedResponseHandler } from './google-error';
|
|
38
38
|
import {
|
|
39
39
|
googleLanguageModelOptions,
|
|
40
|
-
VertexServiceTierMap,
|
|
41
40
|
type GoogleGenerativeAIModelId,
|
|
42
41
|
} from './google-generative-ai-options';
|
|
43
42
|
import type {
|
|
@@ -155,11 +154,43 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
155
154
|
});
|
|
156
155
|
}
|
|
157
156
|
|
|
158
|
-
// Vertex API requires another service tier format.
|
|
159
|
-
let sanitizedServiceTier: string | undefined = googleOptions?.serviceTier;
|
|
160
157
|
if (googleOptions?.serviceTier && isVertexProvider) {
|
|
161
|
-
|
|
158
|
+
warnings.push({
|
|
159
|
+
type: 'other',
|
|
160
|
+
message:
|
|
161
|
+
"'serviceTier' is a Gemini API option and is not supported on Vertex AI. " +
|
|
162
|
+
"Use 'sharedRequestType' (and optionally 'requestType') instead. See " +
|
|
163
|
+
'https://docs.cloud.google.com/vertex-ai/generative-ai/docs/priority-paygo',
|
|
164
|
+
});
|
|
162
165
|
}
|
|
166
|
+
if (
|
|
167
|
+
(googleOptions?.sharedRequestType || googleOptions?.requestType) &&
|
|
168
|
+
!isVertexProvider
|
|
169
|
+
) {
|
|
170
|
+
warnings.push({
|
|
171
|
+
type: 'other',
|
|
172
|
+
message:
|
|
173
|
+
"'sharedRequestType' and 'requestType' are Vertex AI options and " +
|
|
174
|
+
`are ignored with the current Google provider (${this.config.provider}).`,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const vertexPaygoHeaders: Record<string, string> | undefined =
|
|
179
|
+
isVertexProvider &&
|
|
180
|
+
(googleOptions?.sharedRequestType || googleOptions?.requestType)
|
|
181
|
+
? {
|
|
182
|
+
...(googleOptions.sharedRequestType && {
|
|
183
|
+
'X-Vertex-AI-LLM-Shared-Request-Type':
|
|
184
|
+
googleOptions.sharedRequestType,
|
|
185
|
+
}),
|
|
186
|
+
...(googleOptions.requestType && {
|
|
187
|
+
'X-Vertex-AI-LLM-Request-Type': googleOptions.requestType,
|
|
188
|
+
}),
|
|
189
|
+
}
|
|
190
|
+
: undefined;
|
|
191
|
+
const bodyServiceTier = isVertexProvider
|
|
192
|
+
? undefined
|
|
193
|
+
: googleOptions?.serviceTier;
|
|
163
194
|
|
|
164
195
|
const isGemmaModel = this.modelId.toLowerCase().startsWith('gemma-');
|
|
165
196
|
const supportsFunctionResponseParts = this.modelId.startsWith('gemini-3');
|
|
@@ -253,21 +284,24 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
253
284
|
toolConfig,
|
|
254
285
|
cachedContent: googleOptions?.cachedContent,
|
|
255
286
|
labels: googleOptions?.labels,
|
|
256
|
-
serviceTier:
|
|
287
|
+
serviceTier: bodyServiceTier,
|
|
257
288
|
},
|
|
258
289
|
warnings: [...warnings, ...toolWarnings],
|
|
259
290
|
providerOptionsName,
|
|
291
|
+
extraHeaders: vertexPaygoHeaders,
|
|
260
292
|
};
|
|
261
293
|
}
|
|
262
294
|
|
|
263
295
|
async doGenerate(
|
|
264
296
|
options: LanguageModelV3CallOptions,
|
|
265
297
|
): Promise<LanguageModelV3GenerateResult> {
|
|
266
|
-
const { args, warnings, providerOptionsName } =
|
|
298
|
+
const { args, warnings, providerOptionsName, extraHeaders } =
|
|
299
|
+
await this.getArgs(options);
|
|
267
300
|
|
|
268
301
|
const mergedHeaders = combineHeaders(
|
|
269
302
|
await resolve(this.config.headers),
|
|
270
303
|
options.headers,
|
|
304
|
+
extraHeaders,
|
|
271
305
|
);
|
|
272
306
|
|
|
273
307
|
const {
|
|
@@ -464,7 +498,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
464
498
|
safetyRatings: candidate.safetyRatings ?? null,
|
|
465
499
|
usageMetadata: usageMetadata ?? null,
|
|
466
500
|
finishMessage: candidate.finishMessage ?? null,
|
|
467
|
-
serviceTier:
|
|
501
|
+
serviceTier: responseHeaders?.['x-gemini-service-tier'] ?? null,
|
|
468
502
|
} satisfies GoogleGenerativeAIProviderMetadata,
|
|
469
503
|
},
|
|
470
504
|
request: { body: args },
|
|
@@ -479,14 +513,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
479
513
|
async doStream(
|
|
480
514
|
options: LanguageModelV3CallOptions,
|
|
481
515
|
): Promise<LanguageModelV3StreamResult> {
|
|
482
|
-
const { args, warnings, providerOptionsName } =
|
|
483
|
-
options,
|
|
484
|
-
{ isStreaming: true },
|
|
485
|
-
);
|
|
516
|
+
const { args, warnings, providerOptionsName, extraHeaders } =
|
|
517
|
+
await this.getArgs(options, { isStreaming: true });
|
|
486
518
|
|
|
487
519
|
const headers = combineHeaders(
|
|
488
520
|
await resolve(this.config.headers),
|
|
489
521
|
options.headers,
|
|
522
|
+
extraHeaders,
|
|
490
523
|
);
|
|
491
524
|
|
|
492
525
|
const { responseHeaders, value: response } = await postJsonToApi({
|
|
@@ -509,7 +542,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
509
542
|
let providerMetadata: SharedV3ProviderMetadata | undefined = undefined;
|
|
510
543
|
let lastGroundingMetadata: GroundingMetadataSchema | null = null;
|
|
511
544
|
let lastUrlContextMetadata: UrlContextMetadataSchema | null = null;
|
|
512
|
-
|
|
545
|
+
const serviceTier: string | null =
|
|
546
|
+
responseHeaders?.['x-gemini-service-tier'] ?? null;
|
|
513
547
|
|
|
514
548
|
const generateId = this.config.generateId;
|
|
515
549
|
let hasToolCalls = false;
|
|
@@ -533,6 +567,42 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
533
567
|
providerMetadata?: SharedV3ProviderMetadata;
|
|
534
568
|
}> = [];
|
|
535
569
|
|
|
570
|
+
const finishActiveStreamingToolCall = (
|
|
571
|
+
controller: TransformStreamDefaultController<LanguageModelV3StreamPart>,
|
|
572
|
+
) => {
|
|
573
|
+
const active = activeStreamingToolCalls.pop();
|
|
574
|
+
if (active == null) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const { finalJSON, closingDelta } = active.accumulator.finalize();
|
|
579
|
+
|
|
580
|
+
if (closingDelta.length > 0) {
|
|
581
|
+
controller.enqueue({
|
|
582
|
+
type: 'tool-input-delta',
|
|
583
|
+
id: active.toolCallId,
|
|
584
|
+
delta: closingDelta,
|
|
585
|
+
providerMetadata: active.providerMetadata,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
controller.enqueue({
|
|
590
|
+
type: 'tool-input-end',
|
|
591
|
+
id: active.toolCallId,
|
|
592
|
+
providerMetadata: active.providerMetadata,
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
controller.enqueue({
|
|
596
|
+
type: 'tool-call',
|
|
597
|
+
toolCallId: active.toolCallId,
|
|
598
|
+
toolName: active.toolName,
|
|
599
|
+
input: finalJSON,
|
|
600
|
+
providerMetadata: active.providerMetadata,
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
hasToolCalls = true;
|
|
604
|
+
};
|
|
605
|
+
|
|
536
606
|
return {
|
|
537
607
|
stream: response.pipeThrough(
|
|
538
608
|
new TransformStream<
|
|
@@ -561,10 +631,6 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
561
631
|
usage = usageMetadata;
|
|
562
632
|
}
|
|
563
633
|
|
|
564
|
-
if (value.serviceTier != null) {
|
|
565
|
-
serviceTier = value.serviceTier;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
634
|
const candidate = value.candidates?.[0];
|
|
569
635
|
|
|
570
636
|
// sometimes the API returns an empty candidates array
|
|
@@ -824,10 +890,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
824
890
|
part.functionCall.willContinue !== true;
|
|
825
891
|
|
|
826
892
|
if (isStreamingChunk) {
|
|
827
|
-
if (
|
|
828
|
-
part.functionCall.name != null &&
|
|
829
|
-
part.functionCall.willContinue === true
|
|
830
|
-
) {
|
|
893
|
+
if (part.functionCall.name != null) {
|
|
831
894
|
const toolCallId = part.functionCall.id ?? generateId();
|
|
832
895
|
const accumulator = new GoogleJSONAccumulator();
|
|
833
896
|
activeStreamingToolCalls.push({
|
|
@@ -845,9 +908,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
845
908
|
});
|
|
846
909
|
|
|
847
910
|
if (part.functionCall.partialArgs != null) {
|
|
848
|
-
const
|
|
849
|
-
|
|
850
|
-
|
|
911
|
+
const partialArgs = part.functionCall
|
|
912
|
+
.partialArgs as PartialArg[];
|
|
913
|
+
const { textDelta } =
|
|
914
|
+
accumulator.processPartialArgs(partialArgs);
|
|
851
915
|
if (textDelta.length > 0) {
|
|
852
916
|
controller.enqueue({
|
|
853
917
|
type: 'tool-input-delta',
|
|
@@ -856,6 +920,12 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
856
920
|
providerMetadata: providerMeta,
|
|
857
921
|
});
|
|
858
922
|
}
|
|
923
|
+
if (
|
|
924
|
+
part.functionCall.willContinue !== true &&
|
|
925
|
+
partialArgs.every(arg => arg.willContinue !== true)
|
|
926
|
+
) {
|
|
927
|
+
finishActiveStreamingToolCall(controller);
|
|
928
|
+
}
|
|
859
929
|
}
|
|
860
930
|
} else if (
|
|
861
931
|
part.functionCall.partialArgs != null &&
|
|
@@ -865,9 +935,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
865
935
|
activeStreamingToolCalls[
|
|
866
936
|
activeStreamingToolCalls.length - 1
|
|
867
937
|
];
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
|
|
938
|
+
const partialArgs = part.functionCall
|
|
939
|
+
.partialArgs as PartialArg[];
|
|
940
|
+
const { textDelta } =
|
|
941
|
+
active.accumulator.processPartialArgs(partialArgs);
|
|
871
942
|
if (textDelta.length > 0) {
|
|
872
943
|
controller.enqueue({
|
|
873
944
|
type: 'tool-input-delta',
|
|
@@ -876,39 +947,18 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
876
947
|
providerMetadata: providerMeta,
|
|
877
948
|
});
|
|
878
949
|
}
|
|
950
|
+
if (
|
|
951
|
+
part.functionCall.willContinue !== true &&
|
|
952
|
+
partialArgs.every(arg => arg.willContinue !== true)
|
|
953
|
+
) {
|
|
954
|
+
finishActiveStreamingToolCall(controller);
|
|
955
|
+
}
|
|
879
956
|
}
|
|
880
957
|
} else if (
|
|
881
958
|
isTerminalChunk &&
|
|
882
959
|
activeStreamingToolCalls.length > 0
|
|
883
960
|
) {
|
|
884
|
-
|
|
885
|
-
const { finalJSON, closingDelta } =
|
|
886
|
-
active.accumulator.finalize();
|
|
887
|
-
|
|
888
|
-
if (closingDelta.length > 0) {
|
|
889
|
-
controller.enqueue({
|
|
890
|
-
type: 'tool-input-delta',
|
|
891
|
-
id: active.toolCallId,
|
|
892
|
-
delta: closingDelta,
|
|
893
|
-
providerMetadata: active.providerMetadata,
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
controller.enqueue({
|
|
898
|
-
type: 'tool-input-end',
|
|
899
|
-
id: active.toolCallId,
|
|
900
|
-
providerMetadata: active.providerMetadata,
|
|
901
|
-
});
|
|
902
|
-
|
|
903
|
-
controller.enqueue({
|
|
904
|
-
type: 'tool-call',
|
|
905
|
-
toolCallId: active.toolCallId,
|
|
906
|
-
toolName: active.toolName,
|
|
907
|
-
input: finalJSON,
|
|
908
|
-
providerMetadata: active.providerMetadata,
|
|
909
|
-
});
|
|
910
|
-
|
|
911
|
-
hasToolCalls = true;
|
|
961
|
+
finishActiveStreamingToolCall(controller);
|
|
912
962
|
} else if (isCompleteCall) {
|
|
913
963
|
const toolCallId = part.functionCall.id ?? generateId();
|
|
914
964
|
const toolName = part.functionCall.name!;
|
|
@@ -1377,7 +1427,6 @@ const responseSchema = lazySchema(() =>
|
|
|
1377
1427
|
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
1378
1428
|
})
|
|
1379
1429
|
.nullish(),
|
|
1380
|
-
serviceTier: z.string().nullish(),
|
|
1381
1430
|
}),
|
|
1382
1431
|
),
|
|
1383
1432
|
);
|
|
@@ -1433,7 +1482,6 @@ const chunkSchema = lazySchema(() =>
|
|
|
1433
1482
|
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
1434
1483
|
})
|
|
1435
1484
|
.nullish(),
|
|
1436
|
-
serviceTier: z.string().nullish(),
|
|
1437
1485
|
}),
|
|
1438
1486
|
),
|
|
1439
1487
|
);
|
|
@@ -30,6 +30,7 @@ export type GoogleGenerativeAIModelId =
|
|
|
30
30
|
| 'gemini-3.1-flash-image-preview'
|
|
31
31
|
| 'gemini-3.1-flash-lite-preview'
|
|
32
32
|
| 'gemini-3.1-flash-tts-preview'
|
|
33
|
+
| 'gemini-3.5-flash'
|
|
33
34
|
// latest version
|
|
34
35
|
// https://ai.google.dev/gemini-api/docs/models#latest
|
|
35
36
|
| 'gemini-pro-latest'
|
|
@@ -206,9 +207,31 @@ export const googleLanguageModelOptions = lazySchema(() =>
|
|
|
206
207
|
streamFunctionCallArguments: z.boolean().optional(),
|
|
207
208
|
|
|
208
209
|
/**
|
|
209
|
-
* Optional. The service tier to use for the request.
|
|
210
|
+
* Optional. The service tier to use for the request. Sent as the
|
|
211
|
+
* `serviceTier` body field. Gemini API only.
|
|
210
212
|
*/
|
|
211
213
|
serviceTier: z.enum(['standard', 'flex', 'priority']).optional(),
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Optional. Vertex AI only. Sent as the
|
|
217
|
+
* `X-Vertex-AI-LLM-Shared-Request-Type` request header to select a
|
|
218
|
+
* shared (PayGo) tier. With Provisioned Throughput allocated and
|
|
219
|
+
* `requestType` unset, the request falls back to this tier only if
|
|
220
|
+
* PT capacity is exhausted.
|
|
221
|
+
*
|
|
222
|
+
* https://docs.cloud.google.com/vertex-ai/generative-ai/docs/priority-paygo
|
|
223
|
+
* https://docs.cloud.google.com/vertex-ai/generative-ai/docs/flex-paygo
|
|
224
|
+
*/
|
|
225
|
+
sharedRequestType: z.enum(['priority', 'flex', 'standard']).optional(),
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Optional. Vertex AI only. Sent as the `X-Vertex-AI-LLM-Request-Type`
|
|
229
|
+
* request header. Set to `'shared'` together with `sharedRequestType`
|
|
230
|
+
* to bypass Provisioned Throughput entirely.
|
|
231
|
+
*
|
|
232
|
+
* https://docs.cloud.google.com/vertex-ai/generative-ai/docs/priority-paygo
|
|
233
|
+
*/
|
|
234
|
+
requestType: z.enum(['shared']).optional(),
|
|
212
235
|
}),
|
|
213
236
|
),
|
|
214
237
|
);
|
|
@@ -216,10 +239,3 @@ export const googleLanguageModelOptions = lazySchema(() =>
|
|
|
216
239
|
export type GoogleLanguageModelOptions = InferSchema<
|
|
217
240
|
typeof googleLanguageModelOptions
|
|
218
241
|
>;
|
|
219
|
-
|
|
220
|
-
// Vertex API requires another service tier format.
|
|
221
|
-
export const VertexServiceTierMap = {
|
|
222
|
-
standard: 'SERVICE_TIER_STANDARD',
|
|
223
|
-
flex: 'SERVICE_TIER_FLEX',
|
|
224
|
-
priority: 'SERVICE_TIER_PRIORITY',
|
|
225
|
-
} as const;
|
package/src/google-provider.ts
CHANGED
|
@@ -89,13 +89,17 @@ export interface GoogleGenerativeAIProvider extends ProviderV3 {
|
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
91
|
* Creates a language model targeting the Gemini Interactions API
|
|
92
|
-
* (`POST /v1beta/interactions`). Pass
|
|
93
|
-
*
|
|
92
|
+
* (`POST /v1beta/interactions`). Pass:
|
|
93
|
+
* - a model ID (string),
|
|
94
|
+
* - `{ agent: <name> }` to use a known Gemini agent preset, or
|
|
95
|
+
* - `{ managedAgent: <name> }` to use a user-defined agent created via
|
|
96
|
+
* the `/v1beta/agents` endpoint.
|
|
94
97
|
*/
|
|
95
98
|
interactions(
|
|
96
99
|
modelIdOrAgent:
|
|
97
100
|
| GoogleInteractionsModelId
|
|
98
|
-
| { agent: GoogleInteractionsAgentName }
|
|
101
|
+
| { agent: GoogleInteractionsAgentName }
|
|
102
|
+
| { managedAgent: string },
|
|
99
103
|
): LanguageModelV3;
|
|
100
104
|
|
|
101
105
|
tools: typeof googleTools;
|
|
@@ -214,7 +218,8 @@ export function createGoogleGenerativeAI(
|
|
|
214
218
|
const createInteractionsModel = (
|
|
215
219
|
modelIdOrAgent:
|
|
216
220
|
| GoogleInteractionsModelId
|
|
217
|
-
| { agent: GoogleInteractionsAgentName }
|
|
221
|
+
| { agent: GoogleInteractionsAgentName }
|
|
222
|
+
| { managedAgent: string },
|
|
218
223
|
) =>
|
|
219
224
|
new GoogleInteractionsLanguageModel(
|
|
220
225
|
modelIdOrAgent as GoogleInteractionsModelInput,
|
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
* Type-only module: declares the union of supported Gemini Interactions agent
|
|
3
3
|
* names. Used by the `google.interactions({ agent })` factory branch.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* passing an unknown agent name is a compile-time error. Add new agents here
|
|
10
|
-
* as Google publishes them.
|
|
5
|
+
* Strict string-literal union: unknown agent names are a compile-time error.
|
|
6
|
+
* User-defined agents (created via the `/agents` endpoint) are addressed by
|
|
7
|
+
* a separate `{ managedAgent: string }` factory shape — see
|
|
8
|
+
* `GoogleInteractionsModelInput`.
|
|
11
9
|
*/
|
|
12
10
|
|
|
13
11
|
export type GoogleInteractionsAgentName =
|
|
14
12
|
| 'deep-research-pro-preview-12-2025'
|
|
15
13
|
| 'deep-research-preview-04-2026'
|
|
16
|
-
| 'deep-research-max-preview-04-2026'
|
|
14
|
+
| 'deep-research-max-preview-04-2026'
|
|
15
|
+
| 'antigravity-preview-05-2026';
|
|
@@ -32,6 +32,7 @@ export type GoogleInteractionsModelId =
|
|
|
32
32
|
| 'gemini-3.1-flash-image-preview'
|
|
33
33
|
| 'gemini-3.1-flash-lite-preview'
|
|
34
34
|
| 'gemini-3.1-flash-tts-preview'
|
|
35
|
+
| 'gemini-3.5-flash'
|
|
35
36
|
| 'lyria-3-clip-preview'
|
|
36
37
|
| 'lyria-3-pro-preview'
|
|
37
38
|
| (string & {});
|
|
@@ -188,6 +189,70 @@ export const googleInteractionsLanguageModelOptions = lazySchema(() =>
|
|
|
188
189
|
* such as deep research can take tens of minutes — increase if needed.
|
|
189
190
|
*/
|
|
190
191
|
pollingTimeoutMs: z.number().int().positive().nullish(),
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Run the interaction in the background. Required for agents whose
|
|
195
|
+
* server-side workflow cannot complete within a single request/response.
|
|
196
|
+
* When `true`, the POST returns with a non-terminal status and the SDK
|
|
197
|
+
* polls `GET /interactions/{id}` until the work completes. Some agents
|
|
198
|
+
* reject `true`; see the agent's documentation for which mode it
|
|
199
|
+
* requires.
|
|
200
|
+
*/
|
|
201
|
+
background: z.boolean().nullish(),
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Environment configuration for the agent sandbox. Only applies to agent
|
|
205
|
+
* calls (`google.interactions({ agent })`); ignored on model-id calls.
|
|
206
|
+
*
|
|
207
|
+
* - `"remote"`: provision a fresh sandbox for this call.
|
|
208
|
+
* - any other string: an existing `environment_id` to reuse.
|
|
209
|
+
* - object: provision a fresh sandbox and optionally preload `sources`
|
|
210
|
+
* and/or constrain outbound traffic via `network`.
|
|
211
|
+
*/
|
|
212
|
+
environment: z
|
|
213
|
+
.union([
|
|
214
|
+
z.string(),
|
|
215
|
+
z.object({
|
|
216
|
+
type: z.literal('remote'),
|
|
217
|
+
sources: z
|
|
218
|
+
.array(
|
|
219
|
+
z.union([
|
|
220
|
+
z.object({
|
|
221
|
+
type: z.literal('gcs'),
|
|
222
|
+
source: z.string(),
|
|
223
|
+
target: z.string().nullish(),
|
|
224
|
+
}),
|
|
225
|
+
z.object({
|
|
226
|
+
type: z.literal('repository'),
|
|
227
|
+
source: z.string(),
|
|
228
|
+
target: z.string().nullish(),
|
|
229
|
+
}),
|
|
230
|
+
z.object({
|
|
231
|
+
type: z.literal('inline'),
|
|
232
|
+
content: z.string(),
|
|
233
|
+
target: z.string(),
|
|
234
|
+
}),
|
|
235
|
+
]),
|
|
236
|
+
)
|
|
237
|
+
.nullish(),
|
|
238
|
+
network: z
|
|
239
|
+
.union([
|
|
240
|
+
z.literal('disabled'),
|
|
241
|
+
z.object({
|
|
242
|
+
allowlist: z.array(
|
|
243
|
+
z.object({
|
|
244
|
+
domain: z.string(),
|
|
245
|
+
transform: z
|
|
246
|
+
.array(z.record(z.string(), z.string()))
|
|
247
|
+
.nullish(),
|
|
248
|
+
}),
|
|
249
|
+
),
|
|
250
|
+
}),
|
|
251
|
+
])
|
|
252
|
+
.nullish(),
|
|
253
|
+
}),
|
|
254
|
+
])
|
|
255
|
+
.nullish(),
|
|
191
256
|
}),
|
|
192
257
|
),
|
|
193
258
|
);
|
|
@@ -32,7 +32,10 @@ import {
|
|
|
32
32
|
} from './google-interactions-language-model-options';
|
|
33
33
|
import type {
|
|
34
34
|
GoogleInteractionsAgentConfig,
|
|
35
|
+
GoogleInteractionsEnvironmentSource,
|
|
35
36
|
GoogleInteractionsGenerationConfig,
|
|
37
|
+
GoogleInteractionsNetworkAllowlistEntry,
|
|
38
|
+
GoogleInteractionsNetworkConfig,
|
|
36
39
|
GoogleInteractionsRequestBody,
|
|
37
40
|
GoogleInteractionsResponseFormatEntry,
|
|
38
41
|
GoogleInteractionsTool,
|
|
@@ -59,7 +62,8 @@ export type GoogleInteractionsConfig = {
|
|
|
59
62
|
|
|
60
63
|
export type GoogleInteractionsModelInput =
|
|
61
64
|
| GoogleInteractionsModelId
|
|
62
|
-
| { agent: string }
|
|
65
|
+
| { agent: string }
|
|
66
|
+
| { managedAgent: string };
|
|
63
67
|
|
|
64
68
|
export class GoogleInteractionsLanguageModel implements LanguageModelV3 {
|
|
65
69
|
readonly specificationVersion = 'v3';
|
|
@@ -81,6 +85,9 @@ export class GoogleInteractionsLanguageModel implements LanguageModelV3 {
|
|
|
81
85
|
if (typeof modelOrAgent === 'string') {
|
|
82
86
|
this.modelId = modelOrAgent;
|
|
83
87
|
this.agent = undefined;
|
|
88
|
+
} else if ('managedAgent' in modelOrAgent) {
|
|
89
|
+
this.modelId = modelOrAgent.managedAgent;
|
|
90
|
+
this.agent = modelOrAgent.managedAgent;
|
|
84
91
|
} else {
|
|
85
92
|
this.modelId = modelOrAgent.agent;
|
|
86
93
|
this.agent = modelOrAgent.agent;
|
|
@@ -326,18 +333,60 @@ export class GoogleInteractionsLanguageModel implements LanguageModelV3 {
|
|
|
326
333
|
}
|
|
327
334
|
}
|
|
328
335
|
|
|
336
|
+
let environment: GoogleInteractionsRequestBody['environment'];
|
|
337
|
+
if (opts?.environment != null) {
|
|
338
|
+
if (!isAgent) {
|
|
339
|
+
warnings.push({
|
|
340
|
+
type: 'other',
|
|
341
|
+
message:
|
|
342
|
+
'google.interactions: environment is only supported when an agent is set; environment will be omitted from the request body.',
|
|
343
|
+
});
|
|
344
|
+
} else if (typeof opts.environment === 'string') {
|
|
345
|
+
environment = opts.environment;
|
|
346
|
+
} else {
|
|
347
|
+
const env = opts.environment;
|
|
348
|
+
const sources: Array<GoogleInteractionsEnvironmentSource> | undefined =
|
|
349
|
+
env.sources?.map(s => {
|
|
350
|
+
if (s.type === 'inline') {
|
|
351
|
+
return {
|
|
352
|
+
type: 'inline' as const,
|
|
353
|
+
content: s.content,
|
|
354
|
+
target: s.target,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
return pruneUndefined({
|
|
358
|
+
type: s.type,
|
|
359
|
+
source: s.source,
|
|
360
|
+
target: s.target ?? undefined,
|
|
361
|
+
}) as GoogleInteractionsEnvironmentSource;
|
|
362
|
+
});
|
|
363
|
+
let network: GoogleInteractionsNetworkConfig | undefined;
|
|
364
|
+
if (env.network === 'disabled') {
|
|
365
|
+
network = 'disabled';
|
|
366
|
+
} else if (env.network != null) {
|
|
367
|
+
network = {
|
|
368
|
+
allowlist: env.network.allowlist.map(entry =>
|
|
369
|
+
pruneUndefined({
|
|
370
|
+
domain: entry.domain,
|
|
371
|
+
transform: entry.transform ?? undefined,
|
|
372
|
+
}),
|
|
373
|
+
) as Array<GoogleInteractionsNetworkAllowlistEntry>,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
environment = pruneUndefined({
|
|
377
|
+
type: 'remote' as const,
|
|
378
|
+
sources: sources != null && sources.length > 0 ? sources : undefined,
|
|
379
|
+
network,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
329
384
|
/*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
* `doGenerate` / `doStream` so the user-facing surface stays identical to
|
|
336
|
-
* model-id calls.
|
|
337
|
-
*
|
|
338
|
-
* Model-id calls retain their original synchronous behavior — no
|
|
339
|
-
* `background` field is sent. (No documented model accepts `background:
|
|
340
|
-
* true` today; revisit when one does.)
|
|
385
|
+
* `background` is opt-in via `providerOptions.google.background`. Some
|
|
386
|
+
* agents require it because their server-side workflow cannot complete
|
|
387
|
+
* within a single request; others reject it. When `background: true`, the
|
|
388
|
+
* POST returns a non-terminal status and the SDK polls
|
|
389
|
+
* `GET /interactions/{id}` until the work completes.
|
|
341
390
|
*/
|
|
342
391
|
const args: GoogleInteractionsRequestBody = pruneUndefined({
|
|
343
392
|
...(isAgent ? { agent: this.agent } : { model: this.modelId }),
|
|
@@ -360,13 +409,15 @@ export class GoogleInteractionsLanguageModel implements LanguageModelV3 {
|
|
|
360
409
|
? generationConfig
|
|
361
410
|
: undefined,
|
|
362
411
|
agent_config: agentConfig,
|
|
363
|
-
|
|
412
|
+
environment,
|
|
413
|
+
background: opts?.background ?? undefined,
|
|
364
414
|
});
|
|
365
415
|
|
|
366
416
|
return {
|
|
367
417
|
args,
|
|
368
418
|
warnings,
|
|
369
419
|
isAgent,
|
|
420
|
+
isBackground: opts?.background === true,
|
|
370
421
|
pollingTimeoutMs: opts?.pollingTimeoutMs ?? undefined,
|
|
371
422
|
};
|
|
372
423
|
}
|
|
@@ -404,8 +455,8 @@ export class GoogleInteractionsLanguageModel implements LanguageModelV3 {
|
|
|
404
455
|
} = postResult;
|
|
405
456
|
|
|
406
457
|
/*
|
|
407
|
-
* Agent calls
|
|
408
|
-
*
|
|
458
|
+
* Agent calls may return a non-terminal status (`in_progress` /
|
|
459
|
+
* `requires_action`) when invoked with `background: true`. Poll
|
|
409
460
|
* `GET /interactions/{id}` until terminal so the user-facing surface
|
|
410
461
|
* matches a synchronous call.
|
|
411
462
|
*/
|
|
@@ -503,7 +554,7 @@ export class GoogleInteractionsLanguageModel implements LanguageModelV3 {
|
|
|
503
554
|
async doStream(
|
|
504
555
|
options: LanguageModelV3CallOptions,
|
|
505
556
|
): Promise<LanguageModelV3StreamResult> {
|
|
506
|
-
const { args, warnings,
|
|
557
|
+
const { args, warnings, isBackground, pollingTimeoutMs } =
|
|
507
558
|
await this.getArgs(options);
|
|
508
559
|
|
|
509
560
|
const url = `${this.config.baseURL}/interactions`;
|
|
@@ -515,13 +566,13 @@ export class GoogleInteractionsLanguageModel implements LanguageModelV3 {
|
|
|
515
566
|
);
|
|
516
567
|
|
|
517
568
|
/*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
569
|
+
* `background: true` is incompatible with `stream: true` on POST. Drive
|
|
570
|
+
* background calls via POST background -> GET stream (with terminal-status
|
|
571
|
+
* short-circuit). The user-facing stream surface stays identical --
|
|
572
|
+
* text-start / text-delta / text-end / finish parts are emitted in the
|
|
573
|
+
* same order as a true SSE response.
|
|
523
574
|
*/
|
|
524
|
-
if (
|
|
575
|
+
if (isBackground) {
|
|
525
576
|
return this.doStreamBackground({
|
|
526
577
|
args,
|
|
527
578
|
warnings,
|