@ai-sdk/workflow 1.0.0-beta.24 → 1.0.0-beta.26

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,31 @@
1
1
  # @ai-sdk/workflow
2
2
 
3
+ ## 1.0.0-beta.26
4
+
5
+ ### Major Changes
6
+
7
+ - 1949571: feat(ai): make experimental_telemetry stable
8
+
9
+ ### Patch Changes
10
+
11
+ - f32c750: refactoring(ai): simplify mergeAbortSignals
12
+ - Updated dependencies [f319fde]
13
+ - Updated dependencies [1949571]
14
+ - Updated dependencies [511902c]
15
+ - Updated dependencies [6542d93]
16
+ - Updated dependencies [2e98477]
17
+ - Updated dependencies [876fd3e]
18
+ - Updated dependencies [f32c750]
19
+ - ai@7.0.0-beta.111
20
+ - @ai-sdk/provider-utils@5.0.0-beta.26
21
+
22
+ ## 1.0.0-beta.25
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies [72cb801]
27
+ - ai@7.0.0-beta.110
28
+
3
29
  ## 1.0.0-beta.24
4
30
 
5
31
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -252,6 +252,10 @@ interface PrepareCallOptions<TTools extends ToolSet = ToolSet> extends Partial<G
252
252
  tools: TTools;
253
253
  instructions?: string | SystemModelMessage | Array<SystemModelMessage>;
254
254
  toolChoice?: ToolChoice<TTools>;
255
+ telemetry?: TelemetryOptions;
256
+ /**
257
+ * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
258
+ */
255
259
  experimental_telemetry?: TelemetryOptions;
256
260
  experimental_context?: unknown;
257
261
  messages: ModelMessage[];
@@ -303,7 +307,13 @@ interface WorkflowAgentOptions<TTools extends ToolSet = ToolSet> extends Generat
303
307
  */
304
308
  toolChoice?: ToolChoice<TTools>;
305
309
  /**
306
- * Optional telemetry configuration (experimental).
310
+ * Optional telemetry configuration.
311
+ */
312
+ telemetry?: TelemetryOptions;
313
+ /**
314
+ * Optional telemetry configuration.
315
+ *
316
+ * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
307
317
  */
308
318
  experimental_telemetry?: TelemetryOptions;
309
319
  /**
@@ -569,7 +579,13 @@ type WorkflowAgentStreamOptions<TTools extends ToolSet = ToolSet, OUTPUT = never
569
579
  */
570
580
  activeTools?: Array<keyof NoInfer<TTools>>;
571
581
  /**
572
- * Optional telemetry configuration (experimental).
582
+ * Optional telemetry configuration.
583
+ */
584
+ telemetry?: TelemetryOptions;
585
+ /**
586
+ * Optional telemetry configuration.
587
+ *
588
+ * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
573
589
  */
574
590
  experimental_telemetry?: TelemetryOptions;
575
591
  /**
package/dist/index.mjs CHANGED
@@ -279,7 +279,7 @@ async function* streamTextIterator({
279
279
  generationSettings,
280
280
  toolChoice,
281
281
  experimental_context,
282
- experimental_telemetry,
282
+ telemetry,
283
283
  includeRawChunks = false,
284
284
  repairToolCall,
285
285
  responseFormat
@@ -427,7 +427,7 @@ async function* streamTextIterator({
427
427
  ...currentGenerationSettings,
428
428
  toolChoice: currentToolChoice,
429
429
  includeRawChunks,
430
- experimental_telemetry,
430
+ telemetry,
431
431
  repairToolCall,
432
432
  responseFormat
433
433
  }
@@ -544,13 +544,13 @@ function sanitizeProviderMetadataForToolCall(metadata) {
544
544
  // src/workflow-agent.ts
545
545
  var WorkflowAgent = class {
546
546
  constructor(options) {
547
- var _a, _b;
547
+ var _a, _b, _c;
548
548
  this.id = options.id;
549
549
  this.model = options.model;
550
550
  this.tools = (_a = options.tools) != null ? _a : {};
551
551
  this.instructions = (_b = options.instructions) != null ? _b : options.system;
552
552
  this.toolChoice = options.toolChoice;
553
- this.telemetry = options.experimental_telemetry;
553
+ this.telemetry = (_c = options.telemetry) != null ? _c : options.experimental_telemetry;
554
554
  this.experimentalContext = options.experimental_context;
555
555
  this.stopWhen = options.stopWhen;
556
556
  this.activeTools = options.activeTools;
@@ -584,7 +584,7 @@ var WorkflowAgent = class {
584
584
  throw new Error("Not implemented");
585
585
  }
586
586
  async stream(options) {
587
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
587
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C;
588
588
  let effectiveModel = this.model;
589
589
  let effectiveInstructions = (_a = options.system) != null ? _a : this.instructions;
590
590
  let effectivePrompt = options.prompt;
@@ -592,14 +592,15 @@ var WorkflowAgent = class {
592
592
  let effectiveGenerationSettings = { ...this.generationSettings };
593
593
  let effectiveExperimentalContext = (_b = options.experimental_context) != null ? _b : this.experimentalContext;
594
594
  let effectiveToolChoiceFromPrepare = (_c = options.toolChoice) != null ? _c : this.toolChoice;
595
- let effectiveTelemetryFromPrepare = (_d = options.experimental_telemetry) != null ? _d : this.telemetry;
596
- const resolvedMessagesForPrepareCall = (_e = effectiveMessages != null ? effectiveMessages : typeof effectivePrompt === "string" ? [{ role: "user", content: effectivePrompt }] : effectivePrompt) != null ? _e : [];
595
+ let effectiveTelemetryFromPrepare = (_e = (_d = options.telemetry) != null ? _d : options.experimental_telemetry) != null ? _e : this.telemetry;
596
+ const resolvedMessagesForPrepareCall = (_f = effectiveMessages != null ? effectiveMessages : typeof effectivePrompt === "string" ? [{ role: "user", content: effectivePrompt }] : effectivePrompt) != null ? _f : [];
597
597
  if (this.prepareCall) {
598
598
  const prepared = await this.prepareCall({
599
599
  model: effectiveModel,
600
600
  tools: this.tools,
601
601
  instructions: effectiveInstructions,
602
602
  toolChoice: effectiveToolChoiceFromPrepare,
603
+ telemetry: effectiveTelemetryFromPrepare,
603
604
  experimental_telemetry: effectiveTelemetryFromPrepare,
604
605
  experimental_context: effectiveExperimentalContext,
605
606
  messages: resolvedMessagesForPrepareCall,
@@ -616,7 +617,9 @@ var WorkflowAgent = class {
616
617
  effectiveExperimentalContext = prepared.experimental_context;
617
618
  if (prepared.toolChoice !== void 0)
618
619
  effectiveToolChoiceFromPrepare = prepared.toolChoice;
619
- if (prepared.experimental_telemetry !== void 0)
620
+ if (prepared.telemetry !== void 0)
621
+ effectiveTelemetryFromPrepare = prepared.telemetry;
622
+ else if (prepared.experimental_telemetry !== void 0)
620
623
  effectiveTelemetryFromPrepare = prepared.experimental_telemetry;
621
624
  if (prepared.maxOutputTokens !== void 0)
622
625
  effectiveGenerationSettings.maxOutputTokens = prepared.maxOutputTokens;
@@ -737,11 +740,11 @@ var WorkflowAgent = class {
737
740
  const modelPrompt = await convertToLanguageModelPrompt({
738
741
  prompt,
739
742
  supportedUrls: {},
740
- download: (_f = options.experimental_download) != null ? _f : this.experimentalDownload
743
+ download: (_g = options.experimental_download) != null ? _g : this.experimentalDownload
741
744
  });
742
745
  const effectiveAbortSignal = mergeAbortSignals(
743
- (_g = options.abortSignal) != null ? _g : effectiveGenerationSettings.abortSignal,
744
- options.timeout != null ? AbortSignal.timeout(options.timeout) : void 0
746
+ (_h = options.abortSignal) != null ? _h : effectiveGenerationSettings.abortSignal,
747
+ options.timeout
745
748
  );
746
749
  const mergedGenerationSettings = {
747
750
  ...effectiveGenerationSettings,
@@ -800,11 +803,11 @@ var WorkflowAgent = class {
800
803
  );
801
804
  const effectiveToolChoice = effectiveToolChoiceFromPrepare;
802
805
  const effectiveTelemetry = effectiveTelemetryFromPrepare;
803
- const effectiveActiveTools = (_h = options.activeTools) != null ? _h : this.activeTools;
804
- const effectiveTools = effectiveActiveTools && effectiveActiveTools.length > 0 ? (_i = filterActiveTools2({
806
+ const effectiveActiveTools = (_i = options.activeTools) != null ? _i : this.activeTools;
807
+ const effectiveTools = effectiveActiveTools && effectiveActiveTools.length > 0 ? (_j = filterActiveTools2({
805
808
  tools: this.tools,
806
809
  activeTools: effectiveActiveTools
807
- })) != null ? _i : this.tools : this.tools;
810
+ })) != null ? _j : this.tools : this.tools;
808
811
  let experimentalContext = effectiveExperimentalContext;
809
812
  const steps = [];
810
813
  let lastStepToolCalls = [];
@@ -868,7 +871,7 @@ var WorkflowAgent = class {
868
871
  }
869
872
  return result;
870
873
  };
871
- if ((_j = mergedGenerationSettings.abortSignal) == null ? void 0 : _j.aborted) {
874
+ if ((_k = mergedGenerationSettings.abortSignal) == null ? void 0 : _k.aborted) {
872
875
  if (options.onAbort) {
873
876
  await options.onAbort({ steps });
874
877
  }
@@ -885,18 +888,18 @@ var WorkflowAgent = class {
885
888
  tools: effectiveTools,
886
889
  writable: options.writable,
887
890
  prompt: modelPrompt,
888
- stopConditions: (_k = options.stopWhen) != null ? _k : this.stopWhen,
891
+ stopConditions: (_l = options.stopWhen) != null ? _l : this.stopWhen,
889
892
  onStepFinish: mergedOnStepFinish,
890
893
  onStepStart: mergedOnStepStart,
891
894
  onError: options.onError,
892
- prepareStep: (_l = options.prepareStep) != null ? _l : this.prepareStep,
895
+ prepareStep: (_m = options.prepareStep) != null ? _m : this.prepareStep,
893
896
  generationSettings: mergedGenerationSettings,
894
897
  toolChoice: effectiveToolChoice,
895
898
  experimental_context: experimentalContext,
896
- experimental_telemetry: effectiveTelemetry,
897
- includeRawChunks: (_m = options.includeRawChunks) != null ? _m : false,
898
- repairToolCall: (_n = options.experimental_repairToolCall) != null ? _n : this.experimentalRepairToolCall,
899
- responseFormat: await ((_p = (_o = options.output) != null ? _o : this.output) == null ? void 0 : _p.responseFormat)
899
+ telemetry: effectiveTelemetry,
900
+ includeRawChunks: (_n = options.includeRawChunks) != null ? _n : false,
901
+ repairToolCall: (_o = options.experimental_repairToolCall) != null ? _o : this.experimentalRepairToolCall,
902
+ responseFormat: await ((_q = (_p = options.output) != null ? _p : this.output) == null ? void 0 : _q.responseFormat)
900
903
  });
901
904
  let finalMessages;
902
905
  let encounteredError;
@@ -904,7 +907,7 @@ var WorkflowAgent = class {
904
907
  try {
905
908
  let result = await iterator.next();
906
909
  while (!result.done) {
907
- if ((_q = mergedGenerationSettings.abortSignal) == null ? void 0 : _q.aborted) {
910
+ if ((_r = mergedGenerationSettings.abortSignal) == null ? void 0 : _r.aborted) {
908
911
  wasAborted = true;
909
912
  if (options.onAbort) {
910
913
  await options.onAbort({ steps });
@@ -999,8 +1002,8 @@ var WorkflowAgent = class {
999
1002
  await mergedOnFinish({
1000
1003
  steps,
1001
1004
  messages: messages2,
1002
- text: (_r = lastStep == null ? void 0 : lastStep.text) != null ? _r : "",
1003
- finishReason: (_s = lastStep == null ? void 0 : lastStep.finishReason) != null ? _s : "other",
1005
+ text: (_s = lastStep == null ? void 0 : lastStep.text) != null ? _s : "",
1006
+ finishReason: (_t = lastStep == null ? void 0 : lastStep.finishReason) != null ? _t : "other",
1004
1007
  totalUsage: aggregateUsage(steps),
1005
1008
  experimental_context: experimentalContext,
1006
1009
  output: void 0
@@ -1024,8 +1027,8 @@ var WorkflowAgent = class {
1024
1027
  }
1025
1028
  }
1026
1029
  if (options.writable) {
1027
- const sendFinish = (_t = options.sendFinish) != null ? _t : true;
1028
- const preventClose = (_u = options.preventClose) != null ? _u : false;
1030
+ const sendFinish = (_u = options.sendFinish) != null ? _u : true;
1031
+ const preventClose = (_v = options.preventClose) != null ? _v : false;
1029
1032
  if (sendFinish || !preventClose) {
1030
1033
  await closeStream(options.writable, preventClose, sendFinish);
1031
1034
  }
@@ -1120,7 +1123,7 @@ var WorkflowAgent = class {
1120
1123
  }
1121
1124
  }
1122
1125
  const messages = finalMessages != null ? finalMessages : prompt.messages;
1123
- const effectiveOutput = (_v = options.output) != null ? _v : this.output;
1126
+ const effectiveOutput = (_w = options.output) != null ? _w : this.output;
1124
1127
  let experimentalOutput = void 0;
1125
1128
  if (effectiveOutput && steps.length > 0) {
1126
1129
  const lastStep = steps[steps.length - 1];
@@ -1147,8 +1150,8 @@ var WorkflowAgent = class {
1147
1150
  await mergedOnFinish({
1148
1151
  steps,
1149
1152
  messages,
1150
- text: (_w = lastStep == null ? void 0 : lastStep.text) != null ? _w : "",
1151
- finishReason: (_x = lastStep == null ? void 0 : lastStep.finishReason) != null ? _x : "other",
1153
+ text: (_x = lastStep == null ? void 0 : lastStep.text) != null ? _x : "",
1154
+ finishReason: (_y = lastStep == null ? void 0 : lastStep.finishReason) != null ? _y : "other",
1152
1155
  totalUsage: aggregateUsage(steps),
1153
1156
  experimental_context: experimentalContext,
1154
1157
  output: experimentalOutput
@@ -1156,8 +1159,8 @@ var WorkflowAgent = class {
1156
1159
  }
1157
1160
  if (encounteredError) {
1158
1161
  if (options.writable) {
1159
- const sendFinish = (_y = options.sendFinish) != null ? _y : true;
1160
- const preventClose = (_z = options.preventClose) != null ? _z : false;
1162
+ const sendFinish = (_z = options.sendFinish) != null ? _z : true;
1163
+ const preventClose = (_A = options.preventClose) != null ? _A : false;
1161
1164
  if (sendFinish || !preventClose) {
1162
1165
  await closeStream(options.writable, preventClose, sendFinish);
1163
1166
  }
@@ -1165,8 +1168,8 @@ var WorkflowAgent = class {
1165
1168
  throw encounteredError;
1166
1169
  }
1167
1170
  if (options.writable) {
1168
- const sendFinish = (_A = options.sendFinish) != null ? _A : true;
1169
- const preventClose = (_B = options.preventClose) != null ? _B : false;
1171
+ const sendFinish = (_B = options.sendFinish) != null ? _B : true;
1172
+ const preventClose = (_C = options.preventClose) != null ? _C : false;
1170
1173
  if (sendFinish || !preventClose) {
1171
1174
  await closeStream(options.writable, preventClose, sendFinish);
1172
1175
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/workflow-agent.ts","../src/stream-text-iterator.ts","../src/do-stream-step.ts","../src/serializable-schema.ts","../src/to-ui-message-chunk.ts","../src/workflow-chat-transport.ts"],"sourcesContent":["import type {\n JSONValue,\n LanguageModelV4CallOptions,\n LanguageModelV4Prompt,\n LanguageModelV4StreamPart,\n LanguageModelV4ToolResultPart,\n SharedV4ProviderOptions,\n} from '@ai-sdk/provider';\nimport {\n type FinishReason,\n LanguageModel,\n type LanguageModelResponseMetadata,\n type LanguageModelUsage,\n type Experimental_LanguageModelStreamPart as ModelCallStreamPart,\n type ModelMessage,\n Output,\n type StepResult,\n type StopCondition,\n type StreamTextOnStepFinishCallback,\n type SystemModelMessage,\n type ToolCallRepairFunction,\n type ToolChoice,\n type ToolSet,\n type UIMessage,\n experimental_filterActiveTools as filterActiveTools,\n} from 'ai';\nimport {\n convertToLanguageModelPrompt,\n mergeAbortSignals,\n mergeCallbacks,\n standardizePrompt,\n} from 'ai/internal';\nimport { streamTextIterator } from './stream-text-iterator.js';\n\n// Re-export for consumers\nexport type { CompatibleLanguageModel } from './types.js';\n\n/**\n * Callback function to be called after each step completes.\n * Alias for the AI SDK's StreamTextOnStepFinishCallback, using\n * WorkflowAgent-consistent naming.\n */\nexport type WorkflowAgentOnStepFinishCallback<\n TTools extends ToolSet = ToolSet,\n> = StreamTextOnStepFinishCallback<TTools, any>;\n\n/**\n * Infer the type of the tools of a workflow agent.\n */\nexport type InferWorkflowAgentTools<WORKFLOW_AGENT> =\n WORKFLOW_AGENT extends WorkflowAgent<infer TOOLS> ? TOOLS : never;\n\n/**\n * Infer the UI message type of a workflow agent.\n */\nexport type InferWorkflowAgentUIMessage<\n _WORKFLOW_AGENT,\n MESSAGE_METADATA = unknown,\n> = UIMessage<MESSAGE_METADATA>;\n\n/**\n * Re-export the Output helper for structured output specifications.\n * Use `Output.object({ schema })` for structured output or `Output.text()` for text output.\n */\nexport { Output };\n\n/**\n * Output specification interface for structured outputs.\n * Use `Output.object({ schema })` or `Output.text()` to create an output specification.\n */\nexport interface OutputSpecification<OUTPUT, PARTIAL> {\n readonly name: string;\n responseFormat: PromiseLike<LanguageModelV4CallOptions['responseFormat']>;\n parsePartialOutput(options: {\n text: string;\n }): Promise<{ partial: PARTIAL } | undefined>;\n parseCompleteOutput(\n options: { text: string },\n context: {\n response: LanguageModelResponseMetadata;\n usage: LanguageModelUsage;\n finishReason: FinishReason;\n },\n ): Promise<OUTPUT>;\n}\n\n/**\n * Provider-specific options type. This is equivalent to SharedV4ProviderOptions from @ai-sdk/provider.\n */\nexport type ProviderOptions = SharedV4ProviderOptions;\n\n/**\n * Telemetry settings for observability.\n */\nexport interface TelemetryOptions {\n /**\n * Enable or disable telemetry. Defaults to true.\n */\n isEnabled?: boolean;\n\n /**\n * Identifier for this function. Used to group telemetry data by function.\n */\n functionId?: string;\n\n /**\n * Additional information to include in the telemetry data.\n */\n metadata?: Record<\n string,\n | string\n | number\n | boolean\n | Array<string | number | boolean>\n | null\n | undefined\n >;\n\n /**\n * Enable or disable input recording. Enabled by default.\n *\n * You might want to disable input recording to avoid recording sensitive\n * information, to reduce data transfers, or to increase performance.\n */\n recordInputs?: boolean;\n\n /**\n * Enable or disable output recording. Enabled by default.\n *\n * You might want to disable output recording to avoid recording sensitive\n * information, to reduce data transfers, or to increase performance.\n */\n recordOutputs?: boolean;\n\n /**\n * Custom tracer for the telemetry.\n */\n tracer?: unknown;\n}\n\n/**\n * A transformation that is applied to the stream.\n */\nexport type StreamTextTransform<TTools extends ToolSet> = (options: {\n tools: TTools;\n stopStream: () => void;\n}) => TransformStream<LanguageModelV4StreamPart, LanguageModelV4StreamPart>;\n\n/**\n * Function to repair a tool call that failed to parse.\n * Re-exported from the AI SDK core.\n */\nexport type { ToolCallRepairFunction } from 'ai';\n\n/**\n * Custom download function for URLs.\n * The function receives an array of URLs with information about whether\n * the model supports them directly.\n */\nexport type DownloadFunction = (\n options: {\n url: URL;\n isUrlSupportedByModel: boolean;\n }[],\n) => PromiseLike<\n ({ data: Uint8Array; mediaType: string | undefined } | null)[]\n>;\n\n/**\n * Generation settings that can be passed to the model.\n * These map directly to LanguageModelV4CallOptions.\n */\nexport interface GenerationSettings {\n /**\n * Maximum number of tokens to generate.\n */\n maxOutputTokens?: number;\n\n /**\n * Temperature setting. The range depends on the provider and model.\n * It is recommended to set either `temperature` or `topP`, but not both.\n */\n temperature?: number;\n\n /**\n * Nucleus sampling. This is a number between 0 and 1.\n * E.g. 0.1 would mean that only tokens with the top 10% probability mass are considered.\n * It is recommended to set either `temperature` or `topP`, but not both.\n */\n topP?: number;\n\n /**\n * Only sample from the top K options for each subsequent token.\n * Used to remove \"long tail\" low probability responses.\n * Recommended for advanced use cases only. You usually only need to use temperature.\n */\n topK?: number;\n\n /**\n * Presence penalty setting. It affects the likelihood of the model to\n * repeat information that is already in the prompt.\n * The presence penalty is a number between -1 (increase repetition)\n * and 1 (maximum penalty, decrease repetition). 0 means no penalty.\n */\n presencePenalty?: number;\n\n /**\n * Frequency penalty setting. It affects the likelihood of the model\n * to repeatedly use the same words or phrases.\n * The frequency penalty is a number between -1 (increase repetition)\n * and 1 (maximum penalty, decrease repetition). 0 means no penalty.\n */\n frequencyPenalty?: number;\n\n /**\n * Stop sequences. If set, the model will stop generating text when one of the stop sequences is generated.\n * Providers may have limits on the number of stop sequences.\n */\n stopSequences?: string[];\n\n /**\n * The seed (integer) to use for random sampling. If set and supported\n * by the model, calls will generate deterministic results.\n */\n seed?: number;\n\n /**\n * Maximum number of retries. Set to 0 to disable retries.\n * Note: In workflow context, retries are typically handled by the workflow step mechanism.\n * @default 2\n */\n maxRetries?: number;\n\n /**\n * Abort signal for cancelling the operation.\n */\n abortSignal?: AbortSignal;\n\n /**\n * Additional HTTP headers to be sent with the request.\n * Only applicable for HTTP-based providers.\n */\n headers?: Record<string, string | undefined>;\n\n /**\n * Additional provider-specific options. They are passed through\n * to the provider from the AI SDK and enable provider-specific\n * functionality that can be fully encapsulated in the provider.\n */\n providerOptions?: ProviderOptions;\n}\n\n/**\n * Information passed to the prepareStep callback.\n */\nexport interface PrepareStepInfo<TTools extends ToolSet = ToolSet> {\n /**\n * The current model configuration (string or function).\n * The function should return a LanguageModelV4 instance.\n */\n model: LanguageModel;\n\n /**\n * The current step number (0-indexed).\n */\n stepNumber: number;\n\n /**\n * All previous steps with their results.\n */\n steps: StepResult<TTools, any>[];\n\n /**\n * The messages that will be sent to the model.\n * This is the LanguageModelV4Prompt format used internally.\n */\n messages: LanguageModelV4Prompt;\n\n /**\n * The context passed via the experimental_context setting (experimental).\n */\n experimental_context: unknown;\n}\n\n/**\n * Return type from the prepareStep callback.\n * All properties are optional - only return the ones you want to override.\n */\nexport interface PrepareStepResult extends Partial<GenerationSettings> {\n /**\n * Override the model for this step.\n */\n model?: LanguageModel;\n\n /**\n * Override the system message for this step.\n */\n system?: string;\n\n /**\n * Override the messages for this step.\n * Use this for context management or message injection.\n */\n messages?: LanguageModelV4Prompt;\n\n /**\n * Override the tool choice for this step.\n */\n toolChoice?: ToolChoice<ToolSet>;\n\n /**\n * Override the active tools for this step.\n * Limits the tools that are available for the model to call.\n */\n activeTools?: string[];\n\n /**\n * Context that is passed into tool execution. Experimental.\n * Changing the context will affect the context in this step and all subsequent steps.\n */\n experimental_context?: unknown;\n}\n\n/**\n * Callback function called before each step in the agent loop.\n * Use this to modify settings, manage context, or implement dynamic behavior.\n */\nexport type PrepareStepCallback<TTools extends ToolSet = ToolSet> = (\n info: PrepareStepInfo<TTools>,\n) => PrepareStepResult | Promise<PrepareStepResult>;\n\n/**\n * Options passed to the prepareCall callback.\n */\nexport interface PrepareCallOptions<\n TTools extends ToolSet = ToolSet,\n> extends Partial<GenerationSettings> {\n model: LanguageModel;\n tools: TTools;\n instructions?: string | SystemModelMessage | Array<SystemModelMessage>;\n toolChoice?: ToolChoice<TTools>;\n experimental_telemetry?: TelemetryOptions;\n experimental_context?: unknown;\n messages: ModelMessage[];\n}\n\n/**\n * Result of the prepareCall callback. All fields are optional —\n * only returned fields override the defaults.\n * Note: `tools` cannot be overridden via prepareCall because they are\n * bound at construction time for type safety.\n */\nexport type PrepareCallResult<TTools extends ToolSet = ToolSet> = Partial<\n Omit<PrepareCallOptions<TTools>, 'tools'>\n>;\n\n/**\n * Callback called once before the agent loop starts to transform call parameters.\n */\nexport type PrepareCallCallback<TTools extends ToolSet = ToolSet> = (\n options: PrepareCallOptions<TTools>,\n) => PrepareCallResult<TTools> | Promise<PrepareCallResult<TTools>>;\n\n/**\n * Configuration options for creating a {@link WorkflowAgent} instance.\n */\nexport interface WorkflowAgentOptions<\n TTools extends ToolSet = ToolSet,\n> extends GenerationSettings {\n /**\n * The id of the agent.\n */\n id?: string;\n\n /**\n * The model provider to use for the agent.\n *\n * This should be a string compatible with the Vercel AI Gateway (e.g., 'anthropic/claude-opus'),\n * or a LanguageModelV4 instance from a provider.\n */\n model: LanguageModel;\n\n /**\n * A set of tools available to the agent.\n * Tools can be implemented as workflow steps for automatic retries and persistence,\n * or as regular workflow-level logic using core library features like sleep() and Hooks.\n */\n tools?: TTools;\n\n /**\n * Agent instructions. Can be a string, a SystemModelMessage, or an array of SystemModelMessages.\n * Supports provider-specific options (e.g., caching) when using the SystemModelMessage form.\n */\n instructions?: string | SystemModelMessage | Array<SystemModelMessage>;\n\n /**\n * Optional system prompt to guide the agent's behavior.\n * @deprecated Use `instructions` instead.\n */\n system?: string;\n\n /**\n * The tool choice strategy. Default: 'auto'.\n */\n toolChoice?: ToolChoice<TTools>;\n\n /**\n * Optional telemetry configuration (experimental).\n */\n experimental_telemetry?: TelemetryOptions;\n\n /**\n * Default context that is passed into tool execution for every stream call on this agent.\n *\n * Per-stream `experimental_context` values passed to `stream()` override this default.\n * Experimental (can break in patch releases).\n * @default undefined\n */\n experimental_context?: unknown;\n\n /**\n * Default stop condition for the agent loop. When the condition is an array,\n * any of the conditions can be met to stop the generation.\n *\n * Per-stream `stopWhen` values passed to `stream()` override this default.\n */\n stopWhen?:\n | StopCondition<NoInfer<ToolSet>, any>\n | Array<StopCondition<NoInfer<ToolSet>, any>>;\n\n /**\n * Default set of active tools that limits which tools the model can call,\n * without changing the tool call and result types in the result.\n *\n * Per-stream `activeTools` values passed to `stream()` override this default.\n */\n activeTools?: Array<keyof NoInfer<TTools>>;\n\n /**\n * Default output specification for structured outputs.\n * Use `Output.object({ schema })` for structured output or `Output.text()` for text output.\n *\n * Per-stream `output` values passed to `stream()` override this default.\n */\n output?: OutputSpecification<any, any>;\n\n /**\n * Default function that attempts to repair a tool call that failed to parse.\n *\n * Per-stream `experimental_repairToolCall` values passed to `stream()` override this default.\n */\n experimental_repairToolCall?: ToolCallRepairFunction<TTools>;\n\n /**\n * Default custom download function to use for URLs.\n *\n * Per-stream `experimental_download` values passed to `stream()` override this default.\n */\n experimental_download?: DownloadFunction;\n\n /**\n * Default callback function called before each step in the agent loop.\n * Use this to modify settings, manage context, or inject messages dynamically\n * for every stream call on this agent instance.\n *\n * Per-stream `prepareStep` values passed to `stream()` override this default.\n */\n prepareStep?: PrepareStepCallback<TTools>;\n\n /**\n * Callback function to be called after each step completes.\n */\n onStepFinish?: WorkflowAgentOnStepFinishCallback<ToolSet>;\n\n /**\n * Callback that is called when the LLM response and all request tool executions are finished.\n */\n onFinish?: WorkflowAgentOnFinishCallback<ToolSet>;\n\n /**\n * Callback called when the agent starts streaming, before any LLM calls.\n */\n experimental_onStart?: WorkflowAgentOnStartCallback;\n\n /**\n * Callback called before each step (LLM call) begins.\n */\n experimental_onStepStart?: WorkflowAgentOnStepStartCallback;\n\n /**\n * Callback called before a tool's execute function runs.\n */\n experimental_onToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback;\n\n /**\n * Callback called after a tool execution completes.\n */\n experimental_onToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback;\n\n /**\n * Prepare the parameters for the stream call.\n * Called once before the agent loop starts. Use this to transform\n * model, tools, instructions, or other settings based on runtime context.\n */\n prepareCall?: PrepareCallCallback<TTools>;\n}\n\n/**\n * Callback that is called when the LLM response and all request tool executions are finished.\n */\nexport type WorkflowAgentOnFinishCallback<\n TTools extends ToolSet = ToolSet,\n OUTPUT = never,\n> = (event: {\n /**\n * Details for all steps.\n */\n readonly steps: StepResult<TTools, any>[];\n\n /**\n * The final messages including all tool calls and results.\n */\n readonly messages: ModelMessage[];\n\n /**\n * The text output from the last step.\n */\n readonly text: string;\n\n /**\n * The finish reason from the last step.\n */\n readonly finishReason: FinishReason;\n\n /**\n * The total token usage across all steps.\n */\n readonly totalUsage: LanguageModelUsage;\n\n /**\n * Context that is passed into tool execution.\n */\n readonly experimental_context: unknown;\n\n /**\n * The generated structured output. It uses the `output` specification.\n * Only available when `output` is specified.\n */\n readonly output: OUTPUT;\n}) => PromiseLike<void> | void;\n\n/**\n * Callback that is invoked when an error occurs during streaming.\n */\nexport type WorkflowAgentOnErrorCallback = (event: {\n error: unknown;\n}) => PromiseLike<void> | void;\n\n/**\n * Callback that is set using the `onAbort` option.\n */\nexport type WorkflowAgentOnAbortCallback<TTools extends ToolSet = ToolSet> =\n (event: {\n /**\n * Details for all previously finished steps.\n */\n readonly steps: StepResult<TTools, any>[];\n }) => PromiseLike<void> | void;\n\n/**\n * Callback that is called when the agent starts streaming, before any LLM calls.\n */\nexport type WorkflowAgentOnStartCallback = (event: {\n /** The model being used */\n readonly model: LanguageModel;\n /** The messages being sent */\n readonly messages: ModelMessage[];\n}) => PromiseLike<void> | void;\n\n/**\n * Callback that is called before each step (LLM call) begins.\n */\nexport type WorkflowAgentOnStepStartCallback<TTools extends ToolSet = ToolSet> =\n (event: {\n /** The current step number (0-based) */\n readonly stepNumber: number;\n /** The model being used for this step */\n readonly model: LanguageModel;\n /** The messages being sent for this step */\n readonly messages: ModelMessage[];\n /** Results from all previously finished steps */\n readonly steps: ReadonlyArray<StepResult<TTools, any>>;\n }) => PromiseLike<void> | void;\n\n/**\n * Callback that is called before a tool's execute function runs.\n */\nexport type WorkflowAgentOnToolExecutionStartCallback = (event: {\n /** The tool call being executed */\n readonly toolCall: ToolCall;\n /** The current step number (0-based) */\n readonly stepNumber: number;\n}) => PromiseLike<void> | void;\n\n/**\n * Callback that is called after a tool execution completes.\n * Uses a discriminated union pattern: check `success` to determine\n * whether `output` or `error` is available.\n */\nexport type WorkflowAgentOnToolExecutionEndCallback = (\n event:\n | {\n /** The tool call that was executed */\n readonly toolCall: ToolCall;\n /** The current step number (0-based) */\n readonly stepNumber: number;\n /** Execution time in milliseconds */\n readonly durationMs: number;\n /** Whether the tool call succeeded */\n readonly success: true;\n /** The tool result */\n readonly output: unknown;\n readonly error?: never;\n }\n | {\n /** The tool call that was executed */\n readonly toolCall: ToolCall;\n /** The current step number (0-based) */\n readonly stepNumber: number;\n /** Execution time in milliseconds */\n readonly durationMs: number;\n /** Whether the tool call succeeded */\n readonly success: false;\n /** The error that occurred */\n readonly error: unknown;\n readonly output?: never;\n },\n) => PromiseLike<void> | void;\n\n/**\n * Options for the {@link WorkflowAgent.stream} method.\n */\nexport type WorkflowAgentStreamOptions<\n TTools extends ToolSet = ToolSet,\n OUTPUT = never,\n PARTIAL_OUTPUT = never,\n> = Partial<GenerationSettings> &\n (\n | {\n /**\n * A prompt. It can be either a text prompt or a list of messages.\n *\n * You can either use `prompt` or `messages` but not both.\n */\n prompt: string | Array<ModelMessage>;\n\n /**\n * A list of messages.\n *\n * You can either use `prompt` or `messages` but not both.\n */\n messages?: never;\n }\n | {\n /**\n * The conversation messages to process. Should follow the AI SDK's ModelMessage format.\n *\n * You can either use `prompt` or `messages` but not both.\n */\n messages: Array<ModelMessage>;\n\n /**\n * A prompt. It can be either a text prompt or a list of messages.\n *\n * You can either use `prompt` or `messages` but not both.\n */\n prompt?: never;\n }\n ) & {\n /**\n * Optional system prompt override. If provided, overrides the system prompt from the constructor.\n */\n system?: string;\n\n /**\n * A WritableStream that receives raw LanguageModelV4StreamPart chunks in real-time\n * as the model generates them. This enables streaming to the client without\n * coupling WorkflowAgent to UIMessageChunk format.\n *\n * Convert to UIMessageChunks at the response boundary using\n * `createUIMessageChunkTransform()` from `@ai-sdk/workflow`.\n *\n * @example\n * ```typescript\n * // In the workflow:\n * await agent.stream({\n * messages,\n * writable: getWritable<ModelCallStreamPart>(),\n * });\n *\n * // In the route handler:\n * return createUIMessageStreamResponse({\n * stream: run.readable.pipeThrough(createModelCallToUIChunkTransform()),\n * });\n * ```\n */\n writable?: WritableStream<ModelCallStreamPart<ToolSet>>;\n\n /**\n * Condition for stopping the generation when there are tool results in the last step.\n * When the condition is an array, any of the conditions can be met to stop the generation.\n */\n stopWhen?:\n | StopCondition<NoInfer<ToolSet>, any>\n | Array<StopCondition<NoInfer<ToolSet>, any>>;\n\n /**\n * The tool choice strategy. Default: 'auto'.\n * Overrides the toolChoice from the constructor if provided.\n */\n toolChoice?: ToolChoice<TTools>;\n\n /**\n * Limits the tools that are available for the model to call without\n * changing the tool call and result types in the result.\n */\n activeTools?: Array<keyof NoInfer<TTools>>;\n\n /**\n * Optional telemetry configuration (experimental).\n */\n experimental_telemetry?: TelemetryOptions;\n\n /**\n * Context that is passed into tool execution.\n * Experimental (can break in patch releases).\n * @default undefined\n */\n experimental_context?: unknown;\n\n /**\n * Optional specification for parsing structured outputs from the LLM response.\n * Use `Output.object({ schema })` for structured output or `Output.text()` for text output.\n *\n * @example\n * ```typescript\n * import { Output } from '@workflow/ai';\n * import { z } from 'zod';\n *\n * const result = await agent.stream({\n * messages: [...],\n * writable: getWritable(),\n * output: Output.object({\n * schema: z.object({\n * sentiment: z.enum(['positive', 'negative', 'neutral']),\n * confidence: z.number(),\n * }),\n * }),\n * });\n *\n * console.log(result.output); // { sentiment: 'positive', confidence: 0.95 }\n * ```\n */\n output?: OutputSpecification<OUTPUT, PARTIAL_OUTPUT>;\n\n /**\n * Whether to include raw chunks from the provider in the stream.\n * When enabled, you will receive raw chunks with type 'raw' that contain the unprocessed data from the provider.\n * This allows access to cutting-edge provider features not yet wrapped by the AI SDK.\n * Defaults to false.\n */\n includeRawChunks?: boolean;\n\n /**\n * A function that attempts to repair a tool call that failed to parse.\n */\n experimental_repairToolCall?: ToolCallRepairFunction<TTools>;\n\n /**\n * Optional stream transformations.\n * They are applied in the order they are provided.\n * The stream transformations must maintain the stream structure for streamText to work correctly.\n */\n experimental_transform?:\n | StreamTextTransform<TTools>\n | Array<StreamTextTransform<TTools>>;\n\n /**\n * Custom download function to use for URLs.\n * By default, files are downloaded if the model does not support the URL for the given media type.\n */\n experimental_download?: DownloadFunction;\n\n /**\n * Callback function to be called after each step completes.\n */\n onStepFinish?: WorkflowAgentOnStepFinishCallback<TTools>;\n\n /**\n * Callback that is invoked when an error occurs during streaming.\n * You can use it to log errors.\n */\n onError?: WorkflowAgentOnErrorCallback;\n\n /**\n * Callback that is called when the LLM response and all request tool executions\n * (for tools that have an `execute` function) are finished.\n */\n onFinish?: WorkflowAgentOnFinishCallback<TTools, OUTPUT>;\n\n /**\n * Callback that is called when the operation is aborted.\n */\n onAbort?: WorkflowAgentOnAbortCallback<TTools>;\n\n /**\n * Callback called when the agent starts streaming, before any LLM calls.\n */\n experimental_onStart?: WorkflowAgentOnStartCallback;\n\n /**\n * Callback called before each step (LLM call) begins.\n */\n experimental_onStepStart?: WorkflowAgentOnStepStartCallback;\n\n /**\n * Callback called before a tool's execute function runs.\n */\n experimental_onToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback;\n\n /**\n * Callback called after a tool execution completes.\n */\n experimental_onToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback;\n\n /**\n * Callback function called before each step in the agent loop.\n * Use this to modify settings, manage context, or inject messages dynamically.\n *\n * @example\n * ```typescript\n * prepareStep: async ({ messages, stepNumber }) => {\n * // Inject messages from a queue\n * const queuedMessages = await getQueuedMessages();\n * if (queuedMessages.length > 0) {\n * return {\n * messages: [...messages, ...queuedMessages],\n * };\n * }\n * return {};\n * }\n * ```\n */\n prepareStep?: PrepareStepCallback<TTools>;\n\n /**\n * Timeout in milliseconds for the stream operation.\n * When specified, creates an AbortSignal that will abort the operation after the given time.\n * If both `timeout` and `abortSignal` are provided, whichever triggers first will abort.\n */\n timeout?: number;\n\n /**\n * Whether to send a 'finish' chunk to the writable stream when streaming completes.\n * @default true\n */\n sendFinish?: boolean;\n\n /**\n * Whether to prevent the writable stream from being closed after streaming completes.\n * @default false\n */\n preventClose?: boolean;\n };\n\n/**\n * A tool call made by the model. Matches the AI SDK's tool call shape.\n */\nexport interface ToolCall {\n /** Discriminator for content part arrays */\n type: 'tool-call';\n /** The unique identifier of the tool call */\n toolCallId: string;\n /** The name of the tool that was called */\n toolName: string;\n /** The parsed input arguments for the tool call */\n input: unknown;\n}\n\n/**\n * A tool result from executing a tool. Matches the AI SDK's tool result shape.\n */\nexport interface ToolResult {\n /** Discriminator for content part arrays */\n type: 'tool-result';\n /** The tool call ID this result corresponds to */\n toolCallId: string;\n /** The name of the tool that was executed */\n toolName: string;\n /** The parsed input arguments that were passed to the tool */\n input: unknown;\n /** The output produced by the tool */\n output: unknown;\n}\n\n/**\n * Result of the WorkflowAgent.stream method.\n */\nexport interface WorkflowAgentStreamResult<\n TTools extends ToolSet = ToolSet,\n OUTPUT = never,\n> {\n /**\n * The final messages including all tool calls and results.\n */\n messages: ModelMessage[];\n\n /**\n * Details for all steps.\n */\n steps: StepResult<TTools, any>[];\n\n /**\n * The tool calls from the last step.\n * Includes all tool calls regardless of whether they were executed.\n *\n * When the agent stops because a tool without an `execute` function was called,\n * this array will contain those calls. Compare with `toolResults` to find\n * unresolved tool calls that need client-side handling:\n *\n * ```ts\n * const unresolved = result.toolCalls.filter(\n * tc => !result.toolResults.some(tr => tr.toolCallId === tc.toolCallId)\n * );\n * ```\n *\n * This matches the AI SDK's `GenerateTextResult.toolCalls` behavior.\n */\n toolCalls: ToolCall[];\n\n /**\n * The tool results from the last step.\n * Only includes results for tools that were actually executed (server-side or provider-executed).\n * Tools without an `execute` function will NOT have entries here.\n *\n * This matches the AI SDK's `GenerateTextResult.toolResults` behavior.\n */\n toolResults: ToolResult[];\n\n /**\n * The generated structured output. It uses the `output` specification.\n * Only available when `output` is specified.\n */\n output: OUTPUT;\n}\n\n/**\n * A class for building durable AI agents within workflows.\n *\n * WorkflowAgent enables you to create AI-powered agents that can maintain state\n * across workflow steps, call tools, and gracefully handle interruptions and resumptions.\n * It integrates seamlessly with the AI SDK and the Workflow DevKit for\n * production-grade reliability.\n *\n * @example\n * ```typescript\n * const agent = new WorkflowAgent({\n * model: 'anthropic/claude-opus',\n * tools: {\n * getWeather: {\n * description: 'Get weather for a location',\n * inputSchema: z.object({ location: z.string() }),\n * execute: getWeatherStep,\n * },\n * },\n * instructions: 'You are a helpful weather assistant.',\n * });\n *\n * const result = await agent.stream({\n * messages: [{ role: 'user', content: 'What is the weather?' }],\n * });\n * ```\n */\nexport class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {\n /**\n * The id of the agent.\n */\n public readonly id: string | undefined;\n\n private model: LanguageModel;\n /**\n * The tool set configured for this agent.\n */\n public readonly tools: TBaseTools;\n private instructions?:\n | string\n | SystemModelMessage\n | Array<SystemModelMessage>;\n private generationSettings: GenerationSettings;\n private toolChoice?: ToolChoice<TBaseTools>;\n private telemetry?: TelemetryOptions;\n private experimentalContext: unknown;\n private stopWhen?:\n | StopCondition<ToolSet, any>\n | Array<StopCondition<ToolSet, any>>;\n private activeTools?: Array<keyof TBaseTools>;\n private output?: OutputSpecification<any, any>;\n private experimentalRepairToolCall?: ToolCallRepairFunction<TBaseTools>;\n private experimentalDownload?: DownloadFunction;\n private prepareStep?: PrepareStepCallback<TBaseTools>;\n private constructorOnStepFinish?: WorkflowAgentOnStepFinishCallback<ToolSet>;\n private constructorOnFinish?: WorkflowAgentOnFinishCallback<ToolSet>;\n private constructorOnStart?: WorkflowAgentOnStartCallback;\n private constructorOnStepStart?: WorkflowAgentOnStepStartCallback;\n private constructorOnToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback;\n private constructorOnToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback;\n private prepareCall?: PrepareCallCallback<TBaseTools>;\n\n constructor(options: WorkflowAgentOptions<TBaseTools>) {\n this.id = options.id;\n this.model = options.model;\n this.tools = (options.tools ?? {}) as TBaseTools;\n // `instructions` takes precedence over deprecated `system`\n this.instructions = options.instructions ?? options.system;\n this.toolChoice = options.toolChoice;\n this.telemetry = options.experimental_telemetry;\n this.experimentalContext = options.experimental_context;\n this.stopWhen = options.stopWhen;\n this.activeTools = options.activeTools;\n this.output = options.output;\n this.experimentalRepairToolCall = options.experimental_repairToolCall;\n this.experimentalDownload = options.experimental_download;\n this.prepareStep = options.prepareStep;\n this.constructorOnStepFinish = options.onStepFinish;\n this.constructorOnFinish = options.onFinish;\n this.constructorOnStart = options.experimental_onStart;\n this.constructorOnStepStart = options.experimental_onStepStart;\n this.constructorOnToolExecutionStart =\n options.experimental_onToolExecutionStart;\n this.constructorOnToolExecutionEnd =\n options.experimental_onToolExecutionEnd;\n this.prepareCall = options.prepareCall;\n\n // Extract generation settings\n this.generationSettings = {\n maxOutputTokens: options.maxOutputTokens,\n temperature: options.temperature,\n topP: options.topP,\n topK: options.topK,\n presencePenalty: options.presencePenalty,\n frequencyPenalty: options.frequencyPenalty,\n stopSequences: options.stopSequences,\n seed: options.seed,\n maxRetries: options.maxRetries,\n abortSignal: options.abortSignal,\n headers: options.headers,\n providerOptions: options.providerOptions,\n };\n }\n\n generate() {\n throw new Error('Not implemented');\n }\n\n async stream<\n TTools extends TBaseTools = TBaseTools,\n OUTPUT = never,\n PARTIAL_OUTPUT = never,\n >(\n options: WorkflowAgentStreamOptions<TTools, OUTPUT, PARTIAL_OUTPUT>,\n ): Promise<WorkflowAgentStreamResult<TTools, OUTPUT>> {\n // Call prepareCall to transform parameters before the agent loop\n let effectiveModel: LanguageModel = this.model;\n let effectiveInstructions = options.system ?? this.instructions;\n let effectivePrompt: string | Array<ModelMessage> | undefined =\n options.prompt;\n let effectiveMessages: Array<ModelMessage> | undefined = options.messages;\n let effectiveGenerationSettings = { ...this.generationSettings };\n let effectiveExperimentalContext =\n options.experimental_context ?? this.experimentalContext;\n let effectiveToolChoiceFromPrepare = options.toolChoice ?? this.toolChoice;\n let effectiveTelemetryFromPrepare =\n options.experimental_telemetry ?? this.telemetry;\n\n // Resolve messages for prepareCall: use messages directly, or convert prompt\n const resolvedMessagesForPrepareCall: ModelMessage[] =\n effectiveMessages ??\n (typeof effectivePrompt === 'string'\n ? [{ role: 'user' as const, content: effectivePrompt }]\n : (effectivePrompt as ModelMessage[])) ??\n [];\n\n if (this.prepareCall) {\n const prepared = await this.prepareCall({\n model: effectiveModel,\n tools: this.tools,\n instructions: effectiveInstructions,\n toolChoice: effectiveToolChoiceFromPrepare as ToolChoice<TBaseTools>,\n experimental_telemetry: effectiveTelemetryFromPrepare,\n experimental_context: effectiveExperimentalContext,\n messages: resolvedMessagesForPrepareCall,\n ...effectiveGenerationSettings,\n } as PrepareCallOptions<TBaseTools>);\n\n if (prepared.model !== undefined) effectiveModel = prepared.model;\n if (prepared.instructions !== undefined)\n effectiveInstructions = prepared.instructions;\n if (prepared.messages !== undefined) {\n effectiveMessages = prepared.messages as Array<ModelMessage>;\n effectivePrompt = undefined; // messages from prepareCall take precedence\n }\n if (prepared.experimental_context !== undefined)\n effectiveExperimentalContext = prepared.experimental_context;\n if (prepared.toolChoice !== undefined)\n effectiveToolChoiceFromPrepare =\n prepared.toolChoice as ToolChoice<TBaseTools>;\n if (prepared.experimental_telemetry !== undefined)\n effectiveTelemetryFromPrepare = prepared.experimental_telemetry;\n if (prepared.maxOutputTokens !== undefined)\n effectiveGenerationSettings.maxOutputTokens = prepared.maxOutputTokens;\n if (prepared.temperature !== undefined)\n effectiveGenerationSettings.temperature = prepared.temperature;\n if (prepared.topP !== undefined)\n effectiveGenerationSettings.topP = prepared.topP;\n if (prepared.topK !== undefined)\n effectiveGenerationSettings.topK = prepared.topK;\n if (prepared.presencePenalty !== undefined)\n effectiveGenerationSettings.presencePenalty = prepared.presencePenalty;\n if (prepared.frequencyPenalty !== undefined)\n effectiveGenerationSettings.frequencyPenalty =\n prepared.frequencyPenalty;\n if (prepared.stopSequences !== undefined)\n effectiveGenerationSettings.stopSequences = prepared.stopSequences;\n if (prepared.seed !== undefined)\n effectiveGenerationSettings.seed = prepared.seed;\n if (prepared.headers !== undefined)\n effectiveGenerationSettings.headers = prepared.headers;\n if (prepared.providerOptions !== undefined)\n effectiveGenerationSettings.providerOptions = prepared.providerOptions;\n }\n\n const prompt = await standardizePrompt({\n system: effectiveInstructions,\n ...(effectivePrompt != null\n ? { prompt: effectivePrompt }\n : { messages: effectiveMessages! }),\n });\n\n // Process tool approval responses before starting the agent loop.\n // This mirrors how stream-text.ts handles tool-approval-response parts:\n // approved tools are executed, denied tools get denial results, and\n // approval parts are stripped from the messages.\n const { approvedToolApprovals, deniedToolApprovals } =\n collectToolApprovalsFromMessages(prompt.messages);\n\n if (approvedToolApprovals.length > 0 || deniedToolApprovals.length > 0) {\n const _toolResultMessages: ModelMessage[] = [];\n const toolResultContent: Array<{\n type: 'tool-result';\n toolCallId: string;\n toolName: string;\n output:\n | { type: 'text'; value: string }\n | { type: 'json'; value: JSONValue }\n | { type: 'execution-denied'; reason: string | undefined };\n }> = [];\n\n // Execute approved tools\n for (const approval of approvedToolApprovals) {\n const tool = (this.tools as ToolSet)[approval.toolName];\n if (tool && typeof tool.execute === 'function') {\n try {\n const { execute } = tool;\n const toolResult = await execute(approval.input, {\n toolCallId: approval.toolCallId,\n messages: [],\n context: effectiveExperimentalContext,\n });\n toolResultContent.push({\n type: 'tool-result' as const,\n toolCallId: approval.toolCallId,\n toolName: approval.toolName,\n output:\n typeof toolResult === 'string'\n ? { type: 'text' as const, value: toolResult }\n : { type: 'json' as const, value: toolResult },\n });\n } catch (error) {\n toolResultContent.push({\n type: 'tool-result' as const,\n toolCallId: approval.toolCallId,\n toolName: approval.toolName,\n output: {\n type: 'text' as const,\n value: getErrorMessage(error),\n },\n });\n }\n }\n }\n\n // Create denial results for denied tools\n for (const denial of deniedToolApprovals) {\n toolResultContent.push({\n type: 'tool-result' as const,\n toolCallId: denial.toolCallId,\n toolName: denial.toolName,\n output: {\n type: 'execution-denied' as const,\n reason: denial.reason,\n },\n });\n }\n\n // Strip approval parts from messages and inject tool results\n const cleanedMessages: ModelMessage[] = [];\n for (const msg of prompt.messages) {\n if (msg.role === 'assistant' && Array.isArray(msg.content)) {\n const filtered = (msg.content as any[]).filter(\n (p: any) => p.type !== 'tool-approval-request',\n );\n if (filtered.length > 0) {\n cleanedMessages.push({ ...msg, content: filtered });\n }\n } else if (msg.role === 'tool') {\n const filtered = (msg.content as any[]).filter(\n (p: any) => p.type !== 'tool-approval-response',\n );\n if (filtered.length > 0) {\n cleanedMessages.push({ ...msg, content: filtered });\n }\n } else {\n cleanedMessages.push(msg);\n }\n }\n\n // Add tool results as a new tool message\n if (toolResultContent.length > 0) {\n cleanedMessages.push({\n role: 'tool',\n content: toolResultContent,\n } as ModelMessage);\n }\n\n prompt.messages = cleanedMessages;\n\n // Write tool results and step boundaries to the stream so the UI\n // can transition approved/denied tool parts to the correct state\n // and properly separate them from the subsequent model step.\n if (options.writable && toolResultContent.length > 0) {\n const approvedResults = toolResultContent\n .filter(r => r.output.type !== 'execution-denied')\n .map(r => ({\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: approvedToolApprovals.find(\n a => a.toolCallId === r.toolCallId,\n )?.input,\n output: 'value' in r.output ? r.output.value : undefined,\n }));\n const deniedResults = toolResultContent\n .filter(r => r.output.type === 'execution-denied')\n .map(r => ({ toolCallId: r.toolCallId }));\n await writeApprovalToolResults(\n options.writable,\n approvedResults,\n deniedResults,\n );\n }\n }\n\n const modelPrompt = await convertToLanguageModelPrompt({\n prompt,\n supportedUrls: {},\n download: options.experimental_download ?? this.experimentalDownload,\n });\n\n const effectiveAbortSignal = mergeAbortSignals(\n options.abortSignal ?? effectiveGenerationSettings.abortSignal,\n options.timeout != null\n ? AbortSignal.timeout(options.timeout)\n : undefined,\n );\n\n // Merge generation settings: constructor defaults < prepareCall < stream options\n const mergedGenerationSettings: GenerationSettings = {\n ...effectiveGenerationSettings,\n ...(options.maxOutputTokens !== undefined && {\n maxOutputTokens: options.maxOutputTokens,\n }),\n ...(options.temperature !== undefined && {\n temperature: options.temperature,\n }),\n ...(options.topP !== undefined && { topP: options.topP }),\n ...(options.topK !== undefined && { topK: options.topK }),\n ...(options.presencePenalty !== undefined && {\n presencePenalty: options.presencePenalty,\n }),\n ...(options.frequencyPenalty !== undefined && {\n frequencyPenalty: options.frequencyPenalty,\n }),\n ...(options.stopSequences !== undefined && {\n stopSequences: options.stopSequences,\n }),\n ...(options.seed !== undefined && { seed: options.seed }),\n ...(options.maxRetries !== undefined && {\n maxRetries: options.maxRetries,\n }),\n ...(effectiveAbortSignal !== undefined && {\n abortSignal: effectiveAbortSignal,\n }),\n ...(options.headers !== undefined && { headers: options.headers }),\n ...(options.providerOptions !== undefined && {\n providerOptions: options.providerOptions,\n }),\n };\n\n // Merge constructor + stream callbacks (constructor first, then stream)\n const mergedOnStepFinish = mergeCallbacks(\n this.constructorOnStepFinish as\n | WorkflowAgentOnStepFinishCallback<TTools>\n | undefined,\n options.onStepFinish,\n );\n const mergedOnFinish = mergeCallbacks(\n this.constructorOnFinish as\n | WorkflowAgentOnFinishCallback<TTools, OUTPUT>\n | undefined,\n options.onFinish,\n );\n const mergedOnStart = mergeCallbacks(\n this.constructorOnStart,\n options.experimental_onStart,\n );\n const mergedOnStepStart = mergeCallbacks(\n this.constructorOnStepStart,\n options.experimental_onStepStart,\n );\n const mergedOnToolExecutionStart = mergeCallbacks(\n this.constructorOnToolExecutionStart,\n options.experimental_onToolExecutionStart,\n );\n const mergedOnToolExecutionEnd = mergeCallbacks(\n this.constructorOnToolExecutionEnd,\n options.experimental_onToolExecutionEnd,\n );\n\n // Determine effective tool choice\n const effectiveToolChoice = effectiveToolChoiceFromPrepare;\n\n // Merge telemetry settings\n const effectiveTelemetry = effectiveTelemetryFromPrepare;\n\n // Filter tools if activeTools is specified (stream-level overrides constructor default)\n const effectiveActiveTools = options.activeTools ?? this.activeTools;\n const effectiveTools =\n effectiveActiveTools && effectiveActiveTools.length > 0\n ? (filterActiveTools({\n tools: this.tools,\n activeTools: effectiveActiveTools as string[],\n }) ?? this.tools)\n : this.tools;\n\n // Initialize context\n let experimentalContext = effectiveExperimentalContext;\n\n const steps: StepResult<TTools, any>[] = [];\n\n // Track tool calls and results from the last step for the result\n let lastStepToolCalls: ToolCall[] = [];\n let lastStepToolResults: ToolResult[] = [];\n\n // Call onStart before the agent loop\n if (mergedOnStart) {\n await mergedOnStart({\n model: effectiveModel,\n messages: prompt.messages,\n });\n }\n\n // Helper to wrap executeTool with onToolExecutionStart/onToolExecutionEnd callbacks\n const executeToolWithCallbacks = async (\n toolCall: { toolCallId: string; toolName: string; input: unknown },\n tools: ToolSet,\n messages: LanguageModelV4Prompt,\n context?: unknown,\n currentStepNumber: number = 0,\n ): Promise<LanguageModelV4ToolResultPart> => {\n const toolCallEvent: ToolCall = {\n type: 'tool-call',\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n input: toolCall.input,\n };\n\n if (mergedOnToolExecutionStart) {\n await mergedOnToolExecutionStart({\n toolCall: toolCallEvent,\n stepNumber: currentStepNumber,\n });\n }\n\n const startTime = Date.now();\n let result: LanguageModelV4ToolResultPart;\n try {\n result = await executeTool(toolCall, tools, messages, context);\n } catch (err) {\n const durationMs = Date.now() - startTime;\n if (mergedOnToolExecutionEnd) {\n await mergedOnToolExecutionEnd({\n toolCall: toolCallEvent,\n stepNumber: currentStepNumber,\n durationMs,\n success: false,\n error: err,\n });\n }\n throw err;\n }\n\n const durationMs = Date.now() - startTime;\n if (mergedOnToolExecutionEnd) {\n const isError =\n result.output &&\n 'type' in result.output &&\n (result.output.type === 'error-text' ||\n result.output.type === 'error-json');\n if (isError) {\n await mergedOnToolExecutionEnd({\n toolCall: toolCallEvent,\n stepNumber: currentStepNumber,\n durationMs,\n success: false,\n error: 'value' in result.output ? result.output.value : undefined,\n });\n } else {\n await mergedOnToolExecutionEnd({\n toolCall: toolCallEvent,\n stepNumber: currentStepNumber,\n durationMs,\n success: true,\n output:\n result.output && 'value' in result.output\n ? result.output.value\n : undefined,\n });\n }\n }\n return result;\n };\n\n // Check for abort before starting\n if (mergedGenerationSettings.abortSignal?.aborted) {\n if (options.onAbort) {\n await options.onAbort({ steps });\n }\n return {\n messages: prompt.messages,\n steps,\n toolCalls: [],\n toolResults: [],\n output: undefined as OUTPUT,\n };\n }\n\n const iterator = streamTextIterator({\n model: effectiveModel,\n tools: effectiveTools as ToolSet,\n writable: options.writable,\n prompt: modelPrompt,\n stopConditions: options.stopWhen ?? this.stopWhen,\n\n onStepFinish: mergedOnStepFinish,\n onStepStart: mergedOnStepStart,\n onError: options.onError,\n prepareStep:\n options.prepareStep ??\n (this.prepareStep as PrepareStepCallback<ToolSet> | undefined),\n generationSettings: mergedGenerationSettings,\n toolChoice: effectiveToolChoice as ToolChoice<ToolSet>,\n experimental_context: experimentalContext,\n experimental_telemetry: effectiveTelemetry,\n includeRawChunks: options.includeRawChunks ?? false,\n repairToolCall: (options.experimental_repairToolCall ??\n this.experimentalRepairToolCall) as\n | ToolCallRepairFunction<ToolSet>\n | undefined,\n responseFormat: await (options.output ?? this.output)?.responseFormat,\n });\n\n // Track the final conversation messages from the iterator\n let finalMessages: LanguageModelV4Prompt | undefined;\n let encounteredError: unknown;\n let wasAborted = false;\n\n try {\n let result = await iterator.next();\n while (!result.done) {\n // Check for abort during iteration\n if (mergedGenerationSettings.abortSignal?.aborted) {\n wasAborted = true;\n if (options.onAbort) {\n await options.onAbort({ steps });\n }\n break;\n }\n\n const {\n toolCalls,\n messages: iterMessages,\n step,\n context,\n providerExecutedToolResults,\n } = result.value;\n // Capture current step number before pushing (0-based)\n const currentStepNumber = steps.length;\n if (step) {\n steps.push(step as unknown as StepResult<TTools, any>);\n }\n if (context !== undefined) {\n experimentalContext = context;\n }\n\n // Only execute tools if there are tool calls\n if (toolCalls.length > 0) {\n // Separate provider-executed tool calls from client-executed ones\n const nonProviderToolCalls = toolCalls.filter(\n tc => !tc.providerExecuted,\n );\n const providerToolCalls = toolCalls.filter(tc => tc.providerExecuted);\n\n // Check which tools need approval (can be async)\n const approvalNeeded = await Promise.all(\n nonProviderToolCalls.map(async tc => {\n const tool = (effectiveTools as ToolSet)[tc.toolName];\n if (!tool) return false;\n if (tool.needsApproval == null) return false;\n if (typeof tool.needsApproval === 'boolean')\n return tool.needsApproval;\n return tool.needsApproval(tc.input, {\n toolCallId: tc.toolCallId,\n messages: iterMessages as unknown as ModelMessage[],\n context: experimentalContext,\n });\n }),\n );\n\n // Further split non-provider tool calls into:\n // - executable: has execute function and doesn't need approval\n // - paused: no execute function (client-side) OR needs approval\n // Note: missing tools (!tool) are left to executeTool which will throw.\n const executableToolCalls = nonProviderToolCalls.filter((tc, i) => {\n const tool = (effectiveTools as ToolSet)[tc.toolName];\n return (\n (!tool || typeof tool.execute === 'function') &&\n !approvalNeeded[i]\n );\n });\n const pausedToolCalls = nonProviderToolCalls.filter((tc, i) => {\n const tool = (effectiveTools as ToolSet)[tc.toolName];\n return (\n (tool && typeof tool.execute !== 'function') || approvalNeeded[i]\n );\n });\n\n // If there are paused tool calls (client-side or needing approval),\n // stop the loop and return them.\n // This matches AI SDK behavior: tools without execute or needing\n // approval pause the agent loop.\n if (pausedToolCalls.length > 0) {\n // Execute any executable tools that were also called in this step\n const executableResults = await Promise.all(\n executableToolCalls.map(\n (toolCall): Promise<LanguageModelV4ToolResultPart> =>\n executeToolWithCallbacks(\n toolCall,\n effectiveTools as ToolSet,\n iterMessages,\n experimentalContext,\n currentStepNumber,\n ),\n ),\n );\n\n // Collect provider tool results\n const providerResults: LanguageModelV4ToolResultPart[] =\n providerToolCalls.map(toolCall =>\n resolveProviderToolResult(\n toolCall,\n providerExecutedToolResults,\n ),\n );\n\n const resolvedResults = [...executableResults, ...providerResults];\n\n const allToolCalls: ToolCall[] = toolCalls.map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n }));\n\n const allToolResults: ToolResult[] = resolvedResults.map(r => ({\n type: 'tool-result' as const,\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: toolCalls.find(tc => tc.toolCallId === r.toolCallId)\n ?.input,\n output: 'value' in r.output ? r.output.value : undefined,\n }));\n\n if (resolvedResults.length > 0) {\n iterMessages.push({\n role: 'tool',\n content: resolvedResults,\n });\n }\n\n const messages = iterMessages as unknown as ModelMessage[];\n\n if (mergedOnFinish && !wasAborted) {\n const lastStep = steps[steps.length - 1];\n await mergedOnFinish({\n steps,\n messages,\n text: lastStep?.text ?? '',\n finishReason: lastStep?.finishReason ?? 'other',\n totalUsage: aggregateUsage(steps),\n experimental_context: experimentalContext,\n output: undefined as OUTPUT,\n });\n }\n\n // Emit tool-approval-request chunks for tools that need approval\n // so useChat can show the approval UI\n if (options.writable) {\n const approvalToolCalls = pausedToolCalls.filter((_, i) => {\n const tcIndex = nonProviderToolCalls.indexOf(\n pausedToolCalls[i],\n );\n return approvalNeeded[tcIndex];\n });\n if (approvalToolCalls.length > 0) {\n await writeApprovalRequests(\n options.writable,\n approvalToolCalls.map(tc => ({\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n })),\n );\n }\n }\n\n // Close the stream before returning for paused tools\n if (options.writable) {\n const sendFinish = options.sendFinish ?? true;\n const preventClose = options.preventClose ?? false;\n if (sendFinish || !preventClose) {\n await closeStream(options.writable, preventClose, sendFinish);\n }\n }\n\n return {\n messages,\n steps,\n toolCalls: allToolCalls,\n toolResults: allToolResults,\n output: undefined as OUTPUT,\n };\n }\n\n // Execute client tools (all have execute functions at this point)\n const clientToolResults = await Promise.all(\n nonProviderToolCalls.map(\n (toolCall): Promise<LanguageModelV4ToolResultPart> =>\n executeToolWithCallbacks(\n toolCall,\n effectiveTools as ToolSet,\n iterMessages,\n experimentalContext,\n currentStepNumber,\n ),\n ),\n );\n\n // For provider-executed tools, use the results from the stream\n const providerToolResults: LanguageModelV4ToolResultPart[] =\n providerToolCalls.map(toolCall =>\n resolveProviderToolResult(toolCall, providerExecutedToolResults),\n );\n\n // Combine results in the original order\n const toolResults = toolCalls.map(tc => {\n const clientResult = clientToolResults.find(\n r => r.toolCallId === tc.toolCallId,\n );\n if (clientResult) return clientResult;\n const providerResult = providerToolResults.find(\n r => r.toolCallId === tc.toolCallId,\n );\n if (providerResult) return providerResult;\n // This should never happen, but return empty result as fallback\n return {\n type: 'tool-result' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n output: { type: 'text' as const, value: '' },\n };\n });\n\n // Write tool results and step boundaries to the stream so the\n // UI can transition tool parts to output-available state and\n // properly separate multi-step model calls in the message history.\n if (options.writable) {\n await writeToolResultsWithStepBoundary(\n options.writable,\n toolResults.map(r => ({\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: toolCalls.find(tc => tc.toolCallId === r.toolCallId)\n ?.input,\n output: 'value' in r.output ? r.output.value : undefined,\n })),\n );\n }\n\n // Track the tool calls and results for this step\n lastStepToolCalls = toolCalls.map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n }));\n lastStepToolResults = toolResults.map(r => ({\n type: 'tool-result' as const,\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: toolCalls.find(tc => tc.toolCallId === r.toolCallId)?.input,\n output: 'value' in r.output ? r.output.value : undefined,\n }));\n\n result = await iterator.next(toolResults);\n } else {\n // Final step with no tool calls - reset tracking\n lastStepToolCalls = [];\n lastStepToolResults = [];\n result = await iterator.next([]);\n }\n }\n\n // When the iterator completes normally, result.value contains the final conversation prompt\n if (result.done) {\n finalMessages = result.value;\n }\n } catch (error) {\n encounteredError = error;\n // Check if this is an abort error\n if (error instanceof Error && error.name === 'AbortError') {\n wasAborted = true;\n if (options.onAbort) {\n await options.onAbort({ steps });\n }\n } else if (options.onError) {\n // Call onError for non-abort errors (including tool execution errors)\n await options.onError({ error });\n }\n // Don't throw yet - we want to call onFinish first\n }\n\n // Use the final messages from the iterator, or fall back to standardized messages\n const messages = (finalMessages ??\n prompt.messages) as unknown as ModelMessage[];\n\n // Parse structured output if output is specified (stream-level overrides constructor default)\n const effectiveOutput = options.output ?? this.output;\n let experimentalOutput: OUTPUT = undefined as OUTPUT;\n if (effectiveOutput && steps.length > 0) {\n const lastStep = steps[steps.length - 1];\n const text = lastStep.text;\n if (text) {\n try {\n experimentalOutput = await effectiveOutput.parseCompleteOutput(\n { text },\n {\n response: lastStep.response,\n usage: lastStep.usage,\n finishReason: lastStep.finishReason,\n },\n );\n } catch (parseError) {\n // If there's already an error, don't override it\n // If not, set this as the error\n if (!encounteredError) {\n encounteredError = parseError;\n }\n }\n }\n }\n\n // Call onFinish callback if provided (always call, even on errors, but not on abort)\n if (mergedOnFinish && !wasAborted) {\n const lastStep = steps[steps.length - 1];\n await mergedOnFinish({\n steps,\n messages: messages as ModelMessage[],\n text: lastStep?.text ?? '',\n finishReason: lastStep?.finishReason ?? 'other',\n totalUsage: aggregateUsage(steps),\n experimental_context: experimentalContext,\n output: experimentalOutput,\n });\n }\n\n // Re-throw any error that occurred\n if (encounteredError) {\n // Close the stream before throwing\n if (options.writable) {\n const sendFinish = options.sendFinish ?? true;\n const preventClose = options.preventClose ?? false;\n if (sendFinish || !preventClose) {\n await closeStream(options.writable, preventClose, sendFinish);\n }\n }\n throw encounteredError;\n }\n\n // Close the writable stream\n if (options.writable) {\n const sendFinish = options.sendFinish ?? true;\n const preventClose = options.preventClose ?? false;\n if (sendFinish || !preventClose) {\n await closeStream(options.writable, preventClose, sendFinish);\n }\n }\n\n return {\n messages: messages as ModelMessage[],\n steps,\n toolCalls: lastStepToolCalls,\n toolResults: lastStepToolResults,\n output: experimentalOutput,\n };\n }\n}\n\n/**\n * Filter tools to only include the specified active tools.\n */\n/**\n * Aggregate token usage across all steps.\n */\n/**\n * Close the writable stream, optionally sending a finish chunk first.\n * This is a step function because writable.getWriter() and writable.close()\n * cannot be called in workflow context (sandbox limitation).\n */\nasync function closeStream(\n writable: WritableStream<any>,\n preventClose?: boolean,\n sendFinish?: boolean,\n) {\n 'use step';\n if (sendFinish) {\n const writer = writable.getWriter();\n try {\n await writer.write({ type: 'finish' });\n } finally {\n writer.releaseLock();\n }\n }\n if (!preventClose) {\n await writable.close();\n }\n}\n\n/**\n * Write tool-approval-request chunks to the writable stream.\n * These are consumed by useChat to show the approval UI.\n */\nasync function writeApprovalRequests(\n writable: WritableStream<any>,\n toolCalls: Array<{ toolCallId: string; toolName: string }>,\n) {\n 'use step';\n const writer = writable.getWriter();\n try {\n for (const tc of toolCalls) {\n await writer.write({\n type: 'tool-approval-request',\n approvalId: `approval-${tc.toolCallId}`,\n toolCallId: tc.toolCallId,\n });\n }\n } finally {\n writer.releaseLock();\n }\n}\n\nasync function writeToolResultsWithStepBoundary(\n writable: WritableStream<any>,\n results: Array<{\n toolCallId: string;\n toolName: string;\n input: unknown;\n output: unknown;\n }>,\n) {\n 'use step';\n const writer = writable.getWriter();\n try {\n for (const r of results) {\n await writer.write({\n type: 'tool-result',\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: r.input,\n output: r.output,\n });\n }\n // Emit step boundaries so the UI message history properly separates\n // the tool call step from the subsequent text step. This ensures\n // convertToModelMessages creates separate assistant messages for\n // tool calls and text responses.\n await writer.write({ type: 'finish-step' });\n await writer.write({ type: 'start-step' });\n } finally {\n writer.releaseLock();\n }\n}\n\nasync function writeApprovalToolResults(\n writable: WritableStream<any>,\n approvedResults: Array<{\n toolCallId: string;\n toolName: string;\n input: unknown;\n output: unknown;\n }>,\n deniedResults: Array<{ toolCallId: string }>,\n) {\n 'use step';\n const writer = writable.getWriter();\n try {\n for (const r of approvedResults) {\n await writer.write({\n type: 'tool-result',\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: r.input,\n output: r.output,\n });\n }\n for (const r of deniedResults) {\n await writer.write({\n type: 'tool-output-denied',\n toolCallId: r.toolCallId,\n });\n }\n await writer.write({ type: 'finish-step' });\n await writer.write({ type: 'start-step' });\n } finally {\n writer.releaseLock();\n }\n}\n\nfunction aggregateUsage(steps: StepResult<any, any>[]): LanguageModelUsage {\n let inputTokens = 0;\n let outputTokens = 0;\n for (const step of steps) {\n inputTokens += step.usage?.inputTokens ?? 0;\n outputTokens += step.usage?.outputTokens ?? 0;\n }\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n } as LanguageModelUsage;\n}\n\n// Matches AI SDK's getErrorMessage from @ai-sdk/provider-utils\nfunction getErrorMessage(error: unknown): string {\n if (error == null) {\n return 'unknown error';\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n if (error instanceof Error) {\n return error.message;\n }\n\n return JSON.stringify(error);\n}\n\nfunction resolveProviderToolResult(\n toolCall: { toolCallId: string; toolName: string },\n providerExecutedToolResults?: Map<\n string,\n { toolCallId: string; toolName: string; result: unknown; isError?: boolean }\n >,\n): LanguageModelV4ToolResultPart {\n const streamResult = providerExecutedToolResults?.get(toolCall.toolCallId);\n if (!streamResult) {\n console.warn(\n `[WorkflowAgent] Provider-executed tool \"${toolCall.toolName}\" (${toolCall.toolCallId}) ` +\n `did not receive a result from the stream. This may indicate a provider issue.`,\n );\n return {\n type: 'tool-result' as const,\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n output: {\n type: 'text' as const,\n value: '',\n },\n };\n }\n\n const result = streamResult.result;\n const isString = typeof result === 'string';\n\n return {\n type: 'tool-result' as const,\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n output: isString\n ? streamResult.isError\n ? { type: 'error-text' as const, value: result }\n : { type: 'text' as const, value: result }\n : streamResult.isError\n ? {\n type: 'error-json' as const,\n value: result as JSONValue,\n }\n : {\n type: 'json' as const,\n value: result as JSONValue,\n },\n };\n}\n\nasync function executeTool(\n toolCall: { toolCallId: string; toolName: string; input: unknown },\n tools: ToolSet,\n messages: LanguageModelV4Prompt,\n experimentalContext?: unknown,\n): Promise<LanguageModelV4ToolResultPart> {\n const tool = tools[toolCall.toolName];\n if (!tool) throw new Error(`Tool \"${toolCall.toolName}\" not found`);\n if (typeof tool.execute !== 'function') {\n throw new Error(\n `Tool \"${toolCall.toolName}\" does not have an execute function. ` +\n `Client-side tools should be filtered before calling executeTool.`,\n );\n }\n // Input is already parsed and validated by streamModelCall's parseToolCall\n const parsedInput = toolCall.input;\n\n try {\n // Extract execute function to avoid binding `this` to the tool object.\n // If we called `tool.execute(...)` directly, JavaScript would bind `this`\n // to `tool`, which contains non-serializable properties like `inputSchema`.\n // When the execute function is a workflow step (marked with 'use step'),\n // the step system captures `this` for serialization, causing failures.\n const { execute } = tool;\n const toolResult = await execute(parsedInput, {\n toolCallId: toolCall.toolCallId,\n // Pass the conversation messages to the tool so it has context about the conversation\n messages,\n // Pass context to the tool\n context: experimentalContext,\n });\n\n // Use the appropriate output type based on the result\n // AI SDK supports 'text' for strings and 'json' for objects\n const output =\n typeof toolResult === 'string'\n ? { type: 'text' as const, value: toolResult }\n : { type: 'json' as const, value: toolResult };\n\n return {\n type: 'tool-result' as const,\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n output,\n };\n } catch (error) {\n // Convert tool errors to error-text results sent back to the model,\n // allowing the agent to recover rather than killing the entire stream.\n // This aligns with AI SDK's streamText behavior for individual tool failures.\n return {\n type: 'tool-result',\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n output: {\n type: 'error-text',\n value: getErrorMessage(error),\n },\n };\n }\n}\n\n/**\n * Collected tool approval information for a single tool call.\n */\ninterface CollectedApproval {\n toolCallId: string;\n toolName: string;\n input: unknown;\n approvalId: string;\n reason?: string;\n}\n\n/**\n * Collect tool approval responses from model messages.\n * Mirrors the logic from `collectToolApprovals` in the AI SDK core\n * (`packages/ai/src/generate-text/collect-tool-approvals.ts`).\n *\n * Scans the last tool message for `tool-approval-response` parts,\n * matches them with `tool-approval-request` parts in assistant messages\n * and the corresponding `tool-call` parts.\n */\nfunction collectToolApprovalsFromMessages(messages: ModelMessage[]): {\n approvedToolApprovals: CollectedApproval[];\n deniedToolApprovals: CollectedApproval[];\n} {\n const lastMessage = messages.at(-1);\n\n if (lastMessage?.role !== 'tool') {\n return { approvedToolApprovals: [], deniedToolApprovals: [] };\n }\n\n // Gather tool calls from assistant messages\n const toolCallsByToolCallId: Record<\n string,\n { toolName: string; input: unknown }\n > = {};\n for (const message of messages) {\n if (message.role === 'assistant' && Array.isArray(message.content)) {\n for (const part of message.content as any[]) {\n if (part.type === 'tool-call') {\n toolCallsByToolCallId[part.toolCallId] = {\n toolName: part.toolName,\n input: part.input ?? part.args,\n };\n }\n }\n }\n }\n\n // Gather approval requests from assistant messages\n const approvalRequestsByApprovalId: Record<\n string,\n { approvalId: string; toolCallId: string }\n > = {};\n for (const message of messages) {\n if (message.role === 'assistant' && Array.isArray(message.content)) {\n for (const part of message.content as any[]) {\n if (part.type === 'tool-approval-request') {\n approvalRequestsByApprovalId[part.approvalId] = {\n approvalId: part.approvalId,\n toolCallId: part.toolCallId,\n };\n }\n }\n }\n }\n\n // Gather existing tool results to avoid re-executing\n const existingToolResults = new Set<string>();\n for (const part of lastMessage.content as any[]) {\n if (part.type === 'tool-result') {\n existingToolResults.add(part.toolCallId);\n }\n }\n\n const approvedToolApprovals: CollectedApproval[] = [];\n const deniedToolApprovals: CollectedApproval[] = [];\n\n // Collect approval responses from the last tool message\n const approvalResponses = (lastMessage.content as any[]).filter(\n (part: any) => part.type === 'tool-approval-response',\n );\n\n for (const response of approvalResponses) {\n const approvalRequest = approvalRequestsByApprovalId[response.approvalId];\n if (approvalRequest == null) continue;\n\n // Skip if there's already a tool result for this tool call\n if (existingToolResults.has(approvalRequest.toolCallId)) continue;\n\n const toolCall = toolCallsByToolCallId[approvalRequest.toolCallId];\n if (toolCall == null) continue;\n\n const approval: CollectedApproval = {\n toolCallId: approvalRequest.toolCallId,\n toolName: toolCall.toolName,\n input: toolCall.input,\n approvalId: response.approvalId,\n reason: response.reason,\n };\n\n if (response.approved) {\n approvedToolApprovals.push(approval);\n } else {\n deniedToolApprovals.push(approval);\n }\n }\n\n return { approvedToolApprovals, deniedToolApprovals };\n}\n","import type {\n LanguageModelV4CallOptions,\n LanguageModelV4Prompt,\n LanguageModelV4ToolResultPart,\n} from '@ai-sdk/provider';\nimport {\n type Experimental_LanguageModelStreamPart as ModelCallStreamPart,\n type LanguageModel,\n type ModelMessage,\n type StepResult,\n type ToolCallRepairFunction,\n type ToolChoice,\n type ToolSet,\n experimental_filterActiveTools as filterActiveTools,\n} from 'ai';\nimport {\n doStreamStep,\n type ModelStopCondition,\n type ParsedToolCall,\n type ProviderExecutedToolResult,\n} from './do-stream-step.js';\nimport { serializeToolSet } from './serializable-schema.js';\nimport type {\n GenerationSettings,\n PrepareStepCallback,\n WorkflowAgentOnErrorCallback,\n WorkflowAgentOnStepFinishCallback,\n TelemetryOptions,\n WorkflowAgentOnStepStartCallback,\n} from './workflow-agent.js';\n\n// Re-export for consumers\nexport type { ProviderExecutedToolResult } from './do-stream-step.js';\n\n/**\n * The value yielded by the stream text iterator when tool calls are requested.\n * Contains both the tool calls and the current conversation messages.\n */\nexport interface StreamTextIteratorYieldValue {\n /** The tool calls requested by the model (parsed with typed inputs) */\n toolCalls: ParsedToolCall[];\n /** The conversation messages up to (and including) the tool call request */\n messages: LanguageModelV4Prompt;\n /** The step result from the current step */\n step?: StepResult<ToolSet, any>;\n /** The current experimental context */\n context?: unknown;\n /** Provider-executed tool results (keyed by tool call ID) */\n providerExecutedToolResults?: Map<string, ProviderExecutedToolResult>;\n}\n\n// This runs in the workflow context\nexport async function* streamTextIterator({\n prompt,\n tools = {},\n writable,\n model,\n stopConditions,\n onStepFinish,\n onStepStart,\n onError,\n prepareStep,\n generationSettings,\n toolChoice,\n experimental_context,\n experimental_telemetry,\n includeRawChunks = false,\n repairToolCall,\n responseFormat,\n}: {\n prompt: LanguageModelV4Prompt;\n tools: ToolSet;\n writable?: WritableStream<ModelCallStreamPart<ToolSet>>;\n model: LanguageModel;\n stopConditions?: ModelStopCondition[] | ModelStopCondition;\n onStepFinish?: WorkflowAgentOnStepFinishCallback<any>;\n onStepStart?: WorkflowAgentOnStepStartCallback;\n onError?: WorkflowAgentOnErrorCallback;\n prepareStep?: PrepareStepCallback<any>;\n generationSettings?: GenerationSettings;\n toolChoice?: ToolChoice<ToolSet>;\n experimental_context?: unknown;\n experimental_telemetry?: TelemetryOptions;\n includeRawChunks?: boolean;\n repairToolCall?: ToolCallRepairFunction<ToolSet>;\n responseFormat?: LanguageModelV4CallOptions['responseFormat'];\n}): AsyncGenerator<\n StreamTextIteratorYieldValue,\n LanguageModelV4Prompt,\n LanguageModelV4ToolResultPart[]\n> {\n let conversationPrompt = [...prompt]; // Create a mutable copy\n let currentModel: LanguageModel = model;\n let currentGenerationSettings = generationSettings ?? {};\n let currentToolChoice = toolChoice;\n let currentContext = experimental_context;\n let currentActiveTools: string[] | undefined;\n\n const steps: StepResult<any, any>[] = [];\n let done = false;\n let _isFirstIteration = true;\n let stepNumber = 0;\n let lastStep: StepResult<any, any> | undefined;\n let lastStepWasToolCalls = false;\n\n while (!done) {\n // Check for abort signal\n if (currentGenerationSettings.abortSignal?.aborted) {\n break;\n }\n\n // Call prepareStep callback before each step if provided\n if (prepareStep) {\n const prepareResult = await prepareStep({\n model: currentModel,\n stepNumber,\n steps,\n messages: conversationPrompt,\n experimental_context: currentContext,\n });\n\n // Apply any overrides from prepareStep\n if (prepareResult.model !== undefined) {\n currentModel = prepareResult.model;\n }\n // Apply messages override BEFORE system so the system message\n // isn't lost when messages replaces the prompt.\n if (prepareResult.messages !== undefined) {\n conversationPrompt = [...prepareResult.messages];\n }\n if (prepareResult.system !== undefined) {\n // Update or prepend system message in the conversation prompt.\n // Applied AFTER messages override so the system message isn't\n // lost when messages replaces the prompt.\n if (\n conversationPrompt.length > 0 &&\n conversationPrompt[0].role === 'system'\n ) {\n // Replace existing system message\n conversationPrompt[0] = {\n role: 'system',\n content: prepareResult.system,\n };\n } else {\n // Prepend new system message\n conversationPrompt.unshift({\n role: 'system',\n content: prepareResult.system,\n });\n }\n }\n if (prepareResult.experimental_context !== undefined) {\n currentContext = prepareResult.experimental_context;\n }\n if (prepareResult.activeTools !== undefined) {\n currentActiveTools = prepareResult.activeTools;\n }\n // Apply generation settings overrides\n if (prepareResult.maxOutputTokens !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n maxOutputTokens: prepareResult.maxOutputTokens,\n };\n }\n if (prepareResult.temperature !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n temperature: prepareResult.temperature,\n };\n }\n if (prepareResult.topP !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n topP: prepareResult.topP,\n };\n }\n if (prepareResult.topK !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n topK: prepareResult.topK,\n };\n }\n if (prepareResult.presencePenalty !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n presencePenalty: prepareResult.presencePenalty,\n };\n }\n if (prepareResult.frequencyPenalty !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n frequencyPenalty: prepareResult.frequencyPenalty,\n };\n }\n if (prepareResult.stopSequences !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n stopSequences: prepareResult.stopSequences,\n };\n }\n if (prepareResult.seed !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n seed: prepareResult.seed,\n };\n }\n if (prepareResult.maxRetries !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n maxRetries: prepareResult.maxRetries,\n };\n }\n if (prepareResult.headers !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n headers: prepareResult.headers,\n };\n }\n if (prepareResult.providerOptions !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n providerOptions: prepareResult.providerOptions,\n };\n }\n if (prepareResult.toolChoice !== undefined) {\n currentToolChoice = prepareResult.toolChoice;\n }\n }\n\n if (onStepStart) {\n await onStepStart({\n stepNumber,\n model: currentModel,\n messages: conversationPrompt as unknown as ModelMessage[],\n steps: [...steps],\n });\n }\n\n try {\n // Filter tools if activeTools is specified\n const effectiveTools =\n currentActiveTools && currentActiveTools.length > 0\n ? (filterActiveTools({\n tools,\n activeTools: currentActiveTools,\n }) ?? tools)\n : tools;\n\n // Serialize tools before crossing the step boundary — zod schemas\n // contain functions that can't be serialized by the workflow runtime.\n // Tools are reconstructed with Ajv validation inside doStreamStep.\n const serializedTools = serializeToolSet(effectiveTools);\n\n const { toolCalls, finish, step, providerExecutedToolResults } =\n await doStreamStep(\n conversationPrompt,\n currentModel,\n writable,\n serializedTools,\n {\n ...currentGenerationSettings,\n toolChoice: currentToolChoice,\n includeRawChunks,\n experimental_telemetry,\n repairToolCall,\n responseFormat,\n },\n );\n\n _isFirstIteration = false;\n stepNumber++;\n steps.push(step);\n lastStep = step;\n lastStepWasToolCalls = false;\n\n const finishReason = finish?.finishReason;\n\n if (finishReason === 'tool-calls') {\n lastStepWasToolCalls = true;\n\n // Add assistant message with tool calls to the conversation\n // Note: providerMetadata from the tool call is mapped to providerOptions\n // in the prompt format, following the AI SDK convention. This is critical\n // for providers like Gemini that require thoughtSignature to be preserved\n // across multi-turn tool calls. Some fields are sanitized before mapping.\n conversationPrompt.push({\n role: 'assistant',\n content: toolCalls.map(toolCall => {\n const sanitizedMetadata = sanitizeProviderMetadataForToolCall(\n toolCall.providerMetadata,\n );\n return {\n type: 'tool-call',\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n input: toolCall.input,\n ...(sanitizedMetadata != null\n ? { providerOptions: sanitizedMetadata }\n : {}),\n };\n }) as typeof toolCalls,\n });\n\n // Yield the tool calls along with the current conversation messages\n // This allows executeTool to pass the conversation context to tool execute functions\n // Also include provider-executed tool results so they can be used instead of local execution\n const toolResults = yield {\n toolCalls,\n messages: conversationPrompt,\n step,\n context: currentContext,\n providerExecutedToolResults,\n };\n\n conversationPrompt.push({\n role: 'tool',\n content: toolResults,\n });\n\n if (stopConditions) {\n const stopConditionList = Array.isArray(stopConditions)\n ? stopConditions\n : [stopConditions];\n if (stopConditionList.some(test => test({ steps }))) {\n done = true;\n }\n }\n } else if (finishReason === 'stop') {\n // Add assistant message with text content to the conversation\n const textContent = step.content.filter(\n item => item.type === 'text',\n ) as Array<{ type: 'text'; text: string }>;\n\n if (textContent.length > 0) {\n conversationPrompt.push({\n role: 'assistant',\n content: textContent,\n });\n }\n\n done = true;\n } else if (finishReason === 'length') {\n // Model hit max tokens - stop but don't throw\n done = true;\n } else if (finishReason === 'content-filter') {\n // Content filter triggered - stop but don't throw\n done = true;\n } else if (finishReason === 'error') {\n // Model error - stop but don't throw\n done = true;\n } else if (finishReason === 'other') {\n // Other reason - stop but don't throw\n done = true;\n } else if (finishReason === 'unknown') {\n // Unknown reason - stop but don't throw\n done = true;\n } else if (!finishReason) {\n // No finish reason - this might happen on incomplete streams\n done = true;\n } else {\n throw new Error(\n `Unexpected finish reason: ${typeof finish?.finishReason === 'object' ? JSON.stringify(finish?.finishReason) : finish?.finishReason}`,\n );\n }\n\n if (onStepFinish) {\n await onStepFinish(step);\n }\n } catch (error) {\n if (onError) {\n await onError({ error });\n }\n throw error;\n }\n }\n\n // Yield the final step if it wasn't already yielded (tool-calls steps are yielded inside the loop)\n if (lastStep && !lastStepWasToolCalls) {\n yield {\n toolCalls: [],\n messages: conversationPrompt,\n step: lastStep,\n context: currentContext,\n };\n }\n\n return conversationPrompt;\n}\n\n/**\n * Strip OpenAI's itemId from providerMetadata (requires reasoning items we don't preserve).\n * Preserves all other provider metadata (e.g., Gemini's thoughtSignature).\n */\nfunction sanitizeProviderMetadataForToolCall(\n metadata: unknown,\n): Record<string, unknown> | undefined {\n if (metadata == null) return undefined;\n\n const meta = metadata as Record<string, unknown>;\n\n // Check if OpenAI metadata exists and needs sanitization\n if ('openai' in meta && meta.openai != null) {\n const { openai, ...restProviders } = meta;\n const openaiMeta = openai as Record<string, unknown>;\n\n // Remove itemId from OpenAI metadata - it requires reasoning items we don't preserve\n const { itemId: _itemId, ...restOpenai } = openaiMeta;\n\n // Reconstruct metadata without itemId\n const hasOtherOpenaiFields = Object.keys(restOpenai).length > 0;\n const hasOtherProviders = Object.keys(restProviders).length > 0;\n\n if (hasOtherOpenaiFields && hasOtherProviders) {\n return { ...restProviders, openai: restOpenai };\n } else if (hasOtherOpenaiFields) {\n return { openai: restOpenai };\n } else if (hasOtherProviders) {\n return restProviders;\n }\n return undefined;\n }\n\n return meta;\n}\n","import type {\n LanguageModelV4CallOptions,\n LanguageModelV4Prompt,\n} from '@ai-sdk/provider';\nimport {\n type Experimental_LanguageModelStreamPart as ModelCallStreamPart,\n experimental_streamLanguageModelCall as streamModelCall,\n type FinishReason,\n type LanguageModel,\n type LanguageModelUsage,\n type ModelMessage,\n type StepResult,\n type StopCondition,\n type ToolCallRepairFunction,\n type ToolChoice,\n type ToolSet,\n} from 'ai';\nimport { gateway } from 'ai';\nimport type { ProviderOptions, TelemetryOptions } from './workflow-agent.js';\nimport {\n resolveSerializableTools,\n type SerializableToolDef,\n} from './serializable-schema.js';\n\nexport type { Experimental_LanguageModelStreamPart as ModelCallStreamPart } from 'ai';\n\nexport type ModelStopCondition = StopCondition<NoInfer<ToolSet>, any>;\n\n/**\n * Provider-executed tool result captured from the stream.\n */\nexport interface ProviderExecutedToolResult {\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n}\n\n/**\n * Options for the doStreamStep function.\n */\nexport interface DoStreamStepOptions {\n maxOutputTokens?: number;\n temperature?: number;\n topP?: number;\n topK?: number;\n presencePenalty?: number;\n frequencyPenalty?: number;\n stopSequences?: string[];\n seed?: number;\n maxRetries?: number;\n abortSignal?: AbortSignal;\n headers?: Record<string, string | undefined>;\n providerOptions?: ProviderOptions;\n toolChoice?: ToolChoice<ToolSet>;\n includeRawChunks?: boolean;\n experimental_telemetry?: TelemetryOptions;\n repairToolCall?: ToolCallRepairFunction<ToolSet>;\n responseFormat?: LanguageModelV4CallOptions['responseFormat'];\n}\n\n/**\n * Parsed tool call from the stream (parsed by streamModelCall's transform).\n */\nexport interface ParsedToolCall {\n type: 'tool-call';\n toolCallId: string;\n toolName: string;\n input: unknown;\n providerExecuted?: boolean;\n providerMetadata?: Record<string, unknown>;\n dynamic?: boolean;\n invalid?: boolean;\n error?: unknown;\n}\n\n/**\n * Finish metadata from the stream.\n */\nexport interface StreamFinish {\n finishReason: FinishReason;\n rawFinishReason: string | undefined;\n usage: LanguageModelUsage;\n providerMetadata?: Record<string, unknown>;\n}\n\nexport async function doStreamStep(\n conversationPrompt: LanguageModelV4Prompt,\n modelInit: LanguageModel,\n writable?: WritableStream<ModelCallStreamPart<ToolSet>>,\n serializedTools?: Record<string, SerializableToolDef>,\n options?: DoStreamStepOptions,\n) {\n 'use step';\n\n // Resolve model inside step (must happen here for serialization boundary)\n const model: LanguageModel =\n typeof modelInit === 'string'\n ? gateway.languageModel(modelInit)\n : modelInit;\n\n // Reconstruct tools from serializable definitions with Ajv validation.\n // Tools are serialized before crossing the step boundary because zod schemas\n // contain functions that can't be serialized by the workflow runtime.\n const tools = serializedTools\n ? resolveSerializableTools(serializedTools)\n : undefined;\n\n // streamModelCall handles: prompt standardization, tool preparation,\n // model.doStream(), retry logic, and stream part transformation\n // (tool call parsing, finish reason mapping, file wrapping).\n const { stream: modelStream } = await streamModelCall({\n model,\n // streamModelCall expects Prompt (ModelMessage[]) but we pass the\n // pre-converted LanguageModelV4Prompt. standardizePrompt inside\n // streamModelCall handles both formats.\n messages: conversationPrompt as unknown as ModelMessage[],\n tools,\n toolChoice: options?.toolChoice,\n includeRawChunks: options?.includeRawChunks,\n providerOptions: options?.providerOptions,\n abortSignal: options?.abortSignal,\n headers: options?.headers,\n maxOutputTokens: options?.maxOutputTokens,\n temperature: options?.temperature,\n topP: options?.topP,\n topK: options?.topK,\n presencePenalty: options?.presencePenalty,\n frequencyPenalty: options?.frequencyPenalty,\n stopSequences: options?.stopSequences,\n seed: options?.seed,\n repairToolCall: options?.repairToolCall,\n });\n\n // Consume the stream: capture data and write to writable in real-time\n const toolCalls: ParsedToolCall[] = [];\n const providerExecutedToolResults = new Map<\n string,\n ProviderExecutedToolResult\n >();\n let finish: StreamFinish | undefined;\n\n // Aggregation for StepResult\n let text = '';\n const reasoningParts: Array<{ text: string }> = [];\n let responseMetadata:\n | { id?: string; timestamp?: Date; modelId?: string }\n | undefined;\n let warnings: unknown[] | undefined;\n\n // Acquire writer once before the loop to avoid per-chunk lock overhead\n const writer = writable?.getWriter();\n\n try {\n for await (const part of modelStream) {\n switch (part.type) {\n case 'text-delta':\n text += part.text;\n break;\n case 'reasoning-delta':\n reasoningParts.push({ text: part.text });\n break;\n case 'tool-call': {\n // parseToolCall adds dynamic/invalid/error at runtime\n const toolCallPart = part as typeof part & Partial<ParsedToolCall>;\n toolCalls.push({\n type: 'tool-call',\n toolCallId: toolCallPart.toolCallId,\n toolName: toolCallPart.toolName,\n input: toolCallPart.input,\n providerExecuted: toolCallPart.providerExecuted,\n providerMetadata: toolCallPart.providerMetadata as\n | Record<string, unknown>\n | undefined,\n dynamic: toolCallPart.dynamic,\n invalid: toolCallPart.invalid,\n error: toolCallPart.error,\n });\n break;\n }\n case 'tool-result':\n if (part.providerExecuted) {\n providerExecutedToolResults.set(part.toolCallId, {\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n result: part.output,\n isError: false,\n });\n }\n break;\n case 'tool-error': {\n const errorPart = part as typeof part & {\n providerExecuted?: boolean;\n };\n if (errorPart.providerExecuted) {\n providerExecutedToolResults.set(errorPart.toolCallId, {\n toolCallId: errorPart.toolCallId,\n toolName: errorPart.toolName,\n result: errorPart.error,\n isError: true,\n });\n }\n break;\n }\n case 'model-call-end':\n finish = {\n finishReason: part.finishReason,\n rawFinishReason: part.rawFinishReason,\n usage: part.usage,\n providerMetadata: part.providerMetadata as\n | Record<string, unknown>\n | undefined,\n };\n break;\n case 'model-call-start':\n warnings = part.warnings;\n break;\n case 'model-call-response-metadata':\n responseMetadata = part;\n break;\n }\n\n // Write to writable in real-time\n if (writer) {\n await writer.write(part);\n }\n }\n } finally {\n writer?.releaseLock();\n }\n\n // Build StepResult\n const reasoningText = reasoningParts.map(r => r.text).join('') || undefined;\n\n const step: StepResult<ToolSet, any> = {\n callId: 'workflow-agent',\n stepNumber: 0,\n model: {\n provider: responseMetadata?.modelId?.split(':')[0] ?? 'unknown',\n modelId: responseMetadata?.modelId ?? 'unknown',\n },\n functionId: undefined,\n metadata: undefined,\n runtimeContext: undefined,\n toolsContext: {},\n content: [\n ...(text ? [{ type: 'text' as const, text }] : []),\n ...toolCalls\n .filter(tc => !tc.invalid)\n .map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n ...(tc.dynamic ? { dynamic: true as const } : {}),\n })),\n ],\n text,\n reasoning: reasoningParts.map(r => ({\n type: 'reasoning' as const,\n text: r.text,\n })),\n reasoningText,\n files: [],\n sources: [],\n toolCalls: toolCalls\n .filter(tc => !tc.invalid)\n .map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n ...(tc.dynamic ? { dynamic: true as const } : {}),\n })),\n staticToolCalls: [],\n dynamicToolCalls: toolCalls\n .filter(tc => !tc.invalid && tc.dynamic)\n .map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n dynamic: true as const,\n })),\n toolResults: [],\n staticToolResults: [],\n dynamicToolResults: [],\n finishReason: finish?.finishReason ?? 'other',\n rawFinishReason: finish?.rawFinishReason,\n usage:\n finish?.usage ??\n ({\n inputTokens: 0,\n inputTokenDetails: {\n noCacheTokens: undefined,\n cacheReadTokens: undefined,\n cacheWriteTokens: undefined,\n },\n outputTokens: 0,\n outputTokenDetails: {\n textTokens: undefined,\n reasoningTokens: undefined,\n },\n totalTokens: 0,\n } as LanguageModelUsage),\n warnings,\n request: { body: '' },\n response: {\n id: responseMetadata?.id ?? 'unknown',\n timestamp: responseMetadata?.timestamp ?? new Date(),\n modelId: responseMetadata?.modelId ?? 'unknown',\n messages: [],\n },\n providerMetadata: finish?.providerMetadata ?? {},\n } as StepResult<ToolSet, any>;\n\n return {\n toolCalls,\n finish,\n step,\n providerExecutedToolResults,\n };\n}\n","/**\n * Helpers for passing tool schemas across workflow step boundaries.\n *\n * Tool schemas (zod, valibot, arktype, etc.) contain functions that can't be\n * serialized by the workflow runtime. These helpers extract JSON Schema from\n * schemas, then reconstruct tools with Ajv validation inside step functions.\n *\n * Uses `asSchema()` from `@ai-sdk/provider-utils` for JSON Schema extraction,\n * which supports Standard Schema compatible libraries. When libraries adopt\n * `~standard.jsonSchema` (Standard Schema v2), extraction can be simplified\n * to use that interface directly.\n */\nimport type { JSONSchema7 } from '@ai-sdk/provider';\nimport { asSchema, jsonSchema } from '@ai-sdk/provider-utils';\nimport { tool, type ToolSet } from 'ai';\nimport Ajv from 'ajv';\n\n/**\n * Serializable tool definition — plain objects only, safe for workflow steps.\n */\nexport type SerializableToolDef = {\n description?: string;\n inputSchema: JSONSchema7;\n /** Present on provider tools (e.g. anthropic.tools.webSearch). */\n type?: 'provider';\n /** Provider tool ID, e.g. 'anthropic.web_search_20250305'. */\n id?: `${string}.${string}`;\n /** Provider tool configuration args (maxUses, allowedDomains, etc.). */\n args?: Record<string, unknown>;\n};\n\n/**\n * Converts a ToolSet (with zod/standard schemas and execute functions) to a\n * serializable record of tool definitions. Only description and inputSchema\n * (as JSON Schema) are preserved — execute functions are stripped since they\n * run outside the step.\n */\nexport function serializeToolSet(\n tools: ToolSet,\n): Record<string, SerializableToolDef> {\n return Object.fromEntries(\n Object.entries(tools).map(([name, t]) => {\n const def: SerializableToolDef = {\n description: t.description,\n inputSchema: asSchema(t.inputSchema).jsonSchema as JSONSchema7,\n };\n\n // Preserve provider tool identity so the Gateway can recognize\n // them as provider-executed tools (e.g. anthropic webSearch).\n if ((t as any).type === 'provider') {\n def.type = 'provider';\n def.id = (t as any).id;\n def.args = (t as any).args;\n }\n\n return [name, def];\n }),\n );\n}\n\n/**\n * Reconstructs tool objects from serializable tool definitions inside a step.\n *\n * Wraps each tool's JSON Schema with `jsonSchema()` and validates tool call\n * arguments against the schema using Ajv. This provides runtime type safety\n * equivalent to using zod schemas directly with the AI SDK.\n */\nexport function resolveSerializableTools(\n tools: Record<string, SerializableToolDef>,\n): ToolSet {\n const ajv = new Ajv();\n\n return Object.fromEntries(\n Object.entries(tools).map(([name, t]) => {\n // Provider tools are executed server-side — pass them through\n // with their identity intact, no client-side validation needed.\n if (t.type === 'provider') {\n return [\n name,\n tool({\n type: 'provider' as const,\n id: t.id!,\n args: t.args ?? {},\n inputSchema: jsonSchema(t.inputSchema),\n }),\n ];\n }\n\n const validateFn = ajv.compile(t.inputSchema);\n\n return [\n name,\n tool({\n description: t.description,\n inputSchema: jsonSchema(t.inputSchema, {\n validate: value => {\n if (validateFn(value)) {\n return { success: true, value: value as any };\n }\n return {\n success: false,\n error: new Error(ajv.errorsText(validateFn.errors)),\n };\n },\n }),\n }),\n ];\n }),\n );\n}\n","import { type ToolSet, type UIMessageChunk } from 'ai';\nimport type { Experimental_LanguageModelStreamPart as ModelCallStreamPart } from 'ai';\n\n/**\n * Convert a single ModelCallStreamPart to a UIMessageChunk.\n * Returns undefined for parts that don't map to UI chunks.\n */\nexport function toUIMessageChunk(\n part: ModelCallStreamPart<ToolSet>,\n): UIMessageChunk | undefined {\n switch (part.type) {\n case 'text-start':\n return {\n type: 'text-start',\n id: part.id,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'text-delta':\n return {\n type: 'text-delta',\n id: part.id,\n delta: part.text,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'text-end':\n return {\n type: 'text-end',\n id: part.id,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'reasoning-start':\n return {\n type: 'reasoning-start',\n id: part.id,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'reasoning-delta':\n return {\n type: 'reasoning-delta',\n id: part.id,\n delta: part.text,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'reasoning-end':\n return {\n type: 'reasoning-end',\n id: part.id,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'file': {\n const file = part.file;\n // GeneratedFile.base64 always has data (lazy-converted from Uint8Array if needed)\n return {\n type: 'file',\n mediaType: file.mediaType,\n url: `data:${file.mediaType};base64,${file.base64}`,\n };\n }\n\n case 'source': {\n if (part.sourceType === 'url') {\n return {\n type: 'source-url',\n sourceId: part.id,\n url: part.url,\n title: part.title,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n }\n if (part.sourceType === 'document') {\n return {\n type: 'source-document',\n sourceId: part.id,\n mediaType: part.mediaType,\n title: part.title,\n filename: part.filename,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n }\n return undefined;\n }\n\n case 'tool-input-start':\n return {\n type: 'tool-input-start',\n toolCallId: part.id,\n toolName: part.toolName,\n ...(part.providerExecuted != null\n ? { providerExecuted: part.providerExecuted }\n : {}),\n };\n\n case 'tool-input-delta':\n return {\n type: 'tool-input-delta',\n toolCallId: part.id,\n inputTextDelta: part.delta,\n };\n\n case 'tool-call': {\n // parseToolCall adds invalid/error at runtime for failed parses\n const toolCallPart = part as typeof part & {\n invalid?: boolean;\n error?: unknown;\n };\n if (toolCallPart.invalid) {\n return {\n type: 'tool-input-error',\n toolCallId: toolCallPart.toolCallId,\n toolName: toolCallPart.toolName,\n input: toolCallPart.input,\n errorText:\n toolCallPart.error instanceof Error\n ? toolCallPart.error.message\n : String(toolCallPart.error ?? 'Invalid tool call'),\n };\n }\n return {\n type: 'tool-input-available',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n input: part.input,\n ...(part.providerExecuted != null\n ? { providerExecuted: part.providerExecuted }\n : {}),\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n }\n\n case 'tool-result':\n return {\n type: 'tool-output-available',\n toolCallId: part.toolCallId,\n output: part.output,\n };\n\n case 'tool-error':\n return {\n type: 'tool-output-error',\n toolCallId: part.toolCallId,\n errorText:\n part.error instanceof Error ? part.error.message : String(part.error),\n };\n\n case 'error': {\n const error = part.error;\n return {\n type: 'error',\n errorText: error instanceof Error ? error.message : String(error),\n };\n }\n\n // These don't produce UI chunks\n case 'tool-input-end':\n case 'model-call-start':\n case 'model-call-response-metadata':\n case 'model-call-end':\n case 'raw':\n return undefined;\n\n default: {\n // Pass through tool-approval-request, step boundaries, and other\n // chunks as-is. Step boundaries (finish-step/start-step) are not\n // standard ModelCallStreamPart types but are written by the\n // WorkflowAgent between tool execution and the next model step\n // to ensure proper message splitting in convertToModelMessages.\n const p = part as any;\n if (p.type === 'tool-approval-request') {\n return {\n type: 'tool-approval-request',\n approvalId: p.approvalId,\n toolCallId: p.toolCallId,\n } as UIMessageChunk;\n }\n if (\n p.type === 'finish-step' ||\n p.type === 'start-step' ||\n p.type === 'tool-output-denied'\n ) {\n return p as UIMessageChunk;\n }\n return undefined;\n }\n }\n}\n\n/**\n * Create a TransformStream that converts ModelCallStreamPart to UIMessageChunk.\n * Wraps toUIMessageChunk with start/start-step/finish-step lifecycle chunks.\n */\nexport function createModelCallToUIChunkTransform(): TransformStream<\n ModelCallStreamPart<ToolSet>,\n UIMessageChunk\n> {\n return new TransformStream<ModelCallStreamPart<ToolSet>, UIMessageChunk>({\n start: controller => {\n controller.enqueue({ type: 'start' });\n controller.enqueue({ type: 'start-step' });\n },\n flush: controller => {\n controller.enqueue({ type: 'finish-step' });\n controller.enqueue({ type: 'finish' });\n },\n transform: (part, controller) => {\n const uiChunk = toUIMessageChunk(part);\n if (uiChunk) {\n controller.enqueue(uiChunk);\n }\n },\n });\n}\n","import {\n type ChatRequestOptions,\n type ChatTransport,\n type PrepareReconnectToStreamRequest,\n type PrepareSendMessagesRequest,\n parseJsonEventStream,\n type UIMessage,\n type UIMessageChunk,\n uiMessageChunkSchema,\n} from 'ai';\nimport {\n convertAsyncIteratorToReadableStream,\n getErrorMessage,\n} from '@ai-sdk/provider-utils';\nimport { createAsyncIterableStream } from 'ai/internal';\n\nexport interface SendMessagesOptions<UI_MESSAGE extends UIMessage> {\n trigger: 'submit-message' | 'regenerate-message';\n chatId: string;\n messageId?: string;\n messages: UI_MESSAGE[];\n abortSignal?: AbortSignal;\n}\n\nexport interface ReconnectToStreamOptions {\n chatId: string;\n abortSignal?: AbortSignal;\n /**\n * Override the `startIndex` for this reconnection.\n * Negative values read from the end of the stream.\n * When omitted, falls back to the constructor's `initialStartIndex`.\n */\n startIndex?: number;\n}\n\ntype OnChatSendMessage<UI_MESSAGE extends UIMessage> = (\n response: Response,\n options: SendMessagesOptions<UI_MESSAGE>,\n) => void | Promise<void>;\n\ntype OnChatEnd = ({\n chatId,\n chunkIndex,\n}: {\n chatId: string;\n chunkIndex: number;\n}) => void | Promise<void>;\n\n/**\n * Configuration options for the WorkflowChatTransport.\n *\n * @template UI_MESSAGE - The type of UI messages being sent and received,\n * must extend the UIMessage interface from the AI SDK.\n */\nexport interface WorkflowChatTransportOptions<UI_MESSAGE extends UIMessage> {\n /**\n * API endpoint for chat requests\n * Defaults to /api/chat if not provided\n */\n api?: string;\n\n /**\n * Custom fetch implementation to use for HTTP requests.\n * Defaults to the global fetch function if not provided.\n */\n fetch?: typeof fetch;\n\n /**\n * Callback invoked after successfully sending messages to the chat endpoint.\n * Useful for tracking chat history and inspecting response headers.\n *\n * @param response - The HTTP response object from the chat endpoint\n * @param options - The original options passed to sendMessages\n */\n onChatSendMessage?: OnChatSendMessage<UI_MESSAGE>;\n\n /**\n * Callback invoked when a chat stream ends (receives a \"finish\" chunk).\n * Useful for cleanup operations or state updates.\n *\n * @param chatId - The ID of the chat that ended\n * @param chunkIndex - The total number of chunks received\n */\n onChatEnd?: OnChatEnd;\n\n /**\n * Maximum number of consecutive errors allowed during reconnection attempts.\n * Defaults to 3 if not provided.\n */\n maxConsecutiveErrors?: number;\n\n /**\n * Default `startIndex` to use when reconnecting to a stream without a known\n * chunk position (i.e. the initial reconnection, not a retry).\n * Negative values read from the end of the stream (e.g. `-10` fetches the\n * last 10 chunks), which is useful for resuming a chat UI after a page\n * refresh without replaying the full conversation.\n *\n * Can be overridden per-call via `ReconnectToStreamOptions.startIndex`.\n *\n * Defaults to `0` (replay from the beginning).\n */\n initialStartIndex?: number;\n\n /**\n * Function to prepare the request for sending messages.\n * Allows customizing the API endpoint, headers, credentials, and body.\n */\n prepareSendMessagesRequest?: PrepareSendMessagesRequest<UI_MESSAGE>;\n\n /**\n * Function to prepare the request for reconnecting to a stream.\n * Allows customizing the API endpoint, headers, and credentials.\n */\n prepareReconnectToStreamRequest?: PrepareReconnectToStreamRequest;\n}\n\n/**\n * A transport implementation for managing chat workflows with support for\n * streaming responses and automatic reconnection to interrupted streams.\n *\n * This class implements the ChatTransport interface from the AI SDK and provides\n * reliable message streaming with automatic recovery from network interruptions\n * or function timeouts.\n *\n * @template UI_MESSAGE - The type of UI messages being sent and received,\n * must extend the UIMessage interface from the AI SDK.\n *\n * @implements {ChatTransport<UI_MESSAGE>}\n */\nexport class WorkflowChatTransport<\n UI_MESSAGE extends UIMessage,\n> implements ChatTransport<UI_MESSAGE> {\n private readonly api: string;\n private readonly fetch: typeof fetch;\n private readonly onChatSendMessage?: OnChatSendMessage<UI_MESSAGE>;\n private readonly onChatEnd?: OnChatEnd;\n private readonly maxConsecutiveErrors: number;\n private readonly initialStartIndex: number;\n private readonly prepareSendMessagesRequest?: PrepareSendMessagesRequest<UI_MESSAGE>;\n private readonly prepareReconnectToStreamRequest?: PrepareReconnectToStreamRequest;\n\n /**\n * Creates a new WorkflowChatTransport instance.\n *\n * @param options - Configuration options for the transport\n * @param options.api - API endpoint for chat requests (defaults to '/api/chat')\n * @param options.fetch - Custom fetch implementation (defaults to global fetch)\n * @param options.onChatSendMessage - Callback after sending messages\n * @param options.onChatEnd - Callback when chat stream ends\n * @param options.maxConsecutiveErrors - Maximum consecutive errors for reconnection\n * @param options.prepareSendMessagesRequest - Function to prepare send messages request\n * @param options.prepareReconnectToStreamRequest - Function to prepare reconnect request\n */\n constructor(options: WorkflowChatTransportOptions<UI_MESSAGE> = {}) {\n this.api = options.api ?? '/api/chat';\n this.fetch = options.fetch ?? fetch.bind(globalThis);\n this.onChatSendMessage = options.onChatSendMessage;\n this.onChatEnd = options.onChatEnd;\n this.maxConsecutiveErrors = options.maxConsecutiveErrors ?? 3;\n this.initialStartIndex = options.initialStartIndex ?? 0;\n this.prepareSendMessagesRequest = options.prepareSendMessagesRequest;\n this.prepareReconnectToStreamRequest =\n options.prepareReconnectToStreamRequest;\n }\n\n /**\n * Sends messages to the chat endpoint and returns a stream of response chunks.\n *\n * This method handles the entire chat lifecycle including:\n * - Sending messages to the /api/chat endpoint\n * - Streaming response chunks\n * - Automatic reconnection if the stream is interrupted\n *\n * @param options - Options for sending messages\n * @param options.trigger - The type of message submission ('submit-message' or 'regenerate-message')\n * @param options.chatId - Unique identifier for this chat session\n * @param options.messageId - Optional message ID for tracking specific messages\n * @param options.messages - Array of UI messages to send\n * @param options.abortSignal - Optional AbortSignal to cancel the request\n *\n * @returns A ReadableStream of UIMessageChunk objects containing the response\n * @throws Error if the fetch request fails or returns a non-OK status\n */\n async sendMessages(\n options: SendMessagesOptions<UI_MESSAGE> & ChatRequestOptions,\n ): Promise<ReadableStream<UIMessageChunk>> {\n return convertAsyncIteratorToReadableStream(\n this.sendMessagesIterator(options),\n );\n }\n\n private async *sendMessagesIterator(\n options: SendMessagesOptions<UI_MESSAGE> & ChatRequestOptions,\n ): AsyncGenerator<UIMessageChunk> {\n const { chatId, messages, abortSignal, trigger, messageId } = options;\n\n // We keep track of if the \"finish\" chunk is received to determine\n // if we need to reconnect, and keep track of the chunk index to resume from.\n let gotFinish = false;\n let chunkIndex = 0;\n\n // Prepare the request using the configurator if provided\n const requestConfig = this.prepareSendMessagesRequest\n ? await this.prepareSendMessagesRequest({\n id: chatId,\n messages,\n requestMetadata: options.metadata,\n body: options.body,\n credentials: undefined,\n headers: options.headers,\n api: this.api,\n trigger,\n messageId,\n })\n : undefined;\n\n const url = requestConfig?.api ?? this.api;\n const res = await this.fetch(url, {\n method: 'POST',\n body: JSON.stringify(\n requestConfig?.body ?? { messages, ...options.body },\n ),\n headers: requestConfig?.headers,\n credentials: requestConfig?.credentials,\n signal: abortSignal,\n });\n\n if (!res.ok || !res.body) {\n throw new Error(\n `Failed to fetch chat: ${res.status} ${await res.text()}`,\n );\n }\n\n const workflowRunId = res.headers.get('x-workflow-run-id');\n if (!workflowRunId) {\n throw new Error(\n 'Workflow run ID not found in \"x-workflow-run-id\" response header',\n );\n }\n\n // Notify the caller that the chat POST request was sent.\n // This is useful for tracking the chat history on the client\n // side and allows for inspecting response headers.\n await this.onChatSendMessage?.(res, options);\n\n // Flush the initial stream until the end or an error occurs\n try {\n const chunkStream = parseJsonEventStream({\n stream: res.body,\n schema: uiMessageChunkSchema,\n });\n for await (const chunk of createAsyncIterableStream(chunkStream)) {\n if (!chunk.success) {\n throw chunk.error;\n }\n\n chunkIndex++;\n\n yield chunk.value;\n\n if (chunk.value.type === 'finish') {\n gotFinish = true;\n }\n }\n } catch (error) {\n console.error('Error in chat POST stream', error);\n }\n\n if (gotFinish) {\n await this.onFinish(gotFinish, { chatId, chunkIndex });\n } else {\n // If the initial POST request did not include the \"finish\" chunk,\n // we need to reconnect to the stream. This could indicate that a\n // network error occurred or the Vercel Function timed out.\n yield* this.reconnectToStreamIterator(options, workflowRunId, chunkIndex);\n }\n }\n\n /**\n * Reconnects to an existing chat stream that was previously interrupted.\n *\n * This method is useful for resuming a chat session after network issues,\n * page refreshes, or Vercel Function timeouts.\n *\n * @param options - Options for reconnecting to the stream\n * @param options.chatId - The chat ID to reconnect to\n *\n * @returns A ReadableStream of UIMessageChunk objects\n * @throws Error if the reconnection request fails or returns a non-OK status\n */\n async reconnectToStream(\n options: ReconnectToStreamOptions & ChatRequestOptions,\n ): Promise<ReadableStream<UIMessageChunk> | null> {\n const it = this.reconnectToStreamIterator(options);\n return convertAsyncIteratorToReadableStream(it);\n }\n\n private async *reconnectToStreamIterator(\n options: ReconnectToStreamOptions & ChatRequestOptions,\n workflowRunId?: string,\n initialChunkIndex = 0,\n ): AsyncGenerator<UIMessageChunk> {\n let chunkIndex = initialChunkIndex;\n\n // When called from the public reconnectToStream (initialChunkIndex === 0),\n // honour the caller's startIndex (or the constructor default) for the\n // first request. This enables negative values so the client can read only\n // the tail of the stream (e.g. the last 10 chunks) instead of replaying\n // everything. After the first request, fall back to the running chunkIndex\n // so that retries resume from the correct position.\n const explicitStartIndex = options.startIndex ?? this.initialStartIndex;\n let useExplicitStartIndex =\n initialChunkIndex === 0 && explicitStartIndex !== 0;\n\n const defaultApi = `${this.api}/${encodeURIComponent(workflowRunId ?? options.chatId)}/stream`;\n\n // Prepare the request using the configurator if provided\n const requestConfig = this.prepareReconnectToStreamRequest\n ? await this.prepareReconnectToStreamRequest({\n id: options.chatId,\n requestMetadata: options.metadata,\n body: undefined,\n credentials: undefined,\n headers: undefined,\n api: defaultApi,\n })\n : undefined;\n\n const baseUrl = requestConfig?.api ?? defaultApi;\n\n let gotFinish = false;\n let consecutiveErrors = 0;\n // When a negative startIndex is used but the tail-index header is absent,\n // retries fall back to startIndex 0 (replay everything) instead of using\n // the incremental chunkIndex which would be wrong.\n let replayFromStart = false;\n\n while (!gotFinish) {\n const startIndex = useExplicitStartIndex\n ? explicitStartIndex\n : replayFromStart\n ? 0\n : chunkIndex;\n\n const url = `${baseUrl}?startIndex=${startIndex}`;\n const res = await this.fetch(url, {\n headers: requestConfig?.headers,\n credentials: requestConfig?.credentials,\n signal: options.abortSignal,\n });\n\n if (!res.ok || !res.body) {\n throw new Error(\n `Failed to fetch chat: ${res.status} ${await res.text()}`,\n );\n }\n\n // When using a negative startIndex, the server resolves it to an\n // absolute position. The reconnection endpoint should return the tail\n // index so we can compute the resolved position for subsequent retries.\n if (useExplicitStartIndex && explicitStartIndex > 0) {\n // Positive startIndex: the first request starts at this absolute\n // position, so set chunkIndex to match so subsequent retries\n // resume from (explicitStartIndex + chunks received).\n chunkIndex = explicitStartIndex;\n } else if (useExplicitStartIndex && explicitStartIndex < 0) {\n const tailIndexHeader = res.headers.get('x-workflow-stream-tail-index');\n const tailIndex =\n tailIndexHeader !== null ? parseInt(tailIndexHeader, 10) : NaN;\n\n if (!Number.isNaN(tailIndex)) {\n // Resolve: e.g. tailIndex=499, startIndex=-20 → 500 + (-20) = 480\n chunkIndex = Math.max(0, tailIndex + 1 + explicitStartIndex);\n } else {\n // Header missing or unparseable — fall back to replaying from the\n // beginning so retries don't resume from a wrong position.\n console.warn(\n '[WorkflowChatTransport] Negative initialStartIndex is configured ' +\n `(${explicitStartIndex}) but the reconnection endpoint did not ` +\n 'return a valid \"x-workflow-stream-tail-index\" header. Retries ' +\n 'will replay the stream from the beginning. See: ' +\n 'https://workflow.dev/docs/ai/resumable-streams#resuming-from-the-end-of-the-stream',\n );\n replayFromStart = true;\n }\n }\n useExplicitStartIndex = false;\n\n try {\n const chunkStream = parseJsonEventStream({\n stream: res.body,\n schema: uiMessageChunkSchema,\n });\n for await (const chunk of createAsyncIterableStream(chunkStream)) {\n if (!chunk.success) {\n throw chunk.error;\n }\n\n chunkIndex++;\n\n yield chunk.value;\n\n if (chunk.value.type === 'finish') {\n gotFinish = true;\n }\n }\n // Reset consecutive error count only after successful stream parsing\n consecutiveErrors = 0;\n } catch (error) {\n console.error('Error in chat GET reconnectToStream', error);\n consecutiveErrors++;\n\n if (consecutiveErrors >= this.maxConsecutiveErrors) {\n throw new Error(\n `Failed to reconnect after ${this.maxConsecutiveErrors} consecutive errors. Last error: ${getErrorMessage(error)}`,\n );\n }\n }\n }\n\n await this.onFinish(gotFinish, { chatId: options.chatId, chunkIndex });\n }\n\n private async onFinish(\n gotFinish: boolean,\n { chatId, chunkIndex }: { chatId: string; chunkIndex: number },\n ) {\n if (gotFinish) {\n await this.onChatEnd?.({ chatId, chunkIndex });\n } else {\n throw new Error('No finish chunk received');\n }\n }\n}\n"],"mappings":"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","names":["filterActiveTools","tool","_a","filterActiveTools","messages","durationMs","getErrorMessage"]}
1
+ {"version":3,"sources":["../src/workflow-agent.ts","../src/stream-text-iterator.ts","../src/do-stream-step.ts","../src/serializable-schema.ts","../src/to-ui-message-chunk.ts","../src/workflow-chat-transport.ts"],"sourcesContent":["import type {\n JSONValue,\n LanguageModelV4CallOptions,\n LanguageModelV4Prompt,\n LanguageModelV4StreamPart,\n LanguageModelV4ToolResultPart,\n SharedV4ProviderOptions,\n} from '@ai-sdk/provider';\nimport {\n type FinishReason,\n LanguageModel,\n type LanguageModelResponseMetadata,\n type LanguageModelUsage,\n type Experimental_LanguageModelStreamPart as ModelCallStreamPart,\n type ModelMessage,\n Output,\n type StepResult,\n type StopCondition,\n type StreamTextOnStepFinishCallback,\n type SystemModelMessage,\n type ToolCallRepairFunction,\n type ToolChoice,\n type ToolSet,\n type UIMessage,\n experimental_filterActiveTools as filterActiveTools,\n} from 'ai';\nimport {\n convertToLanguageModelPrompt,\n mergeAbortSignals,\n mergeCallbacks,\n standardizePrompt,\n} from 'ai/internal';\nimport { streamTextIterator } from './stream-text-iterator.js';\n\n// Re-export for consumers\nexport type { CompatibleLanguageModel } from './types.js';\n\n/**\n * Callback function to be called after each step completes.\n * Alias for the AI SDK's StreamTextOnStepFinishCallback, using\n * WorkflowAgent-consistent naming.\n */\nexport type WorkflowAgentOnStepFinishCallback<\n TTools extends ToolSet = ToolSet,\n> = StreamTextOnStepFinishCallback<TTools, any>;\n\n/**\n * Infer the type of the tools of a workflow agent.\n */\nexport type InferWorkflowAgentTools<WORKFLOW_AGENT> =\n WORKFLOW_AGENT extends WorkflowAgent<infer TOOLS> ? TOOLS : never;\n\n/**\n * Infer the UI message type of a workflow agent.\n */\nexport type InferWorkflowAgentUIMessage<\n _WORKFLOW_AGENT,\n MESSAGE_METADATA = unknown,\n> = UIMessage<MESSAGE_METADATA>;\n\n/**\n * Re-export the Output helper for structured output specifications.\n * Use `Output.object({ schema })` for structured output or `Output.text()` for text output.\n */\nexport { Output };\n\n/**\n * Output specification interface for structured outputs.\n * Use `Output.object({ schema })` or `Output.text()` to create an output specification.\n */\nexport interface OutputSpecification<OUTPUT, PARTIAL> {\n readonly name: string;\n responseFormat: PromiseLike<LanguageModelV4CallOptions['responseFormat']>;\n parsePartialOutput(options: {\n text: string;\n }): Promise<{ partial: PARTIAL } | undefined>;\n parseCompleteOutput(\n options: { text: string },\n context: {\n response: LanguageModelResponseMetadata;\n usage: LanguageModelUsage;\n finishReason: FinishReason;\n },\n ): Promise<OUTPUT>;\n}\n\n/**\n * Provider-specific options type. This is equivalent to SharedV4ProviderOptions from @ai-sdk/provider.\n */\nexport type ProviderOptions = SharedV4ProviderOptions;\n\n/**\n * Telemetry settings for observability.\n */\nexport interface TelemetryOptions {\n /**\n * Enable or disable telemetry. Defaults to true.\n */\n isEnabled?: boolean;\n\n /**\n * Identifier for this function. Used to group telemetry data by function.\n */\n functionId?: string;\n\n /**\n * Additional information to include in the telemetry data.\n */\n metadata?: Record<\n string,\n | string\n | number\n | boolean\n | Array<string | number | boolean>\n | null\n | undefined\n >;\n\n /**\n * Enable or disable input recording. Enabled by default.\n *\n * You might want to disable input recording to avoid recording sensitive\n * information, to reduce data transfers, or to increase performance.\n */\n recordInputs?: boolean;\n\n /**\n * Enable or disable output recording. Enabled by default.\n *\n * You might want to disable output recording to avoid recording sensitive\n * information, to reduce data transfers, or to increase performance.\n */\n recordOutputs?: boolean;\n\n /**\n * Custom tracer for the telemetry.\n */\n tracer?: unknown;\n}\n\n/**\n * A transformation that is applied to the stream.\n */\nexport type StreamTextTransform<TTools extends ToolSet> = (options: {\n tools: TTools;\n stopStream: () => void;\n}) => TransformStream<LanguageModelV4StreamPart, LanguageModelV4StreamPart>;\n\n/**\n * Function to repair a tool call that failed to parse.\n * Re-exported from the AI SDK core.\n */\nexport type { ToolCallRepairFunction } from 'ai';\n\n/**\n * Custom download function for URLs.\n * The function receives an array of URLs with information about whether\n * the model supports them directly.\n */\nexport type DownloadFunction = (\n options: {\n url: URL;\n isUrlSupportedByModel: boolean;\n }[],\n) => PromiseLike<\n ({ data: Uint8Array; mediaType: string | undefined } | null)[]\n>;\n\n/**\n * Generation settings that can be passed to the model.\n * These map directly to LanguageModelV4CallOptions.\n */\nexport interface GenerationSettings {\n /**\n * Maximum number of tokens to generate.\n */\n maxOutputTokens?: number;\n\n /**\n * Temperature setting. The range depends on the provider and model.\n * It is recommended to set either `temperature` or `topP`, but not both.\n */\n temperature?: number;\n\n /**\n * Nucleus sampling. This is a number between 0 and 1.\n * E.g. 0.1 would mean that only tokens with the top 10% probability mass are considered.\n * It is recommended to set either `temperature` or `topP`, but not both.\n */\n topP?: number;\n\n /**\n * Only sample from the top K options for each subsequent token.\n * Used to remove \"long tail\" low probability responses.\n * Recommended for advanced use cases only. You usually only need to use temperature.\n */\n topK?: number;\n\n /**\n * Presence penalty setting. It affects the likelihood of the model to\n * repeat information that is already in the prompt.\n * The presence penalty is a number between -1 (increase repetition)\n * and 1 (maximum penalty, decrease repetition). 0 means no penalty.\n */\n presencePenalty?: number;\n\n /**\n * Frequency penalty setting. It affects the likelihood of the model\n * to repeatedly use the same words or phrases.\n * The frequency penalty is a number between -1 (increase repetition)\n * and 1 (maximum penalty, decrease repetition). 0 means no penalty.\n */\n frequencyPenalty?: number;\n\n /**\n * Stop sequences. If set, the model will stop generating text when one of the stop sequences is generated.\n * Providers may have limits on the number of stop sequences.\n */\n stopSequences?: string[];\n\n /**\n * The seed (integer) to use for random sampling. If set and supported\n * by the model, calls will generate deterministic results.\n */\n seed?: number;\n\n /**\n * Maximum number of retries. Set to 0 to disable retries.\n * Note: In workflow context, retries are typically handled by the workflow step mechanism.\n * @default 2\n */\n maxRetries?: number;\n\n /**\n * Abort signal for cancelling the operation.\n */\n abortSignal?: AbortSignal;\n\n /**\n * Additional HTTP headers to be sent with the request.\n * Only applicable for HTTP-based providers.\n */\n headers?: Record<string, string | undefined>;\n\n /**\n * Additional provider-specific options. They are passed through\n * to the provider from the AI SDK and enable provider-specific\n * functionality that can be fully encapsulated in the provider.\n */\n providerOptions?: ProviderOptions;\n}\n\n/**\n * Information passed to the prepareStep callback.\n */\nexport interface PrepareStepInfo<TTools extends ToolSet = ToolSet> {\n /**\n * The current model configuration (string or function).\n * The function should return a LanguageModelV4 instance.\n */\n model: LanguageModel;\n\n /**\n * The current step number (0-indexed).\n */\n stepNumber: number;\n\n /**\n * All previous steps with their results.\n */\n steps: StepResult<TTools, any>[];\n\n /**\n * The messages that will be sent to the model.\n * This is the LanguageModelV4Prompt format used internally.\n */\n messages: LanguageModelV4Prompt;\n\n /**\n * The context passed via the experimental_context setting (experimental).\n */\n experimental_context: unknown;\n}\n\n/**\n * Return type from the prepareStep callback.\n * All properties are optional - only return the ones you want to override.\n */\nexport interface PrepareStepResult extends Partial<GenerationSettings> {\n /**\n * Override the model for this step.\n */\n model?: LanguageModel;\n\n /**\n * Override the system message for this step.\n */\n system?: string;\n\n /**\n * Override the messages for this step.\n * Use this for context management or message injection.\n */\n messages?: LanguageModelV4Prompt;\n\n /**\n * Override the tool choice for this step.\n */\n toolChoice?: ToolChoice<ToolSet>;\n\n /**\n * Override the active tools for this step.\n * Limits the tools that are available for the model to call.\n */\n activeTools?: string[];\n\n /**\n * Context that is passed into tool execution. Experimental.\n * Changing the context will affect the context in this step and all subsequent steps.\n */\n experimental_context?: unknown;\n}\n\n/**\n * Callback function called before each step in the agent loop.\n * Use this to modify settings, manage context, or implement dynamic behavior.\n */\nexport type PrepareStepCallback<TTools extends ToolSet = ToolSet> = (\n info: PrepareStepInfo<TTools>,\n) => PrepareStepResult | Promise<PrepareStepResult>;\n\n/**\n * Options passed to the prepareCall callback.\n */\nexport interface PrepareCallOptions<\n TTools extends ToolSet = ToolSet,\n> extends Partial<GenerationSettings> {\n model: LanguageModel;\n tools: TTools;\n instructions?: string | SystemModelMessage | Array<SystemModelMessage>;\n toolChoice?: ToolChoice<TTools>;\n telemetry?: TelemetryOptions;\n /**\n * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.\n */\n experimental_telemetry?: TelemetryOptions;\n experimental_context?: unknown;\n messages: ModelMessage[];\n}\n\n/**\n * Result of the prepareCall callback. All fields are optional —\n * only returned fields override the defaults.\n * Note: `tools` cannot be overridden via prepareCall because they are\n * bound at construction time for type safety.\n */\nexport type PrepareCallResult<TTools extends ToolSet = ToolSet> = Partial<\n Omit<PrepareCallOptions<TTools>, 'tools'>\n>;\n\n/**\n * Callback called once before the agent loop starts to transform call parameters.\n */\nexport type PrepareCallCallback<TTools extends ToolSet = ToolSet> = (\n options: PrepareCallOptions<TTools>,\n) => PrepareCallResult<TTools> | Promise<PrepareCallResult<TTools>>;\n\n/**\n * Configuration options for creating a {@link WorkflowAgent} instance.\n */\nexport interface WorkflowAgentOptions<\n TTools extends ToolSet = ToolSet,\n> extends GenerationSettings {\n /**\n * The id of the agent.\n */\n id?: string;\n\n /**\n * The model provider to use for the agent.\n *\n * This should be a string compatible with the Vercel AI Gateway (e.g., 'anthropic/claude-opus'),\n * or a LanguageModelV4 instance from a provider.\n */\n model: LanguageModel;\n\n /**\n * A set of tools available to the agent.\n * Tools can be implemented as workflow steps for automatic retries and persistence,\n * or as regular workflow-level logic using core library features like sleep() and Hooks.\n */\n tools?: TTools;\n\n /**\n * Agent instructions. Can be a string, a SystemModelMessage, or an array of SystemModelMessages.\n * Supports provider-specific options (e.g., caching) when using the SystemModelMessage form.\n */\n instructions?: string | SystemModelMessage | Array<SystemModelMessage>;\n\n /**\n * Optional system prompt to guide the agent's behavior.\n * @deprecated Use `instructions` instead.\n */\n system?: string;\n\n /**\n * The tool choice strategy. Default: 'auto'.\n */\n toolChoice?: ToolChoice<TTools>;\n\n /**\n * Optional telemetry configuration.\n */\n telemetry?: TelemetryOptions;\n\n /**\n * Optional telemetry configuration.\n *\n * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.\n */\n experimental_telemetry?: TelemetryOptions;\n\n /**\n * Default context that is passed into tool execution for every stream call on this agent.\n *\n * Per-stream `experimental_context` values passed to `stream()` override this default.\n * Experimental (can break in patch releases).\n * @default undefined\n */\n experimental_context?: unknown;\n\n /**\n * Default stop condition for the agent loop. When the condition is an array,\n * any of the conditions can be met to stop the generation.\n *\n * Per-stream `stopWhen` values passed to `stream()` override this default.\n */\n stopWhen?:\n | StopCondition<NoInfer<ToolSet>, any>\n | Array<StopCondition<NoInfer<ToolSet>, any>>;\n\n /**\n * Default set of active tools that limits which tools the model can call,\n * without changing the tool call and result types in the result.\n *\n * Per-stream `activeTools` values passed to `stream()` override this default.\n */\n activeTools?: Array<keyof NoInfer<TTools>>;\n\n /**\n * Default output specification for structured outputs.\n * Use `Output.object({ schema })` for structured output or `Output.text()` for text output.\n *\n * Per-stream `output` values passed to `stream()` override this default.\n */\n output?: OutputSpecification<any, any>;\n\n /**\n * Default function that attempts to repair a tool call that failed to parse.\n *\n * Per-stream `experimental_repairToolCall` values passed to `stream()` override this default.\n */\n experimental_repairToolCall?: ToolCallRepairFunction<TTools>;\n\n /**\n * Default custom download function to use for URLs.\n *\n * Per-stream `experimental_download` values passed to `stream()` override this default.\n */\n experimental_download?: DownloadFunction;\n\n /**\n * Default callback function called before each step in the agent loop.\n * Use this to modify settings, manage context, or inject messages dynamically\n * for every stream call on this agent instance.\n *\n * Per-stream `prepareStep` values passed to `stream()` override this default.\n */\n prepareStep?: PrepareStepCallback<TTools>;\n\n /**\n * Callback function to be called after each step completes.\n */\n onStepFinish?: WorkflowAgentOnStepFinishCallback<ToolSet>;\n\n /**\n * Callback that is called when the LLM response and all request tool executions are finished.\n */\n onFinish?: WorkflowAgentOnFinishCallback<ToolSet>;\n\n /**\n * Callback called when the agent starts streaming, before any LLM calls.\n */\n experimental_onStart?: WorkflowAgentOnStartCallback;\n\n /**\n * Callback called before each step (LLM call) begins.\n */\n experimental_onStepStart?: WorkflowAgentOnStepStartCallback;\n\n /**\n * Callback called before a tool's execute function runs.\n */\n experimental_onToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback;\n\n /**\n * Callback called after a tool execution completes.\n */\n experimental_onToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback;\n\n /**\n * Prepare the parameters for the stream call.\n * Called once before the agent loop starts. Use this to transform\n * model, tools, instructions, or other settings based on runtime context.\n */\n prepareCall?: PrepareCallCallback<TTools>;\n}\n\n/**\n * Callback that is called when the LLM response and all request tool executions are finished.\n */\nexport type WorkflowAgentOnFinishCallback<\n TTools extends ToolSet = ToolSet,\n OUTPUT = never,\n> = (event: {\n /**\n * Details for all steps.\n */\n readonly steps: StepResult<TTools, any>[];\n\n /**\n * The final messages including all tool calls and results.\n */\n readonly messages: ModelMessage[];\n\n /**\n * The text output from the last step.\n */\n readonly text: string;\n\n /**\n * The finish reason from the last step.\n */\n readonly finishReason: FinishReason;\n\n /**\n * The total token usage across all steps.\n */\n readonly totalUsage: LanguageModelUsage;\n\n /**\n * Context that is passed into tool execution.\n */\n readonly experimental_context: unknown;\n\n /**\n * The generated structured output. It uses the `output` specification.\n * Only available when `output` is specified.\n */\n readonly output: OUTPUT;\n}) => PromiseLike<void> | void;\n\n/**\n * Callback that is invoked when an error occurs during streaming.\n */\nexport type WorkflowAgentOnErrorCallback = (event: {\n error: unknown;\n}) => PromiseLike<void> | void;\n\n/**\n * Callback that is set using the `onAbort` option.\n */\nexport type WorkflowAgentOnAbortCallback<TTools extends ToolSet = ToolSet> =\n (event: {\n /**\n * Details for all previously finished steps.\n */\n readonly steps: StepResult<TTools, any>[];\n }) => PromiseLike<void> | void;\n\n/**\n * Callback that is called when the agent starts streaming, before any LLM calls.\n */\nexport type WorkflowAgentOnStartCallback = (event: {\n /** The model being used */\n readonly model: LanguageModel;\n /** The messages being sent */\n readonly messages: ModelMessage[];\n}) => PromiseLike<void> | void;\n\n/**\n * Callback that is called before each step (LLM call) begins.\n */\nexport type WorkflowAgentOnStepStartCallback<TTools extends ToolSet = ToolSet> =\n (event: {\n /** The current step number (0-based) */\n readonly stepNumber: number;\n /** The model being used for this step */\n readonly model: LanguageModel;\n /** The messages being sent for this step */\n readonly messages: ModelMessage[];\n /** Results from all previously finished steps */\n readonly steps: ReadonlyArray<StepResult<TTools, any>>;\n }) => PromiseLike<void> | void;\n\n/**\n * Callback that is called before a tool's execute function runs.\n */\nexport type WorkflowAgentOnToolExecutionStartCallback = (event: {\n /** The tool call being executed */\n readonly toolCall: ToolCall;\n /** The current step number (0-based) */\n readonly stepNumber: number;\n}) => PromiseLike<void> | void;\n\n/**\n * Callback that is called after a tool execution completes.\n * Uses a discriminated union pattern: check `success` to determine\n * whether `output` or `error` is available.\n */\nexport type WorkflowAgentOnToolExecutionEndCallback = (\n event:\n | {\n /** The tool call that was executed */\n readonly toolCall: ToolCall;\n /** The current step number (0-based) */\n readonly stepNumber: number;\n /** Execution time in milliseconds */\n readonly durationMs: number;\n /** Whether the tool call succeeded */\n readonly success: true;\n /** The tool result */\n readonly output: unknown;\n readonly error?: never;\n }\n | {\n /** The tool call that was executed */\n readonly toolCall: ToolCall;\n /** The current step number (0-based) */\n readonly stepNumber: number;\n /** Execution time in milliseconds */\n readonly durationMs: number;\n /** Whether the tool call succeeded */\n readonly success: false;\n /** The error that occurred */\n readonly error: unknown;\n readonly output?: never;\n },\n) => PromiseLike<void> | void;\n\n/**\n * Options for the {@link WorkflowAgent.stream} method.\n */\nexport type WorkflowAgentStreamOptions<\n TTools extends ToolSet = ToolSet,\n OUTPUT = never,\n PARTIAL_OUTPUT = never,\n> = Partial<GenerationSettings> &\n (\n | {\n /**\n * A prompt. It can be either a text prompt or a list of messages.\n *\n * You can either use `prompt` or `messages` but not both.\n */\n prompt: string | Array<ModelMessage>;\n\n /**\n * A list of messages.\n *\n * You can either use `prompt` or `messages` but not both.\n */\n messages?: never;\n }\n | {\n /**\n * The conversation messages to process. Should follow the AI SDK's ModelMessage format.\n *\n * You can either use `prompt` or `messages` but not both.\n */\n messages: Array<ModelMessage>;\n\n /**\n * A prompt. It can be either a text prompt or a list of messages.\n *\n * You can either use `prompt` or `messages` but not both.\n */\n prompt?: never;\n }\n ) & {\n /**\n * Optional system prompt override. If provided, overrides the system prompt from the constructor.\n */\n system?: string;\n\n /**\n * A WritableStream that receives raw LanguageModelV4StreamPart chunks in real-time\n * as the model generates them. This enables streaming to the client without\n * coupling WorkflowAgent to UIMessageChunk format.\n *\n * Convert to UIMessageChunks at the response boundary using\n * `createUIMessageChunkTransform()` from `@ai-sdk/workflow`.\n *\n * @example\n * ```typescript\n * // In the workflow:\n * await agent.stream({\n * messages,\n * writable: getWritable<ModelCallStreamPart>(),\n * });\n *\n * // In the route handler:\n * return createUIMessageStreamResponse({\n * stream: run.readable.pipeThrough(createModelCallToUIChunkTransform()),\n * });\n * ```\n */\n writable?: WritableStream<ModelCallStreamPart<ToolSet>>;\n\n /**\n * Condition for stopping the generation when there are tool results in the last step.\n * When the condition is an array, any of the conditions can be met to stop the generation.\n */\n stopWhen?:\n | StopCondition<NoInfer<ToolSet>, any>\n | Array<StopCondition<NoInfer<ToolSet>, any>>;\n\n /**\n * The tool choice strategy. Default: 'auto'.\n * Overrides the toolChoice from the constructor if provided.\n */\n toolChoice?: ToolChoice<TTools>;\n\n /**\n * Limits the tools that are available for the model to call without\n * changing the tool call and result types in the result.\n */\n activeTools?: Array<keyof NoInfer<TTools>>;\n\n /**\n * Optional telemetry configuration.\n */\n telemetry?: TelemetryOptions;\n\n /**\n * Optional telemetry configuration.\n *\n * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.\n */\n experimental_telemetry?: TelemetryOptions;\n\n /**\n * Context that is passed into tool execution.\n * Experimental (can break in patch releases).\n * @default undefined\n */\n experimental_context?: unknown;\n\n /**\n * Optional specification for parsing structured outputs from the LLM response.\n * Use `Output.object({ schema })` for structured output or `Output.text()` for text output.\n *\n * @example\n * ```typescript\n * import { Output } from '@workflow/ai';\n * import { z } from 'zod';\n *\n * const result = await agent.stream({\n * messages: [...],\n * writable: getWritable(),\n * output: Output.object({\n * schema: z.object({\n * sentiment: z.enum(['positive', 'negative', 'neutral']),\n * confidence: z.number(),\n * }),\n * }),\n * });\n *\n * console.log(result.output); // { sentiment: 'positive', confidence: 0.95 }\n * ```\n */\n output?: OutputSpecification<OUTPUT, PARTIAL_OUTPUT>;\n\n /**\n * Whether to include raw chunks from the provider in the stream.\n * When enabled, you will receive raw chunks with type 'raw' that contain the unprocessed data from the provider.\n * This allows access to cutting-edge provider features not yet wrapped by the AI SDK.\n * Defaults to false.\n */\n includeRawChunks?: boolean;\n\n /**\n * A function that attempts to repair a tool call that failed to parse.\n */\n experimental_repairToolCall?: ToolCallRepairFunction<TTools>;\n\n /**\n * Optional stream transformations.\n * They are applied in the order they are provided.\n * The stream transformations must maintain the stream structure for streamText to work correctly.\n */\n experimental_transform?:\n | StreamTextTransform<TTools>\n | Array<StreamTextTransform<TTools>>;\n\n /**\n * Custom download function to use for URLs.\n * By default, files are downloaded if the model does not support the URL for the given media type.\n */\n experimental_download?: DownloadFunction;\n\n /**\n * Callback function to be called after each step completes.\n */\n onStepFinish?: WorkflowAgentOnStepFinishCallback<TTools>;\n\n /**\n * Callback that is invoked when an error occurs during streaming.\n * You can use it to log errors.\n */\n onError?: WorkflowAgentOnErrorCallback;\n\n /**\n * Callback that is called when the LLM response and all request tool executions\n * (for tools that have an `execute` function) are finished.\n */\n onFinish?: WorkflowAgentOnFinishCallback<TTools, OUTPUT>;\n\n /**\n * Callback that is called when the operation is aborted.\n */\n onAbort?: WorkflowAgentOnAbortCallback<TTools>;\n\n /**\n * Callback called when the agent starts streaming, before any LLM calls.\n */\n experimental_onStart?: WorkflowAgentOnStartCallback;\n\n /**\n * Callback called before each step (LLM call) begins.\n */\n experimental_onStepStart?: WorkflowAgentOnStepStartCallback;\n\n /**\n * Callback called before a tool's execute function runs.\n */\n experimental_onToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback;\n\n /**\n * Callback called after a tool execution completes.\n */\n experimental_onToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback;\n\n /**\n * Callback function called before each step in the agent loop.\n * Use this to modify settings, manage context, or inject messages dynamically.\n *\n * @example\n * ```typescript\n * prepareStep: async ({ messages, stepNumber }) => {\n * // Inject messages from a queue\n * const queuedMessages = await getQueuedMessages();\n * if (queuedMessages.length > 0) {\n * return {\n * messages: [...messages, ...queuedMessages],\n * };\n * }\n * return {};\n * }\n * ```\n */\n prepareStep?: PrepareStepCallback<TTools>;\n\n /**\n * Timeout in milliseconds for the stream operation.\n * When specified, creates an AbortSignal that will abort the operation after the given time.\n * If both `timeout` and `abortSignal` are provided, whichever triggers first will abort.\n */\n timeout?: number;\n\n /**\n * Whether to send a 'finish' chunk to the writable stream when streaming completes.\n * @default true\n */\n sendFinish?: boolean;\n\n /**\n * Whether to prevent the writable stream from being closed after streaming completes.\n * @default false\n */\n preventClose?: boolean;\n };\n\n/**\n * A tool call made by the model. Matches the AI SDK's tool call shape.\n */\nexport interface ToolCall {\n /** Discriminator for content part arrays */\n type: 'tool-call';\n /** The unique identifier of the tool call */\n toolCallId: string;\n /** The name of the tool that was called */\n toolName: string;\n /** The parsed input arguments for the tool call */\n input: unknown;\n}\n\n/**\n * A tool result from executing a tool. Matches the AI SDK's tool result shape.\n */\nexport interface ToolResult {\n /** Discriminator for content part arrays */\n type: 'tool-result';\n /** The tool call ID this result corresponds to */\n toolCallId: string;\n /** The name of the tool that was executed */\n toolName: string;\n /** The parsed input arguments that were passed to the tool */\n input: unknown;\n /** The output produced by the tool */\n output: unknown;\n}\n\n/**\n * Result of the WorkflowAgent.stream method.\n */\nexport interface WorkflowAgentStreamResult<\n TTools extends ToolSet = ToolSet,\n OUTPUT = never,\n> {\n /**\n * The final messages including all tool calls and results.\n */\n messages: ModelMessage[];\n\n /**\n * Details for all steps.\n */\n steps: StepResult<TTools, any>[];\n\n /**\n * The tool calls from the last step.\n * Includes all tool calls regardless of whether they were executed.\n *\n * When the agent stops because a tool without an `execute` function was called,\n * this array will contain those calls. Compare with `toolResults` to find\n * unresolved tool calls that need client-side handling:\n *\n * ```ts\n * const unresolved = result.toolCalls.filter(\n * tc => !result.toolResults.some(tr => tr.toolCallId === tc.toolCallId)\n * );\n * ```\n *\n * This matches the AI SDK's `GenerateTextResult.toolCalls` behavior.\n */\n toolCalls: ToolCall[];\n\n /**\n * The tool results from the last step.\n * Only includes results for tools that were actually executed (server-side or provider-executed).\n * Tools without an `execute` function will NOT have entries here.\n *\n * This matches the AI SDK's `GenerateTextResult.toolResults` behavior.\n */\n toolResults: ToolResult[];\n\n /**\n * The generated structured output. It uses the `output` specification.\n * Only available when `output` is specified.\n */\n output: OUTPUT;\n}\n\n/**\n * A class for building durable AI agents within workflows.\n *\n * WorkflowAgent enables you to create AI-powered agents that can maintain state\n * across workflow steps, call tools, and gracefully handle interruptions and resumptions.\n * It integrates seamlessly with the AI SDK and the Workflow DevKit for\n * production-grade reliability.\n *\n * @example\n * ```typescript\n * const agent = new WorkflowAgent({\n * model: 'anthropic/claude-opus',\n * tools: {\n * getWeather: {\n * description: 'Get weather for a location',\n * inputSchema: z.object({ location: z.string() }),\n * execute: getWeatherStep,\n * },\n * },\n * instructions: 'You are a helpful weather assistant.',\n * });\n *\n * const result = await agent.stream({\n * messages: [{ role: 'user', content: 'What is the weather?' }],\n * });\n * ```\n */\nexport class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {\n /**\n * The id of the agent.\n */\n public readonly id: string | undefined;\n\n private model: LanguageModel;\n /**\n * The tool set configured for this agent.\n */\n public readonly tools: TBaseTools;\n private instructions?:\n | string\n | SystemModelMessage\n | Array<SystemModelMessage>;\n private generationSettings: GenerationSettings;\n private toolChoice?: ToolChoice<TBaseTools>;\n private telemetry?: TelemetryOptions;\n private experimentalContext: unknown;\n private stopWhen?:\n | StopCondition<ToolSet, any>\n | Array<StopCondition<ToolSet, any>>;\n private activeTools?: Array<keyof TBaseTools>;\n private output?: OutputSpecification<any, any>;\n private experimentalRepairToolCall?: ToolCallRepairFunction<TBaseTools>;\n private experimentalDownload?: DownloadFunction;\n private prepareStep?: PrepareStepCallback<TBaseTools>;\n private constructorOnStepFinish?: WorkflowAgentOnStepFinishCallback<ToolSet>;\n private constructorOnFinish?: WorkflowAgentOnFinishCallback<ToolSet>;\n private constructorOnStart?: WorkflowAgentOnStartCallback;\n private constructorOnStepStart?: WorkflowAgentOnStepStartCallback;\n private constructorOnToolExecutionStart?: WorkflowAgentOnToolExecutionStartCallback;\n private constructorOnToolExecutionEnd?: WorkflowAgentOnToolExecutionEndCallback;\n private prepareCall?: PrepareCallCallback<TBaseTools>;\n\n constructor(options: WorkflowAgentOptions<TBaseTools>) {\n this.id = options.id;\n this.model = options.model;\n this.tools = (options.tools ?? {}) as TBaseTools;\n // `instructions` takes precedence over deprecated `system`\n this.instructions = options.instructions ?? options.system;\n this.toolChoice = options.toolChoice;\n this.telemetry = options.telemetry ?? options.experimental_telemetry;\n this.experimentalContext = options.experimental_context;\n this.stopWhen = options.stopWhen;\n this.activeTools = options.activeTools;\n this.output = options.output;\n this.experimentalRepairToolCall = options.experimental_repairToolCall;\n this.experimentalDownload = options.experimental_download;\n this.prepareStep = options.prepareStep;\n this.constructorOnStepFinish = options.onStepFinish;\n this.constructorOnFinish = options.onFinish;\n this.constructorOnStart = options.experimental_onStart;\n this.constructorOnStepStart = options.experimental_onStepStart;\n this.constructorOnToolExecutionStart =\n options.experimental_onToolExecutionStart;\n this.constructorOnToolExecutionEnd =\n options.experimental_onToolExecutionEnd;\n this.prepareCall = options.prepareCall;\n\n // Extract generation settings\n this.generationSettings = {\n maxOutputTokens: options.maxOutputTokens,\n temperature: options.temperature,\n topP: options.topP,\n topK: options.topK,\n presencePenalty: options.presencePenalty,\n frequencyPenalty: options.frequencyPenalty,\n stopSequences: options.stopSequences,\n seed: options.seed,\n maxRetries: options.maxRetries,\n abortSignal: options.abortSignal,\n headers: options.headers,\n providerOptions: options.providerOptions,\n };\n }\n\n generate() {\n throw new Error('Not implemented');\n }\n\n async stream<\n TTools extends TBaseTools = TBaseTools,\n OUTPUT = never,\n PARTIAL_OUTPUT = never,\n >(\n options: WorkflowAgentStreamOptions<TTools, OUTPUT, PARTIAL_OUTPUT>,\n ): Promise<WorkflowAgentStreamResult<TTools, OUTPUT>> {\n // Call prepareCall to transform parameters before the agent loop\n let effectiveModel: LanguageModel = this.model;\n let effectiveInstructions = options.system ?? this.instructions;\n let effectivePrompt: string | Array<ModelMessage> | undefined =\n options.prompt;\n let effectiveMessages: Array<ModelMessage> | undefined = options.messages;\n let effectiveGenerationSettings = { ...this.generationSettings };\n let effectiveExperimentalContext =\n options.experimental_context ?? this.experimentalContext;\n let effectiveToolChoiceFromPrepare = options.toolChoice ?? this.toolChoice;\n let effectiveTelemetryFromPrepare =\n options.telemetry ?? options.experimental_telemetry ?? this.telemetry;\n\n // Resolve messages for prepareCall: use messages directly, or convert prompt\n const resolvedMessagesForPrepareCall: ModelMessage[] =\n effectiveMessages ??\n (typeof effectivePrompt === 'string'\n ? [{ role: 'user' as const, content: effectivePrompt }]\n : (effectivePrompt as ModelMessage[])) ??\n [];\n\n if (this.prepareCall) {\n const prepared = await this.prepareCall({\n model: effectiveModel,\n tools: this.tools,\n instructions: effectiveInstructions,\n toolChoice: effectiveToolChoiceFromPrepare as ToolChoice<TBaseTools>,\n telemetry: effectiveTelemetryFromPrepare,\n experimental_telemetry: effectiveTelemetryFromPrepare,\n experimental_context: effectiveExperimentalContext,\n messages: resolvedMessagesForPrepareCall,\n ...effectiveGenerationSettings,\n } as PrepareCallOptions<TBaseTools>);\n\n if (prepared.model !== undefined) effectiveModel = prepared.model;\n if (prepared.instructions !== undefined)\n effectiveInstructions = prepared.instructions;\n if (prepared.messages !== undefined) {\n effectiveMessages = prepared.messages as Array<ModelMessage>;\n effectivePrompt = undefined; // messages from prepareCall take precedence\n }\n if (prepared.experimental_context !== undefined)\n effectiveExperimentalContext = prepared.experimental_context;\n if (prepared.toolChoice !== undefined)\n effectiveToolChoiceFromPrepare =\n prepared.toolChoice as ToolChoice<TBaseTools>;\n if (prepared.telemetry !== undefined)\n effectiveTelemetryFromPrepare = prepared.telemetry;\n else if (prepared.experimental_telemetry !== undefined)\n effectiveTelemetryFromPrepare = prepared.experimental_telemetry;\n if (prepared.maxOutputTokens !== undefined)\n effectiveGenerationSettings.maxOutputTokens = prepared.maxOutputTokens;\n if (prepared.temperature !== undefined)\n effectiveGenerationSettings.temperature = prepared.temperature;\n if (prepared.topP !== undefined)\n effectiveGenerationSettings.topP = prepared.topP;\n if (prepared.topK !== undefined)\n effectiveGenerationSettings.topK = prepared.topK;\n if (prepared.presencePenalty !== undefined)\n effectiveGenerationSettings.presencePenalty = prepared.presencePenalty;\n if (prepared.frequencyPenalty !== undefined)\n effectiveGenerationSettings.frequencyPenalty =\n prepared.frequencyPenalty;\n if (prepared.stopSequences !== undefined)\n effectiveGenerationSettings.stopSequences = prepared.stopSequences;\n if (prepared.seed !== undefined)\n effectiveGenerationSettings.seed = prepared.seed;\n if (prepared.headers !== undefined)\n effectiveGenerationSettings.headers = prepared.headers;\n if (prepared.providerOptions !== undefined)\n effectiveGenerationSettings.providerOptions = prepared.providerOptions;\n }\n\n const prompt = await standardizePrompt({\n system: effectiveInstructions,\n ...(effectivePrompt != null\n ? { prompt: effectivePrompt }\n : { messages: effectiveMessages! }),\n });\n\n // Process tool approval responses before starting the agent loop.\n // This mirrors how stream-text.ts handles tool-approval-response parts:\n // approved tools are executed, denied tools get denial results, and\n // approval parts are stripped from the messages.\n const { approvedToolApprovals, deniedToolApprovals } =\n collectToolApprovalsFromMessages(prompt.messages);\n\n if (approvedToolApprovals.length > 0 || deniedToolApprovals.length > 0) {\n const _toolResultMessages: ModelMessage[] = [];\n const toolResultContent: Array<{\n type: 'tool-result';\n toolCallId: string;\n toolName: string;\n output:\n | { type: 'text'; value: string }\n | { type: 'json'; value: JSONValue }\n | { type: 'execution-denied'; reason: string | undefined };\n }> = [];\n\n // Execute approved tools\n for (const approval of approvedToolApprovals) {\n const tool = (this.tools as ToolSet)[approval.toolName];\n if (tool && typeof tool.execute === 'function') {\n try {\n const { execute } = tool;\n const toolResult = await execute(approval.input, {\n toolCallId: approval.toolCallId,\n messages: [],\n context: effectiveExperimentalContext,\n });\n toolResultContent.push({\n type: 'tool-result' as const,\n toolCallId: approval.toolCallId,\n toolName: approval.toolName,\n output:\n typeof toolResult === 'string'\n ? { type: 'text' as const, value: toolResult }\n : { type: 'json' as const, value: toolResult },\n });\n } catch (error) {\n toolResultContent.push({\n type: 'tool-result' as const,\n toolCallId: approval.toolCallId,\n toolName: approval.toolName,\n output: {\n type: 'text' as const,\n value: getErrorMessage(error),\n },\n });\n }\n }\n }\n\n // Create denial results for denied tools\n for (const denial of deniedToolApprovals) {\n toolResultContent.push({\n type: 'tool-result' as const,\n toolCallId: denial.toolCallId,\n toolName: denial.toolName,\n output: {\n type: 'execution-denied' as const,\n reason: denial.reason,\n },\n });\n }\n\n // Strip approval parts from messages and inject tool results\n const cleanedMessages: ModelMessage[] = [];\n for (const msg of prompt.messages) {\n if (msg.role === 'assistant' && Array.isArray(msg.content)) {\n const filtered = (msg.content as any[]).filter(\n (p: any) => p.type !== 'tool-approval-request',\n );\n if (filtered.length > 0) {\n cleanedMessages.push({ ...msg, content: filtered });\n }\n } else if (msg.role === 'tool') {\n const filtered = (msg.content as any[]).filter(\n (p: any) => p.type !== 'tool-approval-response',\n );\n if (filtered.length > 0) {\n cleanedMessages.push({ ...msg, content: filtered });\n }\n } else {\n cleanedMessages.push(msg);\n }\n }\n\n // Add tool results as a new tool message\n if (toolResultContent.length > 0) {\n cleanedMessages.push({\n role: 'tool',\n content: toolResultContent,\n } as ModelMessage);\n }\n\n prompt.messages = cleanedMessages;\n\n // Write tool results and step boundaries to the stream so the UI\n // can transition approved/denied tool parts to the correct state\n // and properly separate them from the subsequent model step.\n if (options.writable && toolResultContent.length > 0) {\n const approvedResults = toolResultContent\n .filter(r => r.output.type !== 'execution-denied')\n .map(r => ({\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: approvedToolApprovals.find(\n a => a.toolCallId === r.toolCallId,\n )?.input,\n output: 'value' in r.output ? r.output.value : undefined,\n }));\n const deniedResults = toolResultContent\n .filter(r => r.output.type === 'execution-denied')\n .map(r => ({ toolCallId: r.toolCallId }));\n await writeApprovalToolResults(\n options.writable,\n approvedResults,\n deniedResults,\n );\n }\n }\n\n const modelPrompt = await convertToLanguageModelPrompt({\n prompt,\n supportedUrls: {},\n download: options.experimental_download ?? this.experimentalDownload,\n });\n\n const effectiveAbortSignal = mergeAbortSignals(\n options.abortSignal ?? effectiveGenerationSettings.abortSignal,\n options.timeout,\n );\n\n // Merge generation settings: constructor defaults < prepareCall < stream options\n const mergedGenerationSettings: GenerationSettings = {\n ...effectiveGenerationSettings,\n ...(options.maxOutputTokens !== undefined && {\n maxOutputTokens: options.maxOutputTokens,\n }),\n ...(options.temperature !== undefined && {\n temperature: options.temperature,\n }),\n ...(options.topP !== undefined && { topP: options.topP }),\n ...(options.topK !== undefined && { topK: options.topK }),\n ...(options.presencePenalty !== undefined && {\n presencePenalty: options.presencePenalty,\n }),\n ...(options.frequencyPenalty !== undefined && {\n frequencyPenalty: options.frequencyPenalty,\n }),\n ...(options.stopSequences !== undefined && {\n stopSequences: options.stopSequences,\n }),\n ...(options.seed !== undefined && { seed: options.seed }),\n ...(options.maxRetries !== undefined && {\n maxRetries: options.maxRetries,\n }),\n ...(effectiveAbortSignal !== undefined && {\n abortSignal: effectiveAbortSignal,\n }),\n ...(options.headers !== undefined && { headers: options.headers }),\n ...(options.providerOptions !== undefined && {\n providerOptions: options.providerOptions,\n }),\n };\n\n // Merge constructor + stream callbacks (constructor first, then stream)\n const mergedOnStepFinish = mergeCallbacks(\n this.constructorOnStepFinish as\n | WorkflowAgentOnStepFinishCallback<TTools>\n | undefined,\n options.onStepFinish,\n );\n const mergedOnFinish = mergeCallbacks(\n this.constructorOnFinish as\n | WorkflowAgentOnFinishCallback<TTools, OUTPUT>\n | undefined,\n options.onFinish,\n );\n const mergedOnStart = mergeCallbacks(\n this.constructorOnStart,\n options.experimental_onStart,\n );\n const mergedOnStepStart = mergeCallbacks(\n this.constructorOnStepStart,\n options.experimental_onStepStart,\n );\n const mergedOnToolExecutionStart = mergeCallbacks(\n this.constructorOnToolExecutionStart,\n options.experimental_onToolExecutionStart,\n );\n const mergedOnToolExecutionEnd = mergeCallbacks(\n this.constructorOnToolExecutionEnd,\n options.experimental_onToolExecutionEnd,\n );\n\n // Determine effective tool choice\n const effectiveToolChoice = effectiveToolChoiceFromPrepare;\n\n // Merge telemetry settings\n const effectiveTelemetry = effectiveTelemetryFromPrepare;\n\n // Filter tools if activeTools is specified (stream-level overrides constructor default)\n const effectiveActiveTools = options.activeTools ?? this.activeTools;\n const effectiveTools =\n effectiveActiveTools && effectiveActiveTools.length > 0\n ? (filterActiveTools({\n tools: this.tools,\n activeTools: effectiveActiveTools as string[],\n }) ?? this.tools)\n : this.tools;\n\n // Initialize context\n let experimentalContext = effectiveExperimentalContext;\n\n const steps: StepResult<TTools, any>[] = [];\n\n // Track tool calls and results from the last step for the result\n let lastStepToolCalls: ToolCall[] = [];\n let lastStepToolResults: ToolResult[] = [];\n\n // Call onStart before the agent loop\n if (mergedOnStart) {\n await mergedOnStart({\n model: effectiveModel,\n messages: prompt.messages,\n });\n }\n\n // Helper to wrap executeTool with onToolExecutionStart/onToolExecutionEnd callbacks\n const executeToolWithCallbacks = async (\n toolCall: { toolCallId: string; toolName: string; input: unknown },\n tools: ToolSet,\n messages: LanguageModelV4Prompt,\n context?: unknown,\n currentStepNumber: number = 0,\n ): Promise<LanguageModelV4ToolResultPart> => {\n const toolCallEvent: ToolCall = {\n type: 'tool-call',\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n input: toolCall.input,\n };\n\n if (mergedOnToolExecutionStart) {\n await mergedOnToolExecutionStart({\n toolCall: toolCallEvent,\n stepNumber: currentStepNumber,\n });\n }\n\n const startTime = Date.now();\n let result: LanguageModelV4ToolResultPart;\n try {\n result = await executeTool(toolCall, tools, messages, context);\n } catch (err) {\n const durationMs = Date.now() - startTime;\n if (mergedOnToolExecutionEnd) {\n await mergedOnToolExecutionEnd({\n toolCall: toolCallEvent,\n stepNumber: currentStepNumber,\n durationMs,\n success: false,\n error: err,\n });\n }\n throw err;\n }\n\n const durationMs = Date.now() - startTime;\n if (mergedOnToolExecutionEnd) {\n const isError =\n result.output &&\n 'type' in result.output &&\n (result.output.type === 'error-text' ||\n result.output.type === 'error-json');\n if (isError) {\n await mergedOnToolExecutionEnd({\n toolCall: toolCallEvent,\n stepNumber: currentStepNumber,\n durationMs,\n success: false,\n error: 'value' in result.output ? result.output.value : undefined,\n });\n } else {\n await mergedOnToolExecutionEnd({\n toolCall: toolCallEvent,\n stepNumber: currentStepNumber,\n durationMs,\n success: true,\n output:\n result.output && 'value' in result.output\n ? result.output.value\n : undefined,\n });\n }\n }\n return result;\n };\n\n // Check for abort before starting\n if (mergedGenerationSettings.abortSignal?.aborted) {\n if (options.onAbort) {\n await options.onAbort({ steps });\n }\n return {\n messages: prompt.messages,\n steps,\n toolCalls: [],\n toolResults: [],\n output: undefined as OUTPUT,\n };\n }\n\n const iterator = streamTextIterator({\n model: effectiveModel,\n tools: effectiveTools as ToolSet,\n writable: options.writable,\n prompt: modelPrompt,\n stopConditions: options.stopWhen ?? this.stopWhen,\n\n onStepFinish: mergedOnStepFinish,\n onStepStart: mergedOnStepStart,\n onError: options.onError,\n prepareStep:\n options.prepareStep ??\n (this.prepareStep as PrepareStepCallback<ToolSet> | undefined),\n generationSettings: mergedGenerationSettings,\n toolChoice: effectiveToolChoice as ToolChoice<ToolSet>,\n experimental_context: experimentalContext,\n telemetry: effectiveTelemetry,\n includeRawChunks: options.includeRawChunks ?? false,\n repairToolCall: (options.experimental_repairToolCall ??\n this.experimentalRepairToolCall) as\n | ToolCallRepairFunction<ToolSet>\n | undefined,\n responseFormat: await (options.output ?? this.output)?.responseFormat,\n });\n\n // Track the final conversation messages from the iterator\n let finalMessages: LanguageModelV4Prompt | undefined;\n let encounteredError: unknown;\n let wasAborted = false;\n\n try {\n let result = await iterator.next();\n while (!result.done) {\n // Check for abort during iteration\n if (mergedGenerationSettings.abortSignal?.aborted) {\n wasAborted = true;\n if (options.onAbort) {\n await options.onAbort({ steps });\n }\n break;\n }\n\n const {\n toolCalls,\n messages: iterMessages,\n step,\n context,\n providerExecutedToolResults,\n } = result.value;\n // Capture current step number before pushing (0-based)\n const currentStepNumber = steps.length;\n if (step) {\n steps.push(step as unknown as StepResult<TTools, any>);\n }\n if (context !== undefined) {\n experimentalContext = context;\n }\n\n // Only execute tools if there are tool calls\n if (toolCalls.length > 0) {\n // Separate provider-executed tool calls from client-executed ones\n const nonProviderToolCalls = toolCalls.filter(\n tc => !tc.providerExecuted,\n );\n const providerToolCalls = toolCalls.filter(tc => tc.providerExecuted);\n\n // Check which tools need approval (can be async)\n const approvalNeeded = await Promise.all(\n nonProviderToolCalls.map(async tc => {\n const tool = (effectiveTools as ToolSet)[tc.toolName];\n if (!tool) return false;\n if (tool.needsApproval == null) return false;\n if (typeof tool.needsApproval === 'boolean')\n return tool.needsApproval;\n return tool.needsApproval(tc.input, {\n toolCallId: tc.toolCallId,\n messages: iterMessages as unknown as ModelMessage[],\n context: experimentalContext,\n });\n }),\n );\n\n // Further split non-provider tool calls into:\n // - executable: has execute function and doesn't need approval\n // - paused: no execute function (client-side) OR needs approval\n // Note: missing tools (!tool) are left to executeTool which will throw.\n const executableToolCalls = nonProviderToolCalls.filter((tc, i) => {\n const tool = (effectiveTools as ToolSet)[tc.toolName];\n return (\n (!tool || typeof tool.execute === 'function') &&\n !approvalNeeded[i]\n );\n });\n const pausedToolCalls = nonProviderToolCalls.filter((tc, i) => {\n const tool = (effectiveTools as ToolSet)[tc.toolName];\n return (\n (tool && typeof tool.execute !== 'function') || approvalNeeded[i]\n );\n });\n\n // If there are paused tool calls (client-side or needing approval),\n // stop the loop and return them.\n // This matches AI SDK behavior: tools without execute or needing\n // approval pause the agent loop.\n if (pausedToolCalls.length > 0) {\n // Execute any executable tools that were also called in this step\n const executableResults = await Promise.all(\n executableToolCalls.map(\n (toolCall): Promise<LanguageModelV4ToolResultPart> =>\n executeToolWithCallbacks(\n toolCall,\n effectiveTools as ToolSet,\n iterMessages,\n experimentalContext,\n currentStepNumber,\n ),\n ),\n );\n\n // Collect provider tool results\n const providerResults: LanguageModelV4ToolResultPart[] =\n providerToolCalls.map(toolCall =>\n resolveProviderToolResult(\n toolCall,\n providerExecutedToolResults,\n ),\n );\n\n const resolvedResults = [...executableResults, ...providerResults];\n\n const allToolCalls: ToolCall[] = toolCalls.map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n }));\n\n const allToolResults: ToolResult[] = resolvedResults.map(r => ({\n type: 'tool-result' as const,\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: toolCalls.find(tc => tc.toolCallId === r.toolCallId)\n ?.input,\n output: 'value' in r.output ? r.output.value : undefined,\n }));\n\n if (resolvedResults.length > 0) {\n iterMessages.push({\n role: 'tool',\n content: resolvedResults,\n });\n }\n\n const messages = iterMessages as unknown as ModelMessage[];\n\n if (mergedOnFinish && !wasAborted) {\n const lastStep = steps[steps.length - 1];\n await mergedOnFinish({\n steps,\n messages,\n text: lastStep?.text ?? '',\n finishReason: lastStep?.finishReason ?? 'other',\n totalUsage: aggregateUsage(steps),\n experimental_context: experimentalContext,\n output: undefined as OUTPUT,\n });\n }\n\n // Emit tool-approval-request chunks for tools that need approval\n // so useChat can show the approval UI\n if (options.writable) {\n const approvalToolCalls = pausedToolCalls.filter((_, i) => {\n const tcIndex = nonProviderToolCalls.indexOf(\n pausedToolCalls[i],\n );\n return approvalNeeded[tcIndex];\n });\n if (approvalToolCalls.length > 0) {\n await writeApprovalRequests(\n options.writable,\n approvalToolCalls.map(tc => ({\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n })),\n );\n }\n }\n\n // Close the stream before returning for paused tools\n if (options.writable) {\n const sendFinish = options.sendFinish ?? true;\n const preventClose = options.preventClose ?? false;\n if (sendFinish || !preventClose) {\n await closeStream(options.writable, preventClose, sendFinish);\n }\n }\n\n return {\n messages,\n steps,\n toolCalls: allToolCalls,\n toolResults: allToolResults,\n output: undefined as OUTPUT,\n };\n }\n\n // Execute client tools (all have execute functions at this point)\n const clientToolResults = await Promise.all(\n nonProviderToolCalls.map(\n (toolCall): Promise<LanguageModelV4ToolResultPart> =>\n executeToolWithCallbacks(\n toolCall,\n effectiveTools as ToolSet,\n iterMessages,\n experimentalContext,\n currentStepNumber,\n ),\n ),\n );\n\n // For provider-executed tools, use the results from the stream\n const providerToolResults: LanguageModelV4ToolResultPart[] =\n providerToolCalls.map(toolCall =>\n resolveProviderToolResult(toolCall, providerExecutedToolResults),\n );\n\n // Combine results in the original order\n const toolResults = toolCalls.map(tc => {\n const clientResult = clientToolResults.find(\n r => r.toolCallId === tc.toolCallId,\n );\n if (clientResult) return clientResult;\n const providerResult = providerToolResults.find(\n r => r.toolCallId === tc.toolCallId,\n );\n if (providerResult) return providerResult;\n // This should never happen, but return empty result as fallback\n return {\n type: 'tool-result' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n output: { type: 'text' as const, value: '' },\n };\n });\n\n // Write tool results and step boundaries to the stream so the\n // UI can transition tool parts to output-available state and\n // properly separate multi-step model calls in the message history.\n if (options.writable) {\n await writeToolResultsWithStepBoundary(\n options.writable,\n toolResults.map(r => ({\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: toolCalls.find(tc => tc.toolCallId === r.toolCallId)\n ?.input,\n output: 'value' in r.output ? r.output.value : undefined,\n })),\n );\n }\n\n // Track the tool calls and results for this step\n lastStepToolCalls = toolCalls.map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n }));\n lastStepToolResults = toolResults.map(r => ({\n type: 'tool-result' as const,\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: toolCalls.find(tc => tc.toolCallId === r.toolCallId)?.input,\n output: 'value' in r.output ? r.output.value : undefined,\n }));\n\n result = await iterator.next(toolResults);\n } else {\n // Final step with no tool calls - reset tracking\n lastStepToolCalls = [];\n lastStepToolResults = [];\n result = await iterator.next([]);\n }\n }\n\n // When the iterator completes normally, result.value contains the final conversation prompt\n if (result.done) {\n finalMessages = result.value;\n }\n } catch (error) {\n encounteredError = error;\n // Check if this is an abort error\n if (error instanceof Error && error.name === 'AbortError') {\n wasAborted = true;\n if (options.onAbort) {\n await options.onAbort({ steps });\n }\n } else if (options.onError) {\n // Call onError for non-abort errors (including tool execution errors)\n await options.onError({ error });\n }\n // Don't throw yet - we want to call onFinish first\n }\n\n // Use the final messages from the iterator, or fall back to standardized messages\n const messages = (finalMessages ??\n prompt.messages) as unknown as ModelMessage[];\n\n // Parse structured output if output is specified (stream-level overrides constructor default)\n const effectiveOutput = options.output ?? this.output;\n let experimentalOutput: OUTPUT = undefined as OUTPUT;\n if (effectiveOutput && steps.length > 0) {\n const lastStep = steps[steps.length - 1];\n const text = lastStep.text;\n if (text) {\n try {\n experimentalOutput = await effectiveOutput.parseCompleteOutput(\n { text },\n {\n response: lastStep.response,\n usage: lastStep.usage,\n finishReason: lastStep.finishReason,\n },\n );\n } catch (parseError) {\n // If there's already an error, don't override it\n // If not, set this as the error\n if (!encounteredError) {\n encounteredError = parseError;\n }\n }\n }\n }\n\n // Call onFinish callback if provided (always call, even on errors, but not on abort)\n if (mergedOnFinish && !wasAborted) {\n const lastStep = steps[steps.length - 1];\n await mergedOnFinish({\n steps,\n messages: messages as ModelMessage[],\n text: lastStep?.text ?? '',\n finishReason: lastStep?.finishReason ?? 'other',\n totalUsage: aggregateUsage(steps),\n experimental_context: experimentalContext,\n output: experimentalOutput,\n });\n }\n\n // Re-throw any error that occurred\n if (encounteredError) {\n // Close the stream before throwing\n if (options.writable) {\n const sendFinish = options.sendFinish ?? true;\n const preventClose = options.preventClose ?? false;\n if (sendFinish || !preventClose) {\n await closeStream(options.writable, preventClose, sendFinish);\n }\n }\n throw encounteredError;\n }\n\n // Close the writable stream\n if (options.writable) {\n const sendFinish = options.sendFinish ?? true;\n const preventClose = options.preventClose ?? false;\n if (sendFinish || !preventClose) {\n await closeStream(options.writable, preventClose, sendFinish);\n }\n }\n\n return {\n messages: messages as ModelMessage[],\n steps,\n toolCalls: lastStepToolCalls,\n toolResults: lastStepToolResults,\n output: experimentalOutput,\n };\n }\n}\n\n/**\n * Filter tools to only include the specified active tools.\n */\n/**\n * Aggregate token usage across all steps.\n */\n/**\n * Close the writable stream, optionally sending a finish chunk first.\n * This is a step function because writable.getWriter() and writable.close()\n * cannot be called in workflow context (sandbox limitation).\n */\nasync function closeStream(\n writable: WritableStream<any>,\n preventClose?: boolean,\n sendFinish?: boolean,\n) {\n 'use step';\n if (sendFinish) {\n const writer = writable.getWriter();\n try {\n await writer.write({ type: 'finish' });\n } finally {\n writer.releaseLock();\n }\n }\n if (!preventClose) {\n await writable.close();\n }\n}\n\n/**\n * Write tool-approval-request chunks to the writable stream.\n * These are consumed by useChat to show the approval UI.\n */\nasync function writeApprovalRequests(\n writable: WritableStream<any>,\n toolCalls: Array<{ toolCallId: string; toolName: string }>,\n) {\n 'use step';\n const writer = writable.getWriter();\n try {\n for (const tc of toolCalls) {\n await writer.write({\n type: 'tool-approval-request',\n approvalId: `approval-${tc.toolCallId}`,\n toolCallId: tc.toolCallId,\n });\n }\n } finally {\n writer.releaseLock();\n }\n}\n\nasync function writeToolResultsWithStepBoundary(\n writable: WritableStream<any>,\n results: Array<{\n toolCallId: string;\n toolName: string;\n input: unknown;\n output: unknown;\n }>,\n) {\n 'use step';\n const writer = writable.getWriter();\n try {\n for (const r of results) {\n await writer.write({\n type: 'tool-result',\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: r.input,\n output: r.output,\n });\n }\n // Emit step boundaries so the UI message history properly separates\n // the tool call step from the subsequent text step. This ensures\n // convertToModelMessages creates separate assistant messages for\n // tool calls and text responses.\n await writer.write({ type: 'finish-step' });\n await writer.write({ type: 'start-step' });\n } finally {\n writer.releaseLock();\n }\n}\n\nasync function writeApprovalToolResults(\n writable: WritableStream<any>,\n approvedResults: Array<{\n toolCallId: string;\n toolName: string;\n input: unknown;\n output: unknown;\n }>,\n deniedResults: Array<{ toolCallId: string }>,\n) {\n 'use step';\n const writer = writable.getWriter();\n try {\n for (const r of approvedResults) {\n await writer.write({\n type: 'tool-result',\n toolCallId: r.toolCallId,\n toolName: r.toolName,\n input: r.input,\n output: r.output,\n });\n }\n for (const r of deniedResults) {\n await writer.write({\n type: 'tool-output-denied',\n toolCallId: r.toolCallId,\n });\n }\n await writer.write({ type: 'finish-step' });\n await writer.write({ type: 'start-step' });\n } finally {\n writer.releaseLock();\n }\n}\n\nfunction aggregateUsage(steps: StepResult<any, any>[]): LanguageModelUsage {\n let inputTokens = 0;\n let outputTokens = 0;\n for (const step of steps) {\n inputTokens += step.usage?.inputTokens ?? 0;\n outputTokens += step.usage?.outputTokens ?? 0;\n }\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n } as LanguageModelUsage;\n}\n\n// Matches AI SDK's getErrorMessage from @ai-sdk/provider-utils\nfunction getErrorMessage(error: unknown): string {\n if (error == null) {\n return 'unknown error';\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n if (error instanceof Error) {\n return error.message;\n }\n\n return JSON.stringify(error);\n}\n\nfunction resolveProviderToolResult(\n toolCall: { toolCallId: string; toolName: string },\n providerExecutedToolResults?: Map<\n string,\n { toolCallId: string; toolName: string; result: unknown; isError?: boolean }\n >,\n): LanguageModelV4ToolResultPart {\n const streamResult = providerExecutedToolResults?.get(toolCall.toolCallId);\n if (!streamResult) {\n console.warn(\n `[WorkflowAgent] Provider-executed tool \"${toolCall.toolName}\" (${toolCall.toolCallId}) ` +\n `did not receive a result from the stream. This may indicate a provider issue.`,\n );\n return {\n type: 'tool-result' as const,\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n output: {\n type: 'text' as const,\n value: '',\n },\n };\n }\n\n const result = streamResult.result;\n const isString = typeof result === 'string';\n\n return {\n type: 'tool-result' as const,\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n output: isString\n ? streamResult.isError\n ? { type: 'error-text' as const, value: result }\n : { type: 'text' as const, value: result }\n : streamResult.isError\n ? {\n type: 'error-json' as const,\n value: result as JSONValue,\n }\n : {\n type: 'json' as const,\n value: result as JSONValue,\n },\n };\n}\n\nasync function executeTool(\n toolCall: { toolCallId: string; toolName: string; input: unknown },\n tools: ToolSet,\n messages: LanguageModelV4Prompt,\n experimentalContext?: unknown,\n): Promise<LanguageModelV4ToolResultPart> {\n const tool = tools[toolCall.toolName];\n if (!tool) throw new Error(`Tool \"${toolCall.toolName}\" not found`);\n if (typeof tool.execute !== 'function') {\n throw new Error(\n `Tool \"${toolCall.toolName}\" does not have an execute function. ` +\n `Client-side tools should be filtered before calling executeTool.`,\n );\n }\n // Input is already parsed and validated by streamModelCall's parseToolCall\n const parsedInput = toolCall.input;\n\n try {\n // Extract execute function to avoid binding `this` to the tool object.\n // If we called `tool.execute(...)` directly, JavaScript would bind `this`\n // to `tool`, which contains non-serializable properties like `inputSchema`.\n // When the execute function is a workflow step (marked with 'use step'),\n // the step system captures `this` for serialization, causing failures.\n const { execute } = tool;\n const toolResult = await execute(parsedInput, {\n toolCallId: toolCall.toolCallId,\n // Pass the conversation messages to the tool so it has context about the conversation\n messages,\n // Pass context to the tool\n context: experimentalContext,\n });\n\n // Use the appropriate output type based on the result\n // AI SDK supports 'text' for strings and 'json' for objects\n const output =\n typeof toolResult === 'string'\n ? { type: 'text' as const, value: toolResult }\n : { type: 'json' as const, value: toolResult };\n\n return {\n type: 'tool-result' as const,\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n output,\n };\n } catch (error) {\n // Convert tool errors to error-text results sent back to the model,\n // allowing the agent to recover rather than killing the entire stream.\n // This aligns with AI SDK's streamText behavior for individual tool failures.\n return {\n type: 'tool-result',\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n output: {\n type: 'error-text',\n value: getErrorMessage(error),\n },\n };\n }\n}\n\n/**\n * Collected tool approval information for a single tool call.\n */\ninterface CollectedApproval {\n toolCallId: string;\n toolName: string;\n input: unknown;\n approvalId: string;\n reason?: string;\n}\n\n/**\n * Collect tool approval responses from model messages.\n * Mirrors the logic from `collectToolApprovals` in the AI SDK core\n * (`packages/ai/src/generate-text/collect-tool-approvals.ts`).\n *\n * Scans the last tool message for `tool-approval-response` parts,\n * matches them with `tool-approval-request` parts in assistant messages\n * and the corresponding `tool-call` parts.\n */\nfunction collectToolApprovalsFromMessages(messages: ModelMessage[]): {\n approvedToolApprovals: CollectedApproval[];\n deniedToolApprovals: CollectedApproval[];\n} {\n const lastMessage = messages.at(-1);\n\n if (lastMessage?.role !== 'tool') {\n return { approvedToolApprovals: [], deniedToolApprovals: [] };\n }\n\n // Gather tool calls from assistant messages\n const toolCallsByToolCallId: Record<\n string,\n { toolName: string; input: unknown }\n > = {};\n for (const message of messages) {\n if (message.role === 'assistant' && Array.isArray(message.content)) {\n for (const part of message.content as any[]) {\n if (part.type === 'tool-call') {\n toolCallsByToolCallId[part.toolCallId] = {\n toolName: part.toolName,\n input: part.input ?? part.args,\n };\n }\n }\n }\n }\n\n // Gather approval requests from assistant messages\n const approvalRequestsByApprovalId: Record<\n string,\n { approvalId: string; toolCallId: string }\n > = {};\n for (const message of messages) {\n if (message.role === 'assistant' && Array.isArray(message.content)) {\n for (const part of message.content as any[]) {\n if (part.type === 'tool-approval-request') {\n approvalRequestsByApprovalId[part.approvalId] = {\n approvalId: part.approvalId,\n toolCallId: part.toolCallId,\n };\n }\n }\n }\n }\n\n // Gather existing tool results to avoid re-executing\n const existingToolResults = new Set<string>();\n for (const part of lastMessage.content as any[]) {\n if (part.type === 'tool-result') {\n existingToolResults.add(part.toolCallId);\n }\n }\n\n const approvedToolApprovals: CollectedApproval[] = [];\n const deniedToolApprovals: CollectedApproval[] = [];\n\n // Collect approval responses from the last tool message\n const approvalResponses = (lastMessage.content as any[]).filter(\n (part: any) => part.type === 'tool-approval-response',\n );\n\n for (const response of approvalResponses) {\n const approvalRequest = approvalRequestsByApprovalId[response.approvalId];\n if (approvalRequest == null) continue;\n\n // Skip if there's already a tool result for this tool call\n if (existingToolResults.has(approvalRequest.toolCallId)) continue;\n\n const toolCall = toolCallsByToolCallId[approvalRequest.toolCallId];\n if (toolCall == null) continue;\n\n const approval: CollectedApproval = {\n toolCallId: approvalRequest.toolCallId,\n toolName: toolCall.toolName,\n input: toolCall.input,\n approvalId: response.approvalId,\n reason: response.reason,\n };\n\n if (response.approved) {\n approvedToolApprovals.push(approval);\n } else {\n deniedToolApprovals.push(approval);\n }\n }\n\n return { approvedToolApprovals, deniedToolApprovals };\n}\n","import type {\n LanguageModelV4CallOptions,\n LanguageModelV4Prompt,\n LanguageModelV4ToolResultPart,\n} from '@ai-sdk/provider';\nimport {\n type Experimental_LanguageModelStreamPart as ModelCallStreamPart,\n type LanguageModel,\n type ModelMessage,\n type StepResult,\n type ToolCallRepairFunction,\n type ToolChoice,\n type ToolSet,\n experimental_filterActiveTools as filterActiveTools,\n} from 'ai';\nimport {\n doStreamStep,\n type ModelStopCondition,\n type ParsedToolCall,\n type ProviderExecutedToolResult,\n} from './do-stream-step.js';\nimport { serializeToolSet } from './serializable-schema.js';\nimport type {\n GenerationSettings,\n PrepareStepCallback,\n WorkflowAgentOnErrorCallback,\n WorkflowAgentOnStepFinishCallback,\n TelemetryOptions,\n WorkflowAgentOnStepStartCallback,\n} from './workflow-agent.js';\n\n// Re-export for consumers\nexport type { ProviderExecutedToolResult } from './do-stream-step.js';\n\n/**\n * The value yielded by the stream text iterator when tool calls are requested.\n * Contains both the tool calls and the current conversation messages.\n */\nexport interface StreamTextIteratorYieldValue {\n /** The tool calls requested by the model (parsed with typed inputs) */\n toolCalls: ParsedToolCall[];\n /** The conversation messages up to (and including) the tool call request */\n messages: LanguageModelV4Prompt;\n /** The step result from the current step */\n step?: StepResult<ToolSet, any>;\n /** The current experimental context */\n context?: unknown;\n /** Provider-executed tool results (keyed by tool call ID) */\n providerExecutedToolResults?: Map<string, ProviderExecutedToolResult>;\n}\n\n// This runs in the workflow context\nexport async function* streamTextIterator({\n prompt,\n tools = {},\n writable,\n model,\n stopConditions,\n onStepFinish,\n onStepStart,\n onError,\n prepareStep,\n generationSettings,\n toolChoice,\n experimental_context,\n telemetry,\n includeRawChunks = false,\n repairToolCall,\n responseFormat,\n}: {\n prompt: LanguageModelV4Prompt;\n tools: ToolSet;\n writable?: WritableStream<ModelCallStreamPart<ToolSet>>;\n model: LanguageModel;\n stopConditions?: ModelStopCondition[] | ModelStopCondition;\n onStepFinish?: WorkflowAgentOnStepFinishCallback<any>;\n onStepStart?: WorkflowAgentOnStepStartCallback;\n onError?: WorkflowAgentOnErrorCallback;\n prepareStep?: PrepareStepCallback<any>;\n generationSettings?: GenerationSettings;\n toolChoice?: ToolChoice<ToolSet>;\n experimental_context?: unknown;\n telemetry?: TelemetryOptions;\n includeRawChunks?: boolean;\n repairToolCall?: ToolCallRepairFunction<ToolSet>;\n responseFormat?: LanguageModelV4CallOptions['responseFormat'];\n}): AsyncGenerator<\n StreamTextIteratorYieldValue,\n LanguageModelV4Prompt,\n LanguageModelV4ToolResultPart[]\n> {\n let conversationPrompt = [...prompt]; // Create a mutable copy\n let currentModel: LanguageModel = model;\n let currentGenerationSettings = generationSettings ?? {};\n let currentToolChoice = toolChoice;\n let currentContext = experimental_context;\n let currentActiveTools: string[] | undefined;\n\n const steps: StepResult<any, any>[] = [];\n let done = false;\n let _isFirstIteration = true;\n let stepNumber = 0;\n let lastStep: StepResult<any, any> | undefined;\n let lastStepWasToolCalls = false;\n\n while (!done) {\n // Check for abort signal\n if (currentGenerationSettings.abortSignal?.aborted) {\n break;\n }\n\n // Call prepareStep callback before each step if provided\n if (prepareStep) {\n const prepareResult = await prepareStep({\n model: currentModel,\n stepNumber,\n steps,\n messages: conversationPrompt,\n experimental_context: currentContext,\n });\n\n // Apply any overrides from prepareStep\n if (prepareResult.model !== undefined) {\n currentModel = prepareResult.model;\n }\n // Apply messages override BEFORE system so the system message\n // isn't lost when messages replaces the prompt.\n if (prepareResult.messages !== undefined) {\n conversationPrompt = [...prepareResult.messages];\n }\n if (prepareResult.system !== undefined) {\n // Update or prepend system message in the conversation prompt.\n // Applied AFTER messages override so the system message isn't\n // lost when messages replaces the prompt.\n if (\n conversationPrompt.length > 0 &&\n conversationPrompt[0].role === 'system'\n ) {\n // Replace existing system message\n conversationPrompt[0] = {\n role: 'system',\n content: prepareResult.system,\n };\n } else {\n // Prepend new system message\n conversationPrompt.unshift({\n role: 'system',\n content: prepareResult.system,\n });\n }\n }\n if (prepareResult.experimental_context !== undefined) {\n currentContext = prepareResult.experimental_context;\n }\n if (prepareResult.activeTools !== undefined) {\n currentActiveTools = prepareResult.activeTools;\n }\n // Apply generation settings overrides\n if (prepareResult.maxOutputTokens !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n maxOutputTokens: prepareResult.maxOutputTokens,\n };\n }\n if (prepareResult.temperature !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n temperature: prepareResult.temperature,\n };\n }\n if (prepareResult.topP !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n topP: prepareResult.topP,\n };\n }\n if (prepareResult.topK !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n topK: prepareResult.topK,\n };\n }\n if (prepareResult.presencePenalty !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n presencePenalty: prepareResult.presencePenalty,\n };\n }\n if (prepareResult.frequencyPenalty !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n frequencyPenalty: prepareResult.frequencyPenalty,\n };\n }\n if (prepareResult.stopSequences !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n stopSequences: prepareResult.stopSequences,\n };\n }\n if (prepareResult.seed !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n seed: prepareResult.seed,\n };\n }\n if (prepareResult.maxRetries !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n maxRetries: prepareResult.maxRetries,\n };\n }\n if (prepareResult.headers !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n headers: prepareResult.headers,\n };\n }\n if (prepareResult.providerOptions !== undefined) {\n currentGenerationSettings = {\n ...currentGenerationSettings,\n providerOptions: prepareResult.providerOptions,\n };\n }\n if (prepareResult.toolChoice !== undefined) {\n currentToolChoice = prepareResult.toolChoice;\n }\n }\n\n if (onStepStart) {\n await onStepStart({\n stepNumber,\n model: currentModel,\n messages: conversationPrompt as unknown as ModelMessage[],\n steps: [...steps],\n });\n }\n\n try {\n // Filter tools if activeTools is specified\n const effectiveTools =\n currentActiveTools && currentActiveTools.length > 0\n ? (filterActiveTools({\n tools,\n activeTools: currentActiveTools,\n }) ?? tools)\n : tools;\n\n // Serialize tools before crossing the step boundary — zod schemas\n // contain functions that can't be serialized by the workflow runtime.\n // Tools are reconstructed with Ajv validation inside doStreamStep.\n const serializedTools = serializeToolSet(effectiveTools);\n\n const { toolCalls, finish, step, providerExecutedToolResults } =\n await doStreamStep(\n conversationPrompt,\n currentModel,\n writable,\n serializedTools,\n {\n ...currentGenerationSettings,\n toolChoice: currentToolChoice,\n includeRawChunks,\n telemetry,\n repairToolCall,\n responseFormat,\n },\n );\n\n _isFirstIteration = false;\n stepNumber++;\n steps.push(step);\n lastStep = step;\n lastStepWasToolCalls = false;\n\n const finishReason = finish?.finishReason;\n\n if (finishReason === 'tool-calls') {\n lastStepWasToolCalls = true;\n\n // Add assistant message with tool calls to the conversation\n // Note: providerMetadata from the tool call is mapped to providerOptions\n // in the prompt format, following the AI SDK convention. This is critical\n // for providers like Gemini that require thoughtSignature to be preserved\n // across multi-turn tool calls. Some fields are sanitized before mapping.\n conversationPrompt.push({\n role: 'assistant',\n content: toolCalls.map(toolCall => {\n const sanitizedMetadata = sanitizeProviderMetadataForToolCall(\n toolCall.providerMetadata,\n );\n return {\n type: 'tool-call',\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n input: toolCall.input,\n ...(sanitizedMetadata != null\n ? { providerOptions: sanitizedMetadata }\n : {}),\n };\n }) as typeof toolCalls,\n });\n\n // Yield the tool calls along with the current conversation messages\n // This allows executeTool to pass the conversation context to tool execute functions\n // Also include provider-executed tool results so they can be used instead of local execution\n const toolResults = yield {\n toolCalls,\n messages: conversationPrompt,\n step,\n context: currentContext,\n providerExecutedToolResults,\n };\n\n conversationPrompt.push({\n role: 'tool',\n content: toolResults,\n });\n\n if (stopConditions) {\n const stopConditionList = Array.isArray(stopConditions)\n ? stopConditions\n : [stopConditions];\n if (stopConditionList.some(test => test({ steps }))) {\n done = true;\n }\n }\n } else if (finishReason === 'stop') {\n // Add assistant message with text content to the conversation\n const textContent = step.content.filter(\n item => item.type === 'text',\n ) as Array<{ type: 'text'; text: string }>;\n\n if (textContent.length > 0) {\n conversationPrompt.push({\n role: 'assistant',\n content: textContent,\n });\n }\n\n done = true;\n } else if (finishReason === 'length') {\n // Model hit max tokens - stop but don't throw\n done = true;\n } else if (finishReason === 'content-filter') {\n // Content filter triggered - stop but don't throw\n done = true;\n } else if (finishReason === 'error') {\n // Model error - stop but don't throw\n done = true;\n } else if (finishReason === 'other') {\n // Other reason - stop but don't throw\n done = true;\n } else if (finishReason === 'unknown') {\n // Unknown reason - stop but don't throw\n done = true;\n } else if (!finishReason) {\n // No finish reason - this might happen on incomplete streams\n done = true;\n } else {\n throw new Error(\n `Unexpected finish reason: ${typeof finish?.finishReason === 'object' ? JSON.stringify(finish?.finishReason) : finish?.finishReason}`,\n );\n }\n\n if (onStepFinish) {\n await onStepFinish(step);\n }\n } catch (error) {\n if (onError) {\n await onError({ error });\n }\n throw error;\n }\n }\n\n // Yield the final step if it wasn't already yielded (tool-calls steps are yielded inside the loop)\n if (lastStep && !lastStepWasToolCalls) {\n yield {\n toolCalls: [],\n messages: conversationPrompt,\n step: lastStep,\n context: currentContext,\n };\n }\n\n return conversationPrompt;\n}\n\n/**\n * Strip OpenAI's itemId from providerMetadata (requires reasoning items we don't preserve).\n * Preserves all other provider metadata (e.g., Gemini's thoughtSignature).\n */\nfunction sanitizeProviderMetadataForToolCall(\n metadata: unknown,\n): Record<string, unknown> | undefined {\n if (metadata == null) return undefined;\n\n const meta = metadata as Record<string, unknown>;\n\n // Check if OpenAI metadata exists and needs sanitization\n if ('openai' in meta && meta.openai != null) {\n const { openai, ...restProviders } = meta;\n const openaiMeta = openai as Record<string, unknown>;\n\n // Remove itemId from OpenAI metadata - it requires reasoning items we don't preserve\n const { itemId: _itemId, ...restOpenai } = openaiMeta;\n\n // Reconstruct metadata without itemId\n const hasOtherOpenaiFields = Object.keys(restOpenai).length > 0;\n const hasOtherProviders = Object.keys(restProviders).length > 0;\n\n if (hasOtherOpenaiFields && hasOtherProviders) {\n return { ...restProviders, openai: restOpenai };\n } else if (hasOtherOpenaiFields) {\n return { openai: restOpenai };\n } else if (hasOtherProviders) {\n return restProviders;\n }\n return undefined;\n }\n\n return meta;\n}\n","import type {\n LanguageModelV4CallOptions,\n LanguageModelV4Prompt,\n} from '@ai-sdk/provider';\nimport {\n type Experimental_LanguageModelStreamPart as ModelCallStreamPart,\n experimental_streamLanguageModelCall as streamModelCall,\n type FinishReason,\n type LanguageModel,\n type LanguageModelUsage,\n type ModelMessage,\n type StepResult,\n type StopCondition,\n type ToolCallRepairFunction,\n type ToolChoice,\n type ToolSet,\n} from 'ai';\nimport { gateway } from 'ai';\nimport type { ProviderOptions, TelemetryOptions } from './workflow-agent.js';\nimport {\n resolveSerializableTools,\n type SerializableToolDef,\n} from './serializable-schema.js';\n\nexport type { Experimental_LanguageModelStreamPart as ModelCallStreamPart } from 'ai';\n\nexport type ModelStopCondition = StopCondition<NoInfer<ToolSet>, any>;\n\n/**\n * Provider-executed tool result captured from the stream.\n */\nexport interface ProviderExecutedToolResult {\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n}\n\n/**\n * Options for the doStreamStep function.\n */\nexport interface DoStreamStepOptions {\n maxOutputTokens?: number;\n temperature?: number;\n topP?: number;\n topK?: number;\n presencePenalty?: number;\n frequencyPenalty?: number;\n stopSequences?: string[];\n seed?: number;\n maxRetries?: number;\n abortSignal?: AbortSignal;\n headers?: Record<string, string | undefined>;\n providerOptions?: ProviderOptions;\n toolChoice?: ToolChoice<ToolSet>;\n includeRawChunks?: boolean;\n telemetry?: TelemetryOptions;\n repairToolCall?: ToolCallRepairFunction<ToolSet>;\n responseFormat?: LanguageModelV4CallOptions['responseFormat'];\n}\n\n/**\n * Parsed tool call from the stream (parsed by streamModelCall's transform).\n */\nexport interface ParsedToolCall {\n type: 'tool-call';\n toolCallId: string;\n toolName: string;\n input: unknown;\n providerExecuted?: boolean;\n providerMetadata?: Record<string, unknown>;\n dynamic?: boolean;\n invalid?: boolean;\n error?: unknown;\n}\n\n/**\n * Finish metadata from the stream.\n */\nexport interface StreamFinish {\n finishReason: FinishReason;\n rawFinishReason: string | undefined;\n usage: LanguageModelUsage;\n providerMetadata?: Record<string, unknown>;\n}\n\nexport async function doStreamStep(\n conversationPrompt: LanguageModelV4Prompt,\n modelInit: LanguageModel,\n writable?: WritableStream<ModelCallStreamPart<ToolSet>>,\n serializedTools?: Record<string, SerializableToolDef>,\n options?: DoStreamStepOptions,\n) {\n 'use step';\n\n // Resolve model inside step (must happen here for serialization boundary)\n const model: LanguageModel =\n typeof modelInit === 'string'\n ? gateway.languageModel(modelInit)\n : modelInit;\n\n // Reconstruct tools from serializable definitions with Ajv validation.\n // Tools are serialized before crossing the step boundary because zod schemas\n // contain functions that can't be serialized by the workflow runtime.\n const tools = serializedTools\n ? resolveSerializableTools(serializedTools)\n : undefined;\n\n // streamModelCall handles: prompt standardization, tool preparation,\n // model.doStream(), retry logic, and stream part transformation\n // (tool call parsing, finish reason mapping, file wrapping).\n const { stream: modelStream } = await streamModelCall({\n model,\n // streamModelCall expects Prompt (ModelMessage[]) but we pass the\n // pre-converted LanguageModelV4Prompt. standardizePrompt inside\n // streamModelCall handles both formats.\n messages: conversationPrompt as unknown as ModelMessage[],\n tools,\n toolChoice: options?.toolChoice,\n includeRawChunks: options?.includeRawChunks,\n providerOptions: options?.providerOptions,\n abortSignal: options?.abortSignal,\n headers: options?.headers,\n maxOutputTokens: options?.maxOutputTokens,\n temperature: options?.temperature,\n topP: options?.topP,\n topK: options?.topK,\n presencePenalty: options?.presencePenalty,\n frequencyPenalty: options?.frequencyPenalty,\n stopSequences: options?.stopSequences,\n seed: options?.seed,\n repairToolCall: options?.repairToolCall,\n });\n\n // Consume the stream: capture data and write to writable in real-time\n const toolCalls: ParsedToolCall[] = [];\n const providerExecutedToolResults = new Map<\n string,\n ProviderExecutedToolResult\n >();\n let finish: StreamFinish | undefined;\n\n // Aggregation for StepResult\n let text = '';\n const reasoningParts: Array<{ text: string }> = [];\n let responseMetadata:\n | { id?: string; timestamp?: Date; modelId?: string }\n | undefined;\n let warnings: unknown[] | undefined;\n\n // Acquire writer once before the loop to avoid per-chunk lock overhead\n const writer = writable?.getWriter();\n\n try {\n for await (const part of modelStream) {\n switch (part.type) {\n case 'text-delta':\n text += part.text;\n break;\n case 'reasoning-delta':\n reasoningParts.push({ text: part.text });\n break;\n case 'tool-call': {\n // parseToolCall adds dynamic/invalid/error at runtime\n const toolCallPart = part as typeof part & Partial<ParsedToolCall>;\n toolCalls.push({\n type: 'tool-call',\n toolCallId: toolCallPart.toolCallId,\n toolName: toolCallPart.toolName,\n input: toolCallPart.input,\n providerExecuted: toolCallPart.providerExecuted,\n providerMetadata: toolCallPart.providerMetadata as\n | Record<string, unknown>\n | undefined,\n dynamic: toolCallPart.dynamic,\n invalid: toolCallPart.invalid,\n error: toolCallPart.error,\n });\n break;\n }\n case 'tool-result':\n if (part.providerExecuted) {\n providerExecutedToolResults.set(part.toolCallId, {\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n result: part.output,\n isError: false,\n });\n }\n break;\n case 'tool-error': {\n const errorPart = part as typeof part & {\n providerExecuted?: boolean;\n };\n if (errorPart.providerExecuted) {\n providerExecutedToolResults.set(errorPart.toolCallId, {\n toolCallId: errorPart.toolCallId,\n toolName: errorPart.toolName,\n result: errorPart.error,\n isError: true,\n });\n }\n break;\n }\n case 'model-call-end':\n finish = {\n finishReason: part.finishReason,\n rawFinishReason: part.rawFinishReason,\n usage: part.usage,\n providerMetadata: part.providerMetadata as\n | Record<string, unknown>\n | undefined,\n };\n break;\n case 'model-call-start':\n warnings = part.warnings;\n break;\n case 'model-call-response-metadata':\n responseMetadata = part;\n break;\n }\n\n // Write to writable in real-time\n if (writer) {\n await writer.write(part);\n }\n }\n } finally {\n writer?.releaseLock();\n }\n\n // Build StepResult\n const reasoningText = reasoningParts.map(r => r.text).join('') || undefined;\n\n const step: StepResult<ToolSet, any> = {\n callId: 'workflow-agent',\n stepNumber: 0,\n model: {\n provider: responseMetadata?.modelId?.split(':')[0] ?? 'unknown',\n modelId: responseMetadata?.modelId ?? 'unknown',\n },\n functionId: undefined,\n metadata: undefined,\n runtimeContext: undefined,\n toolsContext: {},\n content: [\n ...(text ? [{ type: 'text' as const, text }] : []),\n ...toolCalls\n .filter(tc => !tc.invalid)\n .map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n ...(tc.dynamic ? { dynamic: true as const } : {}),\n })),\n ],\n text,\n reasoning: reasoningParts.map(r => ({\n type: 'reasoning' as const,\n text: r.text,\n })),\n reasoningText,\n files: [],\n sources: [],\n toolCalls: toolCalls\n .filter(tc => !tc.invalid)\n .map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n ...(tc.dynamic ? { dynamic: true as const } : {}),\n })),\n staticToolCalls: [],\n dynamicToolCalls: toolCalls\n .filter(tc => !tc.invalid && tc.dynamic)\n .map(tc => ({\n type: 'tool-call' as const,\n toolCallId: tc.toolCallId,\n toolName: tc.toolName,\n input: tc.input,\n dynamic: true as const,\n })),\n toolResults: [],\n staticToolResults: [],\n dynamicToolResults: [],\n finishReason: finish?.finishReason ?? 'other',\n rawFinishReason: finish?.rawFinishReason,\n usage:\n finish?.usage ??\n ({\n inputTokens: 0,\n inputTokenDetails: {\n noCacheTokens: undefined,\n cacheReadTokens: undefined,\n cacheWriteTokens: undefined,\n },\n outputTokens: 0,\n outputTokenDetails: {\n textTokens: undefined,\n reasoningTokens: undefined,\n },\n totalTokens: 0,\n } as LanguageModelUsage),\n warnings,\n request: { body: '' },\n response: {\n id: responseMetadata?.id ?? 'unknown',\n timestamp: responseMetadata?.timestamp ?? new Date(),\n modelId: responseMetadata?.modelId ?? 'unknown',\n messages: [],\n },\n providerMetadata: finish?.providerMetadata ?? {},\n } as StepResult<ToolSet, any>;\n\n return {\n toolCalls,\n finish,\n step,\n providerExecutedToolResults,\n };\n}\n","/**\n * Helpers for passing tool schemas across workflow step boundaries.\n *\n * Tool schemas (zod, valibot, arktype, etc.) contain functions that can't be\n * serialized by the workflow runtime. These helpers extract JSON Schema from\n * schemas, then reconstruct tools with Ajv validation inside step functions.\n *\n * Uses `asSchema()` from `@ai-sdk/provider-utils` for JSON Schema extraction,\n * which supports Standard Schema compatible libraries. When libraries adopt\n * `~standard.jsonSchema` (Standard Schema v2), extraction can be simplified\n * to use that interface directly.\n */\nimport type { JSONSchema7 } from '@ai-sdk/provider';\nimport { asSchema, jsonSchema } from '@ai-sdk/provider-utils';\nimport { tool, type ToolSet } from 'ai';\nimport Ajv from 'ajv';\n\n/**\n * Serializable tool definition — plain objects only, safe for workflow steps.\n */\nexport type SerializableToolDef = {\n description?: string;\n inputSchema: JSONSchema7;\n /** Present on provider tools (e.g. anthropic.tools.webSearch). */\n type?: 'provider';\n /** Provider tool ID, e.g. 'anthropic.web_search_20250305'. */\n id?: `${string}.${string}`;\n /** Provider tool configuration args (maxUses, allowedDomains, etc.). */\n args?: Record<string, unknown>;\n};\n\n/**\n * Converts a ToolSet (with zod/standard schemas and execute functions) to a\n * serializable record of tool definitions. Only description and inputSchema\n * (as JSON Schema) are preserved — execute functions are stripped since they\n * run outside the step.\n */\nexport function serializeToolSet(\n tools: ToolSet,\n): Record<string, SerializableToolDef> {\n return Object.fromEntries(\n Object.entries(tools).map(([name, t]) => {\n const def: SerializableToolDef = {\n description: t.description,\n inputSchema: asSchema(t.inputSchema).jsonSchema as JSONSchema7,\n };\n\n // Preserve provider tool identity so the Gateway can recognize\n // them as provider-executed tools (e.g. anthropic webSearch).\n if ((t as any).type === 'provider') {\n def.type = 'provider';\n def.id = (t as any).id;\n def.args = (t as any).args;\n }\n\n return [name, def];\n }),\n );\n}\n\n/**\n * Reconstructs tool objects from serializable tool definitions inside a step.\n *\n * Wraps each tool's JSON Schema with `jsonSchema()` and validates tool call\n * arguments against the schema using Ajv. This provides runtime type safety\n * equivalent to using zod schemas directly with the AI SDK.\n */\nexport function resolveSerializableTools(\n tools: Record<string, SerializableToolDef>,\n): ToolSet {\n const ajv = new Ajv();\n\n return Object.fromEntries(\n Object.entries(tools).map(([name, t]) => {\n // Provider tools are executed server-side — pass them through\n // with their identity intact, no client-side validation needed.\n if (t.type === 'provider') {\n return [\n name,\n tool({\n type: 'provider' as const,\n id: t.id!,\n args: t.args ?? {},\n inputSchema: jsonSchema(t.inputSchema),\n }),\n ];\n }\n\n const validateFn = ajv.compile(t.inputSchema);\n\n return [\n name,\n tool({\n description: t.description,\n inputSchema: jsonSchema(t.inputSchema, {\n validate: value => {\n if (validateFn(value)) {\n return { success: true, value: value as any };\n }\n return {\n success: false,\n error: new Error(ajv.errorsText(validateFn.errors)),\n };\n },\n }),\n }),\n ];\n }),\n );\n}\n","import { type ToolSet, type UIMessageChunk } from 'ai';\nimport type { Experimental_LanguageModelStreamPart as ModelCallStreamPart } from 'ai';\n\n/**\n * Convert a single ModelCallStreamPart to a UIMessageChunk.\n * Returns undefined for parts that don't map to UI chunks.\n */\nexport function toUIMessageChunk(\n part: ModelCallStreamPart<ToolSet>,\n): UIMessageChunk | undefined {\n switch (part.type) {\n case 'text-start':\n return {\n type: 'text-start',\n id: part.id,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'text-delta':\n return {\n type: 'text-delta',\n id: part.id,\n delta: part.text,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'text-end':\n return {\n type: 'text-end',\n id: part.id,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'reasoning-start':\n return {\n type: 'reasoning-start',\n id: part.id,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'reasoning-delta':\n return {\n type: 'reasoning-delta',\n id: part.id,\n delta: part.text,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'reasoning-end':\n return {\n type: 'reasoning-end',\n id: part.id,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n\n case 'file': {\n const file = part.file;\n // GeneratedFile.base64 always has data (lazy-converted from Uint8Array if needed)\n return {\n type: 'file',\n mediaType: file.mediaType,\n url: `data:${file.mediaType};base64,${file.base64}`,\n };\n }\n\n case 'source': {\n if (part.sourceType === 'url') {\n return {\n type: 'source-url',\n sourceId: part.id,\n url: part.url,\n title: part.title,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n }\n if (part.sourceType === 'document') {\n return {\n type: 'source-document',\n sourceId: part.id,\n mediaType: part.mediaType,\n title: part.title,\n filename: part.filename,\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n }\n return undefined;\n }\n\n case 'tool-input-start':\n return {\n type: 'tool-input-start',\n toolCallId: part.id,\n toolName: part.toolName,\n ...(part.providerExecuted != null\n ? { providerExecuted: part.providerExecuted }\n : {}),\n };\n\n case 'tool-input-delta':\n return {\n type: 'tool-input-delta',\n toolCallId: part.id,\n inputTextDelta: part.delta,\n };\n\n case 'tool-call': {\n // parseToolCall adds invalid/error at runtime for failed parses\n const toolCallPart = part as typeof part & {\n invalid?: boolean;\n error?: unknown;\n };\n if (toolCallPart.invalid) {\n return {\n type: 'tool-input-error',\n toolCallId: toolCallPart.toolCallId,\n toolName: toolCallPart.toolName,\n input: toolCallPart.input,\n errorText:\n toolCallPart.error instanceof Error\n ? toolCallPart.error.message\n : String(toolCallPart.error ?? 'Invalid tool call'),\n };\n }\n return {\n type: 'tool-input-available',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n input: part.input,\n ...(part.providerExecuted != null\n ? { providerExecuted: part.providerExecuted }\n : {}),\n ...(part.providerMetadata != null\n ? { providerMetadata: part.providerMetadata }\n : {}),\n };\n }\n\n case 'tool-result':\n return {\n type: 'tool-output-available',\n toolCallId: part.toolCallId,\n output: part.output,\n };\n\n case 'tool-error':\n return {\n type: 'tool-output-error',\n toolCallId: part.toolCallId,\n errorText:\n part.error instanceof Error ? part.error.message : String(part.error),\n };\n\n case 'error': {\n const error = part.error;\n return {\n type: 'error',\n errorText: error instanceof Error ? error.message : String(error),\n };\n }\n\n // These don't produce UI chunks\n case 'tool-input-end':\n case 'model-call-start':\n case 'model-call-response-metadata':\n case 'model-call-end':\n case 'raw':\n return undefined;\n\n default: {\n // Pass through tool-approval-request, step boundaries, and other\n // chunks as-is. Step boundaries (finish-step/start-step) are not\n // standard ModelCallStreamPart types but are written by the\n // WorkflowAgent between tool execution and the next model step\n // to ensure proper message splitting in convertToModelMessages.\n const p = part as any;\n if (p.type === 'tool-approval-request') {\n return {\n type: 'tool-approval-request',\n approvalId: p.approvalId,\n toolCallId: p.toolCallId,\n } as UIMessageChunk;\n }\n if (\n p.type === 'finish-step' ||\n p.type === 'start-step' ||\n p.type === 'tool-output-denied'\n ) {\n return p as UIMessageChunk;\n }\n return undefined;\n }\n }\n}\n\n/**\n * Create a TransformStream that converts ModelCallStreamPart to UIMessageChunk.\n * Wraps toUIMessageChunk with start/start-step/finish-step lifecycle chunks.\n */\nexport function createModelCallToUIChunkTransform(): TransformStream<\n ModelCallStreamPart<ToolSet>,\n UIMessageChunk\n> {\n return new TransformStream<ModelCallStreamPart<ToolSet>, UIMessageChunk>({\n start: controller => {\n controller.enqueue({ type: 'start' });\n controller.enqueue({ type: 'start-step' });\n },\n flush: controller => {\n controller.enqueue({ type: 'finish-step' });\n controller.enqueue({ type: 'finish' });\n },\n transform: (part, controller) => {\n const uiChunk = toUIMessageChunk(part);\n if (uiChunk) {\n controller.enqueue(uiChunk);\n }\n },\n });\n}\n","import {\n type ChatRequestOptions,\n type ChatTransport,\n type PrepareReconnectToStreamRequest,\n type PrepareSendMessagesRequest,\n parseJsonEventStream,\n type UIMessage,\n type UIMessageChunk,\n uiMessageChunkSchema,\n} from 'ai';\nimport {\n convertAsyncIteratorToReadableStream,\n getErrorMessage,\n} from '@ai-sdk/provider-utils';\nimport { createAsyncIterableStream } from 'ai/internal';\n\nexport interface SendMessagesOptions<UI_MESSAGE extends UIMessage> {\n trigger: 'submit-message' | 'regenerate-message';\n chatId: string;\n messageId?: string;\n messages: UI_MESSAGE[];\n abortSignal?: AbortSignal;\n}\n\nexport interface ReconnectToStreamOptions {\n chatId: string;\n abortSignal?: AbortSignal;\n /**\n * Override the `startIndex` for this reconnection.\n * Negative values read from the end of the stream.\n * When omitted, falls back to the constructor's `initialStartIndex`.\n */\n startIndex?: number;\n}\n\ntype OnChatSendMessage<UI_MESSAGE extends UIMessage> = (\n response: Response,\n options: SendMessagesOptions<UI_MESSAGE>,\n) => void | Promise<void>;\n\ntype OnChatEnd = ({\n chatId,\n chunkIndex,\n}: {\n chatId: string;\n chunkIndex: number;\n}) => void | Promise<void>;\n\n/**\n * Configuration options for the WorkflowChatTransport.\n *\n * @template UI_MESSAGE - The type of UI messages being sent and received,\n * must extend the UIMessage interface from the AI SDK.\n */\nexport interface WorkflowChatTransportOptions<UI_MESSAGE extends UIMessage> {\n /**\n * API endpoint for chat requests\n * Defaults to /api/chat if not provided\n */\n api?: string;\n\n /**\n * Custom fetch implementation to use for HTTP requests.\n * Defaults to the global fetch function if not provided.\n */\n fetch?: typeof fetch;\n\n /**\n * Callback invoked after successfully sending messages to the chat endpoint.\n * Useful for tracking chat history and inspecting response headers.\n *\n * @param response - The HTTP response object from the chat endpoint\n * @param options - The original options passed to sendMessages\n */\n onChatSendMessage?: OnChatSendMessage<UI_MESSAGE>;\n\n /**\n * Callback invoked when a chat stream ends (receives a \"finish\" chunk).\n * Useful for cleanup operations or state updates.\n *\n * @param chatId - The ID of the chat that ended\n * @param chunkIndex - The total number of chunks received\n */\n onChatEnd?: OnChatEnd;\n\n /**\n * Maximum number of consecutive errors allowed during reconnection attempts.\n * Defaults to 3 if not provided.\n */\n maxConsecutiveErrors?: number;\n\n /**\n * Default `startIndex` to use when reconnecting to a stream without a known\n * chunk position (i.e. the initial reconnection, not a retry).\n * Negative values read from the end of the stream (e.g. `-10` fetches the\n * last 10 chunks), which is useful for resuming a chat UI after a page\n * refresh without replaying the full conversation.\n *\n * Can be overridden per-call via `ReconnectToStreamOptions.startIndex`.\n *\n * Defaults to `0` (replay from the beginning).\n */\n initialStartIndex?: number;\n\n /**\n * Function to prepare the request for sending messages.\n * Allows customizing the API endpoint, headers, credentials, and body.\n */\n prepareSendMessagesRequest?: PrepareSendMessagesRequest<UI_MESSAGE>;\n\n /**\n * Function to prepare the request for reconnecting to a stream.\n * Allows customizing the API endpoint, headers, and credentials.\n */\n prepareReconnectToStreamRequest?: PrepareReconnectToStreamRequest;\n}\n\n/**\n * A transport implementation for managing chat workflows with support for\n * streaming responses and automatic reconnection to interrupted streams.\n *\n * This class implements the ChatTransport interface from the AI SDK and provides\n * reliable message streaming with automatic recovery from network interruptions\n * or function timeouts.\n *\n * @template UI_MESSAGE - The type of UI messages being sent and received,\n * must extend the UIMessage interface from the AI SDK.\n *\n * @implements {ChatTransport<UI_MESSAGE>}\n */\nexport class WorkflowChatTransport<\n UI_MESSAGE extends UIMessage,\n> implements ChatTransport<UI_MESSAGE> {\n private readonly api: string;\n private readonly fetch: typeof fetch;\n private readonly onChatSendMessage?: OnChatSendMessage<UI_MESSAGE>;\n private readonly onChatEnd?: OnChatEnd;\n private readonly maxConsecutiveErrors: number;\n private readonly initialStartIndex: number;\n private readonly prepareSendMessagesRequest?: PrepareSendMessagesRequest<UI_MESSAGE>;\n private readonly prepareReconnectToStreamRequest?: PrepareReconnectToStreamRequest;\n\n /**\n * Creates a new WorkflowChatTransport instance.\n *\n * @param options - Configuration options for the transport\n * @param options.api - API endpoint for chat requests (defaults to '/api/chat')\n * @param options.fetch - Custom fetch implementation (defaults to global fetch)\n * @param options.onChatSendMessage - Callback after sending messages\n * @param options.onChatEnd - Callback when chat stream ends\n * @param options.maxConsecutiveErrors - Maximum consecutive errors for reconnection\n * @param options.prepareSendMessagesRequest - Function to prepare send messages request\n * @param options.prepareReconnectToStreamRequest - Function to prepare reconnect request\n */\n constructor(options: WorkflowChatTransportOptions<UI_MESSAGE> = {}) {\n this.api = options.api ?? '/api/chat';\n this.fetch = options.fetch ?? fetch.bind(globalThis);\n this.onChatSendMessage = options.onChatSendMessage;\n this.onChatEnd = options.onChatEnd;\n this.maxConsecutiveErrors = options.maxConsecutiveErrors ?? 3;\n this.initialStartIndex = options.initialStartIndex ?? 0;\n this.prepareSendMessagesRequest = options.prepareSendMessagesRequest;\n this.prepareReconnectToStreamRequest =\n options.prepareReconnectToStreamRequest;\n }\n\n /**\n * Sends messages to the chat endpoint and returns a stream of response chunks.\n *\n * This method handles the entire chat lifecycle including:\n * - Sending messages to the /api/chat endpoint\n * - Streaming response chunks\n * - Automatic reconnection if the stream is interrupted\n *\n * @param options - Options for sending messages\n * @param options.trigger - The type of message submission ('submit-message' or 'regenerate-message')\n * @param options.chatId - Unique identifier for this chat session\n * @param options.messageId - Optional message ID for tracking specific messages\n * @param options.messages - Array of UI messages to send\n * @param options.abortSignal - Optional AbortSignal to cancel the request\n *\n * @returns A ReadableStream of UIMessageChunk objects containing the response\n * @throws Error if the fetch request fails or returns a non-OK status\n */\n async sendMessages(\n options: SendMessagesOptions<UI_MESSAGE> & ChatRequestOptions,\n ): Promise<ReadableStream<UIMessageChunk>> {\n return convertAsyncIteratorToReadableStream(\n this.sendMessagesIterator(options),\n );\n }\n\n private async *sendMessagesIterator(\n options: SendMessagesOptions<UI_MESSAGE> & ChatRequestOptions,\n ): AsyncGenerator<UIMessageChunk> {\n const { chatId, messages, abortSignal, trigger, messageId } = options;\n\n // We keep track of if the \"finish\" chunk is received to determine\n // if we need to reconnect, and keep track of the chunk index to resume from.\n let gotFinish = false;\n let chunkIndex = 0;\n\n // Prepare the request using the configurator if provided\n const requestConfig = this.prepareSendMessagesRequest\n ? await this.prepareSendMessagesRequest({\n id: chatId,\n messages,\n requestMetadata: options.metadata,\n body: options.body,\n credentials: undefined,\n headers: options.headers,\n api: this.api,\n trigger,\n messageId,\n })\n : undefined;\n\n const url = requestConfig?.api ?? this.api;\n const res = await this.fetch(url, {\n method: 'POST',\n body: JSON.stringify(\n requestConfig?.body ?? { messages, ...options.body },\n ),\n headers: requestConfig?.headers,\n credentials: requestConfig?.credentials,\n signal: abortSignal,\n });\n\n if (!res.ok || !res.body) {\n throw new Error(\n `Failed to fetch chat: ${res.status} ${await res.text()}`,\n );\n }\n\n const workflowRunId = res.headers.get('x-workflow-run-id');\n if (!workflowRunId) {\n throw new Error(\n 'Workflow run ID not found in \"x-workflow-run-id\" response header',\n );\n }\n\n // Notify the caller that the chat POST request was sent.\n // This is useful for tracking the chat history on the client\n // side and allows for inspecting response headers.\n await this.onChatSendMessage?.(res, options);\n\n // Flush the initial stream until the end or an error occurs\n try {\n const chunkStream = parseJsonEventStream({\n stream: res.body,\n schema: uiMessageChunkSchema,\n });\n for await (const chunk of createAsyncIterableStream(chunkStream)) {\n if (!chunk.success) {\n throw chunk.error;\n }\n\n chunkIndex++;\n\n yield chunk.value;\n\n if (chunk.value.type === 'finish') {\n gotFinish = true;\n }\n }\n } catch (error) {\n console.error('Error in chat POST stream', error);\n }\n\n if (gotFinish) {\n await this.onFinish(gotFinish, { chatId, chunkIndex });\n } else {\n // If the initial POST request did not include the \"finish\" chunk,\n // we need to reconnect to the stream. This could indicate that a\n // network error occurred or the Vercel Function timed out.\n yield* this.reconnectToStreamIterator(options, workflowRunId, chunkIndex);\n }\n }\n\n /**\n * Reconnects to an existing chat stream that was previously interrupted.\n *\n * This method is useful for resuming a chat session after network issues,\n * page refreshes, or Vercel Function timeouts.\n *\n * @param options - Options for reconnecting to the stream\n * @param options.chatId - The chat ID to reconnect to\n *\n * @returns A ReadableStream of UIMessageChunk objects\n * @throws Error if the reconnection request fails or returns a non-OK status\n */\n async reconnectToStream(\n options: ReconnectToStreamOptions & ChatRequestOptions,\n ): Promise<ReadableStream<UIMessageChunk> | null> {\n const it = this.reconnectToStreamIterator(options);\n return convertAsyncIteratorToReadableStream(it);\n }\n\n private async *reconnectToStreamIterator(\n options: ReconnectToStreamOptions & ChatRequestOptions,\n workflowRunId?: string,\n initialChunkIndex = 0,\n ): AsyncGenerator<UIMessageChunk> {\n let chunkIndex = initialChunkIndex;\n\n // When called from the public reconnectToStream (initialChunkIndex === 0),\n // honour the caller's startIndex (or the constructor default) for the\n // first request. This enables negative values so the client can read only\n // the tail of the stream (e.g. the last 10 chunks) instead of replaying\n // everything. After the first request, fall back to the running chunkIndex\n // so that retries resume from the correct position.\n const explicitStartIndex = options.startIndex ?? this.initialStartIndex;\n let useExplicitStartIndex =\n initialChunkIndex === 0 && explicitStartIndex !== 0;\n\n const defaultApi = `${this.api}/${encodeURIComponent(workflowRunId ?? options.chatId)}/stream`;\n\n // Prepare the request using the configurator if provided\n const requestConfig = this.prepareReconnectToStreamRequest\n ? await this.prepareReconnectToStreamRequest({\n id: options.chatId,\n requestMetadata: options.metadata,\n body: undefined,\n credentials: undefined,\n headers: undefined,\n api: defaultApi,\n })\n : undefined;\n\n const baseUrl = requestConfig?.api ?? defaultApi;\n\n let gotFinish = false;\n let consecutiveErrors = 0;\n // When a negative startIndex is used but the tail-index header is absent,\n // retries fall back to startIndex 0 (replay everything) instead of using\n // the incremental chunkIndex which would be wrong.\n let replayFromStart = false;\n\n while (!gotFinish) {\n const startIndex = useExplicitStartIndex\n ? explicitStartIndex\n : replayFromStart\n ? 0\n : chunkIndex;\n\n const url = `${baseUrl}?startIndex=${startIndex}`;\n const res = await this.fetch(url, {\n headers: requestConfig?.headers,\n credentials: requestConfig?.credentials,\n signal: options.abortSignal,\n });\n\n if (!res.ok || !res.body) {\n throw new Error(\n `Failed to fetch chat: ${res.status} ${await res.text()}`,\n );\n }\n\n // When using a negative startIndex, the server resolves it to an\n // absolute position. The reconnection endpoint should return the tail\n // index so we can compute the resolved position for subsequent retries.\n if (useExplicitStartIndex && explicitStartIndex > 0) {\n // Positive startIndex: the first request starts at this absolute\n // position, so set chunkIndex to match so subsequent retries\n // resume from (explicitStartIndex + chunks received).\n chunkIndex = explicitStartIndex;\n } else if (useExplicitStartIndex && explicitStartIndex < 0) {\n const tailIndexHeader = res.headers.get('x-workflow-stream-tail-index');\n const tailIndex =\n tailIndexHeader !== null ? parseInt(tailIndexHeader, 10) : NaN;\n\n if (!Number.isNaN(tailIndex)) {\n // Resolve: e.g. tailIndex=499, startIndex=-20 → 500 + (-20) = 480\n chunkIndex = Math.max(0, tailIndex + 1 + explicitStartIndex);\n } else {\n // Header missing or unparseable — fall back to replaying from the\n // beginning so retries don't resume from a wrong position.\n console.warn(\n '[WorkflowChatTransport] Negative initialStartIndex is configured ' +\n `(${explicitStartIndex}) but the reconnection endpoint did not ` +\n 'return a valid \"x-workflow-stream-tail-index\" header. Retries ' +\n 'will replay the stream from the beginning. See: ' +\n 'https://workflow.dev/docs/ai/resumable-streams#resuming-from-the-end-of-the-stream',\n );\n replayFromStart = true;\n }\n }\n useExplicitStartIndex = false;\n\n try {\n const chunkStream = parseJsonEventStream({\n stream: res.body,\n schema: uiMessageChunkSchema,\n });\n for await (const chunk of createAsyncIterableStream(chunkStream)) {\n if (!chunk.success) {\n throw chunk.error;\n }\n\n chunkIndex++;\n\n yield chunk.value;\n\n if (chunk.value.type === 'finish') {\n gotFinish = true;\n }\n }\n // Reset consecutive error count only after successful stream parsing\n consecutiveErrors = 0;\n } catch (error) {\n console.error('Error in chat GET reconnectToStream', error);\n consecutiveErrors++;\n\n if (consecutiveErrors >= this.maxConsecutiveErrors) {\n throw new Error(\n `Failed to reconnect after ${this.maxConsecutiveErrors} consecutive errors. Last error: ${getErrorMessage(error)}`,\n );\n }\n }\n }\n\n await this.onFinish(gotFinish, { chatId: options.chatId, chunkIndex });\n }\n\n private async onFinish(\n gotFinish: boolean,\n { chatId, chunkIndex }: { chatId: string; chunkIndex: number },\n ) {\n if (gotFinish) {\n await this.onChatEnd?.({ chatId, chunkIndex });\n } else {\n throw new Error('No finish chunk received');\n }\n }\n}\n"],"mappings":"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","names":["filterActiveTools","tool","_a","filterActiveTools","messages","durationMs","getErrorMessage"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/workflow",
3
- "version": "1.0.0-beta.24",
3
+ "version": "1.0.0-beta.26",
4
4
  "description": "WorkflowAgent for building AI agents with AI SDK",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.js",
@@ -28,8 +28,8 @@
28
28
  "dependencies": {
29
29
  "ajv": "^8.18.0",
30
30
  "@ai-sdk/provider": "4.0.0-beta.12",
31
- "@ai-sdk/provider-utils": "5.0.0-beta.25",
32
- "ai": "7.0.0-beta.109"
31
+ "@ai-sdk/provider-utils": "5.0.0-beta.26",
32
+ "ai": "7.0.0-beta.111"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/node": "20.17.24",
@@ -54,7 +54,7 @@ export interface DoStreamStepOptions {
54
54
  providerOptions?: ProviderOptions;
55
55
  toolChoice?: ToolChoice<ToolSet>;
56
56
  includeRawChunks?: boolean;
57
- experimental_telemetry?: TelemetryOptions;
57
+ telemetry?: TelemetryOptions;
58
58
  repairToolCall?: ToolCallRepairFunction<ToolSet>;
59
59
  responseFormat?: LanguageModelV4CallOptions['responseFormat'];
60
60
  }
@@ -63,7 +63,7 @@ export async function* streamTextIterator({
63
63
  generationSettings,
64
64
  toolChoice,
65
65
  experimental_context,
66
- experimental_telemetry,
66
+ telemetry,
67
67
  includeRawChunks = false,
68
68
  repairToolCall,
69
69
  responseFormat,
@@ -80,7 +80,7 @@ export async function* streamTextIterator({
80
80
  generationSettings?: GenerationSettings;
81
81
  toolChoice?: ToolChoice<ToolSet>;
82
82
  experimental_context?: unknown;
83
- experimental_telemetry?: TelemetryOptions;
83
+ telemetry?: TelemetryOptions;
84
84
  includeRawChunks?: boolean;
85
85
  repairToolCall?: ToolCallRepairFunction<ToolSet>;
86
86
  responseFormat?: LanguageModelV4CallOptions['responseFormat'];
@@ -261,7 +261,7 @@ export async function* streamTextIterator({
261
261
  ...currentGenerationSettings,
262
262
  toolChoice: currentToolChoice,
263
263
  includeRawChunks,
264
- experimental_telemetry,
264
+ telemetry,
265
265
  repairToolCall,
266
266
  responseFormat,
267
267
  },
@@ -339,6 +339,10 @@ export interface PrepareCallOptions<
339
339
  tools: TTools;
340
340
  instructions?: string | SystemModelMessage | Array<SystemModelMessage>;
341
341
  toolChoice?: ToolChoice<TTools>;
342
+ telemetry?: TelemetryOptions;
343
+ /**
344
+ * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
345
+ */
342
346
  experimental_telemetry?: TelemetryOptions;
343
347
  experimental_context?: unknown;
344
348
  messages: ModelMessage[];
@@ -405,7 +409,14 @@ export interface WorkflowAgentOptions<
405
409
  toolChoice?: ToolChoice<TTools>;
406
410
 
407
411
  /**
408
- * Optional telemetry configuration (experimental).
412
+ * Optional telemetry configuration.
413
+ */
414
+ telemetry?: TelemetryOptions;
415
+
416
+ /**
417
+ * Optional telemetry configuration.
418
+ *
419
+ * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
409
420
  */
410
421
  experimental_telemetry?: TelemetryOptions;
411
422
 
@@ -727,7 +738,14 @@ export type WorkflowAgentStreamOptions<
727
738
  activeTools?: Array<keyof NoInfer<TTools>>;
728
739
 
729
740
  /**
730
- * Optional telemetry configuration (experimental).
741
+ * Optional telemetry configuration.
742
+ */
743
+ telemetry?: TelemetryOptions;
744
+
745
+ /**
746
+ * Optional telemetry configuration.
747
+ *
748
+ * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
731
749
  */
732
750
  experimental_telemetry?: TelemetryOptions;
733
751
 
@@ -1023,7 +1041,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
1023
1041
  // `instructions` takes precedence over deprecated `system`
1024
1042
  this.instructions = options.instructions ?? options.system;
1025
1043
  this.toolChoice = options.toolChoice;
1026
- this.telemetry = options.experimental_telemetry;
1044
+ this.telemetry = options.telemetry ?? options.experimental_telemetry;
1027
1045
  this.experimentalContext = options.experimental_context;
1028
1046
  this.stopWhen = options.stopWhen;
1029
1047
  this.activeTools = options.activeTools;
@@ -1080,7 +1098,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
1080
1098
  options.experimental_context ?? this.experimentalContext;
1081
1099
  let effectiveToolChoiceFromPrepare = options.toolChoice ?? this.toolChoice;
1082
1100
  let effectiveTelemetryFromPrepare =
1083
- options.experimental_telemetry ?? this.telemetry;
1101
+ options.telemetry ?? options.experimental_telemetry ?? this.telemetry;
1084
1102
 
1085
1103
  // Resolve messages for prepareCall: use messages directly, or convert prompt
1086
1104
  const resolvedMessagesForPrepareCall: ModelMessage[] =
@@ -1096,6 +1114,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
1096
1114
  tools: this.tools,
1097
1115
  instructions: effectiveInstructions,
1098
1116
  toolChoice: effectiveToolChoiceFromPrepare as ToolChoice<TBaseTools>,
1117
+ telemetry: effectiveTelemetryFromPrepare,
1099
1118
  experimental_telemetry: effectiveTelemetryFromPrepare,
1100
1119
  experimental_context: effectiveExperimentalContext,
1101
1120
  messages: resolvedMessagesForPrepareCall,
@@ -1114,7 +1133,9 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
1114
1133
  if (prepared.toolChoice !== undefined)
1115
1134
  effectiveToolChoiceFromPrepare =
1116
1135
  prepared.toolChoice as ToolChoice<TBaseTools>;
1117
- if (prepared.experimental_telemetry !== undefined)
1136
+ if (prepared.telemetry !== undefined)
1137
+ effectiveTelemetryFromPrepare = prepared.telemetry;
1138
+ else if (prepared.experimental_telemetry !== undefined)
1118
1139
  effectiveTelemetryFromPrepare = prepared.experimental_telemetry;
1119
1140
  if (prepared.maxOutputTokens !== undefined)
1120
1141
  effectiveGenerationSettings.maxOutputTokens = prepared.maxOutputTokens;
@@ -1277,9 +1298,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
1277
1298
 
1278
1299
  const effectiveAbortSignal = mergeAbortSignals(
1279
1300
  options.abortSignal ?? effectiveGenerationSettings.abortSignal,
1280
- options.timeout != null
1281
- ? AbortSignal.timeout(options.timeout)
1282
- : undefined,
1301
+ options.timeout,
1283
1302
  );
1284
1303
 
1285
1304
  // Merge generation settings: constructor defaults < prepareCall < stream options
@@ -1479,7 +1498,7 @@ export class WorkflowAgent<TBaseTools extends ToolSet = ToolSet> {
1479
1498
  generationSettings: mergedGenerationSettings,
1480
1499
  toolChoice: effectiveToolChoice as ToolChoice<ToolSet>,
1481
1500
  experimental_context: experimentalContext,
1482
- experimental_telemetry: effectiveTelemetry,
1501
+ telemetry: effectiveTelemetry,
1483
1502
  includeRawChunks: options.includeRawChunks ?? false,
1484
1503
  repairToolCall: (options.experimental_repairToolCall ??
1485
1504
  this.experimentalRepairToolCall) as