ai 7.0.2 → 7.0.4

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # ai
2
2
 
3
+ ## 7.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [6a436e3]
8
+ - @ai-sdk/provider-utils@5.0.1
9
+ - @ai-sdk/gateway@4.0.4
10
+
11
+ ## 7.0.3
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [728eaa0]
16
+ - @ai-sdk/gateway@4.0.3
17
+
3
18
  ## 7.0.2
4
19
 
5
20
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1089,7 +1089,7 @@ import {
1089
1089
  } from "@ai-sdk/provider-utils";
1090
1090
 
1091
1091
  // src/version.ts
1092
- var VERSION = true ? "7.0.2" : "0.0.0-test";
1092
+ var VERSION = true ? "7.0.4" : "0.0.0-test";
1093
1093
 
1094
1094
  // src/util/download/download.ts
1095
1095
  var download = async ({
@@ -83,7 +83,7 @@ import {
83
83
  } from "@ai-sdk/provider-utils";
84
84
 
85
85
  // src/version.ts
86
- var VERSION = true ? "7.0.2" : "0.0.0-test";
86
+ var VERSION = true ? "7.0.4" : "0.0.0-test";
87
87
 
88
88
  // src/util/download/download.ts
89
89
  var download = async ({
@@ -252,7 +252,7 @@ const result = await agent.generate({
252
252
 
253
253
  `isLoopFinished()` lets the agent keep running until the tool loop naturally finishes, which is useful when memory tools need to read and write before the final response.
254
254
 
255
- Session memory supports two modes: **tool-driven** (the LLM decides when to read/write — good for prototypes) and **hook-driven** (the runtime persists every turn via `prepareCall` + `onFinish` hooks — recommended for production). The other memory tiers (semantic, procedural, episodic, scratchpad) are always LLM-controlled and selective by design.
255
+ Session memory supports two modes: **tool-driven** (the LLM decides when to read/write — good for prototypes) and **hook-driven** (the runtime persists every turn via `prepareCall` + `onEnd` hooks — recommended for production). The other memory tiers (semantic, procedural, episodic, scratchpad) are always LLM-controlled and selective by design.
256
256
 
257
257
  MongoDB memory works with any AI SDK model and embedding provider, with no vendor lock-in beyond MongoDB Atlas.
258
258
 
@@ -49,6 +49,53 @@ const mcpClient = await createMCPClient({
49
49
  });
50
50
  ```
51
51
 
52
+ If the MCP server uses Streamable HTTP sessions, you can reattach to a saved
53
+ session by restoring both the previous session id and initialize result:
54
+
55
+ ```typescript
56
+ import { createMCPClient } from '@ai-sdk/mcp';
57
+
58
+ const savedSession = await loadMcpSession();
59
+ let currentSessionId = savedSession?.sessionId;
60
+
61
+ const mcpClient = await createMCPClient({
62
+ transport: {
63
+ type: 'http',
64
+ url: 'https://your-server.com/mcp',
65
+ initialSessionId: savedSession?.sessionId,
66
+ initialProtocolVersion: savedSession?.initializeResult.protocolVersion,
67
+ terminateSessionOnClose: false,
68
+
69
+ onSessionIdChange: sessionId => {
70
+ currentSessionId = sessionId;
71
+ },
72
+
73
+ onSessionExpired: sessionId => {
74
+ if (currentSessionId === sessionId) {
75
+ currentSessionId = undefined;
76
+ void clearMcpSession();
77
+ }
78
+ },
79
+ },
80
+ initialInitializeResult: savedSession?.initializeResult,
81
+ });
82
+
83
+ if (currentSessionId) {
84
+ await saveMcpSession({
85
+ sessionId: currentSessionId,
86
+ initializeResult: mcpClient.initializeResult,
87
+ });
88
+ }
89
+ ```
90
+
91
+ When `initialInitializeResult` is provided, `createMCPClient` reuses the cached
92
+ initialize metadata and does not send another `initialize` request. When
93
+ `onSessionExpired` is called, the transport has already cleared the session id
94
+ and the request still fails with the underlying HTTP error. Retry by creating a
95
+ fresh client without `initialSessionId` or `initialInitializeResult`.
96
+ Set `terminateSessionOnClose` to `false` when closing only the local client but
97
+ keeping the MCP session available for a later reattach.
98
+
52
99
  Alternatively, you can use `StreamableHTTPClientTransport` from MCP's official TypeScript SDK:
53
100
 
54
101
  ```typescript
@@ -116,8 +163,8 @@ You can also bring your own transport by implementing the `MCPTransport` interfa
116
163
  <Note>
117
164
  The client returned by the `createMCPClient` function is a
118
165
  lightweight client intended for use in tool conversion. It currently does not
119
- support all features of the full MCP client, such as: session
120
- management, resumable streams, and receiving notifications.
166
+ support all features of the full MCP client, such as automatic session
167
+ persistence, resumable streams, and receiving notifications.
121
168
 
122
169
  Authorization via OAuth is supported when using the AI SDK MCP HTTP or SSE
123
170
  transports by providing an `authProvider`.
@@ -313,6 +360,52 @@ Resource templates are dynamic URI patterns that allow flexible queries. List al
313
360
  const templates = await mcpClient.listResourceTemplates();
314
361
  ```
315
362
 
363
+ ## Using MCP Completions
364
+
365
+ MCP servers can provide autocompletion suggestions for prompt arguments and
366
+ resource template variables when they advertise the `completions` capability.
367
+ Use `complete` to ask the server for suggestions based on the current partial
368
+ argument value:
369
+
370
+ ```typescript
371
+ const completion = await mcpClient.complete({
372
+ ref: {
373
+ type: 'ref/resource',
374
+ uri: 'file:///{path}',
375
+ },
376
+ argument: {
377
+ name: 'path',
378
+ value: 'doc',
379
+ },
380
+ });
381
+
382
+ console.log(completion.completion.values);
383
+ ```
384
+
385
+ For resource templates or prompts with multiple arguments, pass already resolved
386
+ values through `context.arguments`:
387
+
388
+ ```typescript
389
+ const completion = await mcpClient.complete({
390
+ ref: {
391
+ type: 'ref/resource',
392
+ uri: 'kubernetes://namespaced/{plural}/{namespace}',
393
+ },
394
+ argument: {
395
+ name: 'namespace',
396
+ value: 'auth',
397
+ },
398
+ context: {
399
+ arguments: {
400
+ plural: 'deployments',
401
+ },
402
+ },
403
+ });
404
+ ```
405
+
406
+ If the connected server does not advertise `capabilities.completions`, the
407
+ client throws an `MCPClientError`.
408
+
316
409
  ## Using MCP Prompts
317
410
 
318
411
  <Note type="warning">
@@ -288,7 +288,7 @@ for (const file of result.files) {
288
288
  | Provider | Model | Support sizes (`width x height`) or aspect ratios (`width : height`) |
289
289
  | ------------------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
290
290
  | [xAI Grok](/providers/ai-sdk-providers/xai#image-models) | `grok-imagine-image` | `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3`, `2:1`, `1:2`, `19.5:9`, `9:19.5`, `20:9`, `9:20`, `auto` |
291
- | [OpenAI](/providers/ai-sdk-providers/openai#image-models) | `gpt-image-1` | 1024x1024, 1536x1024, 1024x1536 |
291
+ | [OpenAI](/providers/ai-sdk-providers/openai#image-models) | `gpt-image-2` | 1024x1024, 1536x1024, 1024x1536 |
292
292
  | [OpenAI](/providers/ai-sdk-providers/openai#image-models) | `dall-e-3` | 1024x1024, 1792x1024, 1024x1792 |
293
293
  | [OpenAI](/providers/ai-sdk-providers/openai#image-models) | `dall-e-2` | 256x256, 512x512, 1024x1024 |
294
294
  | [Amazon Bedrock](/providers/ai-sdk-providers/amazon-bedrock#image-models) | `amazon.nova-canvas-v1:0` | 320-4096 (multiples of 16), 1:4 to 4:1, max 4.2M pixels |
@@ -261,6 +261,81 @@ default working directory and is used as the session working directory. When
261
261
  omitted, regular sessions use the default `<harnessId>-<sessionId>` directory,
262
262
  while `onBootstrap` receives the sandbox's default working directory.
263
263
 
264
+ ## Prepare Reusable Sandboxes
265
+
266
+ Use `prepareHarnessSandboxTemplate()` when you want the sandbox provider to
267
+ create or refresh its reusable template for one harness ahead of time:
268
+
269
+ ```ts
270
+ import { prepareHarnessSandboxTemplate } from '@ai-sdk/harness/agent';
271
+
272
+ await prepareHarnessSandboxTemplate({
273
+ harness: claudeCode,
274
+ sandboxProvider: createVercelSandbox({
275
+ runtime: 'node24',
276
+ ports: [4000],
277
+ }),
278
+ sandboxConfig: {
279
+ bootstrapHash: 'ripgrep-v1',
280
+ onBootstrap: async ({ session, abortSignal }) => {
281
+ await session.run({
282
+ command:
283
+ 'command -v rg >/dev/null || (apt-get update && apt-get install -y ripgrep)',
284
+ abortSignal,
285
+ });
286
+ },
287
+ },
288
+ });
289
+ ```
290
+
291
+ Use `prepareSandboxForHarness()` when you own the native sandbox lifecycle and
292
+ want to snapshot the prepared sandbox yourself. It applies the selected harness
293
+ bootstrap recipes and `sandboxConfig.onBootstrap`, then returns preparation
294
+ metadata. It does not stop or snapshot the sandbox.
295
+
296
+ ```ts
297
+ import { HarnessAgent, prepareSandboxForHarness } from '@ai-sdk/harness/agent';
298
+ import { createVercelSandbox } from '@ai-sdk/sandbox-vercel';
299
+ import { Sandbox } from '@vercel/sandbox';
300
+
301
+ const nativeSandbox = await Sandbox.create({
302
+ runtime: 'node24',
303
+ ports: [4000],
304
+ });
305
+ const sandboxProvider = createVercelSandbox({ sandbox: nativeSandbox });
306
+ const session = await sandboxProvider.createSession();
307
+
308
+ const preparation = await prepareSandboxForHarness({
309
+ session: session.restricted(),
310
+ harnesses: [claudeCode, codex],
311
+ sandboxConfig,
312
+ });
313
+
314
+ const { snapshot } = await nativeSandbox.stop();
315
+ if (snapshot == null) {
316
+ throw new Error('Prepared sandbox did not create a snapshot.');
317
+ }
318
+
319
+ const sandboxFromSnapshot = await Sandbox.create({
320
+ source: {
321
+ type: 'snapshot',
322
+ snapshotId: snapshot.id,
323
+ },
324
+ ports: [4000],
325
+ });
326
+
327
+ const agent = new HarnessAgent({
328
+ harness: claudeCode,
329
+ sandbox: createVercelSandbox({
330
+ sandbox: sandboxFromSnapshot,
331
+ bridgePorts: [4000],
332
+ }),
333
+ sandboxConfig,
334
+ });
335
+
336
+ console.log(preparation.identity);
337
+ ```
338
+
264
339
  ## Settings
265
340
 
266
341
  `HarnessAgent` accepts these main settings:
@@ -92,7 +92,7 @@ export async function POST(req: Request) {
92
92
  const result = streamText({
93
93
  model: __MODEL__,
94
94
  messages: await convertToModelMessages(messages),
95
- onFinish() {
95
+ onEnd() {
96
96
  // 4. Update the same data part (reconciliation)
97
97
  writer.write({
98
98
  type: 'data-weather',
@@ -489,7 +489,7 @@ export const AI = createAI({
489
489
 
490
490
  #### After: Save chats using callback function of `streamText`
491
491
 
492
- With AI SDK UI, you will save chats using the `onFinish` callback function of `streamText` in your route handler.
492
+ With AI SDK UI, you will save chats using the `onEnd` callback function of `streamText` in your route handler.
493
493
 
494
494
  ```ts filename="@/app/api/chat/route.ts"
495
495
  import { openai } from '@ai-sdk/openai';
@@ -510,7 +510,7 @@ export async function POST(request) {
510
510
  model: __MODEL__,
511
511
  instructions: 'you are a friendly assistant!',
512
512
  messages: coreMessages,
513
- onFinish: async ({ responseMessages }) => {
513
+ onEnd: async ({ responseMessages }) => {
514
514
  try {
515
515
  await saveChat({
516
516
  id,
@@ -82,7 +82,7 @@ export default function Chat() {
82
82
 
83
83
  When streams are aborted, you may need to perform cleanup operations such as persisting partial results or cleaning up resources. The `onAbort` callback provides a way to handle these scenarios on the server side.
84
84
 
85
- Unlike `onFinish`, which is called when a stream completes normally, `onAbort` is specifically called when a stream is aborted via `AbortSignal`. This distinction allows you to handle normal completion and aborted streams differently.
85
+ Unlike `onEnd`, which is called when a stream completes normally, `onAbort` is specifically called when a stream is aborted via `AbortSignal`. This distinction allows you to handle normal completion and aborted streams differently.
86
86
 
87
87
  <Note>
88
88
  For UI message streams (`toUIMessageStreamResponse`), the `onEnd` callback
@@ -104,7 +104,7 @@ const result = streamText({
104
104
  await savePartialResults(steps);
105
105
  await logAbortEvent(steps.length);
106
106
  },
107
- onFinish: ({ steps, totalUsage }) => {
107
+ onEnd: ({ steps, totalUsage }) => {
108
108
  // Called when stream completes normally
109
109
  await saveFinalResults(steps, totalUsage);
110
110
  },
@@ -118,7 +118,7 @@ You can see a full example of caching with Redis in a Next.js application in our
118
118
 
119
119
  ## Using Lifecycle Callbacks
120
120
 
121
- Alternatively, each AI SDK Core function has special lifecycle callbacks you can use. The one of interest is likely `onFinish`, which is called when the generation is complete. This is where you can cache the full response.
121
+ Alternatively, each AI SDK Core function has special lifecycle callbacks you can use. The one of interest is likely `onEnd`, which is called when the generation is complete. This is where you can cache the full response.
122
122
 
123
123
  Here's an example of how you can implement caching using Vercel KV and Next.js to cache the OpenAI response for 1 hour:
124
124
 
@@ -162,7 +162,7 @@ export async function POST(req: Request) {
162
162
  const result = streamText({
163
163
  model: __MODEL__,
164
164
  messages: await convertToModelMessages(messages),
165
- async onFinish({ text }) {
165
+ async onEnd({ text }) {
166
166
  // Cache the response text:
167
167
  await redis.set(key, text);
168
168
  await redis.expire(key, 60 * 60);
@@ -10,6 +10,7 @@ Creates a lightweight Model Context Protocol (MCP) client that connects to an MC
10
10
  - **Tools**: Automatic conversion between MCP tools and AI SDK tools
11
11
  - **Resources**: Methods to list, read, and discover resource templates from MCP servers
12
12
  - **Prompts**: Methods to list available prompts and retrieve prompt messages
13
+ - **Completions**: Methods to request autocompletion suggestions for prompt arguments and resource template variables
13
14
  - **Elicitation**: Support for handling server requests for additional input during tool execution
14
15
 
15
16
  It currently does not support accepting notifications from an MCP server, and custom configuration of the client.
@@ -86,7 +87,7 @@ It currently does not support accepting notifications from an MCP server, and cu
86
87
  parameters: [
87
88
  {
88
89
  name: 'type',
89
- type: "'sse' | 'http",
90
+ type: "'sse' | 'http'",
90
91
  description: 'Use Server-Sent Events for communication',
91
92
  },
92
93
  {
@@ -115,6 +116,48 @@ It currently does not support accepting notifications from an MCP server, and cu
115
116
  description:
116
117
  "Controls how HTTP redirects are handled for transport requests. Set to 'follow' to allow redirect responses. Defaults to 'error' to reject any redirect response, preventing servers from redirecting requests to unintended hosts.",
117
118
  },
119
+ {
120
+ name: 'initialSessionId',
121
+ type: 'string',
122
+ isOptional: true,
123
+ description:
124
+ 'Initial MCP session id to send with resumed Streamable HTTP requests after initialization. Pair with initialInitializeResult when using createMCPClient. Only used by the HTTP transport.',
125
+ },
126
+ {
127
+ name: 'initialProtocolVersion',
128
+ type: 'string',
129
+ isOptional: true,
130
+ description:
131
+ 'Initial MCP protocol version to send before initialize negotiates one. Only used by the HTTP transport.',
132
+ },
133
+ {
134
+ name: 'onSessionIdChange',
135
+ type: '(sessionId: string | undefined) => void',
136
+ isOptional: true,
137
+ description:
138
+ 'Callback invoked when the Streamable HTTP server creates, changes, or clears the MCP session id. Only used by the HTTP transport.',
139
+ },
140
+ {
141
+ name: 'onSessionExpired',
142
+ type: '(sessionId: string) => void',
143
+ isOptional: true,
144
+ description:
145
+ 'Callback invoked when a Streamable HTTP request returns 404 for an existing MCP session id. The transport clears the session id before reporting the underlying HTTP error. Only used by the HTTP transport.',
146
+ },
147
+ {
148
+ name: 'terminateSessionOnClose',
149
+ type: 'boolean',
150
+ isOptional: true,
151
+ description:
152
+ 'Whether close() should send DELETE for the current MCP session id. Set to false when the application intends to reattach to the session later. Defaults to true. Only used by the HTTP transport.',
153
+ },
154
+ {
155
+ name: 'fetch',
156
+ type: 'FetchFunction',
157
+ isOptional: true,
158
+ description:
159
+ 'Optional custom fetch implementation to use for HTTP requests. Useful for runtimes that need a request-local fetch.',
160
+ },
118
161
  ],
119
162
  },
120
163
  ],
@@ -144,6 +187,13 @@ It currently does not support accepting notifications from an MCP server, and cu
144
187
  isOptional: true,
145
188
  description: 'Handler for uncaught errors',
146
189
  },
190
+ {
191
+ name: 'initialInitializeResult',
192
+ type: 'InitializeResult',
193
+ isOptional: true,
194
+ description:
195
+ 'Initialize result from a previous MCP session. When provided, the client starts the transport and reuses this metadata without sending a new initialize request.',
196
+ },
147
197
  {
148
198
  name: 'capabilities',
149
199
  type: 'ClientCapabilities',
@@ -164,6 +214,12 @@ Returns a Promise that resolves to an `MCPClient` with the following properties
164
214
 
165
215
  <PropertiesTable
166
216
  content={[
217
+ {
218
+ name: 'initializeResult',
219
+ type: 'InitializeResult',
220
+ description:
221
+ 'The full initialize result used by this client, either from the server during initialization or from initialInitializeResult.',
222
+ },
167
223
  {
168
224
  name: 'serverInfo',
169
225
  type: 'Configuration',
@@ -385,6 +441,47 @@ Returns a Promise that resolves to an `MCPClient` with the following properties
385
441
  },
386
442
  ],
387
443
  },
444
+ {
445
+ name: 'complete',
446
+ type: `async (args: CompleteRequestParams & {
447
+ options?: RequestOptions;
448
+ }) => Promise<CompleteResult>`,
449
+ description:
450
+ 'Requests autocompletion suggestions for a prompt argument or resource template variable. The server must advertise the completions capability.',
451
+ properties: [
452
+ {
453
+ type: 'args',
454
+ parameters: [
455
+ {
456
+ name: 'ref',
457
+ type: "{ type: 'ref/prompt'; name: string } | { type: 'ref/resource'; uri: string }",
458
+ description:
459
+ 'Reference to the prompt or resource template being completed.',
460
+ },
461
+ {
462
+ name: 'argument',
463
+ type: '{ name: string; value: string }',
464
+ description:
465
+ 'Argument name and current partial value to complete.',
466
+ },
467
+ {
468
+ name: 'context',
469
+ type: '{ arguments: Record<string, string> }',
470
+ isOptional: true,
471
+ description:
472
+ 'Previously resolved argument values used to provide context for multi-argument prompts or resource templates.',
473
+ },
474
+ {
475
+ name: 'options',
476
+ type: 'RequestOptions',
477
+ isOptional: true,
478
+ description:
479
+ 'Optional request options including signal and timeout.',
480
+ },
481
+ ],
482
+ },
483
+ ],
484
+ },
388
485
  {
389
486
  name: 'experimental_listPrompts',
390
487
  type: `async (options?: {
@@ -13,7 +13,7 @@ import { generateImage, wrapImageModel } from 'ai';
13
13
  import { openai } from '@ai-sdk/openai';
14
14
 
15
15
  const model = wrapImageModel({
16
- model: openai.image('gpt-image-1'),
16
+ model: openai.image('gpt-image-2'),
17
17
  middleware: yourImageModelMiddleware,
18
18
  });
19
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "7.0.2",
3
+ "version": "7.0.4",
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.2",
45
+ "@ai-sdk/gateway": "4.0.4",
46
46
  "@ai-sdk/provider": "4.0.0",
47
- "@ai-sdk/provider-utils": "5.0.0"
47
+ "@ai-sdk/provider-utils": "5.0.1"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@edge-runtime/vm": "^5.0.0",