ai 6.0.92 → 6.0.93

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.
@@ -2,12 +2,14 @@ import {
2
2
  LanguageModelV3,
3
3
  LanguageModelV3Content,
4
4
  LanguageModelV3ToolCall,
5
+ LanguageModelV3ToolChoice,
5
6
  } from '@ai-sdk/provider';
6
7
  import {
7
8
  createIdGenerator,
8
9
  getErrorMessage,
9
10
  IdGenerator,
10
11
  ProviderOptions,
12
+ SystemModelMessage,
11
13
  ToolApprovalResponse,
12
14
  withUserAgentSuffix,
13
15
  } from '@ai-sdk/provider-utils';
@@ -20,6 +22,7 @@ import {
20
22
  CallSettings,
21
23
  getStepTimeoutMs,
22
24
  getTotalTimeoutMs,
25
+ TimeoutConfiguration,
23
26
  } from '../prompt/call-settings';
24
27
  import { convertToLanguageModelPrompt } from '../prompt/convert-to-language-model-prompt';
25
28
  import { createToolModelOutput } from '../prompt/create-tool-model-output';
@@ -85,9 +88,341 @@ const originalGenerateId = createIdGenerator({
85
88
  size: 24,
86
89
  });
87
90
 
91
+ /**
92
+ * Callback that is set using the `experimental_onStart` option.
93
+ *
94
+ * Called when the generateText operation begins, before any LLM calls.
95
+ * Use this callback for logging, analytics, or initializing state at the
96
+ * start of a generation.
97
+ *
98
+ * @param event - The event object containing generation configuration.
99
+ */
100
+ export type GenerateTextOnStartCallback<
101
+ TOOLS extends ToolSet = ToolSet,
102
+ OUTPUT extends Output = Output,
103
+ > = (event: {
104
+ /** The model being used for generation. */
105
+ readonly model: {
106
+ /** The provider identifier (e.g., 'openai', 'anthropic'). */
107
+ readonly provider: string;
108
+ /** The specific model identifier (e.g., 'gpt-4o'). */
109
+ readonly modelId: string;
110
+ };
111
+
112
+ /** The system message(s) provided to the model. */
113
+ readonly system:
114
+ | string
115
+ | SystemModelMessage
116
+ | Array<SystemModelMessage>
117
+ | undefined;
118
+
119
+ /** The prompt string or array of messages if using the prompt option. */
120
+ readonly prompt: string | Array<ModelMessage> | undefined;
121
+
122
+ /** The messages array if using the messages option. */
123
+ readonly messages: Array<ModelMessage> | undefined;
124
+
125
+ /** The tools available for this generation. */
126
+ readonly tools: TOOLS | undefined;
127
+
128
+ /** The tool choice strategy for this generation. */
129
+ readonly toolChoice: ToolChoice<NoInfer<TOOLS>> | undefined;
130
+
131
+ /** Limits which tools are available for the model to call. */
132
+ readonly activeTools: Array<keyof TOOLS> | undefined;
133
+
134
+ /** Maximum number of tokens to generate. */
135
+ readonly maxOutputTokens: number | undefined;
136
+ /** Sampling temperature for generation. */
137
+ readonly temperature: number | undefined;
138
+ /** Top-p (nucleus) sampling parameter. */
139
+ readonly topP: number | undefined;
140
+ /** Top-k sampling parameter. */
141
+ readonly topK: number | undefined;
142
+ /** Presence penalty for generation. */
143
+ readonly presencePenalty: number | undefined;
144
+ /** Frequency penalty for generation. */
145
+ readonly frequencyPenalty: number | undefined;
146
+ /** Sequences that will stop generation. */
147
+ readonly stopSequences: string[] | undefined;
148
+ /** Random seed for reproducible generation. */
149
+ readonly seed: number | undefined;
150
+ /** Maximum number of retries for failed requests. */
151
+ readonly maxRetries: number;
152
+
153
+ /**
154
+ * Timeout configuration for the generation.
155
+ * Can be a number (milliseconds) or an object with totalMs, stepMs, chunkMs.
156
+ */
157
+ readonly timeout: TimeoutConfiguration | undefined;
158
+
159
+ /** Additional HTTP headers sent with the request. */
160
+ readonly headers: Record<string, string | undefined> | undefined;
161
+
162
+ /** Additional provider-specific options. */
163
+ readonly providerOptions: ProviderOptions | undefined;
164
+
165
+ /**
166
+ * Condition(s) for stopping the generation.
167
+ * When the condition is an array, any of the conditions can be met to stop.
168
+ */
169
+ readonly stopWhen:
170
+ | StopCondition<TOOLS>
171
+ | Array<StopCondition<TOOLS>>
172
+ | undefined;
173
+
174
+ /** The output specification for structured outputs, if configured. */
175
+ readonly output: OUTPUT | undefined;
176
+
177
+ /** Abort signal for cancelling the operation. */
178
+ readonly abortSignal: AbortSignal | undefined;
179
+
180
+ /**
181
+ * Settings for controlling what data is included in step results.
182
+ * `requestBody` and `responseBody` control whether these are retained.
183
+ */
184
+ readonly include:
185
+ | {
186
+ requestBody?: boolean;
187
+ responseBody?: boolean;
188
+ }
189
+ | undefined;
190
+
191
+ /** Identifier from telemetry settings for grouping related operations. */
192
+ readonly functionId: string | undefined;
193
+
194
+ /** Additional metadata passed to the generation. */
195
+ readonly metadata: Record<string, unknown> | undefined;
196
+
197
+ /**
198
+ * User-defined context object that flows through the entire generation lifecycle.
199
+ * Can be accessed and modified in `prepareStep` and tool `execute` functions.
200
+ */
201
+ readonly experimental_context: unknown;
202
+ }) => PromiseLike<void> | void;
203
+
204
+ /**
205
+ * Callback that is set using the `experimental_onStepStart` option.
206
+ *
207
+ * Called when a step (LLM call) begins, before the provider is called.
208
+ * Each step represents a single LLM invocation. Multiple steps occur when
209
+ * using tool calls (the model may be called multiple times in a loop).
210
+ *
211
+ * @param event - The event object containing step configuration.
212
+ */
213
+ export type GenerateTextOnStepStartCallback<
214
+ TOOLS extends ToolSet = ToolSet,
215
+ OUTPUT extends Output = Output,
216
+ > = (event: {
217
+ /** Zero-based index of the current step. */
218
+ readonly stepNumber: number;
219
+
220
+ /** The model being used for this step. */
221
+ readonly model: {
222
+ /** The provider identifier. */
223
+ readonly provider: string;
224
+ /** The specific model identifier. */
225
+ readonly modelId: string;
226
+ };
227
+
228
+ /**
229
+ * The system message for this step.
230
+ */
231
+ readonly system:
232
+ | string
233
+ | SystemModelMessage
234
+ | Array<SystemModelMessage>
235
+ | undefined;
236
+
237
+ /**
238
+ * The messages that will be sent to the model for this step.
239
+ * Uses the user-facing `ModelMessage` format.
240
+ * May be overridden by prepareStep.
241
+ */
242
+ readonly messages: Array<ModelMessage>;
243
+
244
+ /** The tools available for this generation. */
245
+ readonly tools: TOOLS | undefined;
246
+
247
+ /** The tool choice configuration for this step. */
248
+ readonly toolChoice: LanguageModelV3ToolChoice | undefined;
249
+
250
+ /** Limits which tools are available for this step. */
251
+ readonly activeTools: Array<keyof TOOLS> | undefined;
252
+
253
+ /** Array of results from previous steps (empty for first step). */
254
+ readonly steps: ReadonlyArray<StepResult<TOOLS>>;
255
+
256
+ /** Additional provider-specific options for this step. */
257
+ readonly providerOptions: ProviderOptions | undefined;
258
+
259
+ /**
260
+ * Timeout configuration for the generation.
261
+ * Can be a number (milliseconds) or an object with totalMs, stepMs, chunkMs.
262
+ */
263
+ readonly timeout: TimeoutConfiguration | undefined;
264
+
265
+ /** Additional HTTP headers sent with the request. */
266
+ readonly headers: Record<string, string | undefined> | undefined;
267
+
268
+ /**
269
+ * Condition(s) for stopping the generation.
270
+ * When the condition is an array, any of the conditions can be met to stop.
271
+ */
272
+ readonly stopWhen:
273
+ | StopCondition<TOOLS>
274
+ | Array<StopCondition<TOOLS>>
275
+ | undefined;
276
+
277
+ /** The output specification for structured outputs, if configured. */
278
+ readonly output: OUTPUT | undefined;
279
+
280
+ /** Abort signal for cancelling the operation. */
281
+ readonly abortSignal: AbortSignal | undefined;
282
+
283
+ /**
284
+ * Settings for controlling what data is included in step results.
285
+ */
286
+ readonly include:
287
+ | {
288
+ requestBody?: boolean;
289
+ responseBody?: boolean;
290
+ }
291
+ | undefined;
292
+
293
+ /** Identifier from telemetry settings for grouping related operations. */
294
+ readonly functionId: string | undefined;
295
+
296
+ /** Additional metadata from telemetry settings. */
297
+ readonly metadata: Record<string, unknown> | undefined;
298
+
299
+ /**
300
+ * User-defined context object. May be updated from `prepareStep` between steps.
301
+ */
302
+ readonly experimental_context: unknown;
303
+ }) => PromiseLike<void> | void;
304
+
305
+ /**
306
+ * Callback that is set using the `experimental_onToolCallStart` option.
307
+ *
308
+ * Called when a tool execution begins, before the tool's `execute` function is invoked.
309
+ * Use this for logging tool invocations, tracking tool usage, or pre-execution validation.
310
+ *
311
+ * @param event - The event object containing tool call information.
312
+ * @param event.stepNumber - Zero-based index of the current step where this tool call occurs.
313
+ * @param event.model - Information about the model being used (provider and modelId).
314
+ * @param event.toolCall - The full tool call object containing toolName, toolCallId, input, and metadata.
315
+ * @param event.messages - The conversation messages available at tool execution time.
316
+ * @param event.abortSignal - Signal for cancelling the operation.
317
+ * @param event.functionId - Identifier from telemetry settings for grouping related operations.
318
+ * @param event.metadata - Additional metadata from telemetry settings.
319
+ * @param event.experimental_context - User-defined context object flowing through the generation.
320
+ */
321
+ export type GenerateTextOnToolCallStartCallback<
322
+ TOOLS extends ToolSet = ToolSet,
323
+ > = (event: {
324
+ /** Zero-based index of the current step where this tool call occurs. May be undefined in streaming contexts. */
325
+ readonly stepNumber: number | undefined;
326
+ /** Information about the model being used. May be undefined in streaming contexts. */
327
+ readonly model:
328
+ | {
329
+ /** The provider of the model. */
330
+ readonly provider: string;
331
+ /** The ID of the model. */
332
+ readonly modelId: string;
333
+ }
334
+ | undefined;
335
+ /** The full tool call object. */
336
+ readonly toolCall: TypedToolCall<TOOLS>;
337
+ /** The conversation messages available at tool execution time. */
338
+ readonly messages: Array<ModelMessage>;
339
+ /** Signal for cancelling the operation. */
340
+ readonly abortSignal: AbortSignal | undefined;
341
+ /** Identifier from telemetry settings for grouping related operations. */
342
+ readonly functionId: string | undefined;
343
+ /** Additional metadata from telemetry settings. */
344
+ readonly metadata: Record<string, unknown> | undefined;
345
+ /** User-defined context object flowing through the generation. */
346
+ readonly experimental_context: unknown;
347
+ }) => PromiseLike<void> | void;
348
+
349
+ /**
350
+ * Callback that is set using the `experimental_onToolCallFinish` option.
351
+ *
352
+ * Called when a tool execution completes, either successfully or with an error.
353
+ * Use this for logging tool results, tracking execution time, or error handling.
354
+ *
355
+ * The event uses a discriminated union on the `success` field:
356
+ * - When `success: true`: `output` contains the tool result, `error` is never present.
357
+ * - When `success: false`: `error` contains the error, `output` is never present.
358
+ *
359
+ * @param event - The event object containing tool call result information.
360
+ * @param event.stepNumber - Zero-based index of the current step where this tool call occurred.
361
+ * @param event.model - Information about the model being used (provider and modelId).
362
+ * @param event.toolCall - The full tool call object containing toolName, toolCallId, input, and metadata.
363
+ * @param event.messages - The conversation messages available at tool execution time.
364
+ * @param event.abortSignal - Signal for cancelling the operation.
365
+ * @param event.durationMs - Execution time of the tool call in milliseconds.
366
+ * @param event.functionId - Identifier from telemetry settings for grouping related operations.
367
+ * @param event.metadata - Additional metadata from telemetry settings.
368
+ * @param event.experimental_context - User-defined context object flowing through the generation.
369
+ * @param event.success - Discriminator indicating whether the tool call succeeded.
370
+ * @param event.output - The tool's return value (only present when `success: true`).
371
+ * @param event.error - The error that occurred (only present when `success: false`).
372
+ */
373
+ export type GenerateTextOnToolCallFinishCallback<
374
+ TOOLS extends ToolSet = ToolSet,
375
+ > = (
376
+ event: {
377
+ /** Zero-based index of the current step where this tool call occurred. May be undefined in streaming contexts. */
378
+ readonly stepNumber: number | undefined;
379
+ /** Information about the model being used. May be undefined in streaming contexts. */
380
+ readonly model:
381
+ | {
382
+ /** The provider of the model. */
383
+ readonly provider: string;
384
+ /** The ID of the model. */
385
+ readonly modelId: string;
386
+ }
387
+ | undefined;
388
+ /** The full tool call object. */
389
+ readonly toolCall: TypedToolCall<TOOLS>;
390
+ /** The conversation messages available at tool execution time. */
391
+ readonly messages: Array<ModelMessage>;
392
+ /** Signal for cancelling the operation. */
393
+ readonly abortSignal: AbortSignal | undefined;
394
+ /** Execution time of the tool call in milliseconds. */
395
+ readonly durationMs: number;
396
+ /** Identifier from telemetry settings for grouping related operations. */
397
+ readonly functionId: string | undefined;
398
+ /** Additional metadata from telemetry settings. */
399
+ readonly metadata: Record<string, unknown> | undefined;
400
+ /** User-defined context object flowing through the generation. */
401
+ readonly experimental_context: unknown;
402
+ } & (
403
+ | {
404
+ /** Indicates the tool call succeeded. */
405
+ readonly success: true;
406
+ /** The tool's return value. */
407
+ readonly output: unknown;
408
+ readonly error?: never;
409
+ }
410
+ | {
411
+ /** Indicates the tool call failed. */
412
+ readonly success: false;
413
+ readonly output?: never;
414
+ /** The error that occurred during tool execution. */
415
+ readonly error: unknown;
416
+ }
417
+ ),
418
+ ) => PromiseLike<void> | void;
419
+
88
420
  /**
89
421
  * Callback that is set using the `onStepFinish` option.
90
422
  *
423
+ * Called when a step (LLM call) completes. The event includes all step result
424
+ * properties (text, tool calls, usage, etc.) along with additional metadata.
425
+ *
91
426
  * @param stepResult - The result of the step.
92
427
  */
93
428
  export type GenerateTextOnStepFinishCallback<TOOLS extends ToolSet> = (
@@ -97,28 +432,64 @@ export type GenerateTextOnStepFinishCallback<TOOLS extends ToolSet> = (
97
432
  /**
98
433
  * Callback that is set using the `onFinish` option.
99
434
  *
100
- * @param event - The event that is passed to the callback.
435
+ * Called when the entire generation completes (all steps finished).
436
+ * The event includes the final step's result properties along with
437
+ * aggregated data from all steps.
438
+ *
439
+ * @param event - The final result along with aggregated step data.
440
+ *
441
+ * Inherited from StepResult (reflects the final step):
442
+ * @param event.content - Array of content parts from the final step.
443
+ * @param event.text - The generated text from the final step.
444
+ * @param event.reasoning - Array of reasoning parts from the final step.
445
+ * @param event.reasoningText - Combined reasoning text from the final step.
446
+ * @param event.files - Array of generated files from the final step.
447
+ * @param event.sources - Array of sources from the final step.
448
+ * @param event.toolCalls - Array of tool calls from the final step.
449
+ * @param event.toolResults - Array of tool results from the final step.
450
+ * @param event.finishReason - Finish reason from the final step.
451
+ * @param event.usage - Token usage from the final step only.
452
+ * @param event.warnings - Warnings from the final step.
453
+ * @param event.request - Request metadata from the final step.
454
+ * @param event.response - Response metadata from the final step.
455
+ * @param event.providerMetadata - Provider metadata from the final step.
456
+ *
457
+ * Additional properties:
458
+ * @param event.steps - Array containing results from all steps in the generation.
459
+ * @param event.totalUsage - Aggregated token usage across all steps.
460
+ * @param event.experimental_context - The final state of the user-defined context object.
461
+ * @param event.functionId - Identifier from telemetry settings for grouping related operations.
462
+ * @param event.metadata - Additional metadata from telemetry settings.
101
463
  */
102
464
  export type GenerateTextOnFinishCallback<TOOLS extends ToolSet> = (
103
465
  event: StepResult<TOOLS> & {
104
466
  /**
105
- * Details for all steps.
467
+ * Array containing results from all steps in the generation.
106
468
  */
107
469
  readonly steps: StepResult<TOOLS>[];
108
470
 
109
471
  /**
110
- * Total usage for all steps. This is the sum of the usage of all steps.
472
+ * Aggregated token usage across all steps.
473
+ * This is the sum of the usage from each individual step.
111
474
  */
112
475
  readonly totalUsage: LanguageModelUsage;
113
476
 
114
477
  /**
115
- * Context that is passed into tool execution.
478
+ * The final state of the user-defined context object.
479
+ * This reflects any modifications made during the generation lifecycle
480
+ * via `prepareStep` or tool execution.
116
481
  *
117
482
  * Experimental (can break in patch releases).
118
483
  *
119
484
  * @default undefined
120
485
  */
121
486
  experimental_context: unknown;
487
+
488
+ /** Identifier from telemetry settings for grouping related operations. */
489
+ readonly functionId: string | undefined;
490
+
491
+ /** Additional metadata from telemetry settings. */
492
+ readonly metadata: Record<string, unknown> | undefined;
122
493
  },
123
494
  ) => PromiseLike<void> | void;
124
495
 
@@ -162,6 +533,14 @@ export type GenerateTextOnFinishCallback<TOOLS extends ToolSet> = (
162
533
  * @param timeout - An optional timeout in milliseconds. The call will be aborted if it takes longer than the specified timeout.
163
534
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
164
535
  *
536
+ * @param experimental_context - User-defined context object that flows through the entire generation lifecycle.
537
+ * @param experimental_onStart - Callback invoked when generation begins, before any LLM calls.
538
+ * @param experimental_onStepStart - Callback invoked when each step begins, before the provider is called.
539
+ * Receives step number, messages (in ModelMessage format), tools, and context.
540
+ * @param experimental_onToolCallStart - Callback invoked before each tool execution begins.
541
+ * Receives tool name, call ID, input, and context.
542
+ * @param experimental_onToolCallFinish - Callback invoked after each tool execution completes.
543
+ * Uses a discriminated union: check `success` to determine if `output` or `error` is present.
165
544
  * @param onStepFinish - Callback that is called when each step (LLM call) is finished, including intermediate steps.
166
545
  * @param onFinish - Callback that is called when all steps are finished and the response is complete.
167
546
  *
@@ -196,6 +575,10 @@ export async function generateText<
196
575
  experimental_context,
197
576
  experimental_include: include,
198
577
  _internal: { generateId = originalGenerateId } = {},
578
+ experimental_onStart: onStart,
579
+ experimental_onStepStart: onStepStart,
580
+ experimental_onToolCallStart: onToolCallStart,
581
+ experimental_onToolCallFinish: onToolCallFinish,
199
582
  onStepFinish,
200
583
  onFinish,
201
584
  ...settings
@@ -283,6 +666,35 @@ export async function generateText<
283
666
  */
284
667
  experimental_repairToolCall?: ToolCallRepairFunction<NoInfer<TOOLS>>;
285
668
 
669
+ /**
670
+ * Callback that is called when the generateText operation begins,
671
+ * before any LLM calls are made.
672
+ */
673
+ experimental_onStart?: GenerateTextOnStartCallback<NoInfer<TOOLS>, OUTPUT>;
674
+
675
+ /**
676
+ * Callback that is called when a step (LLM call) begins,
677
+ * before the provider is called.
678
+ */
679
+ experimental_onStepStart?: GenerateTextOnStepStartCallback<
680
+ NoInfer<TOOLS>,
681
+ OUTPUT
682
+ >;
683
+
684
+ /**
685
+ * Callback that is called right before a tool's execute function runs.
686
+ */
687
+ experimental_onToolCallStart?: GenerateTextOnToolCallStartCallback<
688
+ NoInfer<TOOLS>
689
+ >;
690
+
691
+ /**
692
+ * Callback that is called right after a tool's execute function completes (or errors).
693
+ */
694
+ experimental_onToolCallFinish?: GenerateTextOnToolCallFinishCallback<
695
+ NoInfer<TOOLS>
696
+ >;
697
+
286
698
  /**
287
699
  * Callback that is called when each step (LLM call) is finished, including intermediate steps.
288
700
  */
@@ -369,6 +781,39 @@ export async function generateText<
369
781
  messages,
370
782
  } as Prompt);
371
783
 
784
+ try {
785
+ await onStart?.({
786
+ model: { provider: model.provider, modelId: model.modelId },
787
+ system,
788
+ prompt,
789
+ messages,
790
+ tools,
791
+ toolChoice,
792
+ activeTools,
793
+ maxOutputTokens: callSettings.maxOutputTokens,
794
+ temperature: callSettings.temperature,
795
+ topP: callSettings.topP,
796
+ topK: callSettings.topK,
797
+ presencePenalty: callSettings.presencePenalty,
798
+ frequencyPenalty: callSettings.frequencyPenalty,
799
+ stopSequences: callSettings.stopSequences,
800
+ seed: callSettings.seed,
801
+ maxRetries,
802
+ timeout,
803
+ headers,
804
+ providerOptions,
805
+ stopWhen,
806
+ output,
807
+ abortSignal,
808
+ include,
809
+ functionId: telemetry?.functionId,
810
+ metadata: telemetry?.metadata as Record<string, unknown> | undefined,
811
+ experimental_context,
812
+ });
813
+ } catch (_ignored) {
814
+ // Errors in callbacks should not break the generation flow.
815
+ }
816
+
372
817
  const tracer = getTracer(telemetry);
373
818
 
374
819
  try {
@@ -417,6 +862,10 @@ export async function generateText<
417
862
  messages: initialMessages,
418
863
  abortSignal: mergedAbortSignal,
419
864
  experimental_context,
865
+ stepNumber: 0,
866
+ model: { provider: model.provider, modelId: model.modelId },
867
+ onToolCallStart: onToolCallStart,
868
+ onToolCallFinish: onToolCallFinish,
420
869
  });
421
870
 
422
871
  const toolContent: Array<any> = [];
@@ -540,12 +989,56 @@ export async function generateText<
540
989
  experimental_context =
541
990
  prepareStepResult?.experimental_context ?? experimental_context;
542
991
 
992
+ const stepActiveTools =
993
+ prepareStepResult?.activeTools ?? activeTools;
994
+
543
995
  const { toolChoice: stepToolChoice, tools: stepTools } =
544
996
  await prepareToolsAndToolChoice({
545
997
  tools,
546
998
  toolChoice: prepareStepResult?.toolChoice ?? toolChoice,
547
- activeTools: prepareStepResult?.activeTools ?? activeTools,
999
+ activeTools: stepActiveTools,
1000
+ });
1001
+
1002
+ const stepMessages =
1003
+ prepareStepResult?.messages ?? stepInputMessages;
1004
+
1005
+ const stepSystem =
1006
+ prepareStepResult?.system ?? initialPrompt.system;
1007
+
1008
+ const stepProviderOptions = mergeObjects(
1009
+ providerOptions,
1010
+ prepareStepResult?.providerOptions,
1011
+ );
1012
+
1013
+ try {
1014
+ await onStepStart?.({
1015
+ stepNumber: steps.length,
1016
+ model: {
1017
+ provider: stepModel.provider,
1018
+ modelId: stepModel.modelId,
1019
+ },
1020
+ system: stepSystem,
1021
+ messages: stepMessages,
1022
+ tools,
1023
+ toolChoice: stepToolChoice,
1024
+ activeTools: stepActiveTools,
1025
+ steps: [...steps],
1026
+ providerOptions: stepProviderOptions,
1027
+ timeout,
1028
+ headers,
1029
+ stopWhen,
1030
+ output,
1031
+ abortSignal,
1032
+ include,
1033
+ functionId: telemetry?.functionId,
1034
+ metadata: telemetry?.metadata as
1035
+ | Record<string, unknown>
1036
+ | undefined,
1037
+ experimental_context,
548
1038
  });
1039
+ } catch (_ignored) {
1040
+ // Errors in callbacks should not break the generation flow.
1041
+ }
549
1042
 
550
1043
  currentModelResponse = await retry(() =>
551
1044
  recordSpan({
@@ -592,11 +1085,6 @@ export async function generateText<
592
1085
  }),
593
1086
  tracer,
594
1087
  fn: async span => {
595
- const stepProviderOptions = mergeObjects(
596
- providerOptions,
597
- prepareStepResult?.providerOptions,
598
- );
599
-
600
1088
  const result = await stepModel.doGenerate({
601
1089
  ...callSettings,
602
1090
  tools: stepTools,
@@ -769,6 +1257,13 @@ export async function generateText<
769
1257
  messages: stepInputMessages,
770
1258
  abortSignal: mergedAbortSignal,
771
1259
  experimental_context,
1260
+ stepNumber: steps.length,
1261
+ model: {
1262
+ provider: stepModel.provider,
1263
+ modelId: stepModel.modelId,
1264
+ },
1265
+ onToolCallStart: onToolCallStart,
1266
+ onToolCallFinish: onToolCallFinish,
772
1267
  })),
773
1268
  );
774
1269
  }
@@ -838,7 +1333,19 @@ export async function generateText<
838
1333
  : undefined,
839
1334
  };
840
1335
 
1336
+ const stepNumber = steps.length;
1337
+
841
1338
  const currentStepResult: StepResult<TOOLS> = new DefaultStepResult({
1339
+ stepNumber,
1340
+ model: {
1341
+ provider: stepModel.provider,
1342
+ modelId: stepModel.modelId,
1343
+ },
1344
+ functionId: telemetry?.functionId,
1345
+ metadata: telemetry?.metadata as
1346
+ | Record<string, unknown>
1347
+ | undefined,
1348
+ experimental_context,
842
1349
  content: stepContent,
843
1350
  finishReason: currentModelResponse.finishReason.unified,
844
1351
  rawFinishReason: currentModelResponse.finishReason.raw,
@@ -924,6 +1431,11 @@ export async function generateText<
924
1431
  );
925
1432
 
926
1433
  await onFinish?.({
1434
+ stepNumber: lastStep.stepNumber,
1435
+ model: lastStep.model,
1436
+ functionId: lastStep.functionId,
1437
+ metadata: lastStep.metadata,
1438
+ experimental_context: lastStep.experimental_context,
927
1439
  finishReason: lastStep.finishReason,
928
1440
  rawFinishReason: lastStep.rawFinishReason,
929
1441
  usage: lastStep.usage,
@@ -945,7 +1457,6 @@ export async function generateText<
945
1457
  providerMetadata: lastStep.providerMetadata,
946
1458
  steps,
947
1459
  totalUsage,
948
- experimental_context,
949
1460
  });
950
1461
 
951
1462
  // parse output only if the last step was finished with "stop":
@@ -982,6 +1493,10 @@ async function executeTools<TOOLS extends ToolSet>({
982
1493
  messages,
983
1494
  abortSignal,
984
1495
  experimental_context,
1496
+ stepNumber,
1497
+ model,
1498
+ onToolCallStart,
1499
+ onToolCallFinish,
985
1500
  }: {
986
1501
  toolCalls: Array<TypedToolCall<TOOLS>>;
987
1502
  tools: TOOLS;
@@ -990,6 +1505,10 @@ async function executeTools<TOOLS extends ToolSet>({
990
1505
  messages: ModelMessage[];
991
1506
  abortSignal: AbortSignal | undefined;
992
1507
  experimental_context: unknown;
1508
+ stepNumber: number;
1509
+ model: { provider: string; modelId: string };
1510
+ onToolCallStart: GenerateTextOnToolCallStartCallback<TOOLS> | undefined;
1511
+ onToolCallFinish: GenerateTextOnToolCallFinishCallback<TOOLS> | undefined;
993
1512
  }): Promise<Array<ToolOutput<TOOLS>>> {
994
1513
  const toolOutputs = await Promise.all(
995
1514
  toolCalls.map(async toolCall =>
@@ -1001,6 +1520,10 @@ async function executeTools<TOOLS extends ToolSet>({
1001
1520
  messages,
1002
1521
  abortSignal,
1003
1522
  experimental_context,
1523
+ stepNumber,
1524
+ model,
1525
+ onToolCallStart,
1526
+ onToolCallFinish,
1004
1527
  }),
1005
1528
  ),
1006
1529
  );