ai 7.0.8 → 7.0.10

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.
@@ -133,6 +133,7 @@ Here are the capabilities of popular models:
133
133
  | [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-5.1` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
134
134
  | [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-5-codex` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
135
135
  | [OpenAI](/providers/ai-sdk-providers/openai) | `gpt-5-chat-latest` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
136
+ | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-sonnet-5` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
136
137
  | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-fable-5` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
137
138
  | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-opus-4-8` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
138
139
  | [Anthropic](/providers/ai-sdk-providers/anthropic) | `claude-opus-4-7` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
@@ -203,6 +203,34 @@ This hook is called before the SDK fetches authorization server metadata, so a
203
203
  rejected URL is not requested. It is optional and does not change existing OAuth
204
204
  flows unless you implement it.
205
205
 
206
+ ### Retrying Transient Tool Failures
207
+
208
+ MCP tool calls can fail for transient transport reasons, such as rate limits,
209
+ temporary overload, or gateway timeouts. You can opt into automatic retries for
210
+ `tools/call` requests by passing `maxRetries` when creating the client:
211
+
212
+ ```typescript
213
+ const mcpClient = await createMCPClient({
214
+ transport: {
215
+ type: 'http',
216
+ url: 'https://your-server.com/mcp',
217
+ },
218
+ maxRetries: 2,
219
+ });
220
+ ```
221
+
222
+ Retries are disabled by default. Built-in retry matching is intended for
223
+ transient HTTP and network failures only. JSON-RPC application errors, such as
224
+ invalid tool arguments, are surfaced immediately without retrying. Successful
225
+ MCP tool responses with `isError: true` are also returned to the model without
226
+ retrying.
227
+
228
+ <Note type="warning">
229
+ Only enable retries for MCP tools where retrying is safe. Retrying
230
+ non-idempotent tools, such as tools that send emails or create records, can
231
+ duplicate side effects.
232
+ </Note>
233
+
206
234
  ### Closing the MCP Client
207
235
 
208
236
  After initialization, you should close the MCP client based on your usage pattern:
@@ -345,6 +345,10 @@ console.log(preparation.identity);
345
345
  - `id`: optional stable agent identifier.
346
346
  - `instructions`: instructions applied once to a fresh session.
347
347
  - `tools`: AI SDK tools executed by the host when the harness calls them.
348
+ - `activeTools`: allowlist of built-in and host-executed tools the harness can
349
+ call.
350
+ - `inactiveTools`: denylist of built-in and host-executed tools the harness
351
+ cannot call.
348
352
  - `skills`: instruction bundles surfaced by the adapter.
349
353
  - `permissionMode`: built-in tool permission mode.
350
354
  - `toolApproval`: approval status map for host-executed tools.
@@ -91,6 +91,55 @@ const agent = new HarnessAgent({
91
91
  When the harness calls `weather`, `HarnessAgent` executes the tool in your host
92
92
  process, then submits the result back to the harness runtime.
93
93
 
94
+ ## Tool Filtering
95
+
96
+ Use `activeTools` or `inactiveTools` on `HarnessAgent` to control which tools the
97
+ harness can call. Both settings accept tool names from the combined tool set:
98
+ the built-in tools declared by the harness adapter and the AI SDK tools passed
99
+ with `tools`.
100
+
101
+ `activeTools` is an allowlist:
102
+
103
+ ```ts
104
+ const agent = new HarnessAgent({
105
+ harness: claudeCode,
106
+ sandbox: createVercelSandbox({
107
+ runtime: 'node24',
108
+ ports: [4000],
109
+ }),
110
+ tools: { weather },
111
+ activeTools: ['weather'],
112
+ });
113
+ ```
114
+
115
+ `inactiveTools` is a denylist:
116
+
117
+ ```ts
118
+ const agent = new HarnessAgent({
119
+ harness: claudeCode,
120
+ sandbox: createVercelSandbox({
121
+ runtime: 'node24',
122
+ ports: [4000],
123
+ }),
124
+ tools: { weather },
125
+ inactiveTools: ['bash', 'write'],
126
+ });
127
+ ```
128
+
129
+ Pass either `activeTools` or `inactiveTools`, not both. The TypeScript settings
130
+ type prevents combining them, and `HarnessAgent` also throws at runtime when
131
+ both are specified.
132
+
133
+ For host-executed tools, inactive tools are not passed to the underlying
134
+ harness runtime. If the runtime still attempts to call one, `HarnessAgent`
135
+ returns an execution-denied tool result.
136
+
137
+ For built-in tools, support depends on the harness adapter. Some adapters can
138
+ filter built-ins natively. Others enforce filtering through their built-in tool
139
+ approval mechanism by denying inactive built-in calls before they execute,
140
+ without emitting approval request or response stream parts. Adapters that
141
+ support neither mechanism throw when you filter built-in tools.
142
+
94
143
  ## Sandbox in Tool Execution
95
144
 
96
145
  Host-executed tools receive the session sandbox through the same
@@ -28,10 +28,10 @@ The AI SDK includes the following harness adapters:
28
28
 
29
29
  ## Adapter Capabilities
30
30
 
31
- | Adapter | Runtime location | Custom tools | Custom skills | Built-in tool approval |
32
- | ------------------------------------------------------ | ---------------- | ------------------- | ------------------- | ---------------------- |
33
- | [Claude Code](/providers/ai-sdk-harnesses/claude-code) | Sandbox bridge | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
34
- | [Codex](/providers/ai-sdk-harnesses/codex) | Sandbox bridge | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
35
- | [Deep Agents](/providers/ai-sdk-harnesses/deepagents) | Sandbox bridge | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
36
- | [OpenCode](/providers/ai-sdk-harnesses/opencode) | Sandbox bridge | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
37
- | [Pi](/providers/ai-sdk-harnesses/pi) | Host process | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
31
+ | Adapter | Runtime location | Custom tools | Custom skills | Built-in tool approval | Built-in tool filtering |
32
+ | ------------------------------------------------------ | ---------------- | ------------------- | ------------------- | ---------------------- | -------------------------------------- |
33
+ | [Claude Code](/providers/ai-sdk-harnesses/claude-code) | Sandbox bridge | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
34
+ | [Codex](/providers/ai-sdk-harnesses/codex) | Sandbox bridge | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
35
+ | [Deep Agents](/providers/ai-sdk-harnesses/deepagents) | Sandbox bridge | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> via auto-rejection |
36
+ | [OpenCode](/providers/ai-sdk-harnesses/opencode) | Sandbox bridge | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> via auto-rejection |
37
+ | [Pi](/providers/ai-sdk-harnesses/pi) | Host process | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
@@ -40,7 +40,7 @@ You can create a GitHub repository from within your terminal, or on [github.com]
40
40
 
41
41
  To create your GitHub repository:
42
42
 
43
- 1. Navigate to [github.com](http://github.com/)
43
+ 1. Navigate to [github.com](https://github.com/)
44
44
  2. In the top right corner, click the "plus" icon and select "New repository"
45
45
  3. Pick a name for your repository (this can be anything)
46
46
  4. Click "Create repository"
@@ -187,6 +187,13 @@ It currently does not support accepting notifications from an MCP server, and cu
187
187
  isOptional: true,
188
188
  description: 'Handler for uncaught errors',
189
189
  },
190
+ {
191
+ name: 'maxRetries',
192
+ type: 'number',
193
+ isOptional: true,
194
+ description:
195
+ 'Maximum number of retries for transient MCP tool call failures. Set to 0 to disable retries. Defaults to 0. Retries are opt-in and apply to tools/call requests.',
196
+ },
190
197
  {
191
198
  name: 'initialInitializeResult',
192
199
  type: 'InitializeResult',
@@ -1883,6 +1883,25 @@ The old names still work as deprecated aliases, but you should migrate to the ne
1883
1883
 
1884
1884
  The main entry point the `google` constant, remains unchanged, so if that's all you use from the provider, no changes are required.
1885
1885
 
1886
+ ## xAI Provider
1887
+
1888
+ ### Default Model Now Uses the Responses API
1889
+
1890
+ In AI SDK 7, `xai(modelId)` (and `xai.languageModel(modelId)`) uses the xAI Responses API by default instead of the Chat Completions API. Both APIs were already available in AI SDK 6 via `xai.chat(modelId)` and `xai.responses(modelId)`; AI SDK 7 only changes which one `xai(modelId)` uses by default. To keep using the Chat Completions API, use `xai.chat(modelId)`.
1891
+
1892
+ ```tsx filename="AI SDK 6"
1893
+ // used the Chat Completions API
1894
+ const model = xai('grok-4.3');
1895
+ ```
1896
+
1897
+ ```tsx filename="AI SDK 7"
1898
+ // now uses the Responses API
1899
+ const model = xai('grok-4.3');
1900
+
1901
+ // use the Chat Completions API explicitly
1902
+ const chatModel = xai.chat('grok-4.3');
1903
+ ```
1904
+
1886
1905
  # Migration Skill
1887
1906
 
1888
1907
  Use the command below to add the migration skill and guide your agent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "7.0.8",
3
+ "version": "7.0.10",
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,9 +42,9 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "@ai-sdk/gateway": "4.0.6",
45
+ "@ai-sdk/gateway": "4.0.8",
46
46
  "@ai-sdk/provider": "4.0.1",
47
- "@ai-sdk/provider-utils": "5.0.2"
47
+ "@ai-sdk/provider-utils": "5.0.3"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@edge-runtime/vm": "^5.0.0",
@@ -1,8 +1,6 @@
1
1
  import { InvalidArgumentError } from '../error/invalid-argument-error';
2
- import {
3
- retryWithExponentialBackoffRespectingRetryHeaders,
4
- type RetryFunction,
5
- } from '../util/retry-with-exponential-backoff';
2
+ import type { RetryFunction } from '@ai-sdk/provider-utils';
3
+ import { retryWithExponentialBackoffRespectingRetryHeaders } from '../util/retry-with-exponential-backoff';
6
4
  /**
7
5
  * Validate and prepare retries.
8
6
  */
@@ -1,12 +1,11 @@
1
1
  import { APICallError } from '@ai-sdk/provider';
2
2
  import { GatewayError } from '@ai-sdk/gateway';
3
- import { delay, getErrorMessage, isAbortError } from '@ai-sdk/provider-utils';
3
+ import {
4
+ retryWithExponentialBackoff,
5
+ type RetryFunction,
6
+ } from '@ai-sdk/provider-utils';
4
7
  import { RetryError } from './retry-error';
5
8
 
6
- export type RetryFunction = <OUTPUT>(
7
- fn: () => PromiseLike<OUTPUT>,
8
- ) => PromiseLike<OUTPUT>;
9
-
10
9
  function getRetryDelayInMs({
11
10
  error,
12
11
  exponentialBackoffDelay,
@@ -62,98 +61,31 @@ function getRetryDelayInMs({
62
61
  * while respecting rate limit headers (retry-after-ms and retry-after) if they are provided and reasonable (0-60 seconds).
63
62
  * You can configure the maximum number of retries, the initial delay, and the backoff factor.
64
63
  */
65
- export const retryWithExponentialBackoffRespectingRetryHeaders =
66
- ({
67
- maxRetries = 2,
68
- initialDelayInMs = 2000,
69
- backoffFactor = 2,
70
- abortSignal,
71
- }: {
72
- maxRetries?: number;
73
- initialDelayInMs?: number;
74
- backoffFactor?: number;
75
- abortSignal?: AbortSignal;
76
- } = {}): RetryFunction =>
77
- async <OUTPUT>(f: () => PromiseLike<OUTPUT>) =>
78
- _retryWithExponentialBackoff(f, {
79
- maxRetries,
80
- delayInMs: initialDelayInMs,
81
- backoffFactor,
82
- abortSignal,
83
- });
84
-
85
- async function _retryWithExponentialBackoff<OUTPUT>(
86
- f: () => PromiseLike<OUTPUT>,
87
- {
64
+ export const retryWithExponentialBackoffRespectingRetryHeaders = ({
65
+ maxRetries = 2,
66
+ initialDelayInMs = 2000,
67
+ backoffFactor = 2,
68
+ abortSignal,
69
+ }: {
70
+ maxRetries?: number;
71
+ initialDelayInMs?: number;
72
+ backoffFactor?: number;
73
+ abortSignal?: AbortSignal;
74
+ } = {}): RetryFunction =>
75
+ retryWithExponentialBackoff({
88
76
  maxRetries,
89
- delayInMs,
77
+ initialDelayInMs,
90
78
  backoffFactor,
91
79
  abortSignal,
92
- }: {
93
- maxRetries: number;
94
- delayInMs: number;
95
- backoffFactor: number;
96
- abortSignal: AbortSignal | undefined;
97
- },
98
- errors: unknown[] = [],
99
- ): Promise<OUTPUT> {
100
- try {
101
- return await f();
102
- } catch (error) {
103
- if (isAbortError(error)) {
104
- throw error; // don't retry when the request was aborted
105
- }
106
-
107
- if (maxRetries === 0) {
108
- throw error; // don't wrap the error when retries are disabled
109
- }
110
-
111
- const errorMessage = getErrorMessage(error);
112
- const newErrors = [...errors, error];
113
- const tryNumber = newErrors.length;
114
-
115
- if (tryNumber > maxRetries) {
116
- throw new RetryError({
117
- message: `Failed after ${tryNumber} attempts. Last error: ${errorMessage}`,
118
- reason: 'maxRetriesExceeded',
119
- errors: newErrors,
120
- });
121
- }
122
-
123
- if (
80
+ shouldRetry: error =>
124
81
  error instanceof Error &&
125
82
  ((APICallError.isInstance(error) && error.isRetryable === true) ||
126
- (GatewayError.isInstance(error) && error.isRetryable === true)) &&
127
- tryNumber <= maxRetries
128
- ) {
129
- await delay(
130
- getRetryDelayInMs({
131
- error: error as APICallError | GatewayError,
132
- exponentialBackoffDelay: delayInMs,
133
- }),
134
- { abortSignal },
135
- );
136
-
137
- return _retryWithExponentialBackoff(
138
- f,
139
- {
140
- maxRetries,
141
- delayInMs: backoffFactor * delayInMs,
142
- backoffFactor,
143
- abortSignal,
144
- },
145
- newErrors,
146
- );
147
- }
148
-
149
- if (tryNumber === 1) {
150
- throw error; // don't wrap the error when a non-retryable error occurs on the first try
151
- }
152
-
153
- throw new RetryError({
154
- message: `Failed after ${tryNumber} attempts with non-retryable error: '${errorMessage}'`,
155
- reason: 'errorNotRetryable',
156
- errors: newErrors,
157
- });
158
- }
159
- }
83
+ (GatewayError.isInstance(error) && error.isRetryable === true)),
84
+ getDelayInMs: ({ error, exponentialBackoffDelay }) =>
85
+ getRetryDelayInMs({
86
+ error: error as APICallError | GatewayError,
87
+ exponentialBackoffDelay,
88
+ }),
89
+ createRetryError: ({ message, reason, errors }) =>
90
+ new RetryError({ message, reason, errors }),
91
+ });