@ai-sdk/google 4.0.0-canary.69 → 4.0.0-canary.71

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.
@@ -240,8 +240,14 @@ The following optional provider options are available for Google models:
240
240
  - **serviceTier** _'standard' | 'flex' | 'priority'_
241
241
 
242
242
  Optional. The service tier to use for the request.
243
- Set to 'flex' for 50% cheaper processing at the cost of increased latency.
244
- Set to 'priority' for ultra-low latency at a 75-100% price premium over 'standard'.
243
+ Set to `'flex'` for 50% cheaper processing at the cost of increased latency.
244
+ Set to `'priority'` for ultra-low latency at a 75-100% price premium over `'standard'`.
245
+
246
+ Because Priority can be gracefully downgraded to Standard under load, the
247
+ tier the request actually ran on is surfaced on
248
+ `result.providerMetadata.google.serviceTier`. See
249
+ [Priority inference](https://ai.google.dev/gemini-api/docs/priority-inference)
250
+ and [Flex inference](https://ai.google.dev/gemini-api/docs/flex-inference).
245
251
 
246
252
  - **threshold** _string_
247
253
 
@@ -1545,9 +1551,10 @@ Agents also chain through `previousInteractionId` like model-id calls.
1545
1551
 
1546
1552
  ### Managed Agents
1547
1553
 
1548
- Managed agents run inside a sandboxed Linux environment provisioned per
1549
- interaction. Pass the `environment` provider option to control how the
1550
- sandbox is set up; the option is only accepted on agent calls.
1554
+ [Managed agents](https://ai.google.dev/gemini-api/docs/agents) run inside a
1555
+ sandboxed Linux environment provisioned per interaction. Pass the `environment`
1556
+ provider option to control how the sandbox is set up; the option is only
1557
+ accepted on agent calls.
1551
1558
 
1552
1559
  The simplest form provisions a fresh sandbox:
1553
1560
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/google",
3
- "version": "4.0.0-canary.69",
3
+ "version": "4.0.0-canary.71",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -12,6 +12,7 @@ export type GoogleUsageMetadata = {
12
12
  cachedContentTokenCount?: number | null;
13
13
  thoughtsTokenCount?: number | null;
14
14
  trafficType?: string | null;
15
+ serviceTier?: string | null;
15
16
  promptTokensDetails?: GoogleTokenDetail[] | null;
16
17
  candidatesTokensDetails?: GoogleTokenDetail[] | null;
17
18
  };
@@ -207,9 +207,31 @@ export const googleLanguageModelOptions = lazySchema(() =>
207
207
  streamFunctionCallArguments: z.boolean().optional(),
208
208
 
209
209
  /**
210
- * 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.
211
212
  */
212
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(),
213
235
  }),
214
236
  ),
215
237
  );
@@ -217,10 +239,3 @@ export const googleLanguageModelOptions = lazySchema(() =>
217
239
  export type GoogleLanguageModelOptions = InferSchema<
218
240
  typeof googleLanguageModelOptions
219
241
  >;
220
-
221
- // Vertex API requires another service tier format.
222
- export const VertexServiceTierMap = {
223
- standard: 'SERVICE_TIER_STANDARD',
224
- flex: 'SERVICE_TIER_FLEX',
225
- priority: 'SERVICE_TIER_PRIORITY',
226
- } as const;
@@ -43,7 +43,6 @@ import { getModelPath } from './get-model-path';
43
43
  import { googleFailedResponseHandler } from './google-error';
44
44
  import {
45
45
  googleLanguageModelOptions,
46
- VertexServiceTierMap,
47
46
  type GoogleLanguageModelOptions,
48
47
  type GoogleModelId,
49
48
  } from './google-language-model-options';
@@ -183,11 +182,43 @@ export class GoogleLanguageModel implements LanguageModelV4 {
183
182
  });
184
183
  }
185
184
 
186
- // Vertex API requires another service tier format.
187
- let sanitizedServiceTier: string | undefined = googleOptions?.serviceTier;
188
185
  if (googleOptions?.serviceTier && isVertexProvider) {
189
- sanitizedServiceTier = VertexServiceTierMap[googleOptions.serviceTier];
186
+ warnings.push({
187
+ type: 'other',
188
+ message:
189
+ "'serviceTier' is a Gemini API option and is not supported on Vertex AI. " +
190
+ "Use 'sharedRequestType' (and optionally 'requestType') instead. See " +
191
+ 'https://docs.cloud.google.com/vertex-ai/generative-ai/docs/priority-paygo',
192
+ });
190
193
  }
194
+ if (
195
+ (googleOptions?.sharedRequestType || googleOptions?.requestType) &&
196
+ !isVertexProvider
197
+ ) {
198
+ warnings.push({
199
+ type: 'other',
200
+ message:
201
+ "'sharedRequestType' and 'requestType' are Vertex AI options and " +
202
+ `are ignored with the current Google provider (${this.config.provider}).`,
203
+ });
204
+ }
205
+
206
+ const vertexPaygoHeaders: Record<string, string> | undefined =
207
+ isVertexProvider &&
208
+ (googleOptions?.sharedRequestType || googleOptions?.requestType)
209
+ ? {
210
+ ...(googleOptions.sharedRequestType && {
211
+ 'X-Vertex-AI-LLM-Shared-Request-Type':
212
+ googleOptions.sharedRequestType,
213
+ }),
214
+ ...(googleOptions.requestType && {
215
+ 'X-Vertex-AI-LLM-Request-Type': googleOptions.requestType,
216
+ }),
217
+ }
218
+ : undefined;
219
+ const bodyServiceTier = isVertexProvider
220
+ ? undefined
221
+ : googleOptions?.serviceTier;
191
222
 
192
223
  const isGemmaModel = this.modelId.toLowerCase().startsWith('gemma-');
193
224
  const supportsFunctionResponseParts = this.modelId.startsWith('gemini-3');
@@ -288,17 +319,18 @@ export class GoogleLanguageModel implements LanguageModelV4 {
288
319
  toolConfig,
289
320
  cachedContent: googleOptions?.cachedContent,
290
321
  labels: googleOptions?.labels,
291
- serviceTier: sanitizedServiceTier,
322
+ serviceTier: bodyServiceTier,
292
323
  },
293
324
  warnings: [...warnings, ...toolWarnings],
294
325
  providerOptionsNames,
326
+ extraHeaders: vertexPaygoHeaders,
295
327
  };
296
328
  }
297
329
 
298
330
  async doGenerate(
299
331
  options: LanguageModelV4CallOptions,
300
332
  ): Promise<LanguageModelV4GenerateResult> {
301
- const { args, warnings, providerOptionsNames } =
333
+ const { args, warnings, providerOptionsNames, extraHeaders } =
302
334
  await this.getArgs(options);
303
335
  const wrapProviderMetadata = (payload: Record<string, unknown>) =>
304
336
  Object.fromEntries(
@@ -308,6 +340,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
308
340
  const mergedHeaders = combineHeaders(
309
341
  this.config.headers ? await resolve(this.config.headers) : undefined,
310
342
  options.headers,
343
+ extraHeaders,
311
344
  );
312
345
 
313
346
  const {
@@ -485,7 +518,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
485
518
  safetyRatings: candidate.safetyRatings ?? null,
486
519
  usageMetadata: usageMetadata ?? null,
487
520
  finishMessage: candidate.finishMessage ?? null,
488
- serviceTier: response.serviceTier ?? null,
521
+ serviceTier: usageMetadata?.serviceTier ?? null,
489
522
  } satisfies GoogleProviderMetadata),
490
523
  request: { body: args },
491
524
  response: {
@@ -499,10 +532,8 @@ export class GoogleLanguageModel implements LanguageModelV4 {
499
532
  async doStream(
500
533
  options: LanguageModelV4CallOptions,
501
534
  ): Promise<LanguageModelV4StreamResult> {
502
- const { args, warnings, providerOptionsNames } = await this.getArgs(
503
- options,
504
- { isStreaming: true },
505
- );
535
+ const { args, warnings, providerOptionsNames, extraHeaders } =
536
+ await this.getArgs(options, { isStreaming: true });
506
537
  const wrapProviderMetadata = (payload: Record<string, unknown>) =>
507
538
  Object.fromEntries(
508
539
  providerOptionsNames.map(name => [name, payload]),
@@ -511,6 +542,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
511
542
  const headers = combineHeaders(
512
543
  this.config.headers ? await resolve(this.config.headers) : undefined,
513
544
  options.headers,
545
+ extraHeaders,
514
546
  );
515
547
 
516
548
  const { responseHeaders, value: response } = await postJsonToApi({
@@ -533,7 +565,6 @@ export class GoogleLanguageModel implements LanguageModelV4 {
533
565
  let providerMetadata: SharedV4ProviderMetadata | undefined = undefined;
534
566
  let lastGroundingMetadata: GroundingMetadataSchema | null = null;
535
567
  let lastUrlContextMetadata: UrlContextMetadataSchema | null = null;
536
- let serviceTier: string | null = null;
537
568
 
538
569
  const generateId = this.config.generateId;
539
570
  let hasToolCalls = false;
@@ -621,10 +652,6 @@ export class GoogleLanguageModel implements LanguageModelV4 {
621
652
  usage = usageMetadata;
622
653
  }
623
654
 
624
- if (value.serviceTier != null) {
625
- serviceTier = value.serviceTier;
626
- }
627
-
628
655
  const candidate = value.candidates?.[0];
629
656
 
630
657
  // sometimes the API returns an empty candidates array
@@ -1022,7 +1049,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
1022
1049
  safetyRatings: candidate.safetyRatings ?? null,
1023
1050
  usageMetadata: usageMetadata ?? null,
1024
1051
  finishMessage: candidate.finishMessage ?? null,
1025
- serviceTier,
1052
+ serviceTier: usage?.serviceTier ?? null,
1026
1053
  } satisfies GoogleProviderMetadata);
1027
1054
  }
1028
1055
  },
@@ -1435,6 +1462,7 @@ const usageSchema = z.object({
1435
1462
  totalTokenCount: z.number().nullish(),
1436
1463
  // https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/GenerateContentResponse#TrafficType
1437
1464
  trafficType: z.string().nullish(),
1465
+ serviceTier: z.string().nullish(),
1438
1466
  // https://ai.google.dev/api/generate-content#Modality
1439
1467
  promptTokensDetails: tokenDetailsSchema,
1440
1468
  candidatesTokensDetails: tokenDetailsSchema,
@@ -1473,7 +1501,6 @@ const responseSchema = lazySchema(() =>
1473
1501
  safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
1474
1502
  })
1475
1503
  .nullish(),
1476
- serviceTier: z.string().nullish(),
1477
1504
  }),
1478
1505
  ),
1479
1506
  );
@@ -1522,7 +1549,6 @@ const chunkSchema = lazySchema(() =>
1522
1549
  safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
1523
1550
  })
1524
1551
  .nullish(),
1525
- serviceTier: z.string().nullish(),
1526
1552
  }),
1527
1553
  ),
1528
1554
  );