@ai-sdk/workflow 2.0.71 → 2.0.73

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/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as normalizeUIMessageStreamParts, t as WorkflowChatTransport } from "./workflow-chat-transport-Dj1poviu.js";
2
- import { asArray, asSchema, convertUint8ArrayToBase64, createIdGenerator, generateId, getErrorMessage, isAbortError, jsonSchema, validateTypes, withUserAgentSuffix } from "@ai-sdk/provider-utils";
3
- import { DefaultGeneratedFile, InvalidToolApprovalSignatureError, NoOutputGeneratedError, Output, ToolChoiceViolationError, dynamicTool, experimental_filterActiveTools, experimental_streamLanguageModelCall, gateway, isStepCount, tool, wrapLanguageModel } from "ai";
4
- import { DefaultGenerateTextResult, DefaultStepResult, addLanguageModelUsage, asLanguageModelUsage, calculateTokensPerSecond, collectToolApprovals, convertLanguageModelContent, convertToLanguageModelPrompt, createDefaultDownloadFunction, createNullLanguageModelUsage, createRestrictedTelemetryDispatcher, createTelemetryDispatcher, createToolModelOutput, createToolSearchState, downloadAssets, isOutputChunk, mapToolResultOutput, mergeAbortSignals, mergeCallbacks, parseToolCall, prepareLanguageModelCallOptions, prepareRetries, prepareToolChoice, prepareTools, resolveLanguageModel, signToolApproval, standardizePrompt, validateApprovedToolApprovals, verifyToolApprovalSignature } from "ai/internal";
2
+ import { asArray, asSchema, convertUint8ArrayToBase64, createIdGenerator, generateId, getErrorMessage, isAbortError, jsonSchema, safeParseJSON, validateTypes, withUserAgentSuffix } from "@ai-sdk/provider-utils";
3
+ import { DefaultGeneratedFile, InvalidToolApprovalSignatureError, InvalidToolInputError, NoOutputGeneratedError, Output, ToolChoiceViolationError, dynamicTool, experimental_filterActiveTools, experimental_streamLanguageModelCall, gateway, isDeepEqualData, isStepCount, tool, wrapLanguageModel } from "ai";
4
+ import { DefaultGenerateTextResult, DefaultStepResult, addLanguageModelUsage, asLanguageModelUsage, calculateTokensPerSecond, collectToolApprovals, convertLanguageModelContent, convertToLanguageModelPrompt, createDefaultDownloadFunction, createNullLanguageModelUsage, createRestrictedTelemetryDispatcher, createTelemetryDispatcher, createToolModelOutput, createToolSearchState, downloadAssets, filterIncludedContext, isOutputChunk, mapToolResultOutput, mapWithConcurrency, mergeAbortSignals, mergeCallbacks, parseToolCall, prepareLanguageModelCallOptions, prepareRetries, prepareToolCallConcurrency, prepareToolChoice, prepareTools, resolveLanguageModel, signToolApproval, standardizePrompt, validateApprovedToolApprovals, verifyToolApprovalSignature } from "ai/internal";
5
5
  import { getWorkflowMetadata } from "workflow";
6
6
  import Ajv from "ajv";
7
7
  import Ajv2020 from "ajv/dist/2020.js";
@@ -143,9 +143,9 @@ async function buildModelStepResult(raw, toolCalls, finish, providerExecutedTool
143
143
  if (!("reasoningIndex" in part)) providerContent.push(part);
144
144
  break;
145
145
  case "tool-call": {
146
- const call = toolCalls[part.toolCallIndex];
146
+ const { inputSchemaInput: _inputSchemaInput, ...publicCall } = toolCalls[part.toolCallIndex];
147
147
  providerContent.push({
148
- ...call,
148
+ ...publicCall,
149
149
  input: "",
150
150
  type: "tool-call"
151
151
  });
@@ -410,6 +410,7 @@ function languageModelPromptToModelMessages(prompt) {
410
410
  */
411
411
  function serializeToolSet(tools, { toolsContext = {}, experimental_sandbox: sandbox } = {}) {
412
412
  return Object.fromEntries(Object.entries(tools).map(([name, t]) => {
413
+ const inputSchema = asSchema(t.inputSchema);
413
414
  const def = {
414
415
  title: t.title,
415
416
  metadata: t.metadata,
@@ -419,11 +420,12 @@ function serializeToolSet(tools, { toolsContext = {}, experimental_sandbox: sand
419
420
  toolsContext,
420
421
  experimental_sandbox: sandbox
421
422
  }),
422
- inputSchema: asSchema(t.inputSchema).jsonSchema,
423
+ inputSchema: inputSchema.jsonSchema,
423
424
  strict: t.strict,
424
425
  inputExamples: t.inputExamples,
425
426
  providerOptions: t.providerOptions
426
427
  };
428
+ if (inputSchema.validate != null) def.hasOwnValidator = true;
427
429
  if (t.type === "dynamic") def.type = "dynamic";
428
430
  if (t.onInputStart != null) def.hasOnInputStart = true;
429
431
  if (t.onInputDelta != null) def.hasOnInputDelta = true;
@@ -457,9 +459,9 @@ function formatAjvError(error) {
457
459
  /**
458
460
  * Reconstructs tool objects from serializable tool definitions inside a step.
459
461
  *
460
- * Wraps each tool's JSON Schema with `jsonSchema()` and validates tool call
461
- * arguments against the schema using Ajv. This provides runtime type safety
462
- * equivalent to using zod schemas directly with the AI SDK.
462
+ * Wraps each tool's JSON Schema with `jsonSchema()`. Tools without their own
463
+ * validator are validated with Ajv. Tools with their own validator are
464
+ * validated after the workflow step, where the original schema is available.
463
465
  */
464
466
  function resolveSerializableTools(tools) {
465
467
  const ajvOptions = {
@@ -482,6 +484,7 @@ function resolveSerializableTools(tools) {
482
484
  };
483
485
  } });
484
486
  };
487
+ const createInputSchema = (tool) => tool.hasOwnValidator ? jsonSchema(tool.inputSchema) : createValidatedInputSchema(tool.inputSchema);
485
488
  return Object.fromEntries(Object.entries(tools).map(([name, t]) => {
486
489
  if (t.type === "provider") {
487
490
  const providerTool = {
@@ -506,7 +509,7 @@ function resolveSerializableTools(tools) {
506
509
  description: t.description,
507
510
  inputExamples: t.inputExamples,
508
511
  providerOptions: t.providerOptions,
509
- inputSchema: createValidatedInputSchema(t.inputSchema)
512
+ inputSchema: createInputSchema(t)
510
513
  })];
511
514
  const functionTool = {
512
515
  title: t.title,
@@ -515,7 +518,7 @@ function resolveSerializableTools(tools) {
515
518
  strict: t.strict,
516
519
  inputExamples: t.inputExamples,
517
520
  providerOptions: t.providerOptions,
518
- inputSchema: createValidatedInputSchema(t.inputSchema)
521
+ inputSchema: createInputSchema(t)
519
522
  };
520
523
  return [name, t.type === "dynamic" ? tool({
521
524
  ...functionTool,
@@ -573,7 +576,7 @@ async function runModelCallWithTelemetry({ telemetry, modelInit, prompt, seriali
573
576
  reasoning: options?.reasoning,
574
577
  providerOptions: options?.providerOptions,
575
578
  output: void 0,
576
- runtimeContext: {},
579
+ runtimeContext: telemetry.runtimeContext ?? {},
577
580
  toolsContext: {}
578
581
  });
579
582
  await dispatcher.onStepStart?.({
@@ -589,7 +592,7 @@ async function runModelCallWithTelemetry({ telemetry, modelInit, prompt, seriali
589
592
  steps: [],
590
593
  providerOptions: options?.providerOptions,
591
594
  output: void 0,
592
- runtimeContext: {},
595
+ runtimeContext: telemetry.runtimeContext ?? {},
593
596
  toolsContext: {}
594
597
  });
595
598
  let result;
@@ -625,7 +628,7 @@ async function runModelCallWithTelemetry({ telemetry, modelInit, prompt, seriali
625
628
  callId,
626
629
  tools,
627
630
  stepNumber: telemetry.stepNumber,
628
- runtimeContext: {},
631
+ runtimeContext: telemetry.runtimeContext ?? {},
629
632
  toolsContext: {}
630
633
  });
631
634
  await dispatcher.onStepEnd?.(step);
@@ -733,10 +736,17 @@ async function generateModelCall(prompt, modelInit, serializedTools, options, la
733
736
  performance: { responseTimeMs }
734
737
  });
735
738
  abortSignal?.throwIfAborted();
739
+ const repairedToolCallIds = /* @__PURE__ */ new Set();
740
+ const repairToolCall = options.repairToolCall;
741
+ const trackedRepairToolCall = repairToolCall ? async (repairOptions) => {
742
+ const repaired = await repairToolCall(repairOptions);
743
+ if (repaired != null) repairedToolCallIds.add(repairOptions.toolCall.toolCallId);
744
+ return repaired;
745
+ } : void 0;
736
746
  const toolCalls = await Promise.all(response.content.filter((part) => part.type === "tool-call").map((toolCall) => parseToolCall({
737
747
  toolCall,
738
748
  tools,
739
- repairToolCall: options.repairToolCall,
749
+ repairToolCall: trackedRepairToolCall,
740
750
  instructions: modelPrompt.filter((message) => message.role === "system").map((message) => message.content).join("\n") || void 0,
741
751
  messages: prompt.filter((message) => message.role !== "system")
742
752
  })));
@@ -808,7 +818,8 @@ async function generateModelCall(prompt, modelInit, serializedTools, options, la
808
818
  }
809
819
  },
810
820
  providerExecutedToolResults,
811
- toolInputLifecycleEvents
821
+ toolInputLifecycleEvents,
822
+ repairedToolCallIds: [...repairedToolCallIds]
812
823
  };
813
824
  }
814
825
  doGenerateStep.maxRetries = 0;
@@ -832,6 +843,13 @@ async function streamModelStep(conversationPrompt, modelInit, writable, serializ
832
843
  const abortSignal = timeout == null ? options?.abortSignal : options?.abortSignal == null ? AbortSignal.timeout(timeout) : AbortSignal.any([options.abortSignal, AbortSignal.timeout(timeout)]);
833
844
  const model = typeof modelInit === "string" ? gateway.languageModel(modelInit) : modelInit;
834
845
  const toolInputLifecycleEvents = [];
846
+ const repairedToolCallIds = /* @__PURE__ */ new Set();
847
+ const repairToolCall = options?.repairToolCall;
848
+ const trackedRepairToolCall = repairToolCall ? async (repairOptions) => {
849
+ const repaired = await repairToolCall(repairOptions);
850
+ if (repaired != null) repairedToolCallIds.add(repairOptions.toolCall.toolCallId);
851
+ return repaired;
852
+ } : void 0;
835
853
  const tools = serializedTools ? resolveSerializableTools(serializedTools) : void 0;
836
854
  const modelWithTransforms = options?.experimental_transform == null ? model : wrapLanguageModel({
837
855
  model,
@@ -885,7 +903,7 @@ async function streamModelStep(conversationPrompt, modelInit, writable, serializ
885
903
  frequencyPenalty: options?.frequencyPenalty,
886
904
  stopSequences: options?.stopSequences,
887
905
  seed: options?.seed,
888
- repairToolCall: options?.repairToolCall,
906
+ repairToolCall: trackedRepairToolCall,
889
907
  download: options?.download,
890
908
  ...languageModelCallTelemetry
891
909
  }));
@@ -1086,7 +1104,7 @@ async function streamModelStep(conversationPrompt, modelInit, writable, serializ
1086
1104
  toolCallId: part.toolCall.toolCallId,
1087
1105
  ...part.signature != null ? { signature: part.signature } : {}
1088
1106
  });
1089
- else await writer.write(part);
1107
+ else if (!((part.type === "tool-call" || part.type === "tool-error" && !part.providerExecuted) && serializedTools?.[part.toolName]?.hasOwnValidator)) await writer.write(part);
1090
1108
  }
1091
1109
  if (part.type === "error" && !hasTerminalError) {
1092
1110
  terminalError = part.error;
@@ -1116,6 +1134,7 @@ async function streamModelStep(conversationPrompt, modelInit, writable, serializ
1116
1134
  },
1117
1135
  providerExecutedToolResults,
1118
1136
  toolInputLifecycleEvents,
1137
+ repairedToolCallIds: [...repairedToolCallIds],
1119
1138
  ...hasTerminalError ? { terminalError } : {}
1120
1139
  };
1121
1140
  }
@@ -1343,7 +1362,12 @@ async function* modelCallIterator({ prompt, mode = "stream", include, initialIns
1343
1362
  functionId: telemetry?.functionId,
1344
1363
  recordInputs: telemetry?.recordInputs,
1345
1364
  recordOutputs: telemetry?.recordOutputs,
1346
- stepNumber
1365
+ stepNumber,
1366
+ includeRuntimeContext: telemetry?.includeRuntimeContext,
1367
+ runtimeContext: filterIncludedContext({
1368
+ context: currentRuntimeContext,
1369
+ includeContext: telemetry?.includeRuntimeContext
1370
+ })
1347
1371
  } : void 0
1348
1372
  };
1349
1373
  const modelCallResult = mode === "generate" ? await doGenerateStep(conversationPrompt, currentModel, serializedTools, callOptions) : await doStreamStep(conversationPrompt, currentModel, writable, serializedTools, callOptions);
@@ -1356,7 +1380,18 @@ async function* modelCallIterator({ prompt, mode = "stream", include, initialIns
1356
1380
  terminalError = modelCallResult.terminalError;
1357
1381
  hasTerminalError = true;
1358
1382
  }
1359
- const { toolCalls, finish, raw, providerExecutedToolResults, toolInputLifecycleEvents } = modelCallResult;
1383
+ const { toolCalls: serializedToolCalls, finish, raw, providerExecutedToolResults, toolInputLifecycleEvents, repairedToolCallIds } = modelCallResult;
1384
+ const toolCalls = await validateToolCallInputs({
1385
+ toolCalls: serializedToolCalls,
1386
+ tools: effectiveTools,
1387
+ serializedTools,
1388
+ repairToolCall,
1389
+ repairedToolCallIds: new Set(repairedToolCallIds),
1390
+ instructions: conversationPrompt.filter((message) => message.role === "system").map((message) => message.content).join("\n") || initialInstructions,
1391
+ messages: stepInputMessages.filter((message) => message.role !== "system"),
1392
+ abortSignal: currentGenerationSettings.abortSignal
1393
+ });
1394
+ if (mode === "stream" && writable != null) await writeDeferredToolCalls(writable, toolCalls.filter((_, index) => serializedTools[serializedToolCalls[index].toolName]?.hasOwnValidator));
1360
1395
  await invokeToolInputLifecycleCallbacks({
1361
1396
  events: toolInputLifecycleEvents ?? [],
1362
1397
  toolCalls,
@@ -1460,6 +1495,100 @@ async function* modelCallIterator({ prompt, mode = "stream", include, initialIns
1460
1495
  };
1461
1496
  return conversationPrompt;
1462
1497
  }
1498
+ async function validateToolCallInputs({ toolCalls, tools, serializedTools, repairToolCall, repairedToolCallIds, instructions, messages, abortSignal }) {
1499
+ return Promise.all(toolCalls.map(async (toolCall) => {
1500
+ if (toolCall.invalid || toolCall.providerExecuted) return toolCall;
1501
+ const tool = tools[toolCall.toolName];
1502
+ if (tool == null) return toolCall;
1503
+ if (asSchema(tool.inputSchema).validate == null) return toolCall;
1504
+ let repairedInput;
1505
+ const parsedToolCall = await parseToolCall({
1506
+ toolCall: {
1507
+ type: "tool-call",
1508
+ toolCallId: toolCall.toolCallId,
1509
+ toolName: toolCall.toolName,
1510
+ input: JSON.stringify(toolCall.input) ?? (toolCall.input == null ? "" : String(toolCall.input)),
1511
+ providerExecuted: toolCall.providerExecuted,
1512
+ providerMetadata: toolCall.providerMetadata
1513
+ },
1514
+ tools,
1515
+ repairToolCall: repairToolCall == null || repairedToolCallIds.has(toolCall.toolCallId) ? void 0 : async (options) => {
1516
+ const repairedToolCall = await repairToolCallInStep({
1517
+ repairToolCall,
1518
+ serializedTools,
1519
+ toolCall: options.toolCall,
1520
+ error: {
1521
+ toolName: options.toolCall.toolName,
1522
+ toolInput: options.toolCall.input,
1523
+ message: getErrorMessage(options.error)
1524
+ },
1525
+ instructions,
1526
+ messages: options.messages
1527
+ });
1528
+ if (repairedToolCall != null) {
1529
+ const parsedRepairedInput = repairedToolCall.input.trim() === "" ? {
1530
+ success: true,
1531
+ value: {}
1532
+ } : await safeParseJSON({ text: repairedToolCall.input });
1533
+ if (parsedRepairedInput.success) repairedInput = { value: parsedRepairedInput.value };
1534
+ }
1535
+ return repairedToolCall;
1536
+ },
1537
+ instructions,
1538
+ messages,
1539
+ abortSignal
1540
+ });
1541
+ const inputSchemaInput = repairedInput ?? { value: toolCall.input };
1542
+ return {
1543
+ ...toolCall,
1544
+ ...parsedToolCall,
1545
+ ...!parsedToolCall.invalid && !isDeepEqualData(inputSchemaInput.value, parsedToolCall.input) ? { inputSchemaInput: inputSchemaInput.value } : {}
1546
+ };
1547
+ }));
1548
+ }
1549
+ /**
1550
+ * Runs `repairToolCall` inside a step. The callback may be a `'use step'`
1551
+ * function, so its arguments must be serializable: the tools and the
1552
+ * `inputSchema` accessor are rebuilt here instead of crossing the boundary
1553
+ * from the workflow body.
1554
+ */
1555
+ async function repairToolCallInStep({ repairToolCall, serializedTools, toolCall, error, instructions, messages }) {
1556
+ "use step";
1557
+ const tools = resolveSerializableTools(serializedTools);
1558
+ return repairToolCall({
1559
+ toolCall,
1560
+ tools,
1561
+ inputSchema: async ({ toolName }) => asSchema(tools[toolName]?.inputSchema).jsonSchema,
1562
+ instructions,
1563
+ system: instructions,
1564
+ messages,
1565
+ error: new InvalidToolInputError({
1566
+ toolName: error.toolName,
1567
+ toolInput: error.toolInput,
1568
+ cause: new Error(error.message),
1569
+ message: error.message
1570
+ })
1571
+ });
1572
+ }
1573
+ async function writeDeferredToolCalls(writable, toolCalls) {
1574
+ "use step";
1575
+ const writer = writable.getWriter();
1576
+ try {
1577
+ for (const toolCall of toolCalls) {
1578
+ await writer.write(toolCall);
1579
+ if (toolCall.invalid && !toolCall.providerExecuted) await writer.write({
1580
+ type: "tool-error",
1581
+ toolCallId: toolCall.toolCallId,
1582
+ toolName: toolCall.toolName,
1583
+ input: toolCall.input,
1584
+ error: getErrorMessage(toolCall.error),
1585
+ dynamic: true
1586
+ });
1587
+ }
1588
+ } finally {
1589
+ writer.releaseLock();
1590
+ }
1591
+ }
1463
1592
  async function invokeToolInputLifecycleCallbacks({ events, toolCalls, tools, messages, abortSignal, toolsContext, experimental_sandbox }) {
1464
1593
  const toolNamesByCallId = /* @__PURE__ */ new Map();
1465
1594
  const toolCallsById = new Map(toolCalls.map((toolCall) => [toolCall.toolCallId, toolCall]));
@@ -1499,7 +1628,7 @@ async function invokeToolInputLifecycleCallbacks({ events, toolCalls, tools, mes
1499
1628
  break;
1500
1629
  case "available": {
1501
1630
  const toolCall = toolCallsById.get(toolCallId);
1502
- if (toolCall == null) break;
1631
+ if (toolCall == null || toolCall.invalid) break;
1503
1632
  await tool.onInputAvailable?.({
1504
1633
  ...options,
1505
1634
  input: toolCall.input
@@ -1686,6 +1815,7 @@ var WorkflowAgent = class {
1686
1815
  this.tools = options.tools ?? {};
1687
1816
  this.instructions = options.instructions ?? options.system;
1688
1817
  this.toolChoice = options.toolChoice;
1818
+ this.toolCallConcurrency = options.toolCallConcurrency;
1689
1819
  this.telemetry = options.telemetry;
1690
1820
  this.runtimeContext = options.runtimeContext;
1691
1821
  this.toolsContext = options.toolsContext;
@@ -1759,6 +1889,7 @@ var WorkflowAgent = class {
1759
1889
  let effectiveRuntimeContext = options.runtimeContext ?? this.runtimeContext ?? {};
1760
1890
  let effectiveToolsContext = options.toolsContext ?? this.toolsContext ?? {};
1761
1891
  let effectiveToolChoiceFromPrepare = options.toolChoice ?? this.toolChoice;
1892
+ let effectiveToolCallConcurrency = options.toolCallConcurrency ?? this.toolCallConcurrency;
1762
1893
  let effectiveStopWhenFromPrepare = options.stopWhen ?? this.stopWhen ?? (mode === "generate" ? isStepCount(20) : void 0);
1763
1894
  let effectiveActiveToolsFromPrepare = options.activeTools ?? this.activeTools;
1764
1895
  let effectiveDownloadFromPrepare = options.experimental_download ?? this.experimentalDownload;
@@ -1774,6 +1905,7 @@ var WorkflowAgent = class {
1774
1905
  tools: this.tools,
1775
1906
  instructions: effectiveInstructions,
1776
1907
  toolChoice: effectiveToolChoiceFromPrepare,
1908
+ toolCallConcurrency: effectiveToolCallConcurrency,
1777
1909
  stopWhen: effectiveStopWhenFromPrepare,
1778
1910
  activeTools: effectiveActiveToolsFromPrepare,
1779
1911
  experimental_download: effectiveDownloadFromPrepare,
@@ -1792,6 +1924,7 @@ var WorkflowAgent = class {
1792
1924
  if (prepared.runtimeContext !== void 0) effectiveRuntimeContext = prepared.runtimeContext;
1793
1925
  if (prepared.toolsContext !== void 0) effectiveToolsContext = prepared.toolsContext;
1794
1926
  if (prepared.toolChoice !== void 0) effectiveToolChoiceFromPrepare = prepared.toolChoice;
1927
+ if (prepared.toolCallConcurrency !== void 0) effectiveToolCallConcurrency = prepared.toolCallConcurrency;
1795
1928
  if (prepared.stopWhen !== void 0) effectiveStopWhenFromPrepare = prepared.stopWhen;
1796
1929
  if (prepared.activeTools !== void 0) effectiveActiveToolsFromPrepare = prepared.activeTools;
1797
1930
  if (prepared.experimental_download !== void 0) effectiveDownloadFromPrepare = prepared.experimental_download;
@@ -1810,6 +1943,7 @@ var WorkflowAgent = class {
1810
1943
  if (prepared.reasoning !== void 0) effectiveGenerationSettings.reasoning = prepared.reasoning;
1811
1944
  if (prepared.providerOptions !== void 0) effectiveGenerationSettings.providerOptions = prepared.providerOptions;
1812
1945
  }
1946
+ const toolCallConcurrency = prepareToolCallConcurrency(options.toolCallConcurrency ?? effectiveToolCallConcurrency);
1813
1947
  const effectiveTelemetry = effectiveTelemetryFromPrepare;
1814
1948
  const telemetryDispatcher = createRestrictedTelemetryDispatcher({
1815
1949
  telemetry: effectiveTelemetry,
@@ -1836,6 +1970,7 @@ var WorkflowAgent = class {
1836
1970
  effectiveRuntimeContext,
1837
1971
  effectiveToolsContext,
1838
1972
  effectiveToolChoiceFromPrepare,
1973
+ toolCallConcurrency,
1839
1974
  effectiveStopWhenFromPrepare,
1840
1975
  effectiveActiveToolsFromPrepare,
1841
1976
  effectiveToolApprovalSecret,
@@ -1852,7 +1987,7 @@ var WorkflowAgent = class {
1852
1987
  };
1853
1988
  }
1854
1989
  async execute(options, mode = "stream") {
1855
- const { onEnd, effectiveModel, effectiveInstructions, effectiveGenerationSettings, effectiveRuntimeContext, effectiveToolsContext, effectiveToolChoiceFromPrepare, effectiveStopWhenFromPrepare, effectiveActiveToolsFromPrepare, effectiveToolApprovalSecret, effectiveTelemetry, telemetryDispatcher, prompt, download, workflowDownload, sandbox, effectiveAbortSignal, timeoutAt, mergedOnToolExecutionStart, mergedOnToolExecutionEnd } = await this.prepareInvocation(options, mode);
1990
+ const { onEnd, effectiveModel, effectiveInstructions, effectiveGenerationSettings, effectiveRuntimeContext, effectiveToolsContext, effectiveToolChoiceFromPrepare, toolCallConcurrency, effectiveStopWhenFromPrepare, effectiveActiveToolsFromPrepare, effectiveToolApprovalSecret, effectiveTelemetry, telemetryDispatcher, prompt, download, workflowDownload, sandbox, effectiveAbortSignal, timeoutAt, mergedOnToolExecutionStart, mergedOnToolExecutionEnd } = await this.prepareInvocation(options, mode);
1856
1991
  const initialResponseMessages = [];
1857
1992
  const abortReason = () => effectiveAbortSignal?.reason === void 0 ? void 0 : { value: effectiveAbortSignal.reason };
1858
1993
  const collectedApprovals = collectToolApprovals({ messages: prompt.messages });
@@ -1876,13 +2011,55 @@ var WorkflowAgent = class {
1876
2011
  if (approvedToolApprovals.length > 0 || deniedToolApprovals.length > 0) {
1877
2012
  const toolResultContent = [];
1878
2013
  const approvedRawResults = [];
1879
- for (const approval of approvedToolApprovals) {
1880
- if (approval.providerExecuted) continue;
1881
- const tool = this.tools[approval.toolName];
1882
- if (tool && typeof tool.execute === "function") {
1883
- if (!tool.needsApproval) {
1884
- const reason = `Tool "${approval.toolName}" does not require approval`;
1885
- toolResultContent.push({
2014
+ const approvedResults = await mapWithConcurrency({
2015
+ items: approvedToolApprovals.filter((approval) => !approval.providerExecuted),
2016
+ concurrency: toolCallConcurrency,
2017
+ abortSignal: effectiveAbortSignal,
2018
+ execute: async (approval) => {
2019
+ const tool = this.tools[approval.toolName];
2020
+ if (tool && typeof tool.execute === "function") {
2021
+ if (!tool.needsApproval) {
2022
+ const reason = `Tool "${approval.toolName}" does not require approval`;
2023
+ return { modelResult: {
2024
+ type: "tool-result",
2025
+ toolCallId: approval.toolCallId,
2026
+ toolName: approval.toolName,
2027
+ output: await createLanguageModelToolResultOutput({
2028
+ toolCallId: approval.toolCallId,
2029
+ toolName: approval.toolName,
2030
+ input: approval.input,
2031
+ output: reason,
2032
+ tool,
2033
+ errorMode: "text",
2034
+ supportedUrls: {},
2035
+ download: workflowDownload
2036
+ })
2037
+ } };
2038
+ }
2039
+ let revalidationReason;
2040
+ try {
2041
+ await validateWorkflowToolApprovalSignature({
2042
+ secret: effectiveToolApprovalSecret,
2043
+ approvalId: approval.collected.approvalRequest.approvalId,
2044
+ toolCallId: approval.toolCallId,
2045
+ toolName: approval.toolName,
2046
+ input: approval.input,
2047
+ signature: approval.collected.approvalRequest.signature
2048
+ });
2049
+ const { deniedToolApprovals: policyDenied, invalidToolApprovals } = await validateApprovedToolApprovals({
2050
+ approvedToolApprovals: [approval.collected],
2051
+ tools: this.tools,
2052
+ toolApproval: void 0,
2053
+ messages: prompt.messages,
2054
+ toolsContext: effectiveToolsContext,
2055
+ runtimeContext: effectiveRuntimeContext
2056
+ });
2057
+ if (invalidToolApprovals.length > 0) revalidationReason = getErrorMessage(invalidToolApprovals[0].error);
2058
+ else if (policyDenied.length > 0) revalidationReason = policyDenied[0].approvalResponse.reason ?? "Tool approval denied";
2059
+ } catch (error) {
2060
+ revalidationReason = getErrorMessage(error);
2061
+ }
2062
+ if (revalidationReason != null) return { modelResult: {
1886
2063
  type: "tool-result",
1887
2064
  toolCallId: approval.toolCallId,
1888
2065
  toolName: approval.toolName,
@@ -1890,69 +2067,34 @@ var WorkflowAgent = class {
1890
2067
  toolCallId: approval.toolCallId,
1891
2068
  toolName: approval.toolName,
1892
2069
  input: approval.input,
1893
- output: reason,
2070
+ output: revalidationReason,
1894
2071
  tool,
1895
2072
  errorMode: "text",
1896
2073
  supportedUrls: {},
1897
2074
  download: workflowDownload
1898
2075
  })
1899
- });
1900
- continue;
1901
- }
1902
- let revalidationReason;
1903
- try {
1904
- await validateWorkflowToolApprovalSignature({
1905
- secret: effectiveToolApprovalSecret,
1906
- approvalId: approval.collected.approvalRequest.approvalId,
1907
- toolCallId: approval.toolCallId,
1908
- toolName: approval.toolName,
1909
- input: approval.input,
1910
- signature: approval.collected.approvalRequest.signature
1911
- });
1912
- const { deniedToolApprovals: policyDenied, invalidToolApprovals } = await validateApprovedToolApprovals({
1913
- approvedToolApprovals: [approval.collected],
1914
- tools: this.tools,
1915
- toolApproval: void 0,
1916
- messages: prompt.messages,
1917
- toolsContext: effectiveToolsContext,
1918
- runtimeContext: effectiveRuntimeContext
1919
- });
1920
- if (invalidToolApprovals.length > 0) revalidationReason = getErrorMessage(invalidToolApprovals[0].error);
1921
- else if (policyDenied.length > 0) revalidationReason = policyDenied[0].approvalResponse.reason ?? "Tool approval denied";
1922
- } catch (error) {
1923
- revalidationReason = getErrorMessage(error);
1924
- }
1925
- if (revalidationReason != null) {
1926
- toolResultContent.push({
1927
- type: "tool-result",
2076
+ } };
2077
+ const result = await executeToolWithCallbacks({
1928
2078
  toolCallId: approval.toolCallId,
1929
2079
  toolName: approval.toolName,
1930
- output: await createLanguageModelToolResultOutput({
2080
+ input: approval.input
2081
+ }, this.tools, prompt.messages, effectiveToolsContext, 0, sandbox);
2082
+ return {
2083
+ modelResult: result.modelResult,
2084
+ rawResult: {
1931
2085
  toolCallId: approval.toolCallId,
1932
2086
  toolName: approval.toolName,
1933
2087
  input: approval.input,
1934
- output: revalidationReason,
1935
- tool,
1936
- errorMode: "text",
1937
- supportedUrls: {},
1938
- download: workflowDownload
1939
- })
1940
- });
1941
- continue;
2088
+ output: result.rawOutput
2089
+ }
2090
+ };
1942
2091
  }
1943
- const result = await executeToolWithCallbacks({
1944
- toolCallId: approval.toolCallId,
1945
- toolName: approval.toolName,
1946
- input: approval.input
1947
- }, this.tools, prompt.messages, effectiveToolsContext, 0, sandbox);
1948
- toolResultContent.push(result.modelResult);
1949
- approvedRawResults.push({
1950
- toolCallId: approval.toolCallId,
1951
- toolName: approval.toolName,
1952
- input: approval.input,
1953
- output: result.rawOutput
1954
- });
1955
2092
  }
2093
+ });
2094
+ for (const result of approvedResults) {
2095
+ if (result == null) continue;
2096
+ toolResultContent.push(result.modelResult);
2097
+ if (result.rawResult != null) approvedRawResults.push(result.rawResult);
1956
2098
  }
1957
2099
  for (const denial of deniedToolApprovals) {
1958
2100
  if (denial.providerExecuted || denial.existingToolResult !== void 0) continue;
@@ -2309,7 +2451,12 @@ var WorkflowAgent = class {
2309
2451
  });
2310
2452
  const providerApprovalRequests = step?.content.filter((part) => part.type === "tool-approval-request").filter((part) => part.toolCall.providerExecuted) ?? [];
2311
2453
  if (pausedToolCalls.length > 0 || providerApprovalRequests.length > 0) {
2312
- const executableResults = await Promise.all(executableToolCalls.map((toolCall) => executeToolWithCallbacks(toolCall, stepTools, iterMessages, toolsContext, currentStepNumber, toolExecutionSandbox)));
2454
+ const executableResults = await mapWithConcurrency({
2455
+ items: executableToolCalls,
2456
+ concurrency: toolCallConcurrency,
2457
+ abortSignal: effectiveAbortSignal,
2458
+ execute: (toolCall) => executeToolWithCallbacks(toolCall, stepTools, iterMessages, toolsContext, currentStepNumber, toolExecutionSandbox)
2459
+ });
2313
2460
  const providerResultEntries = await Promise.all(providerToolCallsForResults.filter((call) => !providerApprovalRequests.some((request) => request.toolCall.toolCallId === call.toolCallId)).map(async (toolCall) => ({
2314
2461
  toolCall,
2315
2462
  result: await resolveProviderToolResult(toolCall, capturedProviderToolResults, stepTools, workflowDownload)
@@ -2339,6 +2486,7 @@ var WorkflowAgent = class {
2339
2486
  addToolResultsToStep(step, executedResults, mode);
2340
2487
  const approvalToolCalls = pausedToolCalls.filter((tc) => approvalNeeded[nonProviderToolCalls.indexOf(tc)]);
2341
2488
  const approvalRequests = await Promise.all(approvalToolCalls.map(async (tc) => {
2489
+ const { inputSchemaInput, ...toolCallWithoutInputSchemaInput } = tc;
2342
2490
  const approvalId = `approval-${tc.toolCallId}`;
2343
2491
  const signature = effectiveToolApprovalSecret == null ? void 0 : await signWorkflowToolApproval({
2344
2492
  secret: effectiveToolApprovalSecret,
@@ -2350,14 +2498,15 @@ var WorkflowAgent = class {
2350
2498
  return {
2351
2499
  type: "tool-approval-request",
2352
2500
  approvalId,
2501
+ ...inputSchemaInput !== void 0 ? { inputSchemaInput } : {},
2353
2502
  toolCall: {
2354
- ...tc,
2503
+ ...toolCallWithoutInputSchemaInput,
2355
2504
  type: "tool-call"
2356
2505
  },
2357
2506
  ...signature != null ? { signature } : {}
2358
2507
  };
2359
2508
  }));
2360
- step?.content.push(...approvalRequests);
2509
+ step?.content.push(...approvalRequests.map(({ inputSchemaInput: _inputSchemaInput, ...request }) => request));
2361
2510
  const approvalMessages = approvalRequests.map(({ toolCall, ...request }) => ({
2362
2511
  ...request,
2363
2512
  toolCallId: toolCall.toolCallId
@@ -2407,7 +2556,12 @@ var WorkflowAgent = class {
2407
2556
  initialResponseMessages
2408
2557
  };
2409
2558
  }
2410
- const clientToolResults = await Promise.all(nonProviderToolCalls.map((toolCall) => executeToolWithCallbacks(toolCall, stepTools, iterMessages, toolsContext, currentStepNumber, toolExecutionSandbox)));
2559
+ const clientToolResults = await mapWithConcurrency({
2560
+ items: nonProviderToolCalls,
2561
+ concurrency: toolCallConcurrency,
2562
+ abortSignal: effectiveAbortSignal,
2563
+ execute: (toolCall) => executeToolWithCallbacks(toolCall, stepTools, iterMessages, toolsContext, currentStepNumber, toolExecutionSandbox)
2564
+ });
2411
2565
  const providerToolResultEntries = await Promise.all(providerToolCallsForResults.map(async (toolCall) => ({
2412
2566
  toolCall,
2413
2567
  result: await resolveProviderToolResult(toolCall, capturedProviderToolResults, stepTools, workflowDownload)
@@ -2621,7 +2775,8 @@ async function writeApprovalRequests(writable, approvalRequests) {
2621
2775
  type: "tool-approval-request",
2622
2776
  approvalId: request.approvalId,
2623
2777
  toolCallId: request.toolCallId,
2624
- ...request.signature != null ? { signature: request.signature } : {}
2778
+ ...request.signature != null ? { signature: request.signature } : {},
2779
+ ...request.inputSchemaInput !== void 0 ? { inputSchemaInput: request.inputSchemaInput } : {}
2625
2780
  });
2626
2781
  } finally {
2627
2782
  writer.releaseLock();
@@ -3000,6 +3155,7 @@ function toUIMessageChunk(part) {
3000
3155
  type: "tool-approval-request",
3001
3156
  approvalId: part.approvalId,
3002
3157
  toolCallId: "toolCallId" in part ? part.toolCallId : part.toolCall.toolCallId,
3158
+ ..."inputSchemaInput" in part && part.inputSchemaInput !== void 0 ? { inputSchemaInput: part.inputSchemaInput } : {},
3003
3159
  ...part.signature != null ? { signature: part.signature } : {}
3004
3160
  };
3005
3161
  default: {