ai 7.0.153 → 7.0.154

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/index.d.ts +224 -9
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +399 -96
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +52 -4
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +26 -20
  9. package/dist/internal/index.js.map +1 -1
  10. package/docs/02-getting-started/02-nextjs-app-router.mdx +2 -2
  11. package/docs/02-getting-started/08-angular.mdx +327 -0
  12. package/docs/02-getting-started/{03-nextjs-pages-router.mdx → 10-nextjs-pages-router.mdx} +12 -20
  13. package/docs/02-getting-started/index.mdx +2 -0
  14. package/docs/03-agents/01-overview.mdx +1 -0
  15. package/docs/03-agents/04-loop-control.mdx +117 -0
  16. package/docs/03-agents/06-tool-approvals.mdx +1 -0
  17. package/docs/03-agents/09-chat-platforms.mdx +164 -0
  18. package/docs/03-agents/index.mdx +6 -0
  19. package/docs/03-ai-sdk-core/60-telemetry.mdx +16 -3
  20. package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +10 -0
  21. package/docs/04-ai-sdk-ui/21-transport.mdx +86 -0
  22. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +46 -0
  23. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +46 -0
  24. package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +35 -0
  25. package/package.json +11 -11
  26. package/src/agent/create-agent-ui-stream-response.ts +3 -0
  27. package/src/agent/create-agent-ui-stream.ts +16 -0
  28. package/src/agent/pipe-agent-ui-stream-to-response.ts +3 -0
  29. package/src/agent/tool-loop-agent-settings.ts +37 -1
  30. package/src/agent/tool-loop-agent.ts +43 -7
  31. package/src/generate-text/generate-text-events.ts +37 -0
  32. package/src/generate-text/generate-text.ts +521 -373
  33. package/src/generate-text/index.ts +8 -0
  34. package/src/generate-text/prepare-step.ts +12 -0
  35. package/src/generate-text/restricted-telemetry-dispatcher.ts +31 -18
  36. package/src/generate-text/steering.ts +293 -0
  37. package/src/generate-text/step-result.ts +18 -0
  38. package/src/generate-text/stream-text.ts +664 -473
  39. package/src/telemetry/create-telemetry-dispatcher.ts +3 -0
  40. package/src/telemetry/telemetry.ts +15 -1
  41. package/src/util/is-caused-by-abort.ts +20 -0
package/dist/index.js CHANGED
@@ -1175,7 +1175,7 @@ function cloneValue(value) {
1175
1175
  }
1176
1176
  //#endregion
1177
1177
  //#region src/version.ts
1178
- const VERSION = "7.0.153";
1178
+ const VERSION = "7.0.154";
1179
1179
  //#endregion
1180
1180
  //#region src/util/download/download.ts
1181
1181
  /**
@@ -4488,7 +4488,8 @@ function augmentEvent(event, telemetry, filterContext = false) {
4488
4488
  const augmentedEvent = Object.assign(Object.create(Object.getPrototypeOf(event)), event, {
4489
4489
  recordInputs: telemetry.recordInputs,
4490
4490
  recordOutputs: telemetry.recordOutputs,
4491
- functionId: telemetry.functionId
4491
+ functionId: telemetry.functionId,
4492
+ aiVersion: VERSION
4492
4493
  });
4493
4494
  if (filterContext && event != null && typeof event === "object" && "runtimeContext" in event) augmentedEvent.runtimeContext = filterIncludedContext({
4494
4495
  context: event.runtimeContext,
@@ -4565,6 +4566,7 @@ function createTelemetryDispatcher({ telemetry }) {
4565
4566
  onToolExecutionStart: mergeTelemetryCallback("onToolExecutionStart"),
4566
4567
  onToolExecutionEnd: mergeTelemetryCallback("onToolExecutionEnd"),
4567
4568
  onStepEnd: onStepEnd == null && onStepFinish == null ? void 0 : mergeCallbacks(onStepEnd, onStepFinish),
4569
+ onStepError: mergeTelemetryCallback("onStepError"),
4568
4570
  onObjectStepStart: mergeTelemetryCallback("onObjectStepStart"),
4569
4571
  onObjectStepEnd: mergeTelemetryCallback("onObjectStepEnd"),
4570
4572
  onEmbedStart: mergeTelemetryCallback("onEmbedStart"),
@@ -4628,7 +4630,7 @@ function asReasoningText(reasoningParts) {
4628
4630
  //#endregion
4629
4631
  //#region src/generate-text/step-result.ts
4630
4632
  var DefaultStepResult = class {
4631
- constructor({ callId, stepNumber, provider, modelId, runtimeContext, toolsContext, content, finishReason, rawFinishReason, usage, performance, warnings, request, response, providerMetadata }) {
4633
+ constructor({ callId, stepNumber, provider, modelId, runtimeContext, toolsContext, content, finishReason, rawFinishReason, usage, performance, warnings, request, response, providerMetadata, steeringMessages }) {
4632
4634
  this.callId = callId;
4633
4635
  this.stepNumber = stepNumber;
4634
4636
  this.model = {
@@ -4646,6 +4648,7 @@ var DefaultStepResult = class {
4646
4648
  this.request = request;
4647
4649
  this.response = response;
4648
4650
  this.providerMetadata = providerMetadata;
4651
+ if (steeringMessages != null && steeringMessages.length > 0) this.experimental_steeringMessages = steeringMessages;
4649
4652
  }
4650
4653
  get text() {
4651
4654
  return this.content.filter((part) => part.type === "text").map((part) => part.text).join("");
@@ -4709,7 +4712,8 @@ function restrictStepResult({ step, includeRuntimeContext, includeToolsContext }
4709
4712
  warnings: step.warnings,
4710
4713
  request: step.request,
4711
4714
  response: step.response,
4712
- providerMetadata: step.providerMetadata
4715
+ providerMetadata: step.providerMetadata,
4716
+ steeringMessages: step.experimental_steeringMessages
4713
4717
  });
4714
4718
  }
4715
4719
  /**
@@ -4718,6 +4722,22 @@ function restrictStepResult({ step, includeRuntimeContext, includeToolsContext }
4718
4722
  */
4719
4723
  function createRestrictedTelemetryDispatcher$3({ telemetry, includeRuntimeContext, includeToolsContext }) {
4720
4724
  const telemetryDispatcher = createTelemetryDispatcher({ telemetry });
4725
+ const restrictStepStartEvent = (event) => ({
4726
+ ...event,
4727
+ runtimeContext: filterIncludedContext({
4728
+ context: event.runtimeContext,
4729
+ includeContext: includeRuntimeContext
4730
+ }),
4731
+ steps: event.steps.map((step) => restrictStepResult({
4732
+ step,
4733
+ includeRuntimeContext,
4734
+ includeToolsContext
4735
+ })),
4736
+ toolsContext: filterToolsContext({
4737
+ toolsContext: event.toolsContext,
4738
+ includeToolsContext
4739
+ })
4740
+ });
4721
4741
  return {
4722
4742
  ...telemetryDispatcher,
4723
4743
  onStart: (event) => telemetryDispatcher.onStart?.({
@@ -4731,22 +4751,7 @@ function createRestrictedTelemetryDispatcher$3({ telemetry, includeRuntimeContex
4731
4751
  includeToolsContext
4732
4752
  })
4733
4753
  }),
4734
- onStepStart: (event) => telemetryDispatcher.onStepStart?.({
4735
- ...event,
4736
- runtimeContext: filterIncludedContext({
4737
- context: event.runtimeContext,
4738
- includeContext: includeRuntimeContext
4739
- }),
4740
- steps: event.steps.map((step) => restrictStepResult({
4741
- step,
4742
- includeRuntimeContext,
4743
- includeToolsContext
4744
- })),
4745
- toolsContext: filterToolsContext({
4746
- toolsContext: event.toolsContext,
4747
- includeToolsContext
4748
- })
4749
- }),
4754
+ onStepStart: (event) => telemetryDispatcher.onStepStart?.(restrictStepStartEvent(event)),
4750
4755
  onStepEnd: (event) => telemetryDispatcher.onStepEnd?.(restrictStepResult({
4751
4756
  step: event,
4752
4757
  includeRuntimeContext,
@@ -4757,6 +4762,7 @@ function createRestrictedTelemetryDispatcher$3({ telemetry, includeRuntimeContex
4757
4762
  includeRuntimeContext,
4758
4763
  includeToolsContext
4759
4764
  })),
4765
+ onStepError: (event) => telemetryDispatcher.onStepError?.(restrictStepStartEvent(event)),
4760
4766
  onEnd: (event) => telemetryDispatcher.onEnd?.(((restrictedSteps) => {
4761
4767
  return {
4762
4768
  ...event,
@@ -4803,6 +4809,139 @@ function createRestrictedTelemetryDispatcher$3({ telemetry, includeRuntimeContex
4803
4809
  };
4804
4810
  }
4805
4811
  //#endregion
4812
+ //#region src/generate-text/steering.ts
4813
+ const generateSteeringId = createIdGenerator$1({
4814
+ prefix: "steer",
4815
+ size: 24
4816
+ });
4817
+ const steeringRunStarter = Symbol.for("vercel.ai.steering.start");
4818
+ var DefaultSteering = class {
4819
+ constructor() {
4820
+ this.state = "idle";
4821
+ this.pending = [];
4822
+ this.taken = [];
4823
+ this.outcomes = /* @__PURE__ */ new Map();
4824
+ }
4825
+ steer(message, options) {
4826
+ const id = options?.id ?? generateSteeringId();
4827
+ const existingOutcome = this.outcomes.get(id);
4828
+ if (existingOutcome != null) return existingOutcome;
4829
+ const userMessage = typeof message === "string" ? {
4830
+ role: "user",
4831
+ content: message
4832
+ } : message;
4833
+ if (userMessage.role !== "user") throw new InvalidArgumentError({
4834
+ parameter: "message",
4835
+ value: message,
4836
+ message: "Steering messages must be user messages."
4837
+ });
4838
+ const outcome = this.state === "ended" ? Promise.resolve({
4839
+ type: "not-delivered",
4840
+ id,
4841
+ message: userMessage,
4842
+ reason: "finished"
4843
+ }) : new Promise((resolve) => {
4844
+ this.pending.push({
4845
+ id,
4846
+ message: userMessage,
4847
+ resolve
4848
+ });
4849
+ });
4850
+ this.outcomes.set(id, outcome);
4851
+ return outcome;
4852
+ }
4853
+ [steeringRunStarter]() {
4854
+ if (this.state !== "idle") throw new InvalidArgumentError({
4855
+ parameter: "experimental_steering",
4856
+ value: this,
4857
+ message: "The steering object was already used by a generation. Create a new one with experimental_createSteering() for each call."
4858
+ });
4859
+ this.state = "running";
4860
+ return {
4861
+ hasPendingMessages: () => this.state === "running" && this.pending.length > 0,
4862
+ takeMessages: () => {
4863
+ if (this.state !== "running") return [];
4864
+ this.taken = [...this.taken, ...this.pending];
4865
+ this.pending = [];
4866
+ return this.taken.map(({ message }) => message);
4867
+ },
4868
+ resolveTakenMessages: ({ stepNumber, sentMessages }) => {
4869
+ const taken = this.taken;
4870
+ this.taken = [];
4871
+ const delivered = [];
4872
+ for (const { id, message, resolve } of taken) if (isSent({
4873
+ message,
4874
+ sentMessages
4875
+ })) {
4876
+ delivered.push(message);
4877
+ resolve({
4878
+ type: "delivered",
4879
+ id,
4880
+ message,
4881
+ stepNumber
4882
+ });
4883
+ } else resolve({
4884
+ type: "not-delivered",
4885
+ id,
4886
+ message,
4887
+ reason: "removed-by-prepare-step"
4888
+ });
4889
+ return delivered;
4890
+ },
4891
+ end: (reason) => {
4892
+ if (this.state !== "running") return;
4893
+ const notDelivered = [...this.taken, ...this.pending];
4894
+ this.taken = [];
4895
+ this.pending = [];
4896
+ this.state = "ended";
4897
+ for (const { id, message, resolve } of notDelivered) resolve({
4898
+ type: "not-delivered",
4899
+ id,
4900
+ message,
4901
+ reason
4902
+ });
4903
+ }
4904
+ };
4905
+ }
4906
+ };
4907
+ function isSent({ message, sentMessages }) {
4908
+ const content = JSON.stringify(message.content);
4909
+ return sentMessages.some((sentMessage) => sentMessage === message || sentMessage.role === "user" && JSON.stringify(sentMessage.content) === content);
4910
+ }
4911
+ /**
4912
+ * Creates a steering object that sends user messages to a running generation.
4913
+ *
4914
+ * @example
4915
+ * ```ts
4916
+ * const steering = experimental_createSteering();
4917
+ *
4918
+ * const result = streamText({
4919
+ * model,
4920
+ * tools,
4921
+ * stopWhen: isStepCount(20),
4922
+ * experimental_steering: steering,
4923
+ * });
4924
+ *
4925
+ * const outcome = await steering.steer('Use Paris, Texas instead.');
4926
+ * ```
4927
+ */
4928
+ function createSteering() {
4929
+ return new DefaultSteering();
4930
+ }
4931
+ /**
4932
+ * Starts a run for a steering object that was passed to a generation.
4933
+ */
4934
+ function startSteeringRun(steering) {
4935
+ if (steering == null) return;
4936
+ const start = steering[steeringRunStarter];
4937
+ if (typeof start !== "function") throw new InvalidArgumentError({
4938
+ parameter: "experimental_steering",
4939
+ value: steering,
4940
+ message: "The steering object must be created with experimental_createSteering()."
4941
+ });
4942
+ return start.call(steering);
4943
+ }
4944
+ //#endregion
4806
4945
  //#region src/generate-text/stop-condition.ts
4807
4946
  /**
4808
4947
  * Creates a stop condition that returns `true` when the number of completed
@@ -5321,6 +5460,7 @@ const originalGenerateCallId$9 = createIdGenerator$1({
5321
5460
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
5322
5461
  *
5323
5462
  * @param experimental_sandbox - The sandbox environment that is passed through to tool execution.
5463
+ * @param experimental_steering - A steering object that adds user messages to the generation at the next step boundary.
5324
5464
  * @param runtimeContext - User-defined runtime context that flows through the entire generation lifecycle.
5325
5465
  * @param experimental_refineToolInput - Optional mapping of tool names to functions that refine parsed tool inputs before tools are executed and before outputs, callbacks, and telemetry are recorded.
5326
5466
  * @param onStart - Callback invoked when generation begins, before any LLM calls.
@@ -5339,13 +5479,23 @@ const originalGenerateCallId$9 = createIdGenerator$1({
5339
5479
  * Uses a discriminated union: check `success` to determine if `output` or `error` is present.
5340
5480
  * @param experimental_onToolCallFinish - Deprecated alias for `onToolExecutionEnd`.
5341
5481
  * @param onStepFinish - Callback that is called when each step (LLM call) is finished, including intermediate steps.
5482
+ * @param onStepError - Callback that is called when a step that started fails before it produces a step result, i.e. when the provider call throws or rejects, or when the call is aborted or times out.
5342
5483
  * @param onEnd - Callback that is called when all steps are finished and the response is complete.
5343
5484
  * @param onFinish - Deprecated alias for `onEnd`.
5344
5485
  *
5345
5486
  * @returns
5346
5487
  * A result object that contains the generated text, the results of the tool calls, and additional information.
5347
5488
  */
5348
- async function generateText({ model: modelArg, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries: maxRetriesArg, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, providerOptions, activeTools, toolOrder, toolCallConcurrency, prepareStep, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_download: download, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { generateId = originalGenerateId$4, generateCallId = originalGenerateCallId$9, now: now$4 = now } = {}, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, onStepEnd, onStepFinish, onFinish, onEnd = onFinish, ...settings }) {
5489
+ async function generateText(options) {
5490
+ const steeringRun = startSteeringRun(options.experimental_steering);
5491
+ try {
5492
+ return await generateTextInternal(options, steeringRun);
5493
+ } catch (error) {
5494
+ steeringRun?.end(options.abortSignal?.aborted ? "aborted" : "error");
5495
+ throw error;
5496
+ }
5497
+ }
5498
+ async function generateTextInternal({ model: modelArg, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries: maxRetriesArg, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, providerOptions, activeTools, toolOrder, toolCallConcurrency, prepareStep, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_download: download, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { generateId = originalGenerateId$4, generateCallId = originalGenerateCallId$9, now: now$4 = now } = {}, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, onStepEnd, onStepError, onStepFinish, onFinish, onEnd = onFinish, ...settings }, steeringRun) {
5349
5499
  include = {
5350
5500
  requestBody: include?.requestBody ?? false,
5351
5501
  requestMessages: include?.requestMessages ?? false,
@@ -5442,6 +5592,7 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5442
5592
  event: generateTextStartEvent,
5443
5593
  callbacks: [resolvedOnStart, telemetryDispatcher.onStart]
5444
5594
  });
5595
+ let openStep;
5445
5596
  try {
5446
5597
  const initialMessages = initialPrompt.messages;
5447
5598
  const initialResponseMessages = [];
@@ -5533,6 +5684,29 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5533
5684
  let instructionsForNextStep = initialPrompt.instructions;
5534
5685
  let messagesForNextStep = [...initialMessages, ...initialResponseMessages];
5535
5686
  const pendingDeferredToolCalls = /* @__PURE__ */ new Map();
5687
+ let steeringEndReason = "finished";
5688
+ const shouldStartNextStep = async () => {
5689
+ if (steps[steps.length - 1].finishReason === "interrupted") return false;
5690
+ if (clientToolOutputs.length + deniedToolApprovalResponses.length !== clientToolCalls.length) {
5691
+ steeringEndReason = "waiting-for-tool-results";
5692
+ return false;
5693
+ }
5694
+ if (clientToolCalls.length === 0 && pendingDeferredToolCalls.size === 0) {
5695
+ if (!steeringRun?.hasPendingMessages()) return false;
5696
+ if (steps[steps.length - 1].finishReason === "error") {
5697
+ steeringEndReason = "error";
5698
+ return false;
5699
+ }
5700
+ }
5701
+ if (await isStopConditionMet({
5702
+ stopConditions,
5703
+ steps
5704
+ })) {
5705
+ steeringEndReason = "stop-condition";
5706
+ return false;
5707
+ }
5708
+ return true;
5709
+ };
5536
5710
  do {
5537
5711
  if (steps.length > 0) mergedAbortSignal?.throwIfAborted();
5538
5712
  const stepTimeoutId = setAbortTimeout({
@@ -5541,6 +5715,8 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5541
5715
  timeoutMs: stepTimeoutMs
5542
5716
  });
5543
5717
  const stepNumber = steps.length;
5718
+ const steeringMessages = steeringRun?.takeMessages() ?? [];
5719
+ if (steeringMessages.length > 0) messagesForNextStep = [...messagesForNextStep, ...steeringMessages];
5544
5720
  try {
5545
5721
  await runInTracingChannelSpan({
5546
5722
  type: "step",
@@ -5560,6 +5736,7 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5560
5736
  messages: stepInputMessages,
5561
5737
  initialMessages,
5562
5738
  responseMessages: accumulatedResponseMessages,
5739
+ ...steeringMessages.length > 0 ? { experimental_steeringMessages: steeringMessages } : {},
5563
5740
  runtimeContext,
5564
5741
  toolsContext,
5565
5742
  experimental_sandbox: sandbox
@@ -5593,6 +5770,10 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5593
5770
  messages: prepareStepResult?.messages ?? stepInputMessages,
5594
5771
  toolCallerMessages
5595
5772
  });
5773
+ const deliveredSteeringMessages = steeringRun?.resolveTakenMessages({
5774
+ stepNumber,
5775
+ sentMessages: stepMessages
5776
+ }) ?? [];
5596
5777
  const promptMessages = await convertToLanguageModelPrompt({
5597
5778
  prompt: {
5598
5779
  instructions: stepInstructions,
@@ -5608,29 +5789,31 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5608
5789
  callSettings,
5609
5790
  stepSettings: prepareStepResult
5610
5791
  });
5792
+ const stepStartEvent = {
5793
+ callId,
5794
+ provider: stepModel.provider,
5795
+ modelId: stepModel.modelId,
5796
+ stepNumber,
5797
+ instructions: stepInstructions,
5798
+ messages: stepMessages,
5799
+ tools,
5800
+ toolChoice: prepareStepResult?.toolChoice ?? toolChoice,
5801
+ activeTools: prepareStepResult?.activeTools ?? activeTools,
5802
+ toolOrder: stepToolOrder,
5803
+ steps: [...steps],
5804
+ providerOptions: stepProviderOptions,
5805
+ output,
5806
+ runtimeContext,
5807
+ promptMessages,
5808
+ stepTools,
5809
+ stepToolChoice,
5810
+ toolsContext
5811
+ };
5611
5812
  await notify({
5612
- event: {
5613
- callId,
5614
- provider: stepModel.provider,
5615
- modelId: stepModel.modelId,
5616
- stepNumber,
5617
- instructions: stepInstructions,
5618
- messages: stepMessages,
5619
- tools,
5620
- toolChoice: prepareStepResult?.toolChoice ?? toolChoice,
5621
- activeTools: prepareStepResult?.activeTools ?? activeTools,
5622
- toolOrder: stepToolOrder,
5623
- steps: [...steps],
5624
- providerOptions: stepProviderOptions,
5625
- output,
5626
- runtimeContext,
5627
- promptMessages,
5628
- stepTools,
5629
- stepToolChoice,
5630
- toolsContext
5631
- },
5813
+ event: stepStartEvent,
5632
5814
  callbacks: [resolvedOnStepStart, telemetryDispatcher.onStepStart]
5633
5815
  });
5816
+ openStep = stepStartEvent;
5634
5817
  const languageModelCallContext = {
5635
5818
  provider: stepModel.provider,
5636
5819
  modelId: stepModel.modelId,
@@ -5928,7 +6111,8 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5928
6111
  providerMetadata: currentModelResponse.providerMetadata,
5929
6112
  request: stepRequest,
5930
6113
  response: stepResponse,
5931
- toolsContext
6114
+ toolsContext,
6115
+ steeringMessages: deliveredSteeringMessages
5932
6116
  });
5933
6117
  logWarnings({
5934
6118
  warnings: currentModelResponse.warnings ?? [],
@@ -5938,6 +6122,7 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5938
6122
  steps.push(currentStepResult);
5939
6123
  instructionsForNextStep = stepInstructions;
5940
6124
  messagesForNextStep = [...stepMessages, ...stepResponseMessages];
6125
+ openStep = void 0;
5941
6126
  await notify({
5942
6127
  event: currentStepResult,
5943
6128
  callbacks: [resolvedOnStepEnd, telemetryDispatcher.onStepEnd]
@@ -5948,10 +6133,8 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
5948
6133
  } finally {
5949
6134
  if (stepTimeoutId != null) clearTimeout(stepTimeoutId);
5950
6135
  }
5951
- } while (steps[steps.length - 1].finishReason !== "interrupted" && clientToolOutputs.length + deniedToolApprovalResponses.length === clientToolCalls.length && (clientToolCalls.length > 0 || pendingDeferredToolCalls.size > 0) && !await isStopConditionMet({
5952
- stopConditions,
5953
- steps
5954
- }));
6136
+ } while (await shouldStartNextStep());
6137
+ steeringRun?.end(steeringEndReason);
5955
6138
  const lastStep = steps[steps.length - 1];
5956
6139
  const totalUsage = steps.reduce((totalUsage, step) => {
5957
6140
  return addLanguageModelUsage(totalUsage, step.usage);
@@ -6028,11 +6211,20 @@ async function generateText({ model: modelArg, tools, toolChoice, instructions,
6028
6211
  output: resolvedOutput
6029
6212
  });
6030
6213
  } catch (error) {
6214
+ const wrappedError = wrapGatewayError(error);
6215
+ steeringRun?.end(mergedAbortSignal?.aborted ? "aborted" : "error");
6216
+ if (openStep != null) await notify({
6217
+ event: {
6218
+ ...openStep,
6219
+ error: wrappedError
6220
+ },
6221
+ callbacks: [onStepError, telemetryDispatcher.onStepError]
6222
+ });
6031
6223
  await telemetryDispatcher.onError?.({
6032
6224
  callId,
6033
6225
  error
6034
6226
  });
6035
- throw wrapGatewayError(error);
6227
+ throw wrappedError;
6036
6228
  }
6037
6229
  };
6038
6230
  return await runInTracingChannelSpan({
@@ -8832,6 +9024,7 @@ const originalGenerateCallId$7 = createIdGenerator$1({
8832
9024
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
8833
9025
  *
8834
9026
  * @param experimental_sandbox - The sandbox environment that is passed through to tool execution.
9027
+ * @param experimental_steering - A steering object that adds user messages to the generation at the next step boundary.
8835
9028
  * @param runtimeContext - User-defined runtime context that flows through the entire generation lifecycle.
8836
9029
  * @param experimental_refineToolInput - Optional mapping of tool names to functions that refine parsed tool inputs before tools are executed and before outputs, callbacks, and telemetry are recorded.
8837
9030
  *
@@ -8850,6 +9043,7 @@ const originalGenerateCallId$7 = createIdGenerator$1({
8850
9043
  * @param onToolExecutionEnd - Callback invoked after each tool execution completes.
8851
9044
  * @param experimental_onToolCallFinish - Deprecated alias for `onToolExecutionEnd`.
8852
9045
  * @param onStepEnd - Callback that is called when each step (LLM call) ends, including intermediate steps.
9046
+ * @param onStepError - Callback that is called when a step that started fails before it produces a step result, i.e. when the provider call throws or rejects, or when the model stream ends without output. A provider `error` chunk still ends the step with `onStepEnd`, and an abort or timeout ends it with `onAbort`.
8853
9047
  * @param onStepFinish - Deprecated alias for `onStepEnd`.
8854
9048
  * @param onEnd - Callback that is called when all steps are finished and the response is complete.
8855
9049
  * @param onFinish - Deprecated alias for `onEnd`.
@@ -8858,7 +9052,7 @@ const originalGenerateCallId$7 = createIdGenerator$1({
8858
9052
  * A result object for accessing different stream types and additional information.
8859
9053
  */
8860
9054
  function streamText(options) {
8861
- return streamTextInternal(options);
9055
+ return startStreamText(options);
8862
9056
  }
8863
9057
  /**
8864
9058
  * Stream text with a single consumer, without replay or final-content getters.
@@ -8868,7 +9062,7 @@ function streamTextLowMemory(options) {
8868
9062
  const telemetry = options.telemetry ?? options.experimental_telemetry;
8869
9063
  const integrations = telemetry?.integrations != null ? asArray(telemetry.integrations) : getGlobalTelemetryIntegrations();
8870
9064
  const collectContent = options.tools != null && Object.keys(options.tools).length > 0 || options.toolChoice != null || options.output != null || options.prepareStep != null || options.stopWhen != null || options.onEnd != null || options.onFinish != null || options.onStepEnd != null || options.onStepFinish != null || options.onAbort != null || options.onLanguageModelCallEnd != null || options.experimental_onLanguageModelCallEnd != null || telemetry?.isEnabled !== false && integrations.length > 0;
8871
- return createSingleConsumerStreamTextResult(streamTextInternal({
9065
+ return createSingleConsumerStreamTextResult(startStreamText({
8872
9066
  ...options,
8873
9067
  _internal: {
8874
9068
  ...options._internal,
@@ -8879,10 +9073,19 @@ function streamTextLowMemory(options) {
8879
9073
  }
8880
9074
  }));
8881
9075
  }
8882
- function streamTextInternal({ model, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries, streamRetries, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, prepareStep, providerOptions, activeTools, toolOrder, toolCallConcurrency, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_transform: transform, experimental_download: download, includeRawChunks, onChunk, onError: onErrorArg, onFinish, onEnd = onFinish, onAbort, onStepEnd, onStepFinish, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { now: now$2 = now, generateId = originalGenerateId$2, generateCallId = originalGenerateCallId$7, retention = {
9076
+ function startStreamText(options) {
9077
+ const steeringRun = startSteeringRun(options.experimental_steering);
9078
+ try {
9079
+ return streamTextInternal(options, steeringRun);
9080
+ } catch (error) {
9081
+ steeringRun?.end("error");
9082
+ throw error;
9083
+ }
9084
+ }
9085
+ function streamTextInternal({ model, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries, streamRetries, abortSignal, timeout, headers, stopWhen = isStepCount(1), experimental_sandbox: sandbox, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, experimental_telemetry, telemetry = experimental_telemetry, prepareStep, providerOptions, activeTools, toolOrder, toolCallConcurrency, experimental_repairToolCall, repairToolCall = experimental_repairToolCall, experimental_refineToolInput: refineToolInput, experimental_transform: transform, experimental_download: download, includeRawChunks, onChunk, onError: onErrorArg, onFinish, onEnd = onFinish, onAbort, onStepEnd, onStepError, onStepFinish, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onLanguageModelCallStart, experimental_onLanguageModelCallStart, onLanguageModelCallEnd, experimental_onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, experimental_onToolCallStart, experimental_onToolCallFinish, runtimeContext = {}, toolsContext = {}, experimental_include, include = experimental_include, _internal: { now: now$2 = now, generateId = originalGenerateId$2, generateCallId = originalGenerateCallId$7, retention = {
8883
9086
  replay: true,
8884
9087
  collectContent: true
8885
- } } = {}, ...settings }) {
9088
+ } } = {}, ...settings }, steeringRun) {
8886
9089
  const resolvedToolCallConcurrency = prepareToolCallConcurrency(toolCallConcurrency);
8887
9090
  const totalTimeoutMs = getTotalTimeoutMs(timeout);
8888
9091
  const stepTimeoutMs = getStepTimeoutMs(timeout);
@@ -8922,6 +9125,7 @@ function streamTextInternal({ model, tools, toolChoice, instructions, system, pr
8922
9125
  messages,
8923
9126
  allowSystemInMessages,
8924
9127
  experimental_sandbox: sandbox,
9128
+ steeringRun,
8925
9129
  tools,
8926
9130
  toolsContext,
8927
9131
  runtimeContext,
@@ -8946,6 +9150,7 @@ function streamTextInternal({ model, tools, toolChoice, instructions, system, pr
8946
9150
  onEnd,
8947
9151
  onAbort,
8948
9152
  onStepFinish: resolvedOnStepEnd,
9153
+ onStepError,
8949
9154
  onStart: resolvedOnStart,
8950
9155
  onStepStart: resolvedOnStepStart,
8951
9156
  onLanguageModelCallStart: resolvedOnLanguageModelCallStart,
@@ -9143,7 +9348,7 @@ function applyStreamTextTransforms({ stream, transforms, tools, stopStream }) {
9143
9348
  });
9144
9349
  }
9145
9350
  var DefaultStreamTextResult = class {
9146
- constructor({ retention, model, telemetry, headers, settings, maxRetries: maxRetriesArg, streamRetries: streamRetriesArg, abortSignal, stepTimeoutMs, stepAbortController, firstChunkTimeoutMs, firstChunkAbortController, chunkTimeoutMs, chunkAbortController, instructions, system, prompt, messages, allowSystemInMessages, experimental_sandbox: sandbox, tools, toolChoice, transforms, activeTools, toolOrder, toolCallConcurrency, repairToolCall, refineToolInput, stopConditions, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, providerOptions, prepareStep, now, generateId, generateCallId, timeout, onChunk, onError, canRetryStreamViaOnError, onEnd, onAbort, onStepFinish, onStart, onStepStart, onLanguageModelCallStart, onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, runtimeContext, toolsContext, download, include }) {
9351
+ constructor({ retention, model, telemetry, headers, settings, maxRetries: maxRetriesArg, streamRetries: streamRetriesArg, abortSignal, stepTimeoutMs, stepAbortController, firstChunkTimeoutMs, firstChunkAbortController, chunkTimeoutMs, chunkAbortController, instructions, system, prompt, messages, allowSystemInMessages, experimental_sandbox: sandbox, steeringRun, tools, toolChoice, transforms, activeTools, toolOrder, toolCallConcurrency, repairToolCall, refineToolInput, stopConditions, output, toolApproval, experimental_toolCallers, experimental_toolApprovalSecret, providerOptions, prepareStep, now, generateId, generateCallId, timeout, onChunk, onError, canRetryStreamViaOnError, onEnd, onAbort, onStepFinish, onStepError, onStart, onStepStart, onLanguageModelCallStart, onLanguageModelCallEnd, onToolExecutionStart, onToolExecutionEnd, runtimeContext, toolsContext, download, include }) {
9147
9352
  this._totalUsage = new DelayedPromise();
9148
9353
  this._finishReason = new DelayedPromise();
9149
9354
  this._rawFinishReason = new DelayedPromise();
@@ -9178,6 +9383,7 @@ var DefaultStreamTextResult = class {
9178
9383
  const initialResponseMessages = [];
9179
9384
  let stepMessagesForNextStep;
9180
9385
  let currentStepMessages = [];
9386
+ let currentStepSteeringMessages = [];
9181
9387
  let isAborted = false;
9182
9388
  let currentStepModel = model;
9183
9389
  const createPartIdReserver = () => {
@@ -9202,6 +9408,19 @@ var DefaultStreamTextResult = class {
9202
9408
  let activeReasoningContent = createIdMap();
9203
9409
  let recordedNoOutputError;
9204
9410
  const errorsHandledForStreamRetry = /* @__PURE__ */ new Set();
9411
+ let openStep;
9412
+ const notifyStepError = async (error) => {
9413
+ if (openStep == null || abortSignal?.aborted) return;
9414
+ const { event } = openStep;
9415
+ openStep = void 0;
9416
+ await notify({
9417
+ event: {
9418
+ ...event,
9419
+ error
9420
+ },
9421
+ callbacks: [onStepError, telemetryDispatcher.onStepError]
9422
+ });
9423
+ };
9205
9424
  const eventProcessor = new TransformStream({
9206
9425
  async transform(chunk, controller) {
9207
9426
  if (isStreamRetryBoundaryPart(chunk)) {
@@ -9225,12 +9444,15 @@ var DefaultStreamTextResult = class {
9225
9444
  const error = wrapGatewayError(part.error);
9226
9445
  if (NoOutputGeneratedError.isInstance(error)) recordedNoOutputError = error;
9227
9446
  if (callbacksHandledForStreamRetry) errorsHandledForStreamRetry.delete(part.error);
9228
- else await notify({
9229
- event: { error },
9230
- callbacks: async (event) => {
9231
- await onError(event);
9232
- }
9233
- });
9447
+ else {
9448
+ if (openStep != null) openStep.error = error;
9449
+ await notify({
9450
+ event: { error },
9451
+ callbacks: async (event) => {
9452
+ await onError(event);
9453
+ }
9454
+ });
9455
+ }
9234
9456
  }
9235
9457
  if (part.type === "custom" || part.type === "source" || part.type === "tool-call" || part.type === "tool-approval-request" || part.type === "tool-approval-response" || part.type === "tool-error") {
9236
9458
  if (retention.collectContent) recordedContent.push(part);
@@ -9355,8 +9577,10 @@ var DefaultStreamTextResult = class {
9355
9577
  ...part.response,
9356
9578
  messages: cloneModelMessages(stepResponseMessages)
9357
9579
  },
9358
- providerMetadata: part.providerMetadata
9580
+ providerMetadata: part.providerMetadata,
9581
+ steeringMessages: currentStepSteeringMessages
9359
9582
  });
9583
+ openStep = void 0;
9360
9584
  await notify({
9361
9585
  event: currentStepResult,
9362
9586
  callbacks: [onStepFinish, telemetryDispatcher.onStepEnd]
@@ -9377,9 +9601,16 @@ var DefaultStreamTextResult = class {
9377
9601
  }
9378
9602
  },
9379
9603
  async flush(controller) {
9604
+ steeringRun?.end(recordedSteps.length === 0 || recordedNoOutputError != null ? "error" : "finished");
9380
9605
  try {
9606
+ const noOutputError = new NoOutputGeneratedError({ message: "No output generated. Check the stream for errors." });
9607
+ await notifyStepError(openStep?.error ?? noOutputError);
9381
9608
  if (recordedSteps.length === 0 || recordedNoOutputError != null) {
9382
- const error = abortSignal?.aborted ? abortSignal.reason : recordedNoOutputError ?? new NoOutputGeneratedError({ message: "No output generated. Check the stream for errors." });
9609
+ const error = abortSignal?.aborted ? abortSignal.reason : recordedNoOutputError ?? noOutputError;
9610
+ if (recordedNoOutputError != null && !abortSignal?.aborted) await telemetryDispatcher.onError?.({
9611
+ callId,
9612
+ error: recordedNoOutputError
9613
+ });
9383
9614
  self.rejectResultPromises(error);
9384
9615
  return;
9385
9616
  }
@@ -9479,6 +9710,7 @@ var DefaultStreamTextResult = class {
9479
9710
  async function abort() {
9480
9711
  isAborted = true;
9481
9712
  removeAbortListener();
9713
+ steeringRun?.end("aborted");
9482
9714
  await notify({
9483
9715
  event: {
9484
9716
  callId,
@@ -9509,6 +9741,8 @@ var DefaultStreamTextResult = class {
9509
9741
  removeAbortListener();
9510
9742
  if (isAbortError(error) && abortSignal?.aborted) await abort();
9511
9743
  else {
9744
+ steeringRun?.end("error");
9745
+ await notifyStepError(wrapGatewayError(error));
9512
9746
  await telemetryDispatcher.onError?.({
9513
9747
  callId,
9514
9748
  error
@@ -9519,6 +9753,7 @@ var DefaultStreamTextResult = class {
9519
9753
  },
9520
9754
  cancel(reason) {
9521
9755
  removeAbortListener();
9756
+ steeringRun?.end("aborted");
9522
9757
  return reader.cancel(reason);
9523
9758
  }
9524
9759
  });
@@ -9774,7 +10009,8 @@ var DefaultStreamTextResult = class {
9774
10009
  const runInStepTracingChannelContext = (execute) => stepTracingChannelContext?.run(execute) ?? execute();
9775
10010
  const responseMessagesFromPreviousSteps = recordedSteps.flatMap((step) => step.response.messages);
9776
10011
  const accumulatedResponseMessages = [...initialResponseMessages, ...responseMessagesFromPreviousSteps];
9777
- const stepInputMessages = stepMessagesForNextStep ?? [...initialMessages, ...initialResponseMessages];
10012
+ const steeringMessages = steeringRun?.takeMessages() ?? [];
10013
+ const stepInputMessages = [...stepMessagesForNextStep ?? [...initialMessages, ...initialResponseMessages], ...steeringMessages];
9778
10014
  const prepareStepResult = await prepareStep?.({
9779
10015
  model,
9780
10016
  steps: recordedSteps,
@@ -9784,6 +10020,7 @@ var DefaultStreamTextResult = class {
9784
10020
  messages: stepInputMessages,
9785
10021
  initialMessages,
9786
10022
  responseMessages: accumulatedResponseMessages,
10023
+ ...steeringMessages.length > 0 ? { experimental_steeringMessages: steeringMessages } : {},
9787
10024
  toolsContext,
9788
10025
  runtimeContext,
9789
10026
  experimental_sandbox: sandbox
@@ -9818,6 +10055,10 @@ var DefaultStreamTextResult = class {
9818
10055
  toolCallerMessages
9819
10056
  });
9820
10057
  currentStepMessages = stepMessages;
10058
+ currentStepSteeringMessages = steeringRun?.resolveTakenMessages({
10059
+ stepNumber: currentStep,
10060
+ sentMessages: stepMessages
10061
+ }) ?? [];
9821
10062
  const stepInstructions = prepareStepResult?.instructions ?? prepareStepResult?.system ?? instructionsForNextStep;
9822
10063
  instructionsForNextStep = stepInstructions;
9823
10064
  const stepProviderOptions = mergeObjects(providerOptions, prepareStepResult?.providerOptions);
@@ -9856,29 +10097,31 @@ var DefaultStreamTextResult = class {
9856
10097
  onStart: async ({ promptMessages }) => {
9857
10098
  if (hasNotifiedStepStart) return;
9858
10099
  hasNotifiedStepStart = true;
10100
+ const stepStartEvent = {
10101
+ callId,
10102
+ provider: stepModel.provider,
10103
+ modelId: stepModel.modelId,
10104
+ stepNumber: recordedSteps.length,
10105
+ instructions: stepInstructions,
10106
+ messages: stepMessages,
10107
+ tools,
10108
+ toolChoice: prepareStepResult?.toolChoice ?? toolChoice,
10109
+ activeTools: prepareStepResult?.activeTools ?? activeTools,
10110
+ toolOrder: stepToolOrder,
10111
+ steps: [...recordedSteps],
10112
+ providerOptions: stepProviderOptions,
10113
+ runtimeContext,
10114
+ toolsContext,
10115
+ output,
10116
+ promptMessages,
10117
+ stepTools,
10118
+ stepToolChoice
10119
+ };
9859
10120
  await notify({
9860
- event: {
9861
- callId,
9862
- provider: stepModel.provider,
9863
- modelId: stepModel.modelId,
9864
- stepNumber: recordedSteps.length,
9865
- instructions: stepInstructions,
9866
- messages: stepMessages,
9867
- tools,
9868
- toolChoice: prepareStepResult?.toolChoice ?? toolChoice,
9869
- activeTools: prepareStepResult?.activeTools ?? activeTools,
9870
- toolOrder: stepToolOrder,
9871
- steps: [...recordedSteps],
9872
- providerOptions: stepProviderOptions,
9873
- runtimeContext,
9874
- toolsContext,
9875
- output,
9876
- promptMessages,
9877
- stepTools,
9878
- stepToolChoice
9879
- },
10121
+ event: stepStartEvent,
9880
10122
  callbacks: [onStepStart, telemetryDispatcher.onStepStart]
9881
10123
  });
10124
+ openStep = { event: stepStartEvent };
9882
10125
  },
9883
10126
  _internal: {
9884
10127
  now,
@@ -10259,15 +10502,36 @@ var DefaultStreamTextResult = class {
10259
10502
  }
10260
10503
  for (const output of stepToolOutputs) if (output.type === "tool-result" || output.type === "tool-error") pendingDeferredToolCalls.delete(output.toolCallId);
10261
10504
  cleanupStepTimeouts();
10262
- if (stepFinishReason !== "interrupted" && clientToolCalls.length === clientToolOutputs.length + deniedToolApprovalResponses.length && (clientToolCalls.length > 0 || pendingDeferredToolCalls.size > 0) && !await isStopConditionMet({
10263
- stopConditions,
10264
- steps: recordedSteps
10265
- })) try {
10505
+ let steeringEndReason = "finished";
10506
+ const shouldStartNextStep = async () => {
10507
+ if (stepFinishReason === "interrupted") return false;
10508
+ if (clientToolCalls.length !== clientToolOutputs.length + deniedToolApprovalResponses.length) {
10509
+ steeringEndReason = "waiting-for-tool-results";
10510
+ return false;
10511
+ }
10512
+ if (clientToolCalls.length === 0 && pendingDeferredToolCalls.size === 0) {
10513
+ if (!steeringRun?.hasPendingMessages()) return false;
10514
+ if (stepFinishReason === "error") {
10515
+ steeringEndReason = "error";
10516
+ return false;
10517
+ }
10518
+ }
10519
+ if (await isStopConditionMet({
10520
+ stopConditions,
10521
+ steps: recordedSteps
10522
+ })) {
10523
+ steeringEndReason = "stop-condition";
10524
+ return false;
10525
+ }
10526
+ return true;
10527
+ };
10528
+ if (await shouldStartNextStep()) try {
10266
10529
  await runInStreamTextTracingChannelContext(() => streamStep({
10267
10530
  currentStep: currentStep + 1,
10268
10531
  usage: combinedUsage
10269
10532
  }));
10270
10533
  } catch (error) {
10534
+ steeringRun?.end("error");
10271
10535
  enqueueStepPart(controller, {
10272
10536
  type: "error",
10273
10537
  error
@@ -10275,6 +10539,7 @@ var DefaultStreamTextResult = class {
10275
10539
  self.closeStream();
10276
10540
  }
10277
10541
  else {
10542
+ steeringRun?.end(steeringEndReason);
10278
10543
  enqueueStepPart(controller, {
10279
10544
  type: "finish",
10280
10545
  finishReason: stepFinishReason,
@@ -10298,6 +10563,8 @@ var DefaultStreamTextResult = class {
10298
10563
  usage: createNullLanguageModelUsage()
10299
10564
  }));
10300
10565
  })().catch(async (error) => {
10566
+ steeringRun?.end(abortSignal?.aborted ? "aborted" : "error");
10567
+ await notifyStepError(wrapGatewayError(error));
10301
10568
  await telemetryDispatcher.onError?.({
10302
10569
  callId,
10303
10570
  error
@@ -10583,6 +10850,21 @@ var DefaultStreamTextResult = class {
10583
10850
  }
10584
10851
  };
10585
10852
  //#endregion
10853
+ //#region src/util/is-caused-by-abort.ts
10854
+ /**
10855
+ * Checks if the error is an abort or timeout error, or is caused by one.
10856
+ * Providers can wrap the abort or timeout error, e.g. as the cause of an
10857
+ * API call error.
10858
+ */
10859
+ function isCausedByAbort(error) {
10860
+ let current = error;
10861
+ for (let depth = 0; current != null && depth < 5; depth++) {
10862
+ if (isAbortError(current)) return true;
10863
+ current = current.cause;
10864
+ }
10865
+ return false;
10866
+ }
10867
+ //#endregion
10586
10868
  //#region src/agent/default-stop-condition.ts
10587
10869
  /**
10588
10870
  * Stop conditions are only evaluated when the tool loop can otherwise continue,
@@ -10649,7 +10931,7 @@ var ToolLoopAgent = class {
10649
10931
  options: validatedOptions
10650
10932
  };
10651
10933
  }
10652
- const { onStart: _settingsStableOnStart, experimental_onStart: _settingsExperimentalOnStart, onStepStart: _settingsStableOnStepStart, experimental_onStepStart: _settingsExperimentalOnStepStart, onToolExecutionStart: _settingsOnToolExecutionStart, onToolExecutionEnd: _settingsOnToolExecutionEnd, onStepEnd: _settingsOnStepEnd, onStepFinish: _settingsOnStepFinish, onFinish: _settingsOnFinish, onEnd: _settingsOnEnd, ...settingsWithoutCallbacks } = this.settings;
10934
+ const { onStart: _settingsStableOnStart, experimental_onStart: _settingsExperimentalOnStart, onStepStart: _settingsStableOnStepStart, experimental_onStepStart: _settingsExperimentalOnStepStart, onToolExecutionStart: _settingsOnToolExecutionStart, onToolExecutionEnd: _settingsOnToolExecutionEnd, onStepEnd: _settingsOnStepEnd, onStepFinish: _settingsOnStepFinish, onError: _settingsOnError, onAbort: _settingsOnAbort, onFinish: _settingsOnFinish, onEnd: _settingsOnEnd, ...settingsWithoutCallbacks } = this.settings;
10653
10935
  const baseCallArgs = {
10654
10936
  ...settingsWithoutCallbacks,
10655
10937
  stopWhen: this.settings.stopWhen ?? createDefaultStopCondition(20),
@@ -10683,7 +10965,7 @@ var ToolLoopAgent = class {
10683
10965
  /**
10684
10966
  * Generates an output from the agent (non-streaming).
10685
10967
  */
10686
- async generate({ abortSignal, timeout, experimental_sandbox: sandbox, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onToolExecutionStart, onToolExecutionEnd, onStepEnd, onStepFinish, onFinish, onEnd = onFinish, ...options }) {
10968
+ async generate({ abortSignal, timeout, experimental_sandbox: sandbox, experimental_steering: steering, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onToolExecutionStart, onToolExecutionEnd, onStepEnd, onStepFinish, onFinish, onEnd = onFinish, ...options }) {
10687
10969
  const generate = generateText;
10688
10970
  const preparedCall = await this.prepareCall({
10689
10971
  ...options,
@@ -10693,6 +10975,7 @@ var ToolLoopAgent = class {
10693
10975
  abortSignal,
10694
10976
  timeout: timeout ?? preparedCall.timeout,
10695
10977
  experimental_sandbox: sandbox,
10978
+ experimental_steering: steering,
10696
10979
  onStart: mergeCallbacks(this.settings.onStart ?? this.settings.experimental_onStart, onStart ?? experimental_onStart),
10697
10980
  onStepStart: mergeCallbacks(this.settings.onStepStart ?? this.settings.experimental_onStepStart, onStepStart ?? experimental_onStepStart),
10698
10981
  onToolExecutionStart: mergeCallbacks(this.settings.onToolExecutionStart, onToolExecutionStart),
@@ -10700,16 +10983,24 @@ var ToolLoopAgent = class {
10700
10983
  onStepEnd: mergeCallbacks(this.settings.onStepEnd ?? this.settings.onStepFinish, onStepEnd ?? onStepFinish),
10701
10984
  onEnd: mergeCallbacks(this.settings.onEnd, onEnd)
10702
10985
  };
10703
- return await generate({
10704
- ...preparedCall,
10705
- ...callbackArgs,
10706
- headers: this.agentHeaders(preparedCall)
10707
- });
10986
+ try {
10987
+ return await generate({
10988
+ ...preparedCall,
10989
+ ...callbackArgs,
10990
+ headers: this.agentHeaders(preparedCall)
10991
+ });
10992
+ } catch (error) {
10993
+ if (!isCausedByAbort(error) && !abortSignal?.aborted) await notify({
10994
+ event: { error },
10995
+ callbacks: this.settings.onError
10996
+ });
10997
+ throw error;
10998
+ }
10708
10999
  }
10709
11000
  /**
10710
11001
  * Streams an output from the agent (streaming).
10711
11002
  */
10712
- async stream({ abortSignal, timeout, experimental_sandbox: sandbox, experimental_transform, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onToolExecutionStart, onToolExecutionEnd, onStepEnd, onStepFinish, onFinish, onEnd = onFinish, ...options }) {
11003
+ async stream({ abortSignal, timeout, experimental_sandbox: sandbox, experimental_steering: steering, experimental_transform, onStart, experimental_onStart, onStepStart, experimental_onStepStart, onToolExecutionStart, onToolExecutionEnd, onStepEnd, onStepFinish, onFinish, onEnd = onFinish, ...options }) {
10713
11004
  const stream = streamText;
10714
11005
  const preparedCall = await this.prepareCall({
10715
11006
  ...options,
@@ -10719,13 +11010,16 @@ var ToolLoopAgent = class {
10719
11010
  abortSignal,
10720
11011
  timeout: timeout ?? preparedCall.timeout,
10721
11012
  experimental_sandbox: sandbox,
11013
+ experimental_steering: steering,
10722
11014
  experimental_transform,
10723
11015
  onStart: mergeCallbacks(this.settings.onStart ?? this.settings.experimental_onStart, onStart ?? experimental_onStart),
10724
11016
  onStepStart: mergeCallbacks(this.settings.onStepStart ?? this.settings.experimental_onStepStart, onStepStart ?? experimental_onStepStart),
10725
11017
  onToolExecutionStart: mergeCallbacks(this.settings.onToolExecutionStart, onToolExecutionStart),
10726
11018
  onToolExecutionEnd: mergeCallbacks(this.settings.onToolExecutionEnd, onToolExecutionEnd),
10727
11019
  onStepEnd: mergeCallbacks(this.settings.onStepEnd ?? this.settings.onStepFinish, onStepEnd ?? onStepFinish),
10728
- onEnd: mergeCallbacks(this.settings.onEnd, onEnd)
11020
+ onEnd: mergeCallbacks(this.settings.onEnd, onEnd),
11021
+ onError: this.settings.onError,
11022
+ onAbort: this.settings.onAbort
10729
11023
  };
10730
11024
  return await stream({
10731
11025
  ...preparedCall,
@@ -11683,6 +11977,7 @@ async function validateUIMessagesForAgent(options) {
11683
11977
  * @param abortSignal - The abort signal. Optional.
11684
11978
  * @param timeout - Timeout in milliseconds. Optional.
11685
11979
  * @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
11980
+ * @param experimental_steering - A steering object that adds user messages to the run at the next step boundary. Only supported by `ToolLoopAgent`. Optional.
11686
11981
  * @param options - The options for the agent.
11687
11982
  * @param experimental_transform - The stream transformations. Optional.
11688
11983
  * @param onStepEnd - Callback that is called when each step ends. Optional.
@@ -11691,7 +11986,12 @@ async function validateUIMessagesForAgent(options) {
11691
11986
  *
11692
11987
  * @returns The UI message stream.
11693
11988
  */
11694
- async function createAgentUIStream({ agent, uiMessages, convertDataPart, options, abortSignal, timeout, experimental_sandbox: sandbox, experimental_transform, onStepEnd, onStepFinish, onUIMessageStepEnd, ...uiMessageStreamOptions }) {
11989
+ async function createAgentUIStream({ agent, uiMessages, convertDataPart, options, abortSignal, timeout, experimental_sandbox: sandbox, experimental_steering: steering, experimental_transform, onStepEnd, onStepFinish, onUIMessageStepEnd, ...uiMessageStreamOptions }) {
11990
+ if (steering != null && !(agent instanceof ToolLoopAgent)) throw new InvalidArgumentError({
11991
+ parameter: "experimental_steering",
11992
+ value: steering,
11993
+ message: "Steering is only supported by ToolLoopAgent."
11994
+ });
11695
11995
  const validatedMessages = await validateUIMessagesForAgent({
11696
11996
  messages: uiMessages,
11697
11997
  tools: agent.tools
@@ -11706,6 +12006,7 @@ async function createAgentUIStream({ agent, uiMessages, convertDataPart, options
11706
12006
  abortSignal,
11707
12007
  timeout,
11708
12008
  experimental_sandbox: sandbox,
12009
+ experimental_steering: steering,
11709
12010
  experimental_transform,
11710
12011
  onStepEnd: onStepEnd ?? onStepFinish
11711
12012
  });
@@ -11729,6 +12030,7 @@ async function createAgentUIStream({ agent, uiMessages, convertDataPart, options
11729
12030
  * @param abortSignal - Abort signal. Optional.
11730
12031
  * @param timeout - Timeout in milliseconds. Optional.
11731
12032
  * @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
12033
+ * @param experimental_steering - A steering object that adds user messages to the run at the next step boundary. Only supported by `ToolLoopAgent`. Optional.
11732
12034
  * @param options - The options for the agent. Optional.
11733
12035
  * @param experimental_transform - Stream transformations. Optional.
11734
12036
  * @param onStepEnd - Callback that is called when each step ends. Optional.
@@ -11764,6 +12066,7 @@ async function createAgentUIStreamResponse({ headers, status, statusText, keepAl
11764
12066
  * @param abortSignal - Abort signal. Optional.
11765
12067
  * @param timeout - Timeout in milliseconds. Optional.
11766
12068
  * @param experimental_sandbox - The sandbox environment that is passed through to tool execution. Optional.
12069
+ * @param experimental_steering - A steering object that adds user messages to the run at the next step boundary. Only supported by `ToolLoopAgent`. Optional.
11767
12070
  * @param options - The options for the agent. Optional.
11768
12071
  * @param experimental_transform - Stream transformations. Optional.
11769
12072
  * @param onStepEnd - Callback that is called when each step ends. Optional.
@@ -21501,6 +21804,6 @@ async function uploadSkill({ api, files, displayTitle, providerOptions }) {
21501
21804
  });
21502
21805
  }
21503
21806
  //#endregion
21504
- export { AISDKError, AI_SDK_TELEMETRY_TRACING_CHANNEL, APICallError, AbstractChat, DefaultChatTransport, DefaultGeneratedFile, DirectChatTransport, DownloadError, EmptyResponseBodyError, AbstractRealtimeSession as Experimental_AbstractRealtimeSession, ToolLoopAgent as Experimental_Agent, ToolLoopAgent, Experimental_DecisionRefusalError, Experimental_DecisionUnsupportedQuestionTypeError, Experimental_EvaluationUnsupportedQuestionTypeError, HttpChatTransport, InvalidArgumentError, InvalidDataContentError, InvalidMessageRoleError, InvalidPromptError, InvalidResponseDataError, InvalidStreamPartError, InvalidToolApprovalError, InvalidToolApprovalSignatureError, InvalidToolInputError, JSONParseError, JsonToSseTransformStream, LoadAPIKeyError, LoadSettingError, MessageConversionError, MissingToolResultsError, NoContentGeneratedError, NoImageGeneratedError, NoObjectGeneratedError, NoOutputGeneratedError, NoSpeechGeneratedError, NoSuchModelError, NoSuchProviderError, NoSuchProviderReferenceError, NoSuchToolError, NoTranscriptGeneratedError, NoTranslationGeneratedError, NoVideoGeneratedError, output_exports as Output, RetryError, SerialJobExecutor, StreamProviderError, TextStreamChatTransport, TooManyEmbeddingValuesForCallError, ToolCallNotFoundForApprovalError, ToolCallRepairError, ToolChoiceViolationError, TypeValidationError, UIMessageStreamError, UI_MESSAGE_STREAM_HEADERS, UnsupportedFunctionalityError, UnsupportedModelVersionError, WebSocketChatTransport, addToolInputExamplesMiddleware, asSchema, assistantModelMessageSchema, callCompletionApi, consumeStream, convertDataContentToBase64String, convertFileListToFileUIParts, convertToModelMessages, cosineSimilarity, createAgentUIStream, createAgentUIStreamResponse, createDownload, createGateway, createIdGenerator, createProviderRegistry, createTextStreamResponse, createUIMessageStream, createUIMessageStreamResponse, customProvider, defaultEmbeddingSettingsMiddleware, defaultInstructionsMiddleware, defaultSettingsMiddleware, detectToolDrift, dynamicTool, embed, embedMany, cancelBatch as experimental_cancelBatch, experimental_createProviderRegistry, decide as experimental_decide, decodeRealtimeAudio as experimental_decodeRealtimeAudio, encodeRealtimeAudio as experimental_encodeRealtimeAudio, experimental_evaluate, filterActiveTools as experimental_filterActiveTools, experimental_generateSpeech, experimental_generateVideo, getBatchResults as experimental_getBatchResults, getBatchStatus as experimental_getBatchStatus, getRealtimeToolDefinitions as experimental_getRealtimeToolDefinitions, experimental_getVideoStatus, listBatches as experimental_listBatches, resampleAudio as experimental_resampleAudio, startBatch as experimental_startBatch, experimental_startVideo, streamLanguageModelCall as experimental_streamLanguageModelCall, streamSpeech as experimental_streamSpeech, streamTextLowMemory as experimental_streamTextLowMemory, streamTranscribe as experimental_streamTranscribe, streamTranslate as experimental_streamTranslate, experimental_toolCaller, experimental_transcribe, extractJsonMiddleware, extractReasoningMiddleware, fingerprintTools, gateway, generateId, generateImage, generateObject, generateSpeech, generateText, getChunkTimeoutMs, getFirstChunkTimeoutMs, getStaticToolName, getStepTimeoutMs, getTextFromDataUrl, getToolName, getToolOrDynamicToolName, getToolTimeoutMs, getTotalTimeoutMs, hasToolCall, isCustomContentUIPart, isDataUIPart, isDeepEqualData, isDynamicToolUIPart, isFileUIPart, isLoopFinished, isReasoningFileUIPart, isReasoningUIPart, isStaticToolUIPart, isStepCount, isStepCount as stepCountIs, isTextUIPart, isToolOutputErrorUIPart, isToolUIPart, jsonSchema, lastAssistantMessageIsCompleteWithApprovalResponses, lastAssistantMessageIsCompleteWithToolCalls, modelMessageSchema, parseJsonEventStream, parsePartialJson, pipeAgentUIStreamToResponse, pipeTextStreamToResponse, pipeUIMessageStreamToResponse, pruneMessages, readUIMessageStream, registerTelemetry, rerank, safeValidateUIMessages, safeValidateWebSocketChatTransportRequest, simulateReadableStream, simulateStreamingMiddleware, smoothStream, streamObject, streamText, systemModelMessageSchema, toTextStream, toUIMessageChunk, toUIMessageStream, tool, toolModelMessageSchema, toolSearch, transcribe, uiMessageChunkSchema, uploadFile, uploadSkill, userModelMessageSchema, validateUIMessages, wrapEmbeddingModel, wrapImageModel, wrapLanguageModel, wrapProvider, zodSchema };
21807
+ export { AISDKError, AI_SDK_TELEMETRY_TRACING_CHANNEL, APICallError, AbstractChat, DefaultChatTransport, DefaultGeneratedFile, DirectChatTransport, DownloadError, EmptyResponseBodyError, AbstractRealtimeSession as Experimental_AbstractRealtimeSession, ToolLoopAgent as Experimental_Agent, ToolLoopAgent, Experimental_DecisionRefusalError, Experimental_DecisionUnsupportedQuestionTypeError, Experimental_EvaluationUnsupportedQuestionTypeError, HttpChatTransport, InvalidArgumentError, InvalidDataContentError, InvalidMessageRoleError, InvalidPromptError, InvalidResponseDataError, InvalidStreamPartError, InvalidToolApprovalError, InvalidToolApprovalSignatureError, InvalidToolInputError, JSONParseError, JsonToSseTransformStream, LoadAPIKeyError, LoadSettingError, MessageConversionError, MissingToolResultsError, NoContentGeneratedError, NoImageGeneratedError, NoObjectGeneratedError, NoOutputGeneratedError, NoSpeechGeneratedError, NoSuchModelError, NoSuchProviderError, NoSuchProviderReferenceError, NoSuchToolError, NoTranscriptGeneratedError, NoTranslationGeneratedError, NoVideoGeneratedError, output_exports as Output, RetryError, SerialJobExecutor, StreamProviderError, TextStreamChatTransport, TooManyEmbeddingValuesForCallError, ToolCallNotFoundForApprovalError, ToolCallRepairError, ToolChoiceViolationError, TypeValidationError, UIMessageStreamError, UI_MESSAGE_STREAM_HEADERS, UnsupportedFunctionalityError, UnsupportedModelVersionError, WebSocketChatTransport, addToolInputExamplesMiddleware, asSchema, assistantModelMessageSchema, callCompletionApi, consumeStream, convertDataContentToBase64String, convertFileListToFileUIParts, convertToModelMessages, cosineSimilarity, createAgentUIStream, createAgentUIStreamResponse, createDownload, createGateway, createIdGenerator, createProviderRegistry, createTextStreamResponse, createUIMessageStream, createUIMessageStreamResponse, customProvider, defaultEmbeddingSettingsMiddleware, defaultInstructionsMiddleware, defaultSettingsMiddleware, detectToolDrift, dynamicTool, embed, embedMany, cancelBatch as experimental_cancelBatch, experimental_createProviderRegistry, createSteering as experimental_createSteering, decide as experimental_decide, decodeRealtimeAudio as experimental_decodeRealtimeAudio, encodeRealtimeAudio as experimental_encodeRealtimeAudio, experimental_evaluate, filterActiveTools as experimental_filterActiveTools, experimental_generateSpeech, experimental_generateVideo, getBatchResults as experimental_getBatchResults, getBatchStatus as experimental_getBatchStatus, getRealtimeToolDefinitions as experimental_getRealtimeToolDefinitions, experimental_getVideoStatus, listBatches as experimental_listBatches, resampleAudio as experimental_resampleAudio, startBatch as experimental_startBatch, experimental_startVideo, streamLanguageModelCall as experimental_streamLanguageModelCall, streamSpeech as experimental_streamSpeech, streamTextLowMemory as experimental_streamTextLowMemory, streamTranscribe as experimental_streamTranscribe, streamTranslate as experimental_streamTranslate, experimental_toolCaller, experimental_transcribe, extractJsonMiddleware, extractReasoningMiddleware, fingerprintTools, gateway, generateId, generateImage, generateObject, generateSpeech, generateText, getChunkTimeoutMs, getFirstChunkTimeoutMs, getStaticToolName, getStepTimeoutMs, getTextFromDataUrl, getToolName, getToolOrDynamicToolName, getToolTimeoutMs, getTotalTimeoutMs, hasToolCall, isCustomContentUIPart, isDataUIPart, isDeepEqualData, isDynamicToolUIPart, isFileUIPart, isLoopFinished, isReasoningFileUIPart, isReasoningUIPart, isStaticToolUIPart, isStepCount, isStepCount as stepCountIs, isTextUIPart, isToolOutputErrorUIPart, isToolUIPart, jsonSchema, lastAssistantMessageIsCompleteWithApprovalResponses, lastAssistantMessageIsCompleteWithToolCalls, modelMessageSchema, parseJsonEventStream, parsePartialJson, pipeAgentUIStreamToResponse, pipeTextStreamToResponse, pipeUIMessageStreamToResponse, pruneMessages, readUIMessageStream, registerTelemetry, rerank, safeValidateUIMessages, safeValidateWebSocketChatTransportRequest, simulateReadableStream, simulateStreamingMiddleware, smoothStream, streamObject, streamText, systemModelMessageSchema, toTextStream, toUIMessageChunk, toUIMessageStream, tool, toolModelMessageSchema, toolSearch, transcribe, uiMessageChunkSchema, uploadFile, uploadSkill, userModelMessageSchema, validateUIMessages, wrapEmbeddingModel, wrapImageModel, wrapLanguageModel, wrapProvider, zodSchema };
21505
21808
 
21506
21809
  //# sourceMappingURL=index.js.map