@ai-sdk/workflow 1.0.0-beta.9 → 1.0.0-beta.95

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.mjs CHANGED
@@ -1,19 +1,82 @@
1
1
  // src/workflow-agent.ts
2
2
  import {
3
- Output
3
+ getErrorMessage,
4
+ validateTypes
5
+ } from "@ai-sdk/provider-utils";
6
+ import {
7
+ Output,
8
+ experimental_filterActiveTools as filterActiveTools2
4
9
  } from "ai";
5
10
  import {
11
+ createRestrictedTelemetryDispatcher as createRestrictedTelemetryDispatcher2,
12
+ collectToolApprovals,
6
13
  convertToLanguageModelPrompt,
7
14
  mergeAbortSignals,
8
15
  mergeCallbacks,
9
- standardizePrompt
16
+ standardizePrompt,
17
+ validateApprovedToolApprovals
10
18
  } from "ai/internal";
11
19
 
20
+ // src/create-language-model-tool-result-output.ts
21
+ import {
22
+ createDefaultDownloadFunction,
23
+ createToolModelOutput,
24
+ downloadAssets,
25
+ mapToolResultOutput
26
+ } from "ai/internal";
27
+ async function createLanguageModelToolResultOutput({
28
+ toolCallId,
29
+ toolName,
30
+ input,
31
+ output,
32
+ tool: tool2,
33
+ errorMode,
34
+ supportedUrls,
35
+ download = createDefaultDownloadFunction(),
36
+ provider
37
+ }) {
38
+ const modelOutput = await createToolModelOutput({
39
+ toolCallId,
40
+ input,
41
+ output,
42
+ tool: tool2,
43
+ errorMode
44
+ });
45
+ const downloadedAssets = modelOutput.type === "content" ? await downloadAssets(
46
+ [
47
+ {
48
+ role: "tool",
49
+ content: [
50
+ {
51
+ type: "tool-result",
52
+ toolCallId,
53
+ toolName,
54
+ output: modelOutput
55
+ }
56
+ ]
57
+ }
58
+ ],
59
+ download,
60
+ supportedUrls
61
+ ) : {};
62
+ return mapToolResultOutput({
63
+ output: modelOutput,
64
+ provider,
65
+ downloadedAssets
66
+ });
67
+ }
68
+
69
+ // src/stream-text-iterator.ts
70
+ import {
71
+ experimental_filterActiveTools as filterActiveTools
72
+ } from "ai";
73
+ import { createRestrictedTelemetryDispatcher } from "ai/internal";
74
+
12
75
  // src/do-stream-step.ts
13
76
  import {
14
- experimental_streamLanguageModelCall as streamModelCall
77
+ experimental_streamLanguageModelCall as streamModelCall,
78
+ gateway
15
79
  } from "ai";
16
- import { gateway } from "ai";
17
80
 
18
81
  // src/serializable-schema.ts
19
82
  import { asSchema, jsonSchema } from "@ai-sdk/provider-utils";
@@ -22,12 +85,15 @@ import Ajv from "ajv";
22
85
  function serializeToolSet(tools) {
23
86
  return Object.fromEntries(
24
87
  Object.entries(tools).map(([name, t]) => {
88
+ var _a;
25
89
  const def = {
26
90
  description: t.description,
91
+ // TODO support tools with function descriptions
27
92
  inputSchema: asSchema(t.inputSchema).jsonSchema
28
93
  };
29
94
  if (t.type === "provider") {
30
95
  def.type = "provider";
96
+ def.isProviderExecuted = (_a = t.isProviderExecuted) != null ? _a : false;
31
97
  def.id = t.id;
32
98
  def.args = t.args;
33
99
  }
@@ -39,7 +105,7 @@ function resolveSerializableTools(tools) {
39
105
  const ajv = new Ajv();
40
106
  return Object.fromEntries(
41
107
  Object.entries(tools).map(([name, t]) => {
42
- var _a;
108
+ var _a, _b;
43
109
  if (t.type === "provider") {
44
110
  return [
45
111
  name,
@@ -47,6 +113,7 @@ function resolveSerializableTools(tools) {
47
113
  type: "provider",
48
114
  id: t.id,
49
115
  args: (_a = t.args) != null ? _a : {},
116
+ isProviderExecuted: (_b = t.isProviderExecuted) != null ? _b : false,
50
117
  inputSchema: jsonSchema(t.inputSchema)
51
118
  })
52
119
  ];
@@ -76,7 +143,7 @@ function resolveSerializableTools(tools) {
76
143
  // src/do-stream-step.ts
77
144
  async function doStreamStep(conversationPrompt, modelInit, writable, serializedTools, options) {
78
145
  "use step";
79
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
146
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
80
147
  const model = typeof modelInit === "string" ? gateway.languageModel(modelInit) : modelInit;
81
148
  const tools = serializedTools ? resolveSerializableTools(serializedTools) : void 0;
82
149
  const { stream: modelStream } = await streamModelCall({
@@ -85,6 +152,7 @@ async function doStreamStep(conversationPrompt, modelInit, writable, serializedT
85
152
  // pre-converted LanguageModelV4Prompt. standardizePrompt inside
86
153
  // streamModelCall handles both formats.
87
154
  messages: conversationPrompt,
155
+ allowSystemInMessages: true,
88
156
  tools,
89
157
  toolChoice: options == null ? void 0 : options.toolChoice,
90
158
  includeRawChunks: options == null ? void 0 : options.includeRawChunks,
@@ -106,11 +174,15 @@ async function doStreamStep(conversationPrompt, modelInit, writable, serializedT
106
174
  let finish;
107
175
  let text = "";
108
176
  const reasoningParts = [];
177
+ const chunks = [];
109
178
  let responseMetadata;
110
179
  let warnings;
111
180
  const writer = writable == null ? void 0 : writable.getWriter();
112
181
  try {
113
182
  for await (const part of modelStream) {
183
+ if (part.type !== "model-call-start" && part.type !== "model-call-end" && part.type !== "model-call-response-metadata") {
184
+ chunks.push(part);
185
+ }
114
186
  switch (part.type) {
115
187
  case "text-delta":
116
188
  text += part.text;
@@ -180,14 +252,15 @@ async function doStreamStep(conversationPrompt, modelInit, writable, serializedT
180
252
  const reasoningText = reasoningParts.map((r) => r.text).join("") || void 0;
181
253
  const step = {
182
254
  callId: "workflow-agent",
183
- stepNumber: 0,
255
+ stepNumber: (_a = options == null ? void 0 : options.stepNumber) != null ? _a : 0,
184
256
  model: {
185
- provider: (_b = (_a = responseMetadata == null ? void 0 : responseMetadata.modelId) == null ? void 0 : _a.split(":")[0]) != null ? _b : "unknown",
186
- modelId: (_c = responseMetadata == null ? void 0 : responseMetadata.modelId) != null ? _c : "unknown"
257
+ provider: (_c = (_b = responseMetadata == null ? void 0 : responseMetadata.modelId) == null ? void 0 : _b.split(":")[0]) != null ? _c : "unknown",
258
+ modelId: (_d = responseMetadata == null ? void 0 : responseMetadata.modelId) != null ? _d : "unknown"
187
259
  },
188
260
  functionId: void 0,
189
261
  metadata: void 0,
190
- context: void 0,
262
+ runtimeContext: (_e = options == null ? void 0 : options.runtimeContext) != null ? _e : {},
263
+ toolsContext: (_f = options == null ? void 0 : options.toolsContext) != null ? _f : {},
191
264
  content: [
192
265
  ...text ? [{ type: "text", text }] : [],
193
266
  ...toolCalls.filter((tc) => !tc.invalid).map((tc) => ({
@@ -224,9 +297,9 @@ async function doStreamStep(conversationPrompt, modelInit, writable, serializedT
224
297
  toolResults: [],
225
298
  staticToolResults: [],
226
299
  dynamicToolResults: [],
227
- finishReason: (_d = finish == null ? void 0 : finish.finishReason) != null ? _d : "other",
300
+ finishReason: (_g = finish == null ? void 0 : finish.finishReason) != null ? _g : "other",
228
301
  rawFinishReason: finish == null ? void 0 : finish.rawFinishReason,
229
- usage: (_e = finish == null ? void 0 : finish.usage) != null ? _e : {
302
+ usage: (_h = finish == null ? void 0 : finish.usage) != null ? _h : {
230
303
  inputTokens: 0,
231
304
  inputTokenDetails: {
232
305
  noCacheTokens: void 0,
@@ -240,20 +313,35 @@ async function doStreamStep(conversationPrompt, modelInit, writable, serializedT
240
313
  },
241
314
  totalTokens: 0
242
315
  },
316
+ performance: {
317
+ effectiveOutputTokensPerSecond: 0,
318
+ outputTokensPerSecond: void 0,
319
+ inputTokensPerSecond: void 0,
320
+ effectiveTotalTokensPerSecond: 0,
321
+ stepTimeMs: 0,
322
+ responseTimeMs: 0,
323
+ toolExecutionMs: {},
324
+ timeToFirstOutputMs: void 0
325
+ },
243
326
  warnings,
244
- request: { body: "" },
327
+ request: {
328
+ body: "",
329
+ messages: []
330
+ // TODO implement step request messages
331
+ },
245
332
  response: {
246
- id: (_f = responseMetadata == null ? void 0 : responseMetadata.id) != null ? _f : "unknown",
247
- timestamp: (_g = responseMetadata == null ? void 0 : responseMetadata.timestamp) != null ? _g : /* @__PURE__ */ new Date(),
248
- modelId: (_h = responseMetadata == null ? void 0 : responseMetadata.modelId) != null ? _h : "unknown",
333
+ id: (_i = responseMetadata == null ? void 0 : responseMetadata.id) != null ? _i : "unknown",
334
+ timestamp: (_j = responseMetadata == null ? void 0 : responseMetadata.timestamp) != null ? _j : /* @__PURE__ */ new Date(),
335
+ modelId: (_k = responseMetadata == null ? void 0 : responseMetadata.modelId) != null ? _k : "unknown",
249
336
  messages: []
250
337
  },
251
- providerMetadata: (_i = finish == null ? void 0 : finish.providerMetadata) != null ? _i : {}
338
+ providerMetadata: (_l = finish == null ? void 0 : finish.providerMetadata) != null ? _l : {}
252
339
  };
253
340
  return {
254
341
  toolCalls,
255
342
  finish,
256
343
  step,
344
+ chunks,
257
345
  providerExecutedToolResults
258
346
  };
259
347
  }
@@ -265,25 +353,27 @@ async function* streamTextIterator({
265
353
  writable,
266
354
  model,
267
355
  stopConditions,
268
- maxSteps,
356
+ onStepEnd,
269
357
  onStepFinish,
270
358
  onStepStart,
271
359
  onError,
272
360
  prepareStep,
273
361
  generationSettings,
274
362
  toolChoice,
275
- experimental_context,
276
- experimental_telemetry,
363
+ runtimeContext,
364
+ toolsContext,
365
+ telemetry,
277
366
  includeRawChunks = false,
278
367
  repairToolCall,
279
368
  responseFormat
280
369
  }) {
281
- var _a;
370
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
282
371
  let conversationPrompt = [...prompt];
283
372
  let currentModel = model;
284
373
  let currentGenerationSettings = generationSettings != null ? generationSettings : {};
285
374
  let currentToolChoice = toolChoice;
286
- let currentContext = experimental_context;
375
+ let currentRuntimeContext = runtimeContext != null ? runtimeContext : {};
376
+ let currentToolsContext = toolsContext != null ? toolsContext : {};
287
377
  let currentActiveTools;
288
378
  const steps = [];
289
379
  let done = false;
@@ -291,11 +381,12 @@ async function* streamTextIterator({
291
381
  let stepNumber = 0;
292
382
  let lastStep;
293
383
  let lastStepWasToolCalls = false;
294
- const effectiveMaxSteps = maxSteps != null ? maxSteps : Infinity;
384
+ const telemetryDispatcher = createRestrictedTelemetryDispatcher({
385
+ telemetry,
386
+ includeRuntimeContext: telemetry == null ? void 0 : telemetry.includeRuntimeContext,
387
+ includeToolsContext: telemetry == null ? void 0 : telemetry.includeToolsContext
388
+ });
295
389
  while (!done) {
296
- if (stepNumber >= effectiveMaxSteps) {
297
- break;
298
- }
299
390
  if ((_a = currentGenerationSettings.abortSignal) == null ? void 0 : _a.aborted) {
300
391
  break;
301
392
  }
@@ -305,15 +396,16 @@ async function* streamTextIterator({
305
396
  stepNumber,
306
397
  steps,
307
398
  messages: conversationPrompt,
308
- experimental_context: currentContext
399
+ runtimeContext: currentRuntimeContext,
400
+ toolsContext: currentToolsContext
309
401
  });
310
- if (prepareResult.model !== void 0) {
402
+ if ((prepareResult == null ? void 0 : prepareResult.model) !== void 0) {
311
403
  currentModel = prepareResult.model;
312
404
  }
313
- if (prepareResult.messages !== void 0) {
405
+ if ((prepareResult == null ? void 0 : prepareResult.messages) !== void 0) {
314
406
  conversationPrompt = [...prepareResult.messages];
315
407
  }
316
- if (prepareResult.system !== void 0) {
408
+ if ((prepareResult == null ? void 0 : prepareResult.system) !== void 0) {
317
409
  if (conversationPrompt.length > 0 && conversationPrompt[0].role === "system") {
318
410
  conversationPrompt[0] = {
319
411
  role: "system",
@@ -326,79 +418,82 @@ async function* streamTextIterator({
326
418
  });
327
419
  }
328
420
  }
329
- if (prepareResult.experimental_context !== void 0) {
330
- currentContext = prepareResult.experimental_context;
421
+ if ((prepareResult == null ? void 0 : prepareResult.runtimeContext) !== void 0) {
422
+ currentRuntimeContext = prepareResult.runtimeContext;
423
+ }
424
+ if ((prepareResult == null ? void 0 : prepareResult.toolsContext) !== void 0) {
425
+ currentToolsContext = prepareResult.toolsContext;
331
426
  }
332
- if (prepareResult.activeTools !== void 0) {
427
+ if ((prepareResult == null ? void 0 : prepareResult.activeTools) !== void 0) {
333
428
  currentActiveTools = prepareResult.activeTools;
334
429
  }
335
- if (prepareResult.maxOutputTokens !== void 0) {
430
+ if ((prepareResult == null ? void 0 : prepareResult.maxOutputTokens) !== void 0) {
336
431
  currentGenerationSettings = {
337
432
  ...currentGenerationSettings,
338
433
  maxOutputTokens: prepareResult.maxOutputTokens
339
434
  };
340
435
  }
341
- if (prepareResult.temperature !== void 0) {
436
+ if ((prepareResult == null ? void 0 : prepareResult.temperature) !== void 0) {
342
437
  currentGenerationSettings = {
343
438
  ...currentGenerationSettings,
344
439
  temperature: prepareResult.temperature
345
440
  };
346
441
  }
347
- if (prepareResult.topP !== void 0) {
442
+ if ((prepareResult == null ? void 0 : prepareResult.topP) !== void 0) {
348
443
  currentGenerationSettings = {
349
444
  ...currentGenerationSettings,
350
445
  topP: prepareResult.topP
351
446
  };
352
447
  }
353
- if (prepareResult.topK !== void 0) {
448
+ if ((prepareResult == null ? void 0 : prepareResult.topK) !== void 0) {
354
449
  currentGenerationSettings = {
355
450
  ...currentGenerationSettings,
356
451
  topK: prepareResult.topK
357
452
  };
358
453
  }
359
- if (prepareResult.presencePenalty !== void 0) {
454
+ if ((prepareResult == null ? void 0 : prepareResult.presencePenalty) !== void 0) {
360
455
  currentGenerationSettings = {
361
456
  ...currentGenerationSettings,
362
457
  presencePenalty: prepareResult.presencePenalty
363
458
  };
364
459
  }
365
- if (prepareResult.frequencyPenalty !== void 0) {
460
+ if ((prepareResult == null ? void 0 : prepareResult.frequencyPenalty) !== void 0) {
366
461
  currentGenerationSettings = {
367
462
  ...currentGenerationSettings,
368
463
  frequencyPenalty: prepareResult.frequencyPenalty
369
464
  };
370
465
  }
371
- if (prepareResult.stopSequences !== void 0) {
466
+ if ((prepareResult == null ? void 0 : prepareResult.stopSequences) !== void 0) {
372
467
  currentGenerationSettings = {
373
468
  ...currentGenerationSettings,
374
469
  stopSequences: prepareResult.stopSequences
375
470
  };
376
471
  }
377
- if (prepareResult.seed !== void 0) {
472
+ if ((prepareResult == null ? void 0 : prepareResult.seed) !== void 0) {
378
473
  currentGenerationSettings = {
379
474
  ...currentGenerationSettings,
380
475
  seed: prepareResult.seed
381
476
  };
382
477
  }
383
- if (prepareResult.maxRetries !== void 0) {
478
+ if ((prepareResult == null ? void 0 : prepareResult.maxRetries) !== void 0) {
384
479
  currentGenerationSettings = {
385
480
  ...currentGenerationSettings,
386
481
  maxRetries: prepareResult.maxRetries
387
482
  };
388
483
  }
389
- if (prepareResult.headers !== void 0) {
484
+ if ((prepareResult == null ? void 0 : prepareResult.headers) !== void 0) {
390
485
  currentGenerationSettings = {
391
486
  ...currentGenerationSettings,
392
487
  headers: prepareResult.headers
393
488
  };
394
489
  }
395
- if (prepareResult.providerOptions !== void 0) {
490
+ if ((prepareResult == null ? void 0 : prepareResult.providerOptions) !== void 0) {
396
491
  currentGenerationSettings = {
397
492
  ...currentGenerationSettings,
398
493
  providerOptions: prepareResult.providerOptions
399
494
  };
400
495
  }
401
- if (prepareResult.toolChoice !== void 0) {
496
+ if ((prepareResult == null ? void 0 : prepareResult.toolChoice) !== void 0) {
402
497
  currentToolChoice = prepareResult.toolChoice;
403
498
  }
404
499
  }
@@ -407,12 +502,53 @@ async function* streamTextIterator({
407
502
  stepNumber,
408
503
  model: currentModel,
409
504
  messages: conversationPrompt,
410
- steps: [...steps]
505
+ steps: [...steps],
506
+ runtimeContext: currentRuntimeContext,
507
+ toolsContext: currentToolsContext
411
508
  });
412
509
  }
510
+ const stepStartModelInfo = getModelInfo(currentModel);
511
+ await ((_b = telemetryDispatcher.onStepStart) == null ? void 0 : _b.call(telemetryDispatcher, {
512
+ callId: "workflow-agent",
513
+ provider: stepStartModelInfo.provider,
514
+ modelId: stepStartModelInfo.modelId,
515
+ stepNumber,
516
+ system: void 0,
517
+ messages: conversationPrompt,
518
+ tools,
519
+ toolChoice: currentToolChoice,
520
+ activeTools: currentActiveTools,
521
+ steps: steps.map(normalizeStepForTelemetry),
522
+ providerOptions: currentGenerationSettings.providerOptions,
523
+ output: void 0,
524
+ runtimeContext: currentRuntimeContext,
525
+ toolsContext: currentToolsContext
526
+ }));
413
527
  try {
414
- const effectiveTools = currentActiveTools && currentActiveTools.length > 0 ? filterToolSet(tools, currentActiveTools) : tools;
528
+ const effectiveTools = currentActiveTools && currentActiveTools.length > 0 ? (_c = filterActiveTools({
529
+ tools,
530
+ activeTools: currentActiveTools
531
+ })) != null ? _c : tools : tools;
415
532
  const serializedTools = serializeToolSet(effectiveTools);
533
+ const modelCallInfo = getModelInfo(currentModel);
534
+ await ((_d = telemetryDispatcher.onLanguageModelCallStart) == null ? void 0 : _d.call(telemetryDispatcher, {
535
+ callId: "workflow-agent",
536
+ provider: modelCallInfo.provider,
537
+ modelId: modelCallInfo.modelId,
538
+ system: void 0,
539
+ messages: conversationPrompt,
540
+ tools: serializedTools == null ? void 0 : Object.values(serializedTools).map((tool2) => ({ ...tool2 })),
541
+ maxOutputTokens: currentGenerationSettings.maxOutputTokens,
542
+ temperature: currentGenerationSettings.temperature,
543
+ topP: currentGenerationSettings.topP,
544
+ topK: currentGenerationSettings.topK,
545
+ presencePenalty: currentGenerationSettings.presencePenalty,
546
+ frequencyPenalty: currentGenerationSettings.frequencyPenalty,
547
+ stopSequences: currentGenerationSettings.stopSequences,
548
+ seed: currentGenerationSettings.seed,
549
+ providerOptions: currentGenerationSettings.providerOptions,
550
+ headers: currentGenerationSettings.headers
551
+ }));
416
552
  const { toolCalls, finish, step, providerExecutedToolResults } = await doStreamStep(
417
553
  conversationPrompt,
418
554
  currentModel,
@@ -422,11 +558,22 @@ async function* streamTextIterator({
422
558
  ...currentGenerationSettings,
423
559
  toolChoice: currentToolChoice,
424
560
  includeRawChunks,
425
- experimental_telemetry,
426
561
  repairToolCall,
427
- responseFormat
562
+ responseFormat,
563
+ runtimeContext: currentRuntimeContext,
564
+ toolsContext: currentToolsContext,
565
+ stepNumber
428
566
  }
429
567
  );
568
+ await ((_i = telemetryDispatcher.onLanguageModelCallEnd) == null ? void 0 : _i.call(telemetryDispatcher, {
569
+ callId: step.callId,
570
+ provider: (_f = (_e = step.model) == null ? void 0 : _e.provider) != null ? _f : "unknown",
571
+ modelId: (_h = (_g = step.model) == null ? void 0 : _g.modelId) != null ? _h : "unknown",
572
+ finishReason: step.finishReason,
573
+ usage: step.usage,
574
+ content: step.content,
575
+ responseId: step.response.id
576
+ }));
430
577
  _isFirstIteration = false;
431
578
  stepNumber++;
432
579
  steps.push(step);
@@ -454,7 +601,8 @@ async function* streamTextIterator({
454
601
  toolCalls,
455
602
  messages: conversationPrompt,
456
603
  step,
457
- context: currentContext,
604
+ runtimeContext: currentRuntimeContext,
605
+ toolsContext: currentToolsContext,
458
606
  providerExecutedToolResults
459
607
  };
460
608
  conversationPrompt.push({
@@ -495,9 +643,11 @@ async function* streamTextIterator({
495
643
  `Unexpected finish reason: ${typeof (finish == null ? void 0 : finish.finishReason) === "object" ? JSON.stringify(finish == null ? void 0 : finish.finishReason) : finish == null ? void 0 : finish.finishReason}`
496
644
  );
497
645
  }
498
- if (onStepFinish) {
499
- await onStepFinish(step);
646
+ const resolvedOnStepEnd = onStepEnd != null ? onStepEnd : onStepFinish;
647
+ if (resolvedOnStepEnd) {
648
+ await resolvedOnStepEnd(step);
500
649
  }
650
+ await ((_j = telemetryDispatcher.onStepEnd) == null ? void 0 : _j.call(telemetryDispatcher, normalizeStepForTelemetry(step)));
501
651
  } catch (error) {
502
652
  if (onError) {
503
653
  await onError({ error });
@@ -510,19 +660,22 @@ async function* streamTextIterator({
510
660
  toolCalls: [],
511
661
  messages: conversationPrompt,
512
662
  step: lastStep,
513
- context: currentContext
663
+ runtimeContext: currentRuntimeContext,
664
+ toolsContext: currentToolsContext
514
665
  };
515
666
  }
516
667
  return conversationPrompt;
517
668
  }
518
- function filterToolSet(tools, activeTools) {
519
- const filtered = {};
520
- for (const toolName of activeTools) {
521
- if (toolName in tools) {
522
- filtered[toolName] = tools[toolName];
523
- }
524
- }
525
- return filtered;
669
+ function getModelInfo(model) {
670
+ var _a;
671
+ return typeof model === "string" ? { provider: (_a = model.split("/")[0]) != null ? _a : "gateway", modelId: model } : { provider: model.provider, modelId: model.modelId };
672
+ }
673
+ function normalizeStepForTelemetry(step) {
674
+ var _a;
675
+ return {
676
+ ...step,
677
+ model: (_a = step.model) != null ? _a : { provider: "unknown", modelId: "unknown" }
678
+ };
526
679
  }
527
680
  function sanitizeProviderMetadataForToolCall(metadata) {
528
681
  if (metadata == null) return void 0;
@@ -548,26 +701,28 @@ function sanitizeProviderMetadataForToolCall(metadata) {
548
701
  // src/workflow-agent.ts
549
702
  var WorkflowAgent = class {
550
703
  constructor(options) {
551
- var _a, _b;
704
+ var _a, _b, _c;
552
705
  this.id = options.id;
553
706
  this.model = options.model;
554
707
  this.tools = (_a = options.tools) != null ? _a : {};
555
708
  this.instructions = (_b = options.instructions) != null ? _b : options.system;
556
709
  this.toolChoice = options.toolChoice;
557
- this.telemetry = options.experimental_telemetry;
558
- this.experimentalContext = options.experimental_context;
710
+ this.telemetry = options.telemetry;
711
+ this.runtimeContext = options.runtimeContext;
712
+ this.toolsContext = options.toolsContext;
559
713
  this.stopWhen = options.stopWhen;
560
714
  this.activeTools = options.activeTools;
561
715
  this.output = options.output;
562
716
  this.experimentalRepairToolCall = options.experimental_repairToolCall;
563
717
  this.experimentalDownload = options.experimental_download;
564
718
  this.prepareStep = options.prepareStep;
565
- this.constructorOnStepFinish = options.onStepFinish;
566
- this.constructorOnFinish = options.onFinish;
719
+ this.constructorOnStepEnd = (_c = options.onStepEnd) != null ? _c : options.onStepFinish;
720
+ const { onFinish, onEnd = onFinish } = options;
721
+ this.constructorOnEnd = onEnd;
567
722
  this.constructorOnStart = options.experimental_onStart;
568
723
  this.constructorOnStepStart = options.experimental_onStepStart;
569
- this.constructorOnToolCallStart = options.experimental_onToolCallStart;
570
- this.constructorOnToolCallFinish = options.experimental_onToolCallFinish;
724
+ this.constructorOnToolExecutionStart = options.onToolExecutionStart;
725
+ this.constructorOnToolExecutionEnd = options.onToolExecutionEnd;
571
726
  this.prepareCall = options.prepareCall;
572
727
  this.generationSettings = {
573
728
  maxOutputTokens: options.maxOutputTokens,
@@ -588,24 +743,27 @@ var WorkflowAgent = class {
588
743
  throw new Error("Not implemented");
589
744
  }
590
745
  async stream(options) {
591
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A;
746
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P;
747
+ const { onFinish, onEnd = onFinish } = options;
592
748
  let effectiveModel = this.model;
593
749
  let effectiveInstructions = (_a = options.system) != null ? _a : this.instructions;
594
750
  let effectivePrompt = options.prompt;
595
751
  let effectiveMessages = options.messages;
596
752
  let effectiveGenerationSettings = { ...this.generationSettings };
597
- let effectiveExperimentalContext = (_b = options.experimental_context) != null ? _b : this.experimentalContext;
598
- let effectiveToolChoiceFromPrepare = (_c = options.toolChoice) != null ? _c : this.toolChoice;
599
- let effectiveTelemetryFromPrepare = (_d = options.experimental_telemetry) != null ? _d : this.telemetry;
600
- const resolvedMessagesForPrepareCall = (_e = effectiveMessages != null ? effectiveMessages : typeof effectivePrompt === "string" ? [{ role: "user", content: effectivePrompt }] : effectivePrompt) != null ? _e : [];
753
+ let effectiveRuntimeContext = (_c = (_b = options.runtimeContext) != null ? _b : this.runtimeContext) != null ? _c : {};
754
+ let effectiveToolsContext = (_e = (_d = options.toolsContext) != null ? _d : this.toolsContext) != null ? _e : {};
755
+ let effectiveToolChoiceFromPrepare = (_f = options.toolChoice) != null ? _f : this.toolChoice;
756
+ let effectiveTelemetryFromPrepare = (_g = options.telemetry) != null ? _g : this.telemetry;
757
+ const resolvedMessagesForPrepareCall = (_h = effectiveMessages != null ? effectiveMessages : typeof effectivePrompt === "string" ? [{ role: "user", content: effectivePrompt }] : effectivePrompt) != null ? _h : [];
601
758
  if (this.prepareCall) {
602
759
  const prepared = await this.prepareCall({
603
760
  model: effectiveModel,
604
761
  tools: this.tools,
605
762
  instructions: effectiveInstructions,
606
763
  toolChoice: effectiveToolChoiceFromPrepare,
607
- experimental_telemetry: effectiveTelemetryFromPrepare,
608
- experimental_context: effectiveExperimentalContext,
764
+ telemetry: effectiveTelemetryFromPrepare,
765
+ runtimeContext: effectiveRuntimeContext,
766
+ toolsContext: effectiveToolsContext,
609
767
  messages: resolvedMessagesForPrepareCall,
610
768
  ...effectiveGenerationSettings
611
769
  });
@@ -616,12 +774,14 @@ var WorkflowAgent = class {
616
774
  effectiveMessages = prepared.messages;
617
775
  effectivePrompt = void 0;
618
776
  }
619
- if (prepared.experimental_context !== void 0)
620
- effectiveExperimentalContext = prepared.experimental_context;
777
+ if (prepared.runtimeContext !== void 0)
778
+ effectiveRuntimeContext = prepared.runtimeContext;
779
+ if (prepared.toolsContext !== void 0)
780
+ effectiveToolsContext = prepared.toolsContext;
621
781
  if (prepared.toolChoice !== void 0)
622
782
  effectiveToolChoiceFromPrepare = prepared.toolChoice;
623
- if (prepared.experimental_telemetry !== void 0)
624
- effectiveTelemetryFromPrepare = prepared.experimental_telemetry;
783
+ if (prepared.telemetry !== void 0)
784
+ effectiveTelemetryFromPrepare = prepared.telemetry;
625
785
  if (prepared.maxOutputTokens !== void 0)
626
786
  effectiveGenerationSettings.maxOutputTokens = prepared.maxOutputTokens;
627
787
  if (prepared.temperature !== void 0)
@@ -643,39 +803,196 @@ var WorkflowAgent = class {
643
803
  if (prepared.providerOptions !== void 0)
644
804
  effectiveGenerationSettings.providerOptions = prepared.providerOptions;
645
805
  }
806
+ const effectiveTelemetry = effectiveTelemetryFromPrepare;
807
+ const telemetryDispatcher = createRestrictedTelemetryDispatcher2({
808
+ telemetry: effectiveTelemetry,
809
+ includeRuntimeContext: effectiveTelemetry == null ? void 0 : effectiveTelemetry.includeRuntimeContext,
810
+ includeToolsContext: effectiveTelemetry == null ? void 0 : effectiveTelemetry.includeToolsContext
811
+ });
646
812
  const prompt = await standardizePrompt({
647
813
  system: effectiveInstructions,
814
+ allowSystemInMessages: true,
815
+ // TODO: consider exposing this as a parameter
648
816
  ...effectivePrompt != null ? { prompt: effectivePrompt } : { messages: effectiveMessages }
649
817
  });
650
- const { approvedToolApprovals, deniedToolApprovals } = collectToolApprovalsFromMessages(prompt.messages);
818
+ const download = (_i = options.experimental_download) != null ? _i : this.experimentalDownload;
819
+ const collectedApprovals = collectToolApprovals({
820
+ messages: prompt.messages
821
+ });
822
+ const approvedToolApprovals = collectedApprovals.approvedToolApprovals.map(
823
+ (collected) => ({
824
+ toolCallId: collected.toolCall.toolCallId,
825
+ toolName: collected.toolCall.toolName,
826
+ input: collected.toolCall.input,
827
+ reason: collected.approvalResponse.reason,
828
+ collected
829
+ })
830
+ );
831
+ const deniedToolApprovals = collectedApprovals.deniedToolApprovals.map(
832
+ (collected) => ({
833
+ toolCallId: collected.toolCall.toolCallId,
834
+ toolName: collected.toolCall.toolName,
835
+ input: collected.toolCall.input,
836
+ reason: collected.approvalResponse.reason
837
+ })
838
+ );
651
839
  if (approvedToolApprovals.length > 0 || deniedToolApprovals.length > 0) {
652
840
  const _toolResultMessages = [];
653
841
  const toolResultContent = [];
842
+ const approvedRawResults = [];
654
843
  for (const approval of approvedToolApprovals) {
655
844
  const tool2 = this.tools[approval.toolName];
656
845
  if (tool2 && typeof tool2.execute === "function") {
846
+ if (!tool2.needsApproval) {
847
+ const reason = `Tool "${approval.toolName}" does not require approval`;
848
+ toolResultContent.push({
849
+ type: "tool-result",
850
+ toolCallId: approval.toolCallId,
851
+ toolName: approval.toolName,
852
+ output: await createLanguageModelToolResultOutput({
853
+ toolCallId: approval.toolCallId,
854
+ toolName: approval.toolName,
855
+ input: approval.input,
856
+ output: reason,
857
+ tool: tool2,
858
+ errorMode: "text",
859
+ supportedUrls: {},
860
+ download
861
+ })
862
+ });
863
+ continue;
864
+ }
865
+ let revalidationReason;
866
+ try {
867
+ const { deniedToolApprovals: policyDenied } = await validateApprovedToolApprovals({
868
+ approvedToolApprovals: [approval.collected],
869
+ tools: this.tools,
870
+ toolApproval: void 0,
871
+ messages: prompt.messages,
872
+ toolsContext: effectiveToolsContext,
873
+ runtimeContext: effectiveRuntimeContext
874
+ });
875
+ if (policyDenied.length > 0) {
876
+ revalidationReason = (_j = policyDenied[0].approvalResponse.reason) != null ? _j : "Tool approval denied";
877
+ }
878
+ } catch (error) {
879
+ revalidationReason = getErrorMessage(error);
880
+ }
881
+ if (revalidationReason != null) {
882
+ toolResultContent.push({
883
+ type: "tool-result",
884
+ toolCallId: approval.toolCallId,
885
+ toolName: approval.toolName,
886
+ output: await createLanguageModelToolResultOutput({
887
+ toolCallId: approval.toolCallId,
888
+ toolName: approval.toolName,
889
+ input: approval.input,
890
+ output: revalidationReason,
891
+ tool: tool2,
892
+ errorMode: "text",
893
+ supportedUrls: {},
894
+ download
895
+ })
896
+ });
897
+ continue;
898
+ }
657
899
  try {
658
900
  const { execute } = tool2;
659
- const toolResult = await execute(approval.input, {
901
+ const resolvedContext = await resolveToolContext({
902
+ toolName: approval.toolName,
903
+ tool: tool2,
904
+ toolsContext: effectiveToolsContext
905
+ });
906
+ const toolCallEvent = {
907
+ type: "tool-call",
908
+ toolCallId: approval.toolCallId,
909
+ toolName: approval.toolName,
910
+ input: approval.input
911
+ };
912
+ const messages2 = prompt.messages;
913
+ await ((_k = telemetryDispatcher.onToolExecutionStart) == null ? void 0 : _k.call(telemetryDispatcher, {
914
+ toolCall: toolCallEvent,
915
+ stepNumber: 0,
916
+ messages: messages2,
917
+ toolContext: resolvedContext
918
+ }));
919
+ const startTime = Date.now();
920
+ const executeApprovedTool = () => execute(approval.input, {
660
921
  toolCallId: approval.toolCallId,
661
922
  messages: [],
662
- context: effectiveExperimentalContext
923
+ context: resolvedContext
663
924
  });
925
+ const toolResult = telemetryDispatcher.executeTool != null ? await telemetryDispatcher.executeTool({
926
+ callId: "workflow-agent",
927
+ toolCallId: approval.toolCallId,
928
+ execute: executeApprovedTool
929
+ }) : await executeApprovedTool();
930
+ await ((_l = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _l.call(telemetryDispatcher, {
931
+ toolCall: toolCallEvent,
932
+ stepNumber: 0,
933
+ durationMs: Date.now() - startTime,
934
+ messages: messages2,
935
+ toolContext: resolvedContext,
936
+ success: true,
937
+ output: toolResult
938
+ }));
664
939
  toolResultContent.push({
665
940
  type: "tool-result",
666
941
  toolCallId: approval.toolCallId,
667
942
  toolName: approval.toolName,
668
- output: typeof toolResult === "string" ? { type: "text", value: toolResult } : { type: "json", value: toolResult }
943
+ output: await createLanguageModelToolResultOutput({
944
+ toolCallId: approval.toolCallId,
945
+ toolName: approval.toolName,
946
+ input: approval.input,
947
+ output: toolResult,
948
+ tool: tool2,
949
+ errorMode: "none",
950
+ supportedUrls: {},
951
+ download
952
+ })
953
+ });
954
+ approvedRawResults.push({
955
+ toolCallId: approval.toolCallId,
956
+ toolName: approval.toolName,
957
+ input: approval.input,
958
+ output: toolResult
669
959
  });
670
960
  } catch (error) {
961
+ const errorMessage = getErrorMessage(error);
962
+ await ((_m = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _m.call(telemetryDispatcher, {
963
+ toolCall: {
964
+ type: "tool-call",
965
+ toolCallId: approval.toolCallId,
966
+ toolName: approval.toolName,
967
+ input: approval.input
968
+ },
969
+ stepNumber: 0,
970
+ durationMs: 0,
971
+ messages: prompt.messages,
972
+ toolContext: void 0,
973
+ success: false,
974
+ error
975
+ }));
671
976
  toolResultContent.push({
672
977
  type: "tool-result",
673
978
  toolCallId: approval.toolCallId,
674
979
  toolName: approval.toolName,
675
- output: {
676
- type: "text",
677
- value: getErrorMessage(error)
678
- }
980
+ output: await createLanguageModelToolResultOutput({
981
+ toolCallId: approval.toolCallId,
982
+ toolName: approval.toolName,
983
+ input: approval.input,
984
+ output: errorMessage,
985
+ tool: tool2,
986
+ errorMode: "text",
987
+ supportedUrls: {},
988
+ download
989
+ })
990
+ });
991
+ approvedRawResults.push({
992
+ toolCallId: approval.toolCallId,
993
+ toolName: approval.toolName,
994
+ input: approval.input,
995
+ output: errorMessage
679
996
  });
680
997
  }
681
998
  }
@@ -719,21 +1036,10 @@ var WorkflowAgent = class {
719
1036
  }
720
1037
  prompt.messages = cleanedMessages;
721
1038
  if (options.writable && toolResultContent.length > 0) {
722
- const approvedResults = toolResultContent.filter((r) => r.output.type !== "execution-denied").map((r) => {
723
- var _a2;
724
- return {
725
- toolCallId: r.toolCallId,
726
- toolName: r.toolName,
727
- input: (_a2 = approvedToolApprovals.find(
728
- (a) => a.toolCallId === r.toolCallId
729
- )) == null ? void 0 : _a2.input,
730
- output: "value" in r.output ? r.output.value : void 0
731
- };
732
- });
733
1039
  const deniedResults = toolResultContent.filter((r) => r.output.type === "execution-denied").map((r) => ({ toolCallId: r.toolCallId }));
734
1040
  await writeApprovalToolResults(
735
1041
  options.writable,
736
- approvedResults,
1042
+ approvedRawResults,
737
1043
  deniedResults
738
1044
  );
739
1045
  }
@@ -741,11 +1047,11 @@ var WorkflowAgent = class {
741
1047
  const modelPrompt = await convertToLanguageModelPrompt({
742
1048
  prompt,
743
1049
  supportedUrls: {},
744
- download: (_f = options.experimental_download) != null ? _f : this.experimentalDownload
1050
+ download
745
1051
  });
746
1052
  const effectiveAbortSignal = mergeAbortSignals(
747
- (_g = options.abortSignal) != null ? _g : effectiveGenerationSettings.abortSignal,
748
- options.timeout != null ? AbortSignal.timeout(options.timeout) : void 0
1053
+ (_n = options.abortSignal) != null ? _n : effectiveGenerationSettings.abortSignal,
1054
+ options.timeout
749
1055
  );
750
1056
  const mergedGenerationSettings = {
751
1057
  ...effectiveGenerationSettings,
@@ -778,13 +1084,13 @@ var WorkflowAgent = class {
778
1084
  providerOptions: options.providerOptions
779
1085
  }
780
1086
  };
781
- const mergedOnStepFinish = mergeCallbacks(
782
- this.constructorOnStepFinish,
783
- options.onStepFinish
1087
+ const mergedOnStepEnd = mergeCallbacks(
1088
+ this.constructorOnStepEnd,
1089
+ (_o = options.onStepEnd) != null ? _o : options.onStepFinish
784
1090
  );
785
- const mergedOnFinish = mergeCallbacks(
786
- this.constructorOnFinish,
787
- options.onFinish
1091
+ const mergedOnEnd = mergeCallbacks(
1092
+ this.constructorOnEnd,
1093
+ onEnd
788
1094
  );
789
1095
  const mergedOnStart = mergeCallbacks(
790
1096
  this.constructorOnStart,
@@ -794,82 +1100,200 @@ var WorkflowAgent = class {
794
1100
  this.constructorOnStepStart,
795
1101
  options.experimental_onStepStart
796
1102
  );
797
- const mergedOnToolCallStart = mergeCallbacks(
798
- this.constructorOnToolCallStart,
799
- options.experimental_onToolCallStart
1103
+ const mergedOnToolExecutionStart = mergeCallbacks(
1104
+ this.constructorOnToolExecutionStart,
1105
+ options.onToolExecutionStart
800
1106
  );
801
- const mergedOnToolCallFinish = mergeCallbacks(
802
- this.constructorOnToolCallFinish,
803
- options.experimental_onToolCallFinish
1107
+ const mergedOnToolExecutionEnd = mergeCallbacks(
1108
+ this.constructorOnToolExecutionEnd,
1109
+ options.onToolExecutionEnd
804
1110
  );
805
1111
  const effectiveToolChoice = effectiveToolChoiceFromPrepare;
806
- const effectiveTelemetry = effectiveTelemetryFromPrepare;
807
- const effectiveActiveTools = (_h = options.activeTools) != null ? _h : this.activeTools;
808
- const effectiveTools = effectiveActiveTools && effectiveActiveTools.length > 0 ? filterTools(this.tools, effectiveActiveTools) : this.tools;
809
- let experimentalContext = effectiveExperimentalContext;
1112
+ const effectiveActiveTools = (_p = options.activeTools) != null ? _p : this.activeTools;
1113
+ const effectiveTools = effectiveActiveTools && effectiveActiveTools.length > 0 ? (_q = filterActiveTools2({
1114
+ tools: this.tools,
1115
+ activeTools: effectiveActiveTools
1116
+ })) != null ? _q : this.tools : this.tools;
1117
+ const effectiveModelInfo = getModelInfo2(effectiveModel);
1118
+ let runtimeContext = effectiveRuntimeContext;
1119
+ let toolsContext = effectiveToolsContext;
810
1120
  const steps = [];
811
1121
  let lastStepToolCalls = [];
812
1122
  let lastStepToolResults = [];
813
1123
  if (mergedOnStart) {
814
1124
  await mergedOnStart({
815
1125
  model: effectiveModel,
816
- messages: prompt.messages
1126
+ messages: prompt.messages,
1127
+ runtimeContext,
1128
+ toolsContext
817
1129
  });
818
1130
  }
819
- const executeToolWithCallbacks = async (toolCall, tools, messages2, context, currentStepNumber = 0) => {
1131
+ await ((_t = telemetryDispatcher.onStart) == null ? void 0 : _t.call(telemetryDispatcher, {
1132
+ callId: "workflow-agent",
1133
+ operationId: "ai.workflowAgent.stream",
1134
+ provider: effectiveModelInfo.provider,
1135
+ modelId: effectiveModelInfo.modelId,
1136
+ system: void 0,
1137
+ messages: prompt.messages,
1138
+ tools: effectiveTools,
1139
+ toolChoice: effectiveToolChoice,
1140
+ activeTools: effectiveActiveTools,
1141
+ maxOutputTokens: mergedGenerationSettings.maxOutputTokens,
1142
+ temperature: mergedGenerationSettings.temperature,
1143
+ topP: mergedGenerationSettings.topP,
1144
+ topK: mergedGenerationSettings.topK,
1145
+ presencePenalty: mergedGenerationSettings.presencePenalty,
1146
+ frequencyPenalty: mergedGenerationSettings.frequencyPenalty,
1147
+ stopSequences: mergedGenerationSettings.stopSequences,
1148
+ seed: mergedGenerationSettings.seed,
1149
+ maxRetries: (_r = mergedGenerationSettings.maxRetries) != null ? _r : 2,
1150
+ timeout: void 0,
1151
+ headers: mergedGenerationSettings.headers,
1152
+ providerOptions: mergedGenerationSettings.providerOptions,
1153
+ output: (_s = options.output) != null ? _s : this.output,
1154
+ runtimeContext,
1155
+ toolsContext
1156
+ }));
1157
+ const executeToolWithCallbacks = async (toolCall, tools, messages2, perToolContexts, currentStepNumber = 0) => {
1158
+ var _a2, _b2, _c2, _d2;
820
1159
  const toolCallEvent = {
821
1160
  type: "tool-call",
822
1161
  toolCallId: toolCall.toolCallId,
823
1162
  toolName: toolCall.toolName,
824
1163
  input: toolCall.input
825
1164
  };
826
- if (mergedOnToolCallStart) {
827
- await mergedOnToolCallStart({
1165
+ const tool2 = tools[toolCall.toolName];
1166
+ const resolvedContext = tool2 ? await resolveToolContext({
1167
+ toolName: toolCall.toolName,
1168
+ tool: tool2,
1169
+ toolsContext: perToolContexts
1170
+ }) : void 0;
1171
+ const modelMessages = getToolCallbackMessages(messages2);
1172
+ if (mergedOnToolExecutionStart) {
1173
+ await mergedOnToolExecutionStart({
828
1174
  toolCall: toolCallEvent,
829
- stepNumber: currentStepNumber
1175
+ stepNumber: currentStepNumber,
1176
+ messages: modelMessages,
1177
+ toolContext: resolvedContext
830
1178
  });
831
1179
  }
1180
+ await ((_a2 = telemetryDispatcher.onToolExecutionStart) == null ? void 0 : _a2.call(telemetryDispatcher, {
1181
+ toolCall: toolCallEvent,
1182
+ stepNumber: currentStepNumber,
1183
+ messages: modelMessages,
1184
+ toolContext: resolvedContext
1185
+ }));
832
1186
  const startTime = Date.now();
833
1187
  let result;
834
1188
  try {
835
- result = await executeTool(toolCall, tools, messages2, context);
1189
+ const execute = () => executeTool(toolCall, tools, messages2, resolvedContext, download);
1190
+ result = telemetryDispatcher.executeTool != null ? await telemetryDispatcher.executeTool({
1191
+ callId: "workflow-agent",
1192
+ toolCallId: toolCall.toolCallId,
1193
+ execute
1194
+ }) : await execute();
836
1195
  } catch (err) {
837
1196
  const durationMs2 = Date.now() - startTime;
838
- if (mergedOnToolCallFinish) {
839
- await mergedOnToolCallFinish({
1197
+ if (mergedOnToolExecutionEnd) {
1198
+ await mergedOnToolExecutionEnd({
840
1199
  toolCall: toolCallEvent,
841
1200
  stepNumber: currentStepNumber,
842
1201
  durationMs: durationMs2,
1202
+ messages: modelMessages,
1203
+ toolContext: resolvedContext,
843
1204
  success: false,
844
1205
  error: err
845
1206
  });
846
1207
  }
1208
+ await ((_b2 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _b2.call(telemetryDispatcher, {
1209
+ toolCall: toolCallEvent,
1210
+ stepNumber: currentStepNumber,
1211
+ durationMs: durationMs2,
1212
+ messages: modelMessages,
1213
+ toolContext: resolvedContext,
1214
+ success: false,
1215
+ error: err
1216
+ }));
847
1217
  throw err;
848
1218
  }
849
1219
  const durationMs = Date.now() - startTime;
850
- if (mergedOnToolCallFinish) {
851
- const isError = result.output && "type" in result.output && (result.output.type === "error-text" || result.output.type === "error-json");
852
- if (isError) {
853
- await mergedOnToolCallFinish({
1220
+ if (mergedOnToolExecutionEnd) {
1221
+ if (result.isError) {
1222
+ await mergedOnToolExecutionEnd({
854
1223
  toolCall: toolCallEvent,
855
1224
  stepNumber: currentStepNumber,
856
1225
  durationMs,
1226
+ messages: modelMessages,
1227
+ toolContext: resolvedContext,
857
1228
  success: false,
858
- error: "value" in result.output ? result.output.value : void 0
1229
+ error: result.rawOutput
859
1230
  });
860
1231
  } else {
861
- await mergedOnToolCallFinish({
1232
+ await mergedOnToolExecutionEnd({
862
1233
  toolCall: toolCallEvent,
863
1234
  stepNumber: currentStepNumber,
864
1235
  durationMs,
1236
+ messages: modelMessages,
1237
+ toolContext: resolvedContext,
865
1238
  success: true,
866
- output: result.output && "value" in result.output ? result.output.value : void 0
1239
+ output: result.rawOutput
867
1240
  });
868
1241
  }
869
1242
  }
1243
+ if (result.isError) {
1244
+ await ((_c2 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _c2.call(telemetryDispatcher, {
1245
+ toolCall: toolCallEvent,
1246
+ stepNumber: currentStepNumber,
1247
+ durationMs,
1248
+ messages: modelMessages,
1249
+ toolContext: resolvedContext,
1250
+ success: false,
1251
+ error: result.rawOutput
1252
+ }));
1253
+ } else {
1254
+ await ((_d2 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _d2.call(telemetryDispatcher, {
1255
+ toolCall: toolCallEvent,
1256
+ stepNumber: currentStepNumber,
1257
+ durationMs,
1258
+ messages: modelMessages,
1259
+ toolContext: resolvedContext,
1260
+ success: true,
1261
+ output: result.rawOutput
1262
+ }));
1263
+ }
870
1264
  return result;
871
1265
  };
872
- if ((_i = mergedGenerationSettings.abortSignal) == null ? void 0 : _i.aborted) {
1266
+ const recordProviderExecutedToolTelemetry = async (toolCall, result, messages2, currentStepNumber) => {
1267
+ var _a2, _b2;
1268
+ const toolCallEvent = {
1269
+ type: "tool-call",
1270
+ toolCallId: toolCall.toolCallId,
1271
+ toolName: toolCall.toolName,
1272
+ input: toolCall.input
1273
+ };
1274
+ const modelMessages = getToolCallbackMessages(messages2);
1275
+ await ((_a2 = telemetryDispatcher.onToolExecutionStart) == null ? void 0 : _a2.call(telemetryDispatcher, {
1276
+ toolCall: toolCallEvent,
1277
+ stepNumber: currentStepNumber,
1278
+ messages: modelMessages,
1279
+ toolContext: void 0
1280
+ }));
1281
+ await ((_b2 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _b2.call(telemetryDispatcher, {
1282
+ toolCall: toolCallEvent,
1283
+ stepNumber: currentStepNumber,
1284
+ durationMs: 0,
1285
+ messages: modelMessages,
1286
+ toolContext: void 0,
1287
+ ...result.isError ? {
1288
+ success: false,
1289
+ error: result.rawOutput
1290
+ } : {
1291
+ success: true,
1292
+ output: result.rawOutput
1293
+ }
1294
+ }));
1295
+ };
1296
+ if ((_u = mergedGenerationSettings.abortSignal) == null ? void 0 : _u.aborted) {
873
1297
  if (options.onAbort) {
874
1298
  await options.onAbort({ steps });
875
1299
  }
@@ -886,19 +1310,19 @@ var WorkflowAgent = class {
886
1310
  tools: effectiveTools,
887
1311
  writable: options.writable,
888
1312
  prompt: modelPrompt,
889
- stopConditions: (_j = options.stopWhen) != null ? _j : this.stopWhen,
890
- maxSteps: options.maxSteps,
891
- onStepFinish: mergedOnStepFinish,
1313
+ stopConditions: (_v = options.stopWhen) != null ? _v : this.stopWhen,
1314
+ onStepEnd: mergedOnStepEnd,
892
1315
  onStepStart: mergedOnStepStart,
893
1316
  onError: options.onError,
894
- prepareStep: (_k = options.prepareStep) != null ? _k : this.prepareStep,
1317
+ prepareStep: (_w = options.prepareStep) != null ? _w : this.prepareStep,
895
1318
  generationSettings: mergedGenerationSettings,
896
1319
  toolChoice: effectiveToolChoice,
897
- experimental_context: experimentalContext,
898
- experimental_telemetry: effectiveTelemetry,
899
- includeRawChunks: (_l = options.includeRawChunks) != null ? _l : false,
900
- repairToolCall: (_m = options.experimental_repairToolCall) != null ? _m : this.experimentalRepairToolCall,
901
- responseFormat: await ((_o = (_n = options.output) != null ? _n : this.output) == null ? void 0 : _o.responseFormat)
1320
+ runtimeContext,
1321
+ toolsContext,
1322
+ telemetry: effectiveTelemetry,
1323
+ includeRawChunks: (_x = options.includeRawChunks) != null ? _x : false,
1324
+ repairToolCall: (_y = options.experimental_repairToolCall) != null ? _y : this.experimentalRepairToolCall,
1325
+ responseFormat: await ((_A = (_z = options.output) != null ? _z : this.output) == null ? void 0 : _A.responseFormat)
902
1326
  });
903
1327
  let finalMessages;
904
1328
  let encounteredError;
@@ -906,7 +1330,7 @@ var WorkflowAgent = class {
906
1330
  try {
907
1331
  let result = await iterator.next();
908
1332
  while (!result.done) {
909
- if ((_p = mergedGenerationSettings.abortSignal) == null ? void 0 : _p.aborted) {
1333
+ if ((_B = mergedGenerationSettings.abortSignal) == null ? void 0 : _B.aborted) {
910
1334
  wasAborted = true;
911
1335
  if (options.onAbort) {
912
1336
  await options.onAbort({ steps });
@@ -917,21 +1341,29 @@ var WorkflowAgent = class {
917
1341
  toolCalls,
918
1342
  messages: iterMessages,
919
1343
  step,
920
- context,
1344
+ runtimeContext: yieldedRuntimeContext,
1345
+ toolsContext: yieldedToolsContext,
921
1346
  providerExecutedToolResults
922
1347
  } = result.value;
923
1348
  const currentStepNumber = steps.length;
924
1349
  if (step) {
925
1350
  steps.push(step);
926
1351
  }
927
- if (context !== void 0) {
928
- experimentalContext = context;
1352
+ if (yieldedRuntimeContext !== void 0) {
1353
+ runtimeContext = yieldedRuntimeContext;
1354
+ }
1355
+ if (yieldedToolsContext !== void 0) {
1356
+ toolsContext = yieldedToolsContext;
929
1357
  }
930
1358
  if (toolCalls.length > 0) {
931
- const nonProviderToolCalls = toolCalls.filter(
1359
+ const invalidToolCalls = toolCalls.filter((tc) => tc.invalid === true);
1360
+ const validToolCalls = toolCalls.filter((tc) => tc.invalid !== true);
1361
+ const nonProviderToolCalls = validToolCalls.filter(
932
1362
  (tc) => !tc.providerExecuted
933
1363
  );
934
- const providerToolCalls = toolCalls.filter((tc) => tc.providerExecuted);
1364
+ const providerToolCalls = validToolCalls.filter(
1365
+ (tc) => tc.providerExecuted
1366
+ );
935
1367
  const approvalNeeded = await Promise.all(
936
1368
  nonProviderToolCalls.map(async (tc) => {
937
1369
  const tool2 = effectiveTools[tc.toolName];
@@ -939,10 +1371,15 @@ var WorkflowAgent = class {
939
1371
  if (tool2.needsApproval == null) return false;
940
1372
  if (typeof tool2.needsApproval === "boolean")
941
1373
  return tool2.needsApproval;
1374
+ const resolvedContext = await resolveToolContext({
1375
+ toolName: tc.toolName,
1376
+ tool: tool2,
1377
+ toolsContext
1378
+ });
942
1379
  return tool2.needsApproval(tc.input, {
943
1380
  toolCallId: tc.toolCallId,
944
1381
  messages: iterMessages,
945
- context: experimentalContext
1382
+ context: resolvedContext
946
1383
  });
947
1384
  })
948
1385
  );
@@ -961,32 +1398,56 @@ var WorkflowAgent = class {
961
1398
  toolCall,
962
1399
  effectiveTools,
963
1400
  iterMessages,
964
- experimentalContext,
1401
+ toolsContext,
965
1402
  currentStepNumber
966
1403
  )
967
1404
  )
968
1405
  );
969
- const providerResults = providerToolCalls.map(
970
- (toolCall) => resolveProviderToolResult(
971
- toolCall,
972
- providerExecutedToolResults
1406
+ const providerResults = await Promise.all(
1407
+ providerToolCalls.map(
1408
+ (toolCall) => resolveProviderToolResult(
1409
+ toolCall,
1410
+ providerExecutedToolResults,
1411
+ effectiveTools,
1412
+ download
1413
+ )
1414
+ )
1415
+ );
1416
+ await Promise.all(
1417
+ providerToolCalls.map(
1418
+ (toolCall, index) => recordProviderExecutedToolTelemetry(
1419
+ toolCall,
1420
+ providerResults[index],
1421
+ iterMessages,
1422
+ currentStepNumber
1423
+ )
973
1424
  )
974
1425
  );
975
- const resolvedResults = [...executableResults, ...providerResults];
1426
+ const continuationInvalidResults = invalidToolCalls.map(
1427
+ createInvalidToolResult
1428
+ );
1429
+ const resolvedResults = [
1430
+ ...executableResults.map((result2) => result2.modelResult),
1431
+ ...providerResults.map((result2) => result2.modelResult),
1432
+ ...continuationInvalidResults
1433
+ ];
1434
+ const executedResults = [...executableResults, ...providerResults];
976
1435
  const allToolCalls = toolCalls.map((tc) => ({
977
1436
  type: "tool-call",
978
1437
  toolCallId: tc.toolCallId,
979
1438
  toolName: tc.toolName,
980
1439
  input: tc.input
981
1440
  }));
982
- const allToolResults = resolvedResults.map((r) => {
1441
+ const allToolResults = executedResults.map((r) => {
983
1442
  var _a2;
984
1443
  return {
985
1444
  type: "tool-result",
986
- toolCallId: r.toolCallId,
987
- toolName: r.toolName,
988
- input: (_a2 = toolCalls.find((tc) => tc.toolCallId === r.toolCallId)) == null ? void 0 : _a2.input,
989
- output: "value" in r.output ? r.output.value : void 0
1445
+ toolCallId: r.modelResult.toolCallId,
1446
+ toolName: r.modelResult.toolName,
1447
+ input: (_a2 = toolCalls.find(
1448
+ (tc) => tc.toolCallId === r.modelResult.toolCallId
1449
+ )) == null ? void 0 : _a2.input,
1450
+ output: r.rawOutput
990
1451
  };
991
1452
  });
992
1453
  if (resolvedResults.length > 0) {
@@ -996,18 +1457,32 @@ var WorkflowAgent = class {
996
1457
  });
997
1458
  }
998
1459
  const messages2 = iterMessages;
999
- if (mergedOnFinish && !wasAborted) {
1460
+ if (mergedOnEnd && !wasAborted) {
1000
1461
  const lastStep = steps[steps.length - 1];
1001
- await mergedOnFinish({
1462
+ const totalUsage = aggregateUsage(steps);
1463
+ await mergedOnEnd({
1002
1464
  steps,
1003
1465
  messages: messages2,
1004
- text: (_q = lastStep == null ? void 0 : lastStep.text) != null ? _q : "",
1005
- finishReason: (_r = lastStep == null ? void 0 : lastStep.finishReason) != null ? _r : "other",
1006
- totalUsage: aggregateUsage(steps),
1007
- experimental_context: experimentalContext,
1466
+ text: (_C = lastStep == null ? void 0 : lastStep.text) != null ? _C : "",
1467
+ finishReason: (_D = lastStep == null ? void 0 : lastStep.finishReason) != null ? _D : "other",
1468
+ usage: totalUsage,
1469
+ totalUsage,
1470
+ runtimeContext,
1471
+ toolsContext,
1008
1472
  output: void 0
1009
1473
  });
1010
1474
  }
1475
+ if (!wasAborted && steps.length > 0) {
1476
+ const telemetrySteps = steps.map(normalizeStepForTelemetry2);
1477
+ const lastStep = telemetrySteps[telemetrySteps.length - 1];
1478
+ const totalUsage = aggregateUsage(steps);
1479
+ await ((_E = telemetryDispatcher.onEnd) == null ? void 0 : _E.call(telemetryDispatcher, {
1480
+ ...lastStep,
1481
+ steps: telemetrySteps,
1482
+ usage: totalUsage,
1483
+ totalUsage
1484
+ }));
1485
+ }
1011
1486
  if (options.writable) {
1012
1487
  const approvalToolCalls = pausedToolCalls.filter((_, i) => {
1013
1488
  const tcIndex = nonProviderToolCalls.indexOf(
@@ -1026,8 +1501,8 @@ var WorkflowAgent = class {
1026
1501
  }
1027
1502
  }
1028
1503
  if (options.writable) {
1029
- const sendFinish = (_s = options.sendFinish) != null ? _s : true;
1030
- const preventClose = (_t = options.preventClose) != null ? _t : false;
1504
+ const sendFinish = (_F = options.sendFinish) != null ? _F : true;
1505
+ const preventClose = (_G = options.preventClose) != null ? _G : false;
1031
1506
  if (sendFinish || !preventClose) {
1032
1507
  await closeStream(options.writable, preventClose, sendFinish);
1033
1508
  }
@@ -1046,40 +1521,68 @@ var WorkflowAgent = class {
1046
1521
  toolCall,
1047
1522
  effectiveTools,
1048
1523
  iterMessages,
1049
- experimentalContext,
1524
+ toolsContext,
1525
+ currentStepNumber
1526
+ )
1527
+ )
1528
+ );
1529
+ const providerToolResults = await Promise.all(
1530
+ providerToolCalls.map(
1531
+ (toolCall) => resolveProviderToolResult(
1532
+ toolCall,
1533
+ providerExecutedToolResults,
1534
+ effectiveTools,
1535
+ download
1536
+ )
1537
+ )
1538
+ );
1539
+ await Promise.all(
1540
+ providerToolCalls.map(
1541
+ (toolCall, index) => recordProviderExecutedToolTelemetry(
1542
+ toolCall,
1543
+ providerToolResults[index],
1544
+ iterMessages,
1050
1545
  currentStepNumber
1051
1546
  )
1052
1547
  )
1053
1548
  );
1054
- const providerToolResults = providerToolCalls.map(
1055
- (toolCall) => resolveProviderToolResult(toolCall, providerExecutedToolResults)
1549
+ const continuationInvalidToolResults = invalidToolCalls.map(
1550
+ createInvalidToolResult
1056
1551
  );
1057
- const toolResults = toolCalls.map((tc) => {
1552
+ const executedToolResults = toolCalls.flatMap((tc) => {
1058
1553
  const clientResult = clientToolResults.find(
1059
- (r) => r.toolCallId === tc.toolCallId
1554
+ (r) => r.modelResult.toolCallId === tc.toolCallId
1060
1555
  );
1061
- if (clientResult) return clientResult;
1556
+ if (clientResult) return [clientResult];
1062
1557
  const providerResult = providerToolResults.find(
1558
+ (r) => r.modelResult.toolCallId === tc.toolCallId
1559
+ );
1560
+ if (providerResult) return [providerResult];
1561
+ return [];
1562
+ });
1563
+ const continuationToolResults = toolCalls.flatMap((tc) => {
1564
+ const invalidResult = continuationInvalidToolResults.find(
1063
1565
  (r) => r.toolCallId === tc.toolCallId
1064
1566
  );
1065
- if (providerResult) return providerResult;
1066
- return {
1067
- type: "tool-result",
1068
- toolCallId: tc.toolCallId,
1069
- toolName: tc.toolName,
1070
- output: { type: "text", value: "" }
1071
- };
1567
+ if (invalidResult) return [invalidResult];
1568
+ const executedResult = executedToolResults.find(
1569
+ (r) => r.modelResult.toolCallId === tc.toolCallId
1570
+ );
1571
+ if (executedResult) return [executedResult.modelResult];
1572
+ return [];
1072
1573
  });
1073
1574
  if (options.writable) {
1074
1575
  await writeToolResultsWithStepBoundary(
1075
1576
  options.writable,
1076
- toolResults.map((r) => {
1577
+ executedToolResults.map((r) => {
1077
1578
  var _a2;
1078
1579
  return {
1079
- toolCallId: r.toolCallId,
1080
- toolName: r.toolName,
1081
- input: (_a2 = toolCalls.find((tc) => tc.toolCallId === r.toolCallId)) == null ? void 0 : _a2.input,
1082
- output: "value" in r.output ? r.output.value : void 0
1580
+ toolCallId: r.modelResult.toolCallId,
1581
+ toolName: r.modelResult.toolName,
1582
+ input: (_a2 = toolCalls.find(
1583
+ (tc) => tc.toolCallId === r.modelResult.toolCallId
1584
+ )) == null ? void 0 : _a2.input,
1585
+ output: r.rawOutput
1083
1586
  };
1084
1587
  })
1085
1588
  );
@@ -1090,17 +1593,19 @@ var WorkflowAgent = class {
1090
1593
  toolName: tc.toolName,
1091
1594
  input: tc.input
1092
1595
  }));
1093
- lastStepToolResults = toolResults.map((r) => {
1596
+ lastStepToolResults = executedToolResults.map((r) => {
1094
1597
  var _a2;
1095
1598
  return {
1096
1599
  type: "tool-result",
1097
- toolCallId: r.toolCallId,
1098
- toolName: r.toolName,
1099
- input: (_a2 = toolCalls.find((tc) => tc.toolCallId === r.toolCallId)) == null ? void 0 : _a2.input,
1100
- output: "value" in r.output ? r.output.value : void 0
1600
+ toolCallId: r.modelResult.toolCallId,
1601
+ toolName: r.modelResult.toolName,
1602
+ input: (_a2 = toolCalls.find(
1603
+ (tc) => tc.toolCallId === r.modelResult.toolCallId
1604
+ )) == null ? void 0 : _a2.input,
1605
+ output: r.rawOutput
1101
1606
  };
1102
1607
  });
1103
- result = await iterator.next(toolResults);
1608
+ result = await iterator.next(continuationToolResults);
1104
1609
  } else {
1105
1610
  lastStepToolCalls = [];
1106
1611
  lastStepToolResults = [];
@@ -1120,9 +1625,10 @@ var WorkflowAgent = class {
1120
1625
  } else if (options.onError) {
1121
1626
  await options.onError({ error });
1122
1627
  }
1628
+ await ((_H = telemetryDispatcher.onError) == null ? void 0 : _H.call(telemetryDispatcher, error));
1123
1629
  }
1124
1630
  const messages = finalMessages != null ? finalMessages : prompt.messages;
1125
- const effectiveOutput = (_u = options.output) != null ? _u : this.output;
1631
+ const effectiveOutput = (_I = options.output) != null ? _I : this.output;
1126
1632
  let experimentalOutput = void 0;
1127
1633
  if (effectiveOutput && steps.length > 0) {
1128
1634
  const lastStep = steps[steps.length - 1];
@@ -1144,22 +1650,36 @@ var WorkflowAgent = class {
1144
1650
  }
1145
1651
  }
1146
1652
  }
1147
- if (mergedOnFinish && !wasAborted) {
1653
+ if (mergedOnEnd && !wasAborted) {
1148
1654
  const lastStep = steps[steps.length - 1];
1149
- await mergedOnFinish({
1655
+ const totalUsage = aggregateUsage(steps);
1656
+ await mergedOnEnd({
1150
1657
  steps,
1151
1658
  messages,
1152
- text: (_v = lastStep == null ? void 0 : lastStep.text) != null ? _v : "",
1153
- finishReason: (_w = lastStep == null ? void 0 : lastStep.finishReason) != null ? _w : "other",
1154
- totalUsage: aggregateUsage(steps),
1155
- experimental_context: experimentalContext,
1659
+ text: (_J = lastStep == null ? void 0 : lastStep.text) != null ? _J : "",
1660
+ finishReason: (_K = lastStep == null ? void 0 : lastStep.finishReason) != null ? _K : "other",
1661
+ usage: totalUsage,
1662
+ totalUsage,
1663
+ runtimeContext,
1664
+ toolsContext,
1156
1665
  output: experimentalOutput
1157
1666
  });
1158
1667
  }
1668
+ if (!wasAborted && steps.length > 0) {
1669
+ const telemetrySteps = steps.map(normalizeStepForTelemetry2);
1670
+ const lastStep = telemetrySteps[telemetrySteps.length - 1];
1671
+ const totalUsage = aggregateUsage(steps);
1672
+ await ((_L = telemetryDispatcher.onEnd) == null ? void 0 : _L.call(telemetryDispatcher, {
1673
+ ...lastStep,
1674
+ steps: telemetrySteps,
1675
+ usage: totalUsage,
1676
+ totalUsage
1677
+ }));
1678
+ }
1159
1679
  if (encounteredError) {
1160
1680
  if (options.writable) {
1161
- const sendFinish = (_x = options.sendFinish) != null ? _x : true;
1162
- const preventClose = (_y = options.preventClose) != null ? _y : false;
1681
+ const sendFinish = (_M = options.sendFinish) != null ? _M : true;
1682
+ const preventClose = (_N = options.preventClose) != null ? _N : false;
1163
1683
  if (sendFinish || !preventClose) {
1164
1684
  await closeStream(options.writable, preventClose, sendFinish);
1165
1685
  }
@@ -1167,8 +1687,8 @@ var WorkflowAgent = class {
1167
1687
  throw encounteredError;
1168
1688
  }
1169
1689
  if (options.writable) {
1170
- const sendFinish = (_z = options.sendFinish) != null ? _z : true;
1171
- const preventClose = (_A = options.preventClose) != null ? _A : false;
1690
+ const sendFinish = (_O = options.sendFinish) != null ? _O : true;
1691
+ const preventClose = (_P = options.preventClose) != null ? _P : false;
1172
1692
  if (sendFinish || !preventClose) {
1173
1693
  await closeStream(options.writable, preventClose, sendFinish);
1174
1694
  }
@@ -1182,6 +1702,17 @@ var WorkflowAgent = class {
1182
1702
  };
1183
1703
  }
1184
1704
  };
1705
+ function getModelInfo2(model) {
1706
+ var _a;
1707
+ return typeof model === "string" ? { provider: (_a = model.split("/")[0]) != null ? _a : "gateway", modelId: model } : { provider: model.provider, modelId: model.modelId };
1708
+ }
1709
+ function normalizeStepForTelemetry2(step) {
1710
+ var _a;
1711
+ return {
1712
+ ...step,
1713
+ model: (_a = step.model) != null ? _a : { provider: "unknown", modelId: "unknown" }
1714
+ };
1715
+ }
1185
1716
  async function closeStream(writable, preventClose, sendFinish) {
1186
1717
  "use step";
1187
1718
  if (sendFinish) {
@@ -1255,6 +1786,22 @@ async function writeApprovalToolResults(writable, approvedResults, deniedResults
1255
1786
  writer.releaseLock();
1256
1787
  }
1257
1788
  }
1789
+ async function resolveToolContext({
1790
+ toolName,
1791
+ tool: tool2,
1792
+ toolsContext
1793
+ }) {
1794
+ const contextSchema = tool2.contextSchema;
1795
+ const entry = toolsContext == null ? void 0 : toolsContext[toolName];
1796
+ if (contextSchema == null) {
1797
+ return entry;
1798
+ }
1799
+ return await validateTypes({
1800
+ value: entry,
1801
+ schema: contextSchema,
1802
+ context: { field: "tool context", entityName: toolName }
1803
+ });
1804
+ }
1258
1805
  function aggregateUsage(steps) {
1259
1806
  var _a, _b, _c, _d;
1260
1807
  let inputTokens = 0;
@@ -1269,59 +1816,65 @@ function aggregateUsage(steps) {
1269
1816
  totalTokens: inputTokens + outputTokens
1270
1817
  };
1271
1818
  }
1272
- function filterTools(tools, activeTools) {
1273
- const filtered = {};
1274
- for (const toolName of activeTools) {
1275
- if (toolName in tools) {
1276
- filtered[toolName] = tools[toolName];
1277
- }
1278
- }
1279
- return filtered;
1280
- }
1281
- function getErrorMessage(error) {
1282
- if (error == null) {
1283
- return "unknown error";
1284
- }
1285
- if (typeof error === "string") {
1286
- return error;
1287
- }
1288
- if (error instanceof Error) {
1289
- return error.message;
1290
- }
1291
- return JSON.stringify(error);
1292
- }
1293
- function resolveProviderToolResult(toolCall, providerExecutedToolResults) {
1819
+ async function resolveProviderToolResult(toolCall, providerExecutedToolResults, tools, download) {
1294
1820
  const streamResult = providerExecutedToolResults == null ? void 0 : providerExecutedToolResults.get(toolCall.toolCallId);
1295
1821
  if (!streamResult) {
1296
1822
  console.warn(
1297
1823
  `[WorkflowAgent] Provider-executed tool "${toolCall.toolName}" (${toolCall.toolCallId}) did not receive a result from the stream. This may indicate a provider issue.`
1298
1824
  );
1299
1825
  return {
1300
- type: "tool-result",
1301
- toolCallId: toolCall.toolCallId,
1302
- toolName: toolCall.toolName,
1303
- output: {
1304
- type: "text",
1305
- value: ""
1306
- }
1826
+ modelResult: {
1827
+ type: "tool-result",
1828
+ toolCallId: toolCall.toolCallId,
1829
+ toolName: toolCall.toolName,
1830
+ output: {
1831
+ type: "text",
1832
+ value: ""
1833
+ }
1834
+ },
1835
+ rawOutput: "",
1836
+ isError: false
1307
1837
  };
1308
1838
  }
1309
1839
  const result = streamResult.result;
1310
- const isString = typeof result === "string";
1840
+ const errorMode = streamResult.isError ? typeof result === "string" ? "text" : "json" : "none";
1841
+ return {
1842
+ modelResult: {
1843
+ type: "tool-result",
1844
+ toolCallId: toolCall.toolCallId,
1845
+ toolName: toolCall.toolName,
1846
+ output: await createLanguageModelToolResultOutput({
1847
+ toolCallId: toolCall.toolCallId,
1848
+ toolName: toolCall.toolName,
1849
+ input: toolCall.input,
1850
+ output: result,
1851
+ tool: tools == null ? void 0 : tools[toolCall.toolName],
1852
+ errorMode,
1853
+ supportedUrls: {},
1854
+ download
1855
+ })
1856
+ },
1857
+ rawOutput: result,
1858
+ isError: streamResult.isError === true
1859
+ };
1860
+ }
1861
+ function createInvalidToolResult(toolCall) {
1311
1862
  return {
1312
1863
  type: "tool-result",
1313
1864
  toolCallId: toolCall.toolCallId,
1314
1865
  toolName: toolCall.toolName,
1315
- output: isString ? streamResult.isError ? { type: "error-text", value: result } : { type: "text", value: result } : streamResult.isError ? {
1316
- type: "error-json",
1317
- value: result
1318
- } : {
1319
- type: "json",
1320
- value: result
1866
+ output: {
1867
+ type: "error-text",
1868
+ value: getErrorMessage(toolCall.error)
1321
1869
  }
1322
1870
  };
1323
1871
  }
1324
- async function executeTool(toolCall, tools, messages, experimentalContext) {
1872
+ function getToolCallbackMessages(messages) {
1873
+ var _a;
1874
+ const withoutAssistantToolCall = ((_a = messages.at(-1)) == null ? void 0 : _a.role) === "assistant" ? messages.slice(0, -1) : messages;
1875
+ return withoutAssistantToolCall;
1876
+ }
1877
+ async function executeTool(toolCall, tools, messages, context, download) {
1325
1878
  const tool2 = tools[toolCall.toolName];
1326
1879
  if (!tool2) throw new Error(`Tool "${toolCall.toolName}" not found`);
1327
1880
  if (typeof tool2.execute !== "function") {
@@ -1330,97 +1883,57 @@ async function executeTool(toolCall, tools, messages, experimentalContext) {
1330
1883
  );
1331
1884
  }
1332
1885
  const parsedInput = toolCall.input;
1886
+ let toolResult;
1333
1887
  try {
1334
1888
  const { execute } = tool2;
1335
- const toolResult = await execute(parsedInput, {
1889
+ toolResult = await execute(parsedInput, {
1336
1890
  toolCallId: toolCall.toolCallId,
1337
1891
  // Pass the conversation messages to the tool so it has context about the conversation
1338
1892
  messages,
1339
- // Pass context to the tool
1340
- context: experimentalContext
1893
+ // Pass per-tool context to the tool (resolved from `toolsContext`)
1894
+ context
1341
1895
  });
1342
- const output = typeof toolResult === "string" ? { type: "text", value: toolResult } : { type: "json", value: toolResult };
1343
- return {
1344
- type: "tool-result",
1345
- toolCallId: toolCall.toolCallId,
1346
- toolName: toolCall.toolName,
1347
- output
1348
- };
1349
1896
  } catch (error) {
1897
+ const errorMessage = getErrorMessage(error);
1350
1898
  return {
1351
- type: "tool-result",
1352
- toolCallId: toolCall.toolCallId,
1353
- toolName: toolCall.toolName,
1354
- output: {
1355
- type: "error-text",
1356
- value: getErrorMessage(error)
1357
- }
1899
+ modelResult: {
1900
+ type: "tool-result",
1901
+ toolCallId: toolCall.toolCallId,
1902
+ toolName: toolCall.toolName,
1903
+ output: await createLanguageModelToolResultOutput({
1904
+ toolCallId: toolCall.toolCallId,
1905
+ toolName: toolCall.toolName,
1906
+ input: parsedInput,
1907
+ output: errorMessage,
1908
+ tool: tool2,
1909
+ errorMode: "text",
1910
+ supportedUrls: {},
1911
+ download
1912
+ })
1913
+ },
1914
+ rawOutput: errorMessage,
1915
+ isError: true
1358
1916
  };
1359
1917
  }
1360
- }
1361
- function collectToolApprovalsFromMessages(messages) {
1362
- var _a;
1363
- const lastMessage = messages.at(-1);
1364
- if ((lastMessage == null ? void 0 : lastMessage.role) !== "tool") {
1365
- return { approvedToolApprovals: [], deniedToolApprovals: [] };
1366
- }
1367
- const toolCallsByToolCallId = {};
1368
- for (const message of messages) {
1369
- if (message.role === "assistant" && Array.isArray(message.content)) {
1370
- for (const part of message.content) {
1371
- if (part.type === "tool-call") {
1372
- toolCallsByToolCallId[part.toolCallId] = {
1373
- toolName: part.toolName,
1374
- input: (_a = part.input) != null ? _a : part.args
1375
- };
1376
- }
1377
- }
1378
- }
1379
- }
1380
- const approvalRequestsByApprovalId = {};
1381
- for (const message of messages) {
1382
- if (message.role === "assistant" && Array.isArray(message.content)) {
1383
- for (const part of message.content) {
1384
- if (part.type === "tool-approval-request") {
1385
- approvalRequestsByApprovalId[part.approvalId] = {
1386
- approvalId: part.approvalId,
1387
- toolCallId: part.toolCallId
1388
- };
1389
- }
1390
- }
1391
- }
1392
- }
1393
- const existingToolResults = /* @__PURE__ */ new Set();
1394
- for (const part of lastMessage.content) {
1395
- if (part.type === "tool-result") {
1396
- existingToolResults.add(part.toolCallId);
1397
- }
1398
- }
1399
- const approvedToolApprovals = [];
1400
- const deniedToolApprovals = [];
1401
- const approvalResponses = lastMessage.content.filter(
1402
- (part) => part.type === "tool-approval-response"
1403
- );
1404
- for (const response of approvalResponses) {
1405
- const approvalRequest = approvalRequestsByApprovalId[response.approvalId];
1406
- if (approvalRequest == null) continue;
1407
- if (existingToolResults.has(approvalRequest.toolCallId)) continue;
1408
- const toolCall = toolCallsByToolCallId[approvalRequest.toolCallId];
1409
- if (toolCall == null) continue;
1410
- const approval = {
1411
- toolCallId: approvalRequest.toolCallId,
1918
+ return {
1919
+ modelResult: {
1920
+ type: "tool-result",
1921
+ toolCallId: toolCall.toolCallId,
1412
1922
  toolName: toolCall.toolName,
1413
- input: toolCall.input,
1414
- approvalId: response.approvalId,
1415
- reason: response.reason
1416
- };
1417
- if (response.approved) {
1418
- approvedToolApprovals.push(approval);
1419
- } else {
1420
- deniedToolApprovals.push(approval);
1421
- }
1422
- }
1423
- return { approvedToolApprovals, deniedToolApprovals };
1923
+ output: await createLanguageModelToolResultOutput({
1924
+ toolCallId: toolCall.toolCallId,
1925
+ toolName: toolCall.toolName,
1926
+ input: parsedInput,
1927
+ output: toolResult,
1928
+ tool: tool2,
1929
+ errorMode: "none",
1930
+ supportedUrls: {},
1931
+ download
1932
+ })
1933
+ },
1934
+ rawOutput: toolResult,
1935
+ isError: false
1936
+ };
1424
1937
  }
1425
1938
 
1426
1939
  // src/to-ui-message-chunk.ts
@@ -1555,16 +2068,16 @@ function toUIMessageChunk(part) {
1555
2068
  case "raw":
1556
2069
  return void 0;
1557
2070
  default: {
1558
- const p = part;
1559
- if (p.type === "tool-approval-request") {
2071
+ const passthroughPart = part;
2072
+ if (passthroughPart.type === "tool-approval-request") {
1560
2073
  return {
1561
2074
  type: "tool-approval-request",
1562
- approvalId: p.approvalId,
1563
- toolCallId: p.toolCallId
2075
+ approvalId: passthroughPart.approvalId,
2076
+ toolCallId: passthroughPart.toolCallId
1564
2077
  };
1565
2078
  }
1566
- if (p.type === "finish-step" || p.type === "start-step" || p.type === "tool-output-denied") {
1567
- return p;
2079
+ if (passthroughPart.type === "finish-step" || passthroughPart.type === "start-step" || passthroughPart.type === "tool-output-denied") {
2080
+ return passthroughPart;
1568
2081
  }
1569
2082
  return void 0;
1570
2083
  }
@@ -1663,7 +2176,7 @@ var WorkflowChatTransport = class {
1663
2176
  messageId
1664
2177
  }) : void 0;
1665
2178
  const url = (_a = requestConfig == null ? void 0 : requestConfig.api) != null ? _a : this.api;
1666
- const res = await this.fetch(url, {
2179
+ const response = await this.fetch(url, {
1667
2180
  method: "POST",
1668
2181
  body: JSON.stringify(
1669
2182
  (_b = requestConfig == null ? void 0 : requestConfig.body) != null ? _b : { messages, ...options.body }
@@ -1672,21 +2185,21 @@ var WorkflowChatTransport = class {
1672
2185
  credentials: requestConfig == null ? void 0 : requestConfig.credentials,
1673
2186
  signal: abortSignal
1674
2187
  });
1675
- if (!res.ok || !res.body) {
2188
+ if (!response.ok || !response.body) {
1676
2189
  throw new Error(
1677
- `Failed to fetch chat: ${res.status} ${await res.text()}`
2190
+ `Failed to fetch chat: ${response.status} ${await response.text()}`
1678
2191
  );
1679
2192
  }
1680
- const workflowRunId = res.headers.get("x-workflow-run-id");
2193
+ const workflowRunId = response.headers.get("x-workflow-run-id");
1681
2194
  if (!workflowRunId) {
1682
2195
  throw new Error(
1683
2196
  'Workflow run ID not found in "x-workflow-run-id" response header'
1684
2197
  );
1685
2198
  }
1686
- await ((_c = this.onChatSendMessage) == null ? void 0 : _c.call(this, res, options));
2199
+ await ((_c = this.onChatSendMessage) == null ? void 0 : _c.call(this, response, options));
1687
2200
  try {
1688
2201
  const chunkStream = parseJsonEventStream({
1689
- stream: res.body,
2202
+ stream: response.body,
1690
2203
  schema: uiMessageChunkSchema
1691
2204
  });
1692
2205
  for await (const chunk of createAsyncIterableStream(chunkStream)) {
@@ -1721,8 +2234,8 @@ var WorkflowChatTransport = class {
1721
2234
  * @throws Error if the reconnection request fails or returns a non-OK status
1722
2235
  */
1723
2236
  async reconnectToStream(options) {
1724
- const it = this.reconnectToStreamIterator(options);
1725
- return convertAsyncIteratorToReadableStream(it);
2237
+ const reconnectIterator = this.reconnectToStreamIterator(options);
2238
+ return convertAsyncIteratorToReadableStream(reconnectIterator);
1726
2239
  }
1727
2240
  async *reconnectToStreamIterator(options, workflowRunId, initialChunkIndex = 0) {
1728
2241
  var _a, _b;
@@ -1745,20 +2258,22 @@ var WorkflowChatTransport = class {
1745
2258
  while (!gotFinish) {
1746
2259
  const startIndex = useExplicitStartIndex ? explicitStartIndex : replayFromStart ? 0 : chunkIndex;
1747
2260
  const url = `${baseUrl}?startIndex=${startIndex}`;
1748
- const res = await this.fetch(url, {
2261
+ const response = await this.fetch(url, {
1749
2262
  headers: requestConfig == null ? void 0 : requestConfig.headers,
1750
2263
  credentials: requestConfig == null ? void 0 : requestConfig.credentials,
1751
2264
  signal: options.abortSignal
1752
2265
  });
1753
- if (!res.ok || !res.body) {
2266
+ if (!response.ok || !response.body) {
1754
2267
  throw new Error(
1755
- `Failed to fetch chat: ${res.status} ${await res.text()}`
2268
+ `Failed to fetch chat: ${response.status} ${await response.text()}`
1756
2269
  );
1757
2270
  }
1758
2271
  if (useExplicitStartIndex && explicitStartIndex > 0) {
1759
2272
  chunkIndex = explicitStartIndex;
1760
2273
  } else if (useExplicitStartIndex && explicitStartIndex < 0) {
1761
- const tailIndexHeader = res.headers.get("x-workflow-stream-tail-index");
2274
+ const tailIndexHeader = response.headers.get(
2275
+ "x-workflow-stream-tail-index"
2276
+ );
1762
2277
  const tailIndex = tailIndexHeader !== null ? parseInt(tailIndexHeader, 10) : NaN;
1763
2278
  if (!Number.isNaN(tailIndex)) {
1764
2279
  chunkIndex = Math.max(0, tailIndex + 1 + explicitStartIndex);
@@ -1772,7 +2287,7 @@ var WorkflowChatTransport = class {
1772
2287
  useExplicitStartIndex = false;
1773
2288
  try {
1774
2289
  const chunkStream = parseJsonEventStream({
1775
- stream: res.body,
2290
+ stream: response.body,
1776
2291
  schema: uiMessageChunkSchema
1777
2292
  });
1778
2293
  for await (const chunk of createAsyncIterableStream(chunkStream)) {