ai 7.0.119 → 7.0.120

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.
@@ -90,7 +90,7 @@ import {
90
90
  } from "@ai-sdk/provider-utils";
91
91
 
92
92
  // src/version.ts
93
- var VERSION = true ? "7.0.119" : "0.0.0-test";
93
+ var VERSION = true ? "7.0.120" : "0.0.0-test";
94
94
 
95
95
  // src/util/download/download.ts
96
96
  var download = async ({
@@ -149,6 +149,7 @@ Here are the capabilities of popular models:
149
149
  | [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-5-codex` | <Check /> | <Check /> | <Check /> | <Check /> |
150
150
  | [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-5-chat-latest` | <Check /> | <Check /> | <Check /> | <Check /> |
151
151
  | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-opus-5-5` | <Check /> | <Check /> | <Check /> | <Check /> |
152
+ | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-sonnet-5-5` | <Check /> | <Check /> | <Check /> | <Check /> |
152
153
  | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-sonnet-5` | <Check /> | <Check /> | <Check /> | <Check /> |
153
154
  | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-fable-5-1` | <Check /> | <Check /> | <Check /> | <Check /> |
154
155
  | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-fable-5` | <Check /> | <Check /> | <Check /> | <Check /> |
@@ -45,7 +45,7 @@ The AI Gateway is the default [global provider](/docs/ai-sdk-core/provider-manag
45
45
  import { generateText } from 'ai';
46
46
 
47
47
  const { text } = await generateText({
48
- model: 'anthropic/claude-sonnet-5',
48
+ model: 'anthropic/claude-sonnet-5.5',
49
49
  prompt: 'What is love?',
50
50
  });
51
51
  ```
@@ -55,11 +55,11 @@ You can also explicitly import and use the gateway provider:
55
55
  ```ts
56
56
  // Option 1: Import from 'ai' package (included by default)
57
57
  import { gateway } from 'ai';
58
- model: gateway('anthropic/claude-sonnet-5');
58
+ model: gateway('anthropic/claude-sonnet-5.5');
59
59
 
60
60
  // Option 2: Install and import from '@ai-sdk/gateway' package
61
61
  import { gateway } from '@ai-sdk/gateway';
62
- model: gateway('anthropic/claude-sonnet-5');
62
+ model: gateway('anthropic/claude-sonnet-5.5');
63
63
  ```
64
64
 
65
65
  ## Using Dedicated Providers
@@ -71,7 +71,7 @@ You can also use [first-party](/providers/ai-sdk-providers), [OpenAI-compatible]
71
71
  ```ts
72
72
  import { anthropic } from '@ai-sdk/anthropic';
73
73
 
74
- model: anthropic('claude-sonnet-5');
74
+ model: anthropic('claude-sonnet-5-5');
75
75
  ```
76
76
 
77
77
  You can change the default global provider so string model references use your preferred provider everywhere in your application. Learn more about [provider management](/docs/ai-sdk-core/provider-management#global-provider-configuration).
@@ -122,11 +122,11 @@ You can also explicitly import and use the gateway provider in two other equival
122
122
  ```ts
123
123
  // Option 1: Import from 'ai' package (included by default)
124
124
  import { gateway } from 'ai';
125
- model: gateway('anthropic/claude-sonnet-5');
125
+ model: gateway('anthropic/claude-sonnet-5.5');
126
126
 
127
127
  // Option 2: Install and import from '@ai-sdk/gateway' package
128
128
  import { gateway } from '@ai-sdk/gateway';
129
- model: gateway('anthropic/claude-sonnet-5');
129
+ model: gateway('anthropic/claude-sonnet-5.5');
130
130
  ```
131
131
 
132
132
  ### Using other providers
@@ -126,11 +126,11 @@ You can also explicitly import and use the gateway provider in two other equival
126
126
  ```ts
127
127
  // Option 1: Import from 'ai' package (included by default)
128
128
  import { gateway } from 'ai';
129
- model: gateway('anthropic/claude-sonnet-5');
129
+ model: gateway('anthropic/claude-sonnet-5.5');
130
130
 
131
131
  // Option 2: Install and import from '@ai-sdk/gateway' package
132
132
  import { gateway } from '@ai-sdk/gateway';
133
- model: gateway('anthropic/claude-sonnet-5');
133
+ model: gateway('anthropic/claude-sonnet-5.5');
134
134
  ```
135
135
 
136
136
  ### Using other providers
@@ -87,7 +87,7 @@ export async function POST({ request }) {
87
87
  const { messages }: { messages: UIMessage[] } = await request.json();
88
88
 
89
89
  const result = streamText({
90
- model: gateway('anthropic/claude-sonnet-5'),
90
+ model: gateway('anthropic/claude-sonnet-5.5'),
91
91
  messages: await convertToModelMessages(messages),
92
92
  });
93
93
 
@@ -125,11 +125,11 @@ You can also explicitly import and use the gateway provider in two other equival
125
125
  ```ts
126
126
  // Option 1: Import from 'ai' package (included by default)
127
127
  import { gateway } from 'ai';
128
- model: gateway('anthropic/claude-sonnet-5');
128
+ model: gateway('anthropic/claude-sonnet-5.5');
129
129
 
130
130
  // Option 2: Install and import from '@ai-sdk/gateway' package
131
131
  import { gateway } from '@ai-sdk/gateway';
132
- model: gateway('anthropic/claude-sonnet-5');
132
+ model: gateway('anthropic/claude-sonnet-5.5');
133
133
  ```
134
134
 
135
135
  ### Using other providers
@@ -247,7 +247,7 @@ export async function POST({ request }) {
247
247
  const { messages }: { messages: UIMessage[] } = await request.json();
248
248
 
249
249
  const result = streamText({
250
- model: gateway('anthropic/claude-sonnet-5'),
250
+ model: gateway('anthropic/claude-sonnet-5.5'),
251
251
  messages: await convertToModelMessages(messages),
252
252
  tools: {
253
253
  weather: tool({
@@ -371,7 +371,7 @@ export async function POST({ request }) {
371
371
  const { messages }: { messages: UIMessage[] } = await request.json();
372
372
 
373
373
  const result = streamText({
374
- model: gateway('anthropic/claude-sonnet-5'),
374
+ model: gateway('anthropic/claude-sonnet-5.5'),
375
375
  messages: await convertToModelMessages(messages),
376
376
  stopWhen: isStepCount(5),
377
377
  tools: {
@@ -428,7 +428,7 @@ export async function POST({ request }) {
428
428
  const { messages }: { messages: UIMessage[] } = await request.json();
429
429
 
430
430
  const result = streamText({
431
- model: gateway('anthropic/claude-sonnet-5'),
431
+ model: gateway('anthropic/claude-sonnet-5.5'),
432
432
  messages: await convertToModelMessages(messages),
433
433
  stopWhen: isStepCount(5),
434
434
  tools: {
@@ -99,7 +99,7 @@ export default defineLazyEventHandler(async () => {
99
99
  const { messages }: { messages: UIMessage[] } = await readBody(event);
100
100
 
101
101
  const result = streamText({
102
- model: gateway('anthropic/claude-sonnet-5'),
102
+ model: gateway('anthropic/claude-sonnet-5.5'),
103
103
  messages: await convertToModelMessages(messages),
104
104
  });
105
105
 
@@ -133,11 +133,11 @@ You can also explicitly import and use the gateway provider in two other equival
133
133
  ```ts
134
134
  // Option 1: Import from 'ai' package (included by default)
135
135
  import { gateway } from 'ai';
136
- model: gateway('anthropic/claude-sonnet-5');
136
+ model: gateway('anthropic/claude-sonnet-5.5');
137
137
 
138
138
  // Option 2: Install and import from '@ai-sdk/gateway' package
139
139
  import { gateway } from '@ai-sdk/gateway';
140
- model: gateway('anthropic/claude-sonnet-5');
140
+ model: gateway('anthropic/claude-sonnet-5.5');
141
141
  ```
142
142
 
143
143
  ### Using other providers
@@ -251,7 +251,7 @@ export default defineLazyEventHandler(async () => {
251
251
  const { messages }: { messages: UIMessage[] } = await readBody(event);
252
252
 
253
253
  const result = streamText({
254
- model: gateway('anthropic/claude-sonnet-5'),
254
+ model: gateway('anthropic/claude-sonnet-5.5'),
255
255
  messages: await convertToModelMessages(messages),
256
256
  tools: {
257
257
  weather: tool({
@@ -376,7 +376,7 @@ export default defineLazyEventHandler(async () => {
376
376
  const { messages }: { messages: UIMessage[] } = await readBody(event);
377
377
 
378
378
  const result = streamText({
379
- model: gateway('anthropic/claude-sonnet-5'),
379
+ model: gateway('anthropic/claude-sonnet-5.5'),
380
380
  messages: await convertToModelMessages(messages),
381
381
  stopWhen: isStepCount(5),
382
382
  tools: {
@@ -437,7 +437,7 @@ export default defineLazyEventHandler(async () => {
437
437
  const { messages }: { messages: UIMessage[] } = await readBody(event);
438
438
 
439
439
  const result = streamText({
440
- model: gateway('anthropic/claude-sonnet-5'),
440
+ model: gateway('anthropic/claude-sonnet-5.5'),
441
441
  messages: await convertToModelMessages(messages),
442
442
  stopWhen: isStepCount(5),
443
443
  tools: {
@@ -146,11 +146,11 @@ You can also explicitly import and use the gateway provider in two other equival
146
146
  ```ts
147
147
  // Option 1: Import from 'ai' package (included by default)
148
148
  import { gateway } from 'ai';
149
- model: gateway('anthropic/claude-sonnet-5');
149
+ model: gateway('anthropic/claude-sonnet-5.5');
150
150
 
151
151
  // Option 2: Install and import from '@ai-sdk/gateway' package
152
152
  import { gateway } from '@ai-sdk/gateway';
153
- model: gateway('anthropic/claude-sonnet-5');
153
+ model: gateway('anthropic/claude-sonnet-5.5');
154
154
  ```
155
155
 
156
156
  ### Using other providers
@@ -125,11 +125,11 @@ You can also explicitly import and use the gateway provider in two other equival
125
125
  ```ts
126
126
  // Option 1: Import from 'ai' package (included by default)
127
127
  import { gateway } from 'ai';
128
- model: gateway('anthropic/claude-sonnet-5');
128
+ model: gateway('anthropic/claude-sonnet-5.5');
129
129
 
130
130
  // Option 2: Install and import from '@ai-sdk/gateway' package
131
131
  import { gateway } from '@ai-sdk/gateway';
132
- model: gateway('anthropic/claude-sonnet-5');
132
+ model: gateway('anthropic/claude-sonnet-5.5');
133
133
  ```
134
134
 
135
135
  ### Using other providers
@@ -121,11 +121,11 @@ You can also explicitly import and use the gateway provider in two other equival
121
121
  ```ts
122
122
  // Option 1: Import from 'ai' package (included by default)
123
123
  import { gateway } from 'ai';
124
- model: gateway('anthropic/claude-sonnet-5');
124
+ model: gateway('anthropic/claude-sonnet-5.5');
125
125
 
126
126
  // Option 2: Install and import from '@ai-sdk/gateway' package
127
127
  import { gateway } from '@ai-sdk/gateway';
128
- model: gateway('anthropic/claude-sonnet-5');
128
+ model: gateway('anthropic/claude-sonnet-5.5');
129
129
  ```
130
130
 
131
131
  ### Using other providers
@@ -80,7 +80,7 @@ const toolApproval = opaPolicy({
80
80
 
81
81
  // 3. Pass it to generateText (or streamText / ToolLoopAgent). Everything else is normal.
82
82
  const result = await generateText({
83
- model: anthropic('claude-sonnet-5'),
83
+ model: anthropic('claude-sonnet-5-5'),
84
84
  tools: { git, bash, queryLogs },
85
85
  toolApproval,
86
86
  prompt: 'find the failing test and push the fix',
@@ -291,7 +291,7 @@ import { wasmPolicyClient, opaCapabilityMiddleware } from '@ai-sdk/policy-opa';
291
291
  const client = await wasmPolicyClient({ wasm });
292
292
 
293
293
  const wrappedModel = wrapLanguageModel({
294
- model: anthropic('claude-sonnet-5'),
294
+ model: anthropic('claude-sonnet-5-5'),
295
295
  middleware: opaCapabilityMiddleware({ client, path: 'agent/tools/allowed' }),
296
296
  });
297
297
  ```
@@ -51,7 +51,7 @@ import { tool } from 'ai';
51
51
  import { z } from 'zod';
52
52
 
53
53
  const agent = new WorkflowAgent({
54
- model: 'anthropic/claude-sonnet-5',
54
+ model: 'anthropic/claude-sonnet-5.5',
55
55
  instructions: 'You are a helpful assistant.',
56
56
  tools: {
57
57
  weather: tool({
@@ -74,7 +74,7 @@ The `model` parameter accepts two forms:
74
74
 
75
75
  ```ts
76
76
  // String — AI Gateway model ID
77
- new WorkflowAgent({ model: 'anthropic/claude-sonnet-5' });
77
+ new WorkflowAgent({ model: 'anthropic/claude-sonnet-5.5' });
78
78
 
79
79
  // Provider instance
80
80
  import { openai } from '@ai-sdk/openai';
@@ -103,7 +103,7 @@ export async function chat(messages: UIMessage[]) {
103
103
  const modelMessages = await convertToModelMessages(messages);
104
104
 
105
105
  const agent = new WorkflowAgent({
106
- model: 'anthropic/claude-sonnet-5',
106
+ model: 'anthropic/claude-sonnet-5.5',
107
107
  instructions: 'You are a flight booking assistant.',
108
108
  tools: {
109
109
  searchFlights: tool({
@@ -328,7 +328,7 @@ the writable stream. The workflow suspends until the user approves or denies:
328
328
 
329
329
  ```ts
330
330
  const agent = new WorkflowAgent({
331
- model: 'anthropic/claude-sonnet-5',
331
+ model: 'anthropic/claude-sonnet-5.5',
332
332
  tools: {
333
333
  bookFlight: tool({
334
334
  description: 'Book a flight',
@@ -362,7 +362,7 @@ workflow. For tools that perform sensitive operations, configure
362
362
 
363
363
  ```ts highlight="4"
364
364
  const agent = new WorkflowAgent({
365
- model: 'anthropic/claude-sonnet-5',
365
+ model: 'anthropic/claude-sonnet-5.5',
366
366
  experimental_toolApprovalSecret: {
367
367
  environmentVariable: 'TOOL_APPROVAL_SECRET',
368
368
  },
@@ -526,7 +526,7 @@ current step:
526
526
 
527
527
  ```ts
528
528
  const agent = new WorkflowAgent({
529
- model: 'anthropic/claude-sonnet-5',
529
+ model: 'anthropic/claude-sonnet-5.5',
530
530
  tools: {
531
531
  shell: tool({
532
532
  description: 'Run a shell command in the sandbox.',
@@ -561,7 +561,7 @@ Called once before the agent loop starts. Use it to transform model, instruction
561
561
 
562
562
  ```ts
563
563
  const agent = new WorkflowAgent({
564
- model: 'anthropic/claude-sonnet-5',
564
+ model: 'anthropic/claude-sonnet-5.5',
565
565
  prepareCall: async ({ model, tools, messages }) => {
566
566
  return {
567
567
  instructions: `Current time: ${new Date().toISOString()}`,
@@ -597,7 +597,7 @@ Agents provide lifecycle callbacks for logging, observability, and custom teleme
597
597
 
598
598
  ```ts
599
599
  const agent = new WorkflowAgent({
600
- model: 'anthropic/claude-sonnet-5',
600
+ model: 'anthropic/claude-sonnet-5.5',
601
601
 
602
602
  onStart({ messages }) {
603
603
  console.log(`Agent started with ${messages.length} messages`);
@@ -682,7 +682,7 @@ export type MyAgentUIMessage = InferWorkflowAgentUIMessage<typeof myAgent>;
682
682
 
683
683
  - const agent = new DurableAgent({
684
684
  + const agent = new WorkflowAgent({
685
- model: 'anthropic/claude-sonnet-5',
685
+ model: 'anthropic/claude-sonnet-5.5',
686
686
  instructions: 'You are a helpful assistant.',
687
687
  tools: { /* ... */ },
688
688
  });
@@ -795,7 +795,7 @@ For persistence, store `UIMessage[]` as your source of truth and call [`convertT
795
795
 
796
796
  ```diff
797
797
  const agent = new WorkflowAgent({
798
- model: 'anthropic/claude-sonnet-5',
798
+ model: 'anthropic/claude-sonnet-5.5',
799
799
  tools: { weather: weatherTool },
800
800
  - experimental_context: { tenantId: 'tenant_123', apiKey: 'sk-...' },
801
801
  + runtimeContext: { tenantId: 'tenant_123' },
@@ -13,7 +13,7 @@ When you create prompts that include tools, getting good results can be tricky a
13
13
 
14
14
  Here are a few tips to help you get the best results:
15
15
 
16
- 1. Use a model that is strong at tool calling, such as `gpt-6-astra` or `claude-sonnet-5`. Weaker models will often struggle to call tools effectively and flawlessly.
16
+ 1. Use a model that is strong at tool calling, such as `gpt-6-astra` or `claude-sonnet-5-5`. Weaker models will often struggle to call tools effectively and flawlessly.
17
17
  1. Keep the number of tools low, e.g. to 5 or less.
18
18
  1. Keep the complexity of the tool parameters low. Complex Zod schemas with many nested and optional elements, unions, etc. can be challenging for the model to work with.
19
19
  1. Use semantically meaningful names for your tools, parameters, parameter properties, etc. The more information you pass to the model, the better it can understand what you want.
@@ -13,7 +13,7 @@ Many language models support an internal "reasoning" phase (sometimes also calle
13
13
  import { generateText } from 'ai';
14
14
 
15
15
  const { text, reasoning, reasoningText } = await generateText({
16
- model: 'anthropic/claude-sonnet-5',
16
+ model: 'anthropic/claude-sonnet-5.5',
17
17
  reasoning: 'medium',
18
18
  prompt: 'How many people will live in the world in 2040?',
19
19
  });
@@ -79,7 +79,7 @@ import { customProvider, gateway } from 'ai';
79
79
  export const anthropic = customProvider({
80
80
  languageModels: {
81
81
  opus: gateway('anthropic/claude-opus-5.5'),
82
- sonnet: gateway('anthropic/claude-sonnet-5'),
82
+ sonnet: gateway('anthropic/claude-sonnet-5.5'),
83
83
  haiku: gateway('anthropic/claude-haiku-4.5'),
84
84
  },
85
85
  fallbackProvider: gateway,
@@ -100,7 +100,7 @@ import {
100
100
 
101
101
  export const myProvider = customProvider({
102
102
  languageModels: {
103
- 'text-medium': gateway('anthropic/claude-sonnet-5'),
103
+ 'text-medium': gateway('anthropic/claude-sonnet-5.5'),
104
104
  'text-small': gateway('openai/gpt-6-luna'),
105
105
  'reasoning-medium': wrapLanguageModel({
106
106
  model: gateway('openai/gpt-6-astra'),
@@ -154,7 +154,7 @@ const myOpenAI = customProvider({
154
154
  // custom provider with skills interface:
155
155
  const myAnthropic = customProvider({
156
156
  languageModels: {
157
- sonnet: anthropic('claude-sonnet-5'),
157
+ sonnet: anthropic('claude-sonnet-5-5'),
158
158
  },
159
159
  skills: anthropic.skills(),
160
160
  });
@@ -330,7 +330,7 @@ import { createProviderRegistry, customProvider, uploadSkill } from 'ai';
330
330
 
331
331
  const registry = createProviderRegistry({
332
332
  anthropic: customProvider({
333
- languageModels: { sonnet: anthropic('claude-sonnet-5') },
333
+ languageModels: { sonnet: anthropic('claude-sonnet-5-5') },
334
334
  skills: anthropic.skills(),
335
335
  }),
336
336
  });
@@ -947,7 +947,7 @@ Check out the [stream protocol guide](/docs/ai-sdk-ui/stream-protocol) for more
947
947
  ## Reasoning
948
948
 
949
949
  Some models such as DeepSeek `deepseek-r1`
950
- and Anthropic `claude-sonnet-5` support reasoning tokens.
950
+ and Anthropic `claude-sonnet-5-5` support reasoning tokens.
951
951
  These tokens are typically sent before the message content.
952
952
  You can forward them to the client with the `sendReasoning` option:
953
953
 
@@ -17,7 +17,7 @@ import { tool } from 'ai';
17
17
  import { z } from 'zod';
18
18
 
19
19
  const agent = new WorkflowAgent({
20
- model: 'anthropic/claude-sonnet-5',
20
+ model: 'anthropic/claude-sonnet-5.5',
21
21
  instructions: 'You are a helpful assistant.',
22
22
  tools: {
23
23
  weather: tool({
@@ -71,7 +71,7 @@ To see `WorkflowAgent` in action, check out [these examples](#examples).
71
71
  type: 'LanguageModel',
72
72
  isRequired: true,
73
73
  description:
74
- "The language model to use. A string compatible with the Vercel AI Gateway (e.g., 'anthropic/claude-sonnet-5') or a provider instance (e.g., `openai('gpt-6-astra')`).",
74
+ "The language model to use. A string compatible with the Vercel AI Gateway (e.g., 'anthropic/claude-sonnet-5.5') or a provider instance (e.g., `openai('gpt-6-astra')`).",
75
75
  },
76
76
  {
77
77
  name: 'instructions',
@@ -808,7 +808,7 @@ Infers the UI message type for a `WorkflowAgent` instance. Optionally accepts a
808
808
  import { WorkflowAgent, InferWorkflowAgentUIMessage } from '@ai-sdk/workflow';
809
809
 
810
810
  const agent = new WorkflowAgent({
811
- model: 'anthropic/claude-sonnet-5',
811
+ model: 'anthropic/claude-sonnet-5.5',
812
812
  tools: { weather: weatherTool },
813
813
  });
814
814
 
@@ -835,7 +835,7 @@ import { tool } from 'ai';
835
835
  import { z } from 'zod';
836
836
 
837
837
  const agent = new WorkflowAgent({
838
- model: 'anthropic/claude-sonnet-5',
838
+ model: 'anthropic/claude-sonnet-5.5',
839
839
  instructions: 'You are a helpful assistant.',
840
840
  tools: {
841
841
  weather: tool({
@@ -890,7 +890,7 @@ export async function chat(messages: UIMessage[]) {
890
890
  const modelMessages = await convertToModelMessages(messages);
891
891
 
892
892
  const agent = new WorkflowAgent({
893
- model: 'anthropic/claude-sonnet-5',
893
+ model: 'anthropic/claude-sonnet-5.5',
894
894
  instructions: 'You are a flight booking assistant.',
895
895
  tools: {
896
896
  searchFlights: tool({
@@ -937,7 +937,7 @@ import { WorkflowAgent, Output } from '@ai-sdk/workflow';
937
937
  import { z } from 'zod';
938
938
 
939
939
  const analysisAgent = new WorkflowAgent({
940
- model: 'anthropic/claude-sonnet-5',
940
+ model: 'anthropic/claude-sonnet-5.5',
941
941
  });
942
942
 
943
943
  const result = await analysisAgent.stream({
@@ -977,7 +977,7 @@ import { tool } from 'ai';
977
977
  import { z } from 'zod';
978
978
 
979
979
  const agent = new WorkflowAgent({
980
- model: 'anthropic/claude-sonnet-5',
980
+ model: 'anthropic/claude-sonnet-5.5',
981
981
  experimental_toolApprovalSecret: {
982
982
  environmentVariable: 'TOOL_APPROVAL_SECRET',
983
983
  },
@@ -1009,7 +1009,7 @@ serialize it. A stream-level reference overrides the constructor value.
1009
1009
  import { WorkflowAgent } from '@ai-sdk/workflow';
1010
1010
 
1011
1011
  const agent = new WorkflowAgent({
1012
- model: 'anthropic/claude-sonnet-5',
1012
+ model: 'anthropic/claude-sonnet-5.5',
1013
1013
  tools: { weather: weatherTool },
1014
1014
 
1015
1015
  // Agent-wide callbacks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "7.0.119",
3
+ "version": "7.0.120",
4
4
  "type": "module",
5
5
  "description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
6
6
  "license": "Apache-2.0",
@@ -42,14 +42,14 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "@ai-sdk/gateway": "4.0.97",
45
+ "@ai-sdk/gateway": "4.0.98",
46
46
  "@ai-sdk/provider": "4.0.19",
47
47
  "@ai-sdk/provider-utils": "5.0.50"
48
48
  },
49
49
  "devDependencies": {
50
- "@ai-sdk/amazon-bedrock": "5.0.98",
50
+ "@ai-sdk/amazon-bedrock": "5.0.99",
51
51
  "@ai-sdk/deepseek": "3.0.55",
52
- "@ai-sdk/google": "4.0.83",
52
+ "@ai-sdk/google": "4.0.84",
53
53
  "@ai-sdk/groq": "4.0.51",
54
54
  "@ai-sdk/huggingface": "2.0.58",
55
55
  "@ai-sdk/moonshotai": "3.0.59",
package/src/ui/chat.ts CHANGED
@@ -263,6 +263,9 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
263
263
  private pendingApprovalMessageId: string | undefined;
264
264
  private activeResponse: ActiveResponse<UI_MESSAGE> | undefined = undefined;
265
265
  private activeResumeRequest: ActiveResumeRequest | undefined = undefined;
266
+ private resumableStreamState:
267
+ | StreamingUIMessageState<UI_MESSAGE>
268
+ | undefined = undefined;
266
269
  private jobExecutor = new SerialJobExecutor();
267
270
 
268
271
  constructor({
@@ -723,6 +726,10 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
723
726
  trigger: 'submit-message' | 'resume-stream' | 'regenerate-message';
724
727
  messageId?: string;
725
728
  } & ChatRequestOptions) {
729
+ if (trigger !== 'resume-stream') {
730
+ this.resumableStreamState = undefined;
731
+ }
732
+
726
733
  const abortController = new AbortController();
727
734
  const activeResumeRequest =
728
735
  trigger === 'resume-stream' ? { abortController } : undefined;
@@ -760,6 +767,7 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
760
767
  await reconnect?.cancel().catch(() => {});
761
768
  if (isCurrentRequest()) {
762
769
  this.setStatus({ status: 'ready' });
770
+ this.resumableStreamState = undefined;
763
771
  }
764
772
  clearActiveResumeRequest();
765
773
  return;
@@ -767,6 +775,7 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
767
775
 
768
776
  if (reconnect == null) {
769
777
  this.setStatus({ status: 'ready' });
778
+ this.resumableStreamState = undefined;
770
779
  clearActiveResumeRequest();
771
780
  return; // no active stream found, so we do not resume
772
781
  }
@@ -779,6 +788,7 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
779
788
  ) {
780
789
  if (isCurrentRequest()) {
781
790
  this.setStatus({ status: 'ready' });
791
+ this.resumableStreamState = undefined;
782
792
  }
783
793
  clearActiveResumeRequest();
784
794
  return;
@@ -820,13 +830,17 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
820
830
 
821
831
  try {
822
832
  const response = {
823
- state: createStreamingUIMessageState({
824
- lastMessage:
825
- trigger === 'resume-stream' || trigger === 'regenerate-message'
826
- ? undefined
827
- : this.state.snapshot(responseMessage),
828
- messageId: this.generateId(),
829
- }),
833
+ state:
834
+ trigger === 'resume-stream' && this.resumableStreamState != null
835
+ ? this.resumableStreamState
836
+ : createStreamingUIMessageState({
837
+ lastMessage:
838
+ trigger === 'resume-stream' ||
839
+ trigger === 'regenerate-message'
840
+ ? undefined
841
+ : this.state.snapshot(responseMessage),
842
+ messageId: this.generateId(),
843
+ }),
830
844
  abortController,
831
845
  } as ActiveResponse<UI_MESSAGE>;
832
846
 
@@ -916,12 +930,18 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
916
930
  if (isAbort) {
917
931
  if (isCurrentRequest()) {
918
932
  this.setStatus({ status: 'ready' });
933
+ if (this.resumableStreamState === response.state) {
934
+ this.resumableStreamState = undefined;
935
+ }
919
936
  }
920
937
  return null;
921
938
  }
922
939
 
923
940
  if (isCurrentRequest()) {
924
941
  this.setStatus({ status: 'ready' });
942
+ if (this.resumableStreamState === response.state) {
943
+ this.resumableStreamState = undefined;
944
+ }
925
945
  }
926
946
  } catch (err) {
927
947
  // Ignore abort errors as they are expected.
@@ -929,6 +949,9 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
929
949
  isAbort = true;
930
950
  if (isCurrentRequest()) {
931
951
  this.setStatus({ status: 'ready' });
952
+ if (this.resumableStreamState === activeResponse?.state) {
953
+ this.resumableStreamState = undefined;
954
+ }
932
955
  }
933
956
  return null;
934
957
  }
@@ -948,6 +971,12 @@ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
948
971
  isDisconnect = true;
949
972
  }
950
973
 
974
+ if (isDisconnect) {
975
+ this.resumableStreamState = activeResponse?.state;
976
+ } else if (this.resumableStreamState === activeResponse?.state) {
977
+ this.resumableStreamState = undefined;
978
+ }
979
+
951
980
  if (this.onError && err instanceof Error) {
952
981
  this.onError(err);
953
982
  }
@@ -816,7 +816,8 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
816
816
  providerExecuted: chunk.providerExecuted,
817
817
  providerMetadata: chunk.providerMetadata,
818
818
  title: toolInvocation.title,
819
- toolMetadata: toolInvocation.toolMetadata,
819
+ toolMetadata:
820
+ chunk.toolMetadata ?? toolInvocation.toolMetadata,
820
821
  },
821
822
  toolInvocation,
822
823
  );
@@ -832,7 +833,8 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
832
833
  preliminary: chunk.preliminary,
833
834
  providerMetadata: chunk.providerMetadata,
834
835
  title: toolInvocation.title,
835
- toolMetadata: toolInvocation.toolMetadata,
836
+ toolMetadata:
837
+ chunk.toolMetadata ?? toolInvocation.toolMetadata,
836
838
  },
837
839
  toolInvocation as ToolUIPart<InferUIMessageTools<UI_MESSAGE>>,
838
840
  );
@@ -856,7 +858,8 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
856
858
  providerExecuted: chunk.providerExecuted,
857
859
  providerMetadata: chunk.providerMetadata,
858
860
  title: toolInvocation.title,
859
- toolMetadata: toolInvocation.toolMetadata,
861
+ toolMetadata:
862
+ chunk.toolMetadata ?? toolInvocation.toolMetadata,
860
863
  },
861
864
  toolInvocation,
862
865
  );
@@ -872,7 +875,8 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
872
875
  providerExecuted: chunk.providerExecuted,
873
876
  providerMetadata: chunk.providerMetadata,
874
877
  title: toolInvocation.title,
875
- toolMetadata: toolInvocation.toolMetadata,
878
+ toolMetadata:
879
+ chunk.toolMetadata ?? toolInvocation.toolMetadata,
876
880
  },
877
881
  toolInvocation as ToolUIPart<InferUIMessageTools<UI_MESSAGE>>,
878
882
  );