ai 6.0.272 → 6.0.274

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.
@@ -164,7 +164,7 @@ function detectMediaType({
164
164
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
165
165
 
166
166
  // src/version.ts
167
- var VERSION = true ? "6.0.272" : "0.0.0-test";
167
+ var VERSION = true ? "6.0.274" : "0.0.0-test";
168
168
 
169
169
  // src/util/download/download.ts
170
170
  var download = async ({
@@ -144,7 +144,7 @@ import {
144
144
  } from "@ai-sdk/provider-utils";
145
145
 
146
146
  // src/version.ts
147
- var VERSION = true ? "6.0.272" : "0.0.0-test";
147
+ var VERSION = true ? "6.0.274" : "0.0.0-test";
148
148
 
149
149
  // src/util/download/download.ts
150
150
  var download = async ({
@@ -480,6 +480,13 @@ export default function Chat() {
480
480
  }
481
481
  ```
482
482
 
483
+ Approval request chunks can also include an `approvalDescriptor` with opaque
484
+ application-specific metadata. UI message processing exposes it as
485
+ `part.approval.descriptor` in the `approval-requested` state and preserves it in
486
+ the `approval-responded` state after `addToolApprovalResponse` is called. This
487
+ lets clients render or persist server-computed approval metadata without using
488
+ it to determine whether the tool was approved.
489
+
483
490
  ### Auto-Submit After Approval
484
491
 
485
492
  <Note>
@@ -324,6 +324,24 @@ data: {"type":"tool-input-available","toolCallId":"call_fJdQDqnXeGxTmr4E3YPSR7Ar
324
324
 
325
325
  ```
326
326
 
327
+ ### Tool Approval Request Part
328
+
329
+ Indicates that a tool call requires approval.
330
+
331
+ Format: Server-Sent Event with JSON object
332
+
333
+ Example:
334
+
335
+ ```
336
+ data: {"type":"tool-approval-request","toolCallId":"call_fJdQDqnXeGxTmr4E3YPSR7Ar","approvalId":"approval_123","approvalDescriptor":{"scope":"account:delete"}}
337
+
338
+ ```
339
+
340
+ `approvalDescriptor` is optional opaque metadata for the approval. When the
341
+ stream is processed into UI messages, it is available as
342
+ `part.approval.descriptor` and is retained when the client records an approval
343
+ response.
344
+
327
345
  ### Tool Output Available Part
328
346
 
329
347
  Contains the result of tool execution.
@@ -1450,6 +1450,13 @@ To see `streamText` in action, check out [these examples](#examples).
1450
1450
  description:
1451
1451
  'The raw reason why the generation finished (from the provider).',
1452
1452
  },
1453
+ {
1454
+ name: 'output',
1455
+ type: 'COMPLETE_OUTPUT | undefined',
1456
+ isOptional: true,
1457
+ description:
1458
+ 'The parsed output when an output setting was provided and parsing succeeded.',
1459
+ },
1453
1460
  {
1454
1461
  name: 'usage',
1455
1462
  type: 'LanguageModelUsage',
@@ -150,6 +150,32 @@ type ToolUIPart<TOOLS extends UITools = UITools> = ValueOf<{
150
150
  output?: never;
151
151
  errorText?: never;
152
152
  }
153
+ | {
154
+ state: 'approval-requested';
155
+ input: TOOLS[NAME]['input'];
156
+ output?: never;
157
+ errorText?: never;
158
+ approval: {
159
+ id: string;
160
+ approved?: never;
161
+ descriptor?: unknown;
162
+ reason?: never;
163
+ signature?: string;
164
+ };
165
+ }
166
+ | {
167
+ state: 'approval-responded';
168
+ input: TOOLS[NAME]['input'];
169
+ output?: never;
170
+ errorText?: never;
171
+ approval: {
172
+ id: string;
173
+ approved: boolean;
174
+ descriptor?: unknown;
175
+ reason?: string;
176
+ signature?: string;
177
+ };
178
+ }
153
179
  | {
154
180
  state: 'output-available';
155
181
  input: TOOLS[NAME]['input'];
@@ -168,6 +194,11 @@ type ToolUIPart<TOOLS extends UITools = UITools> = ValueOf<{
168
194
  }>;
169
195
  ```
170
196
 
197
+ `approval.descriptor` contains optional opaque metadata supplied as
198
+ `approvalDescriptor` on the approval request stream chunk. It is preserved when
199
+ the client transitions the tool part from `approval-requested` to
200
+ `approval-responded`, and in later approval-bearing output states.
201
+
171
202
  ### `SourceUrlUIPart`
172
203
 
173
204
  A source URL part of a message.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "6.0.272",
3
+ "version": "6.0.274",
4
4
  "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.",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@opentelemetry/api": "^1.9.0",
48
- "@ai-sdk/gateway": "3.0.185",
48
+ "@ai-sdk/gateway": "3.0.186",
49
49
  "@ai-sdk/provider": "3.0.15",
50
50
  "@ai-sdk/provider-utils": "4.0.50"
51
51
  },
@@ -33,7 +33,9 @@ export {
33
33
  } from './stop-condition';
34
34
  export {
35
35
  streamText,
36
+ type StreamTextEndEvent,
36
37
  type StreamTextOnChunkCallback,
38
+ type StreamTextOnEndCallback,
37
39
  type StreamTextOnErrorCallback,
38
40
  type StreamTextOnFinishCallback,
39
41
  type StreamTextOnStartCallback,
@@ -214,14 +214,31 @@ export type StreamTextOnChunkCallback<TOOLS extends ToolSet> = (event: {
214
214
  >;
215
215
  }) => PromiseLike<void> | void;
216
216
 
217
+ export type StreamTextEndEvent<
218
+ TOOLS extends ToolSet = ToolSet,
219
+ OUTPUT extends Output = Output,
220
+ > = OnFinishEvent<TOOLS> & {
221
+ /**
222
+ * The parsed output when an output setting was provided and parsing
223
+ * succeeded.
224
+ */
225
+ readonly output?: InferCompleteOutput<OUTPUT>;
226
+ };
227
+
228
+ export type StreamTextOnEndCallback<
229
+ TOOLS extends ToolSet = ToolSet,
230
+ OUTPUT extends Output = Output,
231
+ > = (event: StreamTextEndEvent<TOOLS, OUTPUT>) => PromiseLike<void> | void;
232
+
217
233
  /**
218
234
  * Callback that is set using the `onFinish` option.
219
235
  *
220
236
  * @param event - The event that is passed to the callback.
221
237
  */
222
- export type StreamTextOnFinishCallback<TOOLS extends ToolSet> = (
223
- event: OnFinishEvent<TOOLS>,
224
- ) => PromiseLike<void> | void;
238
+ export type StreamTextOnFinishCallback<
239
+ TOOLS extends ToolSet = ToolSet,
240
+ OUTPUT extends Output = Output,
241
+ > = StreamTextOnEndCallback<TOOLS, OUTPUT>;
225
242
 
226
243
  /**
227
244
  * Callback that is set using the `onAbort` option.
@@ -492,7 +509,7 @@ export function streamText<
492
509
  *
493
510
  * The usage is the combined usage of all steps.
494
511
  */
495
- onFinish?: StreamTextOnFinishCallback<TOOLS>;
512
+ onFinish?: StreamTextOnFinishCallback<NoInfer<TOOLS>, NoInfer<OUTPUT>>;
496
513
 
497
514
  onAbort?: StreamTextOnAbortCallback<TOOLS>;
498
515
 
@@ -758,6 +775,8 @@ class DefaultStreamTextResult<
758
775
  Awaited<StreamTextResult<TOOLS, OUTPUT>['steps']>
759
776
  >();
760
777
 
778
+ private outputPromise: Promise<InferCompleteOutput<OUTPUT>> | undefined;
779
+
761
780
  private readonly addStream: (
762
781
  stream: ReadableStream<TextStreamPart<TOOLS>>,
763
782
  callbacks?: {
@@ -862,7 +881,9 @@ class DefaultStreamTextResult<
862
881
  // callbacks:
863
882
  onChunk: undefined | StreamTextOnChunkCallback<TOOLS>;
864
883
  onError: StreamTextOnErrorCallback;
865
- onFinish: undefined | StreamTextOnFinishCallback<TOOLS>;
884
+ onFinish:
885
+ | undefined
886
+ | StreamTextOnFinishCallback<NoInfer<TOOLS>, NoInfer<OUTPUT>>;
866
887
  onAbort: undefined | StreamTextOnAbortCallback<TOOLS>;
867
888
  onStepFinish: undefined | StreamTextOnStepFinishCallback<TOOLS>;
868
889
  onStart: undefined | StreamTextOnStartCallback<TOOLS, OUTPUT>;
@@ -1211,43 +1232,61 @@ class DefaultStreamTextResult<
1211
1232
 
1212
1233
  // call onFinish callback:
1213
1234
  const finalStep = recordedSteps[recordedSteps.length - 1];
1214
-
1215
- await notify({
1216
- event: {
1217
- stepNumber: finalStep.stepNumber,
1218
- model: finalStep.model,
1219
- functionId: finalStep.functionId,
1220
- metadata: finalStep.metadata,
1221
- experimental_context: finalStep.experimental_context,
1222
- finishReason: finalStep.finishReason,
1223
- rawFinishReason: finalStep.rawFinishReason,
1224
- totalUsage,
1225
- usage: finalStep.usage,
1226
- content: finalStep.content,
1227
- text: finalStep.text,
1228
- reasoningText: finalStep.reasoningText,
1229
- reasoning: finalStep.reasoning,
1230
- files: finalStep.files,
1231
- sources: finalStep.sources,
1232
- toolCalls: finalStep.toolCalls,
1233
- staticToolCalls: finalStep.staticToolCalls,
1234
- dynamicToolCalls: finalStep.dynamicToolCalls,
1235
- toolResults: finalStep.toolResults,
1236
- staticToolResults: finalStep.staticToolResults,
1237
- dynamicToolResults: finalStep.dynamicToolResults,
1238
- request: finalStep.request,
1239
- response: finalStep.response,
1240
- warnings: finalStep.warnings,
1241
- providerMetadata: finalStep.providerMetadata,
1242
- steps: recordedSteps,
1243
- },
1244
- callbacks: [
1245
- onFinish,
1246
- globalTelemetry.onFinish as
1235
+ const onFinishEvent: OnFinishEvent<TOOLS> = {
1236
+ stepNumber: finalStep.stepNumber,
1237
+ model: finalStep.model,
1238
+ functionId: finalStep.functionId,
1239
+ metadata: finalStep.metadata,
1240
+ experimental_context: finalStep.experimental_context,
1241
+ finishReason: finalStep.finishReason,
1242
+ rawFinishReason: finalStep.rawFinishReason,
1243
+ totalUsage,
1244
+ usage: finalStep.usage,
1245
+ content: finalStep.content,
1246
+ text: finalStep.text,
1247
+ reasoningText: finalStep.reasoningText,
1248
+ reasoning: finalStep.reasoning,
1249
+ files: finalStep.files,
1250
+ sources: finalStep.sources,
1251
+ toolCalls: finalStep.toolCalls,
1252
+ staticToolCalls: finalStep.staticToolCalls,
1253
+ dynamicToolCalls: finalStep.dynamicToolCalls,
1254
+ toolResults: finalStep.toolResults,
1255
+ staticToolResults: finalStep.staticToolResults,
1256
+ dynamicToolResults: finalStep.dynamicToolResults,
1257
+ request: finalStep.request,
1258
+ response: finalStep.response,
1259
+ warnings: finalStep.warnings,
1260
+ providerMetadata: finalStep.providerMetadata,
1261
+ steps: recordedSteps,
1262
+ };
1263
+ const onFinishWithOutput =
1264
+ onFinish == null
1265
+ ? undefined
1266
+ : async (event: OnFinishEvent<TOOLS>) => {
1267
+ const parsedOutput =
1268
+ output == null
1269
+ ? undefined
1270
+ : await self.getOutputPromise().catch(() => undefined);
1271
+
1272
+ await onFinish({
1273
+ ...event,
1274
+ ...(output != null ? { output: parsedOutput } : {}),
1275
+ });
1276
+ };
1277
+
1278
+ await Promise.all([
1279
+ notify({
1280
+ event: onFinishEvent,
1281
+ callbacks: onFinishWithOutput,
1282
+ }),
1283
+ notify({
1284
+ event: onFinishEvent,
1285
+ callbacks: globalTelemetry.onFinish as
1247
1286
  | undefined
1248
- | StreamTextOnFinishCallback<TOOLS>,
1249
- ],
1250
- });
1287
+ | ((event: OnFinishEvent<TOOLS>) => PromiseLike<void> | void),
1288
+ }),
1289
+ ]);
1251
1290
 
1252
1291
  // Add response information to the root span:
1253
1292
  rootSpan.setAttributes(
@@ -2634,18 +2673,26 @@ class DefaultStreamTextResult<
2634
2673
  return createAsyncIterableStream(this.teeStream().pipeThrough(transform));
2635
2674
  }
2636
2675
 
2676
+ private getOutputPromise(): Promise<InferCompleteOutput<OUTPUT>> {
2677
+ if (this.outputPromise == null) {
2678
+ this.outputPromise = this.finalStep.then(step => {
2679
+ const output = this.outputSpecification ?? text();
2680
+ return output.parseCompleteOutput(
2681
+ { text: step.text },
2682
+ {
2683
+ response: step.response,
2684
+ usage: step.usage,
2685
+ finishReason: step.finishReason,
2686
+ },
2687
+ );
2688
+ });
2689
+ }
2690
+
2691
+ return this.outputPromise;
2692
+ }
2693
+
2637
2694
  get output(): Promise<InferCompleteOutput<OUTPUT>> {
2638
- return this.finalStep.then(step => {
2639
- const output = this.outputSpecification ?? text();
2640
- return output.parseCompleteOutput(
2641
- { text: step.text },
2642
- {
2643
- response: step.response,
2644
- usage: step.usage,
2645
- finishReason: step.finishReason,
2646
- },
2647
- );
2648
- });
2695
+ return this.getOutputPromise();
2649
2696
  }
2650
2697
 
2651
2698
  toUIMessageStream<UI_MESSAGE extends UIMessage>({
@@ -718,6 +718,9 @@ export function processUIMessageStream<UI_MESSAGE extends UIMessage>({
718
718
  toolInvocation.state = 'approval-requested';
719
719
  toolInvocation.approval = {
720
720
  id: chunk.approvalId,
721
+ ...(chunk.approvalDescriptor != null
722
+ ? { descriptor: chunk.approvalDescriptor }
723
+ : {}),
721
724
  ...(chunk.signature != null
722
725
  ? { signature: chunk.signature }
723
726
  : {}),
@@ -260,6 +260,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
260
260
  approval: {
261
261
  id: string;
262
262
  approved?: never;
263
+ descriptor?: unknown;
263
264
  reason?: never;
264
265
  signature?: string;
265
266
  };
@@ -273,6 +274,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
273
274
  approval: {
274
275
  id: string;
275
276
  approved: boolean;
277
+ descriptor?: unknown;
276
278
  reason?: string;
277
279
  signature?: string;
278
280
  };
@@ -288,6 +290,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
288
290
  approval?: {
289
291
  id: string;
290
292
  approved: true;
293
+ descriptor?: unknown;
291
294
  reason?: string;
292
295
  signature?: string;
293
296
  };
@@ -303,6 +306,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
303
306
  approval?: {
304
307
  id: string;
305
308
  approved: true;
309
+ descriptor?: unknown;
306
310
  reason?: string;
307
311
  signature?: string;
308
312
  };
@@ -316,6 +320,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
316
320
  approval: {
317
321
  id: string;
318
322
  approved: false;
323
+ descriptor?: unknown;
319
324
  reason?: string;
320
325
  signature?: string;
321
326
  };
@@ -373,6 +378,7 @@ export type DynamicToolUIPart = {
373
378
  approval: {
374
379
  id: string;
375
380
  approved?: never;
381
+ descriptor?: unknown;
376
382
  reason?: never;
377
383
  signature?: string;
378
384
  };
@@ -386,6 +392,7 @@ export type DynamicToolUIPart = {
386
392
  approval: {
387
393
  id: string;
388
394
  approved: boolean;
395
+ descriptor?: unknown;
389
396
  reason?: string;
390
397
  signature?: string;
391
398
  };
@@ -401,6 +408,7 @@ export type DynamicToolUIPart = {
401
408
  approval?: {
402
409
  id: string;
403
410
  approved: true;
411
+ descriptor?: unknown;
404
412
  reason?: string;
405
413
  signature?: string;
406
414
  };
@@ -415,6 +423,7 @@ export type DynamicToolUIPart = {
415
423
  approval?: {
416
424
  id: string;
417
425
  approved: true;
426
+ descriptor?: unknown;
418
427
  reason?: string;
419
428
  signature?: string;
420
429
  };
@@ -428,6 +437,7 @@ export type DynamicToolUIPart = {
428
437
  approval: {
429
438
  id: string;
430
439
  approved: false;
440
+ descriptor?: unknown;
431
441
  reason?: string;
432
442
  signature?: string;
433
443
  };
@@ -143,6 +143,7 @@ const uiMessagesSchema = lazySchema(() =>
143
143
  approval: z.object({
144
144
  id: z.string(),
145
145
  approved: z.never().optional(),
146
+ descriptor: z.unknown().optional(),
146
147
  reason: z.never().optional(),
147
148
  signature: z.string().optional(),
148
149
  }),
@@ -161,6 +162,7 @@ const uiMessagesSchema = lazySchema(() =>
161
162
  approval: z.object({
162
163
  id: z.string(),
163
164
  approved: z.boolean(),
165
+ descriptor: z.unknown().optional(),
164
166
  reason: z.string().optional(),
165
167
  signature: z.string().optional(),
166
168
  }),
@@ -182,6 +184,7 @@ const uiMessagesSchema = lazySchema(() =>
182
184
  .object({
183
185
  id: z.string(),
184
186
  approved: z.literal(true),
187
+ descriptor: z.unknown().optional(),
185
188
  reason: z.string().optional(),
186
189
  signature: z.string().optional(),
187
190
  })
@@ -204,6 +207,7 @@ const uiMessagesSchema = lazySchema(() =>
204
207
  .object({
205
208
  id: z.string(),
206
209
  approved: z.literal(true),
210
+ descriptor: z.unknown().optional(),
207
211
  reason: z.string().optional(),
208
212
  signature: z.string().optional(),
209
213
  })
@@ -223,6 +227,7 @@ const uiMessagesSchema = lazySchema(() =>
223
227
  approval: z.object({
224
228
  id: z.string(),
225
229
  approved: z.literal(false),
230
+ descriptor: z.unknown().optional(),
226
231
  reason: z.string().optional(),
227
232
  signature: z.string().optional(),
228
233
  }),
@@ -264,6 +269,7 @@ const uiMessagesSchema = lazySchema(() =>
264
269
  approval: z.object({
265
270
  id: z.string(),
266
271
  approved: z.never().optional(),
272
+ descriptor: z.unknown().optional(),
267
273
  reason: z.never().optional(),
268
274
  signature: z.string().optional(),
269
275
  }),
@@ -281,6 +287,7 @@ const uiMessagesSchema = lazySchema(() =>
281
287
  approval: z.object({
282
288
  id: z.string(),
283
289
  approved: z.boolean(),
290
+ descriptor: z.unknown().optional(),
284
291
  reason: z.string().optional(),
285
292
  signature: z.string().optional(),
286
293
  }),
@@ -301,6 +308,7 @@ const uiMessagesSchema = lazySchema(() =>
301
308
  .object({
302
309
  id: z.string(),
303
310
  approved: z.literal(true),
311
+ descriptor: z.unknown().optional(),
304
312
  reason: z.string().optional(),
305
313
  signature: z.string().optional(),
306
314
  })
@@ -322,6 +330,7 @@ const uiMessagesSchema = lazySchema(() =>
322
330
  .object({
323
331
  id: z.string(),
324
332
  approved: z.literal(true),
333
+ descriptor: z.unknown().optional(),
325
334
  reason: z.string().optional(),
326
335
  signature: z.string().optional(),
327
336
  })
@@ -340,6 +349,7 @@ const uiMessagesSchema = lazySchema(() =>
340
349
  approval: z.object({
341
350
  id: z.string(),
342
351
  approved: z.literal(false),
352
+ descriptor: z.unknown().optional(),
343
353
  reason: z.string().optional(),
344
354
  signature: z.string().optional(),
345
355
  }),
@@ -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
+ approvalDescriptor: z.unknown().optional(),
88
89
  signature: z.string().optional(),
89
90
  }),
90
91
  z.looseObject({
@@ -270,6 +271,7 @@ export type UIMessageChunk<
270
271
  type: 'tool-approval-request';
271
272
  approvalId: string;
272
273
  toolCallId: string;
274
+ approvalDescriptor?: unknown;
273
275
  signature?: string;
274
276
  }
275
277
  | {