@ai-sdk/google 4.0.94 → 4.0.96

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.
@@ -1,18 +1,67 @@
1
1
  ---
2
2
  title: Google
3
- description: Learn how to use Google Provider.
3
+ description: Learn how to use Google models through AI Gateway or the direct Google provider.
4
4
  ---
5
5
 
6
6
  # Google Provider
7
7
 
8
- The [Google](https://ai.google.dev) provider contains language and embedding model support for
9
- the [Google](https://ai.google.dev/api/rest) APIs.
8
+ You can use [Google](https://ai.google.dev) models through [AI Gateway](/providers/ai-sdk-providers/ai-gateway) (recommended)
9
+ or connect directly to the [Google APIs](https://ai.google.dev/api/rest) with `@ai-sdk/google`.
10
10
 
11
- ## Setup
11
+ ```ts provider="google" model="google/gemini-4-argon" highlight="5"
12
+ import { generateText } from 'ai';
13
+ __PROVIDER_IMPORT__;
14
+
15
+ const { text } = await generateText({
16
+ model: __MODEL__,
17
+ prompt: 'Write a vegetarian lasagna recipe for 4 people.',
18
+ });
19
+
20
+ console.log(text);
21
+ ```
22
+
23
+ ## Using AI Gateway
24
+
25
+ The AI SDK uses AI Gateway by default for model strings.
26
+ AI Gateway provides access to Google and other providers through a single API key, with usage and cost tracking.
27
+ Install the `ai` package:
28
+
29
+ <InstallPackages packages="ai" />
30
+
31
+ Set an [AI Gateway API key](https://vercel.com/docs/ai-gateway/getting-started) in your environment:
32
+
33
+ ```bash
34
+ export AI_GATEWAY_API_KEY=your_api_key_here
35
+ ```
36
+
37
+ Vercel deployments can also use [OIDC authentication](/providers/ai-sdk-providers/ai-gateway#oidc-authentication-vercel-deployments).
38
+ See the [AI Gateway provider documentation](/providers/ai-sdk-providers/ai-gateway) for configuration
39
+ and the [model catalog](https://vercel.com/ai-gateway/models?search=google) for available Google models.
40
+
41
+ Google model options can be passed through `providerOptions.google` when using AI Gateway.
42
+ Support depends on the model and the provider serving the request; see [Gateway provider options](https://vercel.com/docs/ai-gateway/models-and-providers/provider-options).
43
+
44
+ ## Using `@ai-sdk/google`
12
45
 
13
- The Google provider is available in the `@ai-sdk/google` module. You can install it with
46
+ For direct access to the Google APIs, install `ai` and `@ai-sdk/google`:
14
47
 
15
- <InstallPackages packages="@ai-sdk/google" />
48
+ <InstallPackages packages="ai @ai-sdk/google" />
49
+
50
+ Set your [Google API key](https://aistudio.google.com/apikey) in the `GOOGLE_GENERATIVE_AI_API_KEY` environment variable:
51
+
52
+ ```bash
53
+ export GOOGLE_GENERATIVE_AI_API_KEY=your_api_key_here
54
+ ```
55
+
56
+ AI Gateway does not expose every API in `@ai-sdk/google`.
57
+ Use the direct provider for Google-specific APIs such as [`google.interactions(...)`](#interactions-api),
58
+ or when you need to customize the Google connection with [`createGoogle`](#provider-instance).
59
+
60
+ <Note>
61
+ The following sections document the direct `@ai-sdk/google` provider,
62
+ including its model factories, tools, and settings. Gateway model and feature
63
+ availability can differ from the direct provider.
64
+ </Note>
16
65
 
17
66
  ## Provider Instance
18
67
 
@@ -77,11 +126,11 @@ You can use the following optional settings to customize the Google provider ins
77
126
  ## Language Models
78
127
 
79
128
  You can create models that call the [Google Generative AI API](https://ai.google.dev/api/rest) using the provider instance.
80
- The first argument is the model id, e.g. `gemini-3.8-flash`.
129
+ The first argument is the model id, e.g. `gemini-4-argon`.
81
130
  The models support tool calls and some have multi-modal capabilities.
82
131
 
83
132
  ```ts
84
- const model = google('gemini-3.8-flash');
133
+ const model = google('gemini-4-argon');
85
134
  ```
86
135
 
87
136
  You can use Google language models to generate text with the `generateText` function:
@@ -91,7 +140,7 @@ import { google } from '@ai-sdk/google';
91
140
  import { generateText } from 'ai';
92
141
 
93
142
  const { text } = await generateText({
94
- model: google('gemini-3.8-flash'),
143
+ model: google('gemini-4-argon'),
95
144
  prompt: 'Write a vegetarian lasagna recipe for 4 people.',
96
145
  });
97
146
  ```
@@ -116,7 +165,7 @@ You can pass them as an options argument:
116
165
  ```ts
117
166
  import { google, type GoogleLanguageModelOptions } from '@ai-sdk/google';
118
167
 
119
- const model = google('gemini-3.8-flash');
168
+ const model = google('gemini-4-argon');
120
169
 
121
170
  await generateText({
122
171
  model,
@@ -253,6 +302,12 @@ The following optional provider options are available for Google models:
253
302
  [Priority inference](https://ai.google.dev/gemini-api/docs/priority-inference)
254
303
  and [Flex inference](https://ai.google.dev/gemini-api/docs/flex-inference).
255
304
 
305
+ - **continuationToken** _string_
306
+
307
+ Optional. Resumes a response that stopped because it used up its
308
+ `maxOutputTokens` budget (Gemini 4 long decode). Send it with the original
309
+ request and a higher `maxOutputTokens`. See [Long decode](#long-decode).
310
+
256
311
  - **threshold** _string_
257
312
 
258
313
  Optional. Standalone threshold setting that can be used independently of `safetySettings`.
@@ -270,7 +325,7 @@ For Gemini 3 and later models, use the `thinkingLevel` parameter to control the
270
325
  import { google, GoogleLanguageModelOptions } from '@ai-sdk/google';
271
326
  import { generateText } from 'ai';
272
327
 
273
- const model = google('gemini-3.8-flash');
328
+ const model = google('gemini-4-argon');
274
329
 
275
330
  const { text, reasoning } = await generateText({
276
331
  model: model,
@@ -318,6 +373,136 @@ console.log(text);
318
373
  console.log(reasoning); // Reasoning summary
319
374
  ```
320
375
 
376
+ ### Long decode
377
+
378
+ Gemini 4 models such as `gemini-4-argon` can keep thinking and writing past a
379
+ single request's limits, up to the shared 1M token context window (input,
380
+ thinking, and output tokens together). Use it for hard math, science, proofs,
381
+ and long coding or agentic tasks.
382
+
383
+ - A single request generates at most 32,768 tokens without streaming and 65,536
384
+ tokens with streaming (`streamText`). Thinking tokens count towards this cap.
385
+ - `maxOutputTokens` is a **cumulative budget across requests**, not a target
386
+ length. When a request reaches the per-request cap while budget remains, the
387
+ provider automatically sends the same request again with a continuation token
388
+ and combines the results into one response. Set `maxOutputTokens` above the
389
+ per-request cap (up to 1M minus the input tokens) to enable this. If you do
390
+ not set it, the call ends after one request.
391
+ - A lower `maxOutputTokens` does not make the model think less, it ends the
392
+ response early (possibly before any answer) and you are still charged for the
393
+ tokens. Use `thinkingConfig.thinkingLevel` to control how much the model
394
+ thinks. `thinkingBudget` is not supported by these models.
395
+ - Complex requests can run for several minutes. Make sure your HTTP client
396
+ allows read timeouts of at least 15 to 20 minutes.
397
+
398
+ **Usage across requests.** Each continued request re-sends the prompt plus all
399
+ output so far as input, so its prompt token count includes everything
400
+ generated before it. `usage` is the sum of all requests, which matches what
401
+ Google bills (re-sent tokens are billed at a discount through implicit
402
+ caching). Do not use the summed input tokens for context window checks or
403
+ compaction: they can be several times larger than the real context. When a
404
+ response spanned more than one request,
405
+ `providerMetadata.google.initialPromptTokenCount` holds the prompt token count
406
+ of the first request (the google-genai SDKs expose the same value as
407
+ `initial_prompt_token_count`):
408
+
409
+ ```ts
410
+ const result = await generateText({
411
+ model: google('gemini-4-argon'),
412
+ prompt,
413
+ maxOutputTokens: 500_000,
414
+ });
415
+
416
+ // Billing: summed across all requests
417
+ console.log(result.usage.inputTokens.total);
418
+
419
+ // Context window: the first request's prompt plus the generated output
420
+ const promptTokens =
421
+ result.finalStep.providerMetadata?.google?.initialPromptTokenCount ??
422
+ result.usage.inputTokens.total;
423
+ const contextTokens = promptTokens + (result.usage.outputTokens.total ?? 0);
424
+ ```
425
+
426
+ **Resuming after the budget is used up.** When the cumulative generated tokens
427
+ reach `maxOutputTokens`, the finish reason is `length` and the provider returns
428
+ a continuation token on `result.providerMetadata.google.continuationToken`. To
429
+ continue, send the **original request unchanged** (same prompt, tools, and
430
+ settings; do not append the partial output as a message) together with the
431
+ token as `providerOptions.google.continuationToken` and a **higher**
432
+ `maxOutputTokens`. Resending with the same `maxOutputTokens` fails because the
433
+ budget is used up. Each response contains only the newly generated content.
434
+
435
+ ```ts
436
+ import { google } from '@ai-sdk/google';
437
+ import { generateText } from 'ai';
438
+
439
+ const prompt = 'Prove that sqrt(2) is irrational, in detail.';
440
+
441
+ const result = await generateText({
442
+ model: google('gemini-4-argon'),
443
+ prompt,
444
+ maxOutputTokens: 128_000,
445
+ });
446
+
447
+ const continuationToken =
448
+ result.finalStep.providerMetadata?.google?.continuationToken;
449
+
450
+ if (result.finishReason === 'length' && typeof continuationToken === 'string') {
451
+ // The budget was used up. Raise it to keep going.
452
+ const continued = await generateText({
453
+ model: google('gemini-4-argon'),
454
+ prompt,
455
+ maxOutputTokens: 256_000,
456
+ providerOptions: { google: { continuationToken } },
457
+ });
458
+
459
+ console.log(result.text + continued.text);
460
+ }
461
+ ```
462
+
463
+ Things to keep in mind:
464
+
465
+ - **Dropped streams.** Streamed parts are forwarded as they arrive and are not
466
+ buffered between the server's checkpoints, so a stream that drops mid-request
467
+ is not resumed automatically. Retry the request from the start.
468
+ - **Provider metadata is per call.** If you store the conversation history,
469
+ combine the content of all calls into one model message only after the final
470
+ call finishes. Keep thought signatures unchanged, including the ones on empty
471
+ trailing text parts.
472
+ - **Zero Data Retention.** Continuation works with `store: false` because the
473
+ state travels encrypted inside the token.
474
+
475
+ #### Long decode with the Interactions API
476
+
477
+ With the [Interactions API](#interactions-api), long decode requires
478
+ `background: true`. The server runs every request itself, so no client-side
479
+ continuation is needed, and `usage` covers all requests. Set an explicit
480
+ `maxOutputTokens` above 65,536 (without it, you get a single 64K request) and
481
+ keep `store` enabled (the default). The provider polls the interaction (or
482
+ streams it, reconnecting when the connection drops) until it finishes.
483
+
484
+ ```ts
485
+ import { google } from '@ai-sdk/google';
486
+ import { generateText } from 'ai';
487
+
488
+ const result = await generateText({
489
+ model: google.interactions('gemini-4-argon'),
490
+ prompt: 'Prove that sqrt(2) is irrational, in detail.',
491
+ maxOutputTokens: 500_000,
492
+ providerOptions: {
493
+ google: {
494
+ background: true,
495
+ pollingTimeoutMs: 60 * 60 * 1000, // default: 30 minutes
496
+ },
497
+ },
498
+ });
499
+ ```
500
+
501
+ Without `background: true`, an interaction generates at most 65,536 tokens.
502
+ Requests with a higher `maxOutputTokens` are rejected by the API, and an
503
+ interaction that reaches the cap finishes with `length`. Long decode is not
504
+ available with the Vertex AI Interactions API.
505
+
321
506
  ### File Inputs
322
507
 
323
508
  The Google provider supports file inputs, e.g. PDF files.
@@ -327,7 +512,7 @@ import { google } from '@ai-sdk/google';
327
512
  import { generateText } from 'ai';
328
513
 
329
514
  const result = await generateText({
330
- model: google('gemini-3.8-flash'),
515
+ model: google('gemini-4-argon'),
331
516
  messages: [
332
517
  {
333
518
  role: 'user',
@@ -354,7 +539,7 @@ import { google } from '@ai-sdk/google';
354
539
  import { generateText } from 'ai';
355
540
 
356
541
  const result = await generateText({
357
- model: google('gemini-3.8-flash'),
542
+ model: google('gemini-4-argon'),
358
543
  messages: [
359
544
  {
360
545
  role: 'user',
@@ -390,7 +575,7 @@ Google supports both explicit and implicit caching to help reduce costs on repet
390
575
 
391
576
  #### Implicit Caching
392
577
 
393
- Gemini models automatically provide cache cost savings without needing to create an explicit cache. When you send requests that share common prefixes with previous requests, you'll receive a 75% token discount on cached content.
578
+ Gemini models automatically provide cache cost savings without needing to create an explicit cache. When you send requests that share common prefixes with previous requests, you can receive discounted pricing on cached input tokens.
394
579
 
395
580
  To maximize cache hits with implicit caching:
396
581
 
@@ -409,13 +594,13 @@ const baseContext =
409
594
  'You are a cooking assistant with expertise in Italian cuisine. Here are 1000 lasagna recipes for reference...';
410
595
 
411
596
  const { text: veggieLasagna } = await generateText({
412
- model: google('gemini-3.8-flash'),
597
+ model: google('gemini-4-argon'),
413
598
  prompt: `${baseContext}\n\nWrite a vegetarian lasagna recipe for 4 people.`,
414
599
  });
415
600
 
416
601
  // Second request with same prefix - eligible for cache hit
417
602
  const { text: meatLasagna, providerMetadata } = await generateText({
418
- model: google('gemini-3.8-flash'),
603
+ model: google('gemini-4-argon'),
419
604
  prompt: `${baseContext}\n\nWrite a meat lasagna recipe for 12 people.`,
420
605
  });
421
606
 
@@ -443,7 +628,7 @@ console.log('Cached tokens:', providerMetadata.google);
443
628
 
444
629
  #### Explicit Caching
445
630
 
446
- For guaranteed cost savings, you can still use explicit caching with Gemini 2.5 and 3 series models. See the [models page](https://ai.google.dev/gemini-api/docs/models) to check if caching is supported for the used model:
631
+ For guaranteed cost savings, you can still use explicit caching with Gemini 2.5 and 3 series models. Gemini 4 Argon supports implicit caching only, so this example uses `gemini-3.8-flash`. See the [models page](https://ai.google.dev/gemini-api/docs/models) to check if caching is supported for the used model:
447
632
 
448
633
  ```ts
449
634
  import { google, type GoogleLanguageModelOptions } from '@ai-sdk/google';
@@ -503,7 +688,7 @@ import { googleTools } from '@ai-sdk/google/internal';
503
688
  import { generateText } from 'ai';
504
689
 
505
690
  const { text, toolCalls, toolResults } = await generateText({
506
- model: google('gemini-3.8-flash'),
691
+ model: google('gemini-4-argon'),
507
692
  tools: { code_execution: google.tools.codeExecution({}) },
508
693
  prompt: 'Use python to calculate the 20th fibonacci number.',
509
694
  });
@@ -522,7 +707,7 @@ import { GoogleProviderMetadata } from '@ai-sdk/google';
522
707
  import { generateText } from 'ai';
523
708
 
524
709
  const { text, sources, providerMetadata } = await generateText({
525
- model: google('gemini-3.8-flash'),
710
+ model: google('gemini-4-argon'),
526
711
  tools: {
527
712
  google_search: google.tools.googleSearch({}),
528
713
  },
@@ -630,7 +815,7 @@ const vertex = createGoogleVertex({
630
815
  });
631
816
 
632
817
  const { text, sources, providerMetadata } = await generateText({
633
- model: vertex('gemini-3.8-flash'),
818
+ model: vertex('gemini-4-argon'),
634
819
  tools: {
635
820
  enterprise_web_search: vertex.tools.enterpriseWebSearch({}),
636
821
  },
@@ -653,7 +838,7 @@ import { google } from '@ai-sdk/google';
653
838
  import { generateText } from 'ai';
654
839
 
655
840
  const { text, sources, providerMetadata } = await generateText({
656
- model: google('gemini-3.8-flash'),
841
+ model: google('gemini-4-argon'),
657
842
  tools: {
658
843
  file_search: google.tools.fileSearch({
659
844
  fileSearchStoreNames: [
@@ -683,7 +868,7 @@ import { google } from '@ai-sdk/google';
683
868
  import { generateText } from 'ai';
684
869
 
685
870
  const { text, sources, providerMetadata } = await generateText({
686
- model: google('gemini-3.8-flash'),
871
+ model: google('gemini-4-argon'),
687
872
  prompt: `Based on the document: https://ai.google.dev/gemini-api/docs/url-context.
688
873
  Answer this question: How many links we can consume in one request?`,
689
874
  tools: {
@@ -761,7 +946,7 @@ import { google } from '@ai-sdk/google';
761
946
  import { generateText } from 'ai';
762
947
 
763
948
  const { text, sources, providerMetadata } = await generateText({
764
- model: google('gemini-3.8-flash'),
949
+ model: google('gemini-4-argon'),
765
950
  prompt: `Based on this context: https://ai-sdk.dev/providers/ai-sdk-providers/google, tell me how to use Gemini with AI SDK.
766
951
  Also, provide the latest news about AI SDK V5.`,
767
952
  tools: {
@@ -786,7 +971,7 @@ import { GoogleProviderMetadata } from '@ai-sdk/google';
786
971
  import { generateText } from 'ai';
787
972
 
788
973
  const { text, sources, providerMetadata } = await generateText({
789
- model: google('gemini-3.8-flash'),
974
+ model: google('gemini-4-argon'),
790
975
  tools: {
791
976
  google_maps: google.tools.googleMaps({}),
792
977
  },
@@ -850,7 +1035,7 @@ const vertex = createGoogleVertex({
850
1035
  });
851
1036
 
852
1037
  const { text, sources, providerMetadata } = await generateText({
853
- model: vertex('gemini-3.8-flash'),
1038
+ model: vertex('gemini-4-argon'),
854
1039
  tools: {
855
1040
  vertex_rag_store: vertex.tools.vertexRagStore({
856
1041
  ragCorpus:
@@ -1024,7 +1209,7 @@ You can also disable provider-enforced structured outputs for object generation:
1024
1209
 
1025
1210
  ```ts highlight="3,8"
1026
1211
  const { output } = await generateText({
1027
- model: google('gemini-3.8-flash'),
1212
+ model: google('gemini-4-argon'),
1028
1213
  providerOptions: {
1029
1214
  google: {
1030
1215
  structuredOutputs: false,
@@ -1059,6 +1244,7 @@ will still validate the response against the schema in `Output.object`.
1059
1244
  | Model | Image Input | Object Generation | Tool Usage | Tool Streaming | Google Search | URL Context |
1060
1245
  | ------------------------------------- | ----------- | ----------------- | ---------- | -------------- | ------------- | ----------- |
1061
1246
  | `gemini-nano-banana-2.1` | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Check /> | <Cross /> |
1247
+ | `gemini-4-argon` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
1062
1248
  | `gemini-3.8-flash` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
1063
1249
  | `gemini-3.7-flash` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
1064
1250
  | `gemini-3.6-flash` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
@@ -1106,7 +1292,7 @@ You can pass a `webhookUrl` to receive a notification when the batch reaches a t
1106
1292
  import { google } from '@ai-sdk/google';
1107
1293
  import { experimental_startBatch as startBatch } from 'ai';
1108
1294
 
1109
- const model = 'gemini-3.8-flash';
1295
+ const model = 'gemini-4-argon';
1110
1296
 
1111
1297
  const batch = await startBatch({
1112
1298
  provider: google,
@@ -1325,13 +1511,13 @@ import { google } from '@ai-sdk/google';
1325
1511
  import { generateText } from 'ai';
1326
1512
 
1327
1513
  const { text } = await generateText({
1328
- model: google.interactions('gemini-3.8-flash'),
1514
+ model: google.interactions('gemini-4-argon'),
1329
1515
  prompt: 'Hello, how are you?',
1330
1516
  });
1331
1517
  ```
1332
1518
 
1333
1519
  `google.interactions(...)` accepts a model ID string (e.g.
1334
- `'gemini-3.8-flash'`, `'gemini-3.1-pro-preview'`), `{ agent: <name> }` to use
1520
+ `'gemini-4-argon'`, `'gemini-3.1-pro-preview'`), `{ agent: <name> }` to use
1335
1521
  a Gemini [agent preset](#agent-presets), or `{ managedAgent: <name> }` to
1336
1522
  invoke a [managed agent](#managed-agents) you created on Google's side.
1337
1523
  The returned model can be passed to `generateText` and `streamText` like
@@ -1358,7 +1544,7 @@ import {
1358
1544
  import { generateText } from 'ai';
1359
1545
 
1360
1546
  await generateText({
1361
- model: google.interactions('gemini-3.8-flash'),
1547
+ model: google.interactions('gemini-4-argon'),
1362
1548
  prompt: 'What color is the sky in one word?',
1363
1549
  providerOptions: {
1364
1550
  google: {
@@ -1536,7 +1722,7 @@ import {
1536
1722
  import { generateText } from 'ai';
1537
1723
 
1538
1724
  const turn1 = await generateText({
1539
- model: google.interactions('gemini-3.8-flash'),
1725
+ model: google.interactions('gemini-4-argon'),
1540
1726
  prompt: 'What are the three largest cities in Spain?',
1541
1727
  });
1542
1728
 
@@ -1545,7 +1731,7 @@ const interactionId = turn1.providerMetadata?.google?.interactionId as
1545
1731
  | undefined;
1546
1732
 
1547
1733
  const turn2 = await generateText({
1548
- model: google.interactions('gemini-3.8-flash'),
1734
+ model: google.interactions('gemini-4-argon'),
1549
1735
  prompt: 'What is the most famous landmark in the second one?',
1550
1736
  providerOptions: {
1551
1737
  google: {
@@ -1570,7 +1756,7 @@ const messages: Array<ModelMessage> = [
1570
1756
  ];
1571
1757
 
1572
1758
  const turn1 = await generateText({
1573
- model: google.interactions('gemini-3.8-flash'),
1759
+ model: google.interactions('gemini-4-argon'),
1574
1760
  messages,
1575
1761
  providerOptions: {
1576
1762
  google: { store: false } satisfies GoogleLanguageModelInteractionsOptions,
@@ -1584,7 +1770,7 @@ messages.push({
1584
1770
  });
1585
1771
 
1586
1772
  const turn2 = await generateText({
1587
- model: google.interactions('gemini-3.8-flash'),
1773
+ model: google.interactions('gemini-4-argon'),
1588
1774
  messages,
1589
1775
  providerOptions: {
1590
1776
  google: { store: false } satisfies GoogleLanguageModelInteractionsOptions,
@@ -1594,7 +1780,7 @@ const turn2 = await generateText({
1594
1780
 
1595
1781
  ### Agentic video understanding
1596
1782
 
1597
- Gemini 3.7 Flash, 3.6 Flash, and 3.5 Flash Lite support agentic video
1783
+ Gemini 4 Argon, 3.7 Flash, 3.6 Flash, and 3.5 Flash Lite support agentic video
1598
1784
  understanding through the Interactions API. Instead of sampling the entire
1599
1785
  video at a fixed frame rate, the model dynamically navigates the timeline and
1600
1786
  loads the transcripts, frames, or audio needed for the prompt.
@@ -1608,7 +1794,7 @@ import { google, type GoogleInteractionsVideoOptions } from '@ai-sdk/google';
1608
1794
  import { generateText } from 'ai';
1609
1795
 
1610
1796
  const result = await generateText({
1611
- model: google.interactions('gemini-3.8-flash'),
1797
+ model: google.interactions('gemini-4-argon'),
1612
1798
  messages: [
1613
1799
  {
1614
1800
  role: 'user',
@@ -1708,7 +1894,7 @@ import { google } from '@ai-sdk/google';
1708
1894
  import { generateText } from 'ai';
1709
1895
 
1710
1896
  const { text, sources } = await generateText({
1711
- model: google.interactions('gemini-3.8-flash'),
1897
+ model: google.interactions('gemini-4-argon'),
1712
1898
  tools: {
1713
1899
  google_search: google.tools.googleSearch({}),
1714
1900
  },
@@ -1732,7 +1918,7 @@ const weatherTool = tool({
1732
1918
  });
1733
1919
 
1734
1920
  const { text, toolCalls } = await generateText({
1735
- model: google.interactions('gemini-3.8-flash'),
1921
+ model: google.interactions('gemini-4-argon'),
1736
1922
  tools: { getWeather: weatherTool },
1737
1923
  stopWhen: isStepCount(5),
1738
1924
  prompt: 'What is the weather in San Francisco right now?',
@@ -2031,7 +2217,7 @@ import { google } from '@ai-sdk/google';
2031
2217
  import { streamText } from 'ai';
2032
2218
 
2033
2219
  const result = streamText({
2034
- model: google.interactions('gemini-3.8-flash'),
2220
+ model: google.interactions('gemini-4-argon'),
2035
2221
  prompt: 'Hello, how are you?',
2036
2222
  });
2037
2223
 
@@ -2411,14 +2597,14 @@ Older models continue to use labelled transcripts, such as
2411
2597
 
2412
2598
  Create an experimental decision model with `google.decisionModel(modelId)`.
2413
2599
  It uses Gemini structured output for Choice, Score, and Boolean questions. Choose a model
2414
- that supports structured output, such as `gemini-3.5-flash-lite`.
2600
+ that supports structured output, such as `gemini-4-argon`.
2415
2601
 
2416
2602
  ```ts
2417
2603
  import { google } from '@ai-sdk/google';
2418
2604
  import { experimental_decide } from 'ai';
2419
2605
 
2420
2606
  const { answers } = await experimental_decide({
2421
- model: google.decisionModel('gemini-3.5-flash-lite'),
2607
+ model: google.decisionModel('gemini-4-argon'),
2422
2608
  state: 'I was charged twice.',
2423
2609
  questions: {
2424
2610
  requestsRefund: {
@@ -2432,7 +2618,7 @@ const { answers } = await experimental_decide({
2432
2618
  },
2433
2619
  },
2434
2620
  providerOptions: {
2435
- google: { thinkingConfig: { thinkingLevel: 'minimal' } },
2621
+ google: { thinkingConfig: { thinkingLevel: 'low' } },
2436
2622
  },
2437
2623
  });
2438
2624
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/google",
3
- "version": "4.0.94",
3
+ "version": "4.0.96",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@ai-sdk/provider": "4.0.27",
39
- "@ai-sdk/provider-utils": "5.0.59"
39
+ "@ai-sdk/provider-utils": "5.0.60"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@ai-sdk/test-server": "2.0.4",
@@ -0,0 +1,75 @@
1
+ import type { ParseResult } from '@ai-sdk/provider-utils';
2
+
3
+ /**
4
+ * Concatenates the event streams of a long decode response that spans several
5
+ * requests (Gemini 4 long decode).
6
+ *
7
+ * Events of the current stream are passed through unchanged. When an event
8
+ * signals that the per-request cap was reached while budget remains
9
+ * (`getContinuationToken` returns a token), the next request is sent with that
10
+ * token once the current stream ends, and its events are appended. If the
11
+ * continuation request fails, the error is emitted as a failed parse result
12
+ * and the stream ends.
13
+ */
14
+ export function continueGoogleStream<T>({
15
+ stream,
16
+ getContinuationToken,
17
+ continueStream,
18
+ }: {
19
+ stream: ReadableStream<ParseResult<T>>;
20
+ getContinuationToken: (value: T) => string | undefined;
21
+ continueStream: (
22
+ continuationToken: string,
23
+ ) => Promise<ReadableStream<ParseResult<T>>>;
24
+ }): ReadableStream<ParseResult<T>> {
25
+ let reader = stream.getReader();
26
+ let pendingContinuationToken: string | undefined;
27
+
28
+ return new ReadableStream<ParseResult<T>>({
29
+ async pull(controller) {
30
+ while (true) {
31
+ const { done, value } = await reader.read();
32
+
33
+ if (!done) {
34
+ if (value.success) {
35
+ const token = getContinuationToken(value.value);
36
+ if (token != null) {
37
+ pendingContinuationToken = token;
38
+ }
39
+ }
40
+ controller.enqueue(value);
41
+ return;
42
+ }
43
+
44
+ if (pendingContinuationToken == null) {
45
+ controller.close();
46
+ return;
47
+ }
48
+
49
+ const continuationToken = pendingContinuationToken;
50
+ pendingContinuationToken = undefined;
51
+
52
+ try {
53
+ reader = (await continueStream(continuationToken)).getReader();
54
+ } catch (error) {
55
+ // Surfaced as an `error` stream part, followed by the `finish` part
56
+ // with the last continuation token so the caller can resume.
57
+ controller.enqueue({
58
+ success: false,
59
+ error: error as Extract<
60
+ ParseResult<T>,
61
+ { success: false }
62
+ >['error'],
63
+ rawValue: undefined,
64
+ });
65
+ controller.close();
66
+ return;
67
+ }
68
+ }
69
+ },
70
+
71
+ async cancel(reason) {
72
+ await reader.cancel(reason);
73
+ },
74
+ });
75
+ }