ai 6.0.201 → 6.0.203

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/index.d.mts +61 -15
  3. package/dist/index.d.ts +61 -15
  4. package/dist/index.js +853 -592
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +695 -430
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/internal/index.js +10 -12
  9. package/dist/internal/index.js.map +1 -1
  10. package/dist/internal/index.mjs +11 -13
  11. package/dist/internal/index.mjs.map +1 -1
  12. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +32 -0
  13. package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +20 -2
  14. package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +1 -1
  15. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-tool-approval-signature-error.mdx +31 -0
  16. package/package.json +3 -3
  17. package/src/error/index.ts +1 -0
  18. package/src/error/invalid-tool-approval-signature-error.ts +35 -0
  19. package/src/generate-text/generate-text.ts +48 -6
  20. package/src/generate-text/run-tools-transformation.ts +14 -1
  21. package/src/generate-text/stream-text.ts +47 -11
  22. package/src/generate-text/to-response-messages.ts +1 -0
  23. package/src/generate-text/tool-approval-request-output.ts +5 -0
  24. package/src/generate-text/tool-approval-signature.ts +125 -0
  25. package/src/generate-text/validate-tool-approvals.ts +124 -0
  26. package/src/middleware/extract-json-middleware.ts +2 -1
  27. package/src/middleware/extract-reasoning-middleware.ts +2 -1
  28. package/src/ui/convert-to-model-messages.ts +3 -0
  29. package/src/ui/process-ui-message-stream.ts +6 -1
  30. package/src/ui/ui-messages.ts +10 -0
  31. package/src/ui/validate-ui-messages.ts +10 -0
  32. package/src/ui-message-stream/create-ui-message-stream.ts +2 -3
  33. package/src/ui-message-stream/ui-message-chunks.ts +2 -0
  34. package/src/util/download/download.ts +11 -14
@@ -256,6 +256,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
256
256
  id: string;
257
257
  approved?: never;
258
258
  reason?: never;
259
+ signature?: string;
259
260
  };
260
261
  }
261
262
  | {
@@ -268,6 +269,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
268
269
  id: string;
269
270
  approved: boolean;
270
271
  reason?: string;
272
+ signature?: string;
271
273
  };
272
274
  }
273
275
  | {
@@ -282,6 +284,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
282
284
  id: string;
283
285
  approved: true;
284
286
  reason?: string;
287
+ signature?: string;
285
288
  };
286
289
  }
287
290
  | {
@@ -296,6 +299,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
296
299
  id: string;
297
300
  approved: true;
298
301
  reason?: string;
302
+ signature?: string;
299
303
  };
300
304
  }
301
305
  | {
@@ -308,6 +312,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
308
312
  id: string;
309
313
  approved: false;
310
314
  reason?: string;
315
+ signature?: string;
311
316
  };
312
317
  }
313
318
  );
@@ -364,6 +369,7 @@ export type DynamicToolUIPart = {
364
369
  id: string;
365
370
  approved?: never;
366
371
  reason?: never;
372
+ signature?: string;
367
373
  };
368
374
  }
369
375
  | {
@@ -376,6 +382,7 @@ export type DynamicToolUIPart = {
376
382
  id: string;
377
383
  approved: boolean;
378
384
  reason?: string;
385
+ signature?: string;
379
386
  };
380
387
  }
381
388
  | {
@@ -390,6 +397,7 @@ export type DynamicToolUIPart = {
390
397
  id: string;
391
398
  approved: true;
392
399
  reason?: string;
400
+ signature?: string;
393
401
  };
394
402
  }
395
403
  | {
@@ -403,6 +411,7 @@ export type DynamicToolUIPart = {
403
411
  id: string;
404
412
  approved: true;
405
413
  reason?: string;
414
+ signature?: string;
406
415
  };
407
416
  }
408
417
  | {
@@ -415,6 +424,7 @@ export type DynamicToolUIPart = {
415
424
  id: string;
416
425
  approved: false;
417
426
  reason?: string;
427
+ signature?: string;
418
428
  };
419
429
  }
420
430
  );
@@ -122,6 +122,7 @@ const uiMessagesSchema = lazySchema(() =>
122
122
  id: z.string(),
123
123
  approved: z.never().optional(),
124
124
  reason: z.never().optional(),
125
+ signature: z.string().optional(),
125
126
  }),
126
127
  }),
127
128
  z.object({
@@ -139,6 +140,7 @@ const uiMessagesSchema = lazySchema(() =>
139
140
  id: z.string(),
140
141
  approved: z.boolean(),
141
142
  reason: z.string().optional(),
143
+ signature: z.string().optional(),
142
144
  }),
143
145
  }),
144
146
  z.object({
@@ -159,6 +161,7 @@ const uiMessagesSchema = lazySchema(() =>
159
161
  id: z.string(),
160
162
  approved: z.literal(true),
161
163
  reason: z.string().optional(),
164
+ signature: z.string().optional(),
162
165
  })
163
166
  .optional(),
164
167
  }),
@@ -180,6 +183,7 @@ const uiMessagesSchema = lazySchema(() =>
180
183
  id: z.string(),
181
184
  approved: z.literal(true),
182
185
  reason: z.string().optional(),
186
+ signature: z.string().optional(),
183
187
  })
184
188
  .optional(),
185
189
  }),
@@ -198,6 +202,7 @@ const uiMessagesSchema = lazySchema(() =>
198
202
  id: z.string(),
199
203
  approved: z.literal(false),
200
204
  reason: z.string().optional(),
205
+ signature: z.string().optional(),
201
206
  }),
202
207
  }),
203
208
  z.object({
@@ -238,6 +243,7 @@ const uiMessagesSchema = lazySchema(() =>
238
243
  id: z.string(),
239
244
  approved: z.never().optional(),
240
245
  reason: z.never().optional(),
246
+ signature: z.string().optional(),
241
247
  }),
242
248
  }),
243
249
  z.object({
@@ -254,6 +260,7 @@ const uiMessagesSchema = lazySchema(() =>
254
260
  id: z.string(),
255
261
  approved: z.boolean(),
256
262
  reason: z.string().optional(),
263
+ signature: z.string().optional(),
257
264
  }),
258
265
  }),
259
266
  z.object({
@@ -273,6 +280,7 @@ const uiMessagesSchema = lazySchema(() =>
273
280
  id: z.string(),
274
281
  approved: z.literal(true),
275
282
  reason: z.string().optional(),
283
+ signature: z.string().optional(),
276
284
  })
277
285
  .optional(),
278
286
  }),
@@ -293,6 +301,7 @@ const uiMessagesSchema = lazySchema(() =>
293
301
  id: z.string(),
294
302
  approved: z.literal(true),
295
303
  reason: z.string().optional(),
304
+ signature: z.string().optional(),
296
305
  })
297
306
  .optional(),
298
307
  }),
@@ -310,6 +319,7 @@ const uiMessagesSchema = lazySchema(() =>
310
319
  id: z.string(),
311
320
  approved: z.literal(false),
312
321
  reason: z.string().optional(),
322
+ signature: z.string().optional(),
313
323
  }),
314
324
  }),
315
325
  ]),
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  generateId as generateIdFunc,
3
- getErrorMessage,
4
3
  type IdGenerator,
5
4
  } from '@ai-sdk/provider-utils';
6
5
  import type { UIMessage } from '../ui/ui-messages';
@@ -14,7 +13,7 @@ import type { UIMessageStreamWriter } from './ui-message-stream-writer';
14
13
  * Creates a UI message stream that can be used to send messages to the client.
15
14
  *
16
15
  * @param options.execute - A function that is called with a writer to write UI message chunks to the stream.
17
- * @param options.onError - A function that extracts an error message from an error. Defaults to `getErrorMessage`.
16
+ * @param options.onError - A function that extracts an error message from an error. Defaults to `() => 'An error occurred.'` so server-side error details are not leaked to the client; supply your own to surface richer messages.
18
17
  * @param options.originalMessages - The original messages. If provided, persistence mode is assumed
19
18
  * and a message ID is provided for the response message.
20
19
  * @param options.onStepFinish - A callback that is called when each step finishes. Useful for persisting intermediate messages.
@@ -25,7 +24,7 @@ import type { UIMessageStreamWriter } from './ui-message-stream-writer';
25
24
  */
26
25
  export function createUIMessageStream<UI_MESSAGE extends UIMessage>({
27
26
  execute,
28
- onError = getErrorMessage,
27
+ onError = () => 'An error occurred.', // prevent leaking server error details to the client by default
29
28
  originalMessages,
30
29
  onStepFinish,
31
30
  onFinish,
@@ -85,6 +85,7 @@ export const uiMessageChunkSchema = lazySchema(() =>
85
85
  type: z.literal('tool-approval-request'),
86
86
  approvalId: z.string(),
87
87
  toolCallId: z.string(),
88
+ signature: z.string().optional(),
88
89
  }),
89
90
  z.strictObject({
90
91
  type: z.literal('tool-output-available'),
@@ -269,6 +270,7 @@ export type UIMessageChunk<
269
270
  type: 'tool-approval-request';
270
271
  approvalId: string;
271
272
  toolCallId: string;
273
+ signature?: string;
272
274
  }
273
275
  | {
274
276
  type: 'tool-output-available';
@@ -2,7 +2,7 @@ import {
2
2
  DownloadError,
3
3
  readResponseWithSizeLimit,
4
4
  DEFAULT_MAX_DOWNLOAD_SIZE,
5
- validateDownloadUrl,
5
+ fetchWithValidatedRedirects,
6
6
  withUserAgentSuffix,
7
7
  getRuntimeEnvironmentUserAgent,
8
8
  } from '@ai-sdk/provider-utils';
@@ -28,21 +28,18 @@ export const download = async ({
28
28
  abortSignal?: AbortSignal;
29
29
  }) => {
30
30
  const urlText = url.toString();
31
- validateDownloadUrl(urlText);
32
31
  try {
33
- const response = await fetch(urlText, {
34
- headers: withUserAgentSuffix(
35
- {},
36
- `ai-sdk/${VERSION}`,
37
- getRuntimeEnvironmentUserAgent(),
38
- ),
39
- signal: abortSignal,
40
- });
32
+ const headers = withUserAgentSuffix(
33
+ {},
34
+ `ai-sdk/${VERSION}`,
35
+ getRuntimeEnvironmentUserAgent(),
36
+ );
41
37
 
42
- // Validate final URL after redirects to prevent SSRF via open redirect
43
- if (response.redirected) {
44
- validateDownloadUrl(response.url);
45
- }
38
+ const response = await fetchWithValidatedRedirects({
39
+ url: urlText,
40
+ headers,
41
+ abortSignal,
42
+ });
46
43
 
47
44
  if (!response.ok) {
48
45
  throw new DownloadError({