@ai-sdk/workflow 0.0.0-07500555-20260730161446

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 ADDED
@@ -0,0 +1,2530 @@
1
+ // src/workflow-agent.ts
2
+ import {
3
+ getErrorMessage,
4
+ validateTypes,
5
+ withUserAgentSuffix
6
+ } from "@ai-sdk/provider-utils";
7
+ import {
8
+ Output,
9
+ experimental_filterActiveTools as filterActiveTools2
10
+ } from "ai";
11
+ import {
12
+ createRestrictedTelemetryDispatcher as createRestrictedTelemetryDispatcher2,
13
+ collectToolApprovals,
14
+ convertToLanguageModelPrompt,
15
+ mergeAbortSignals,
16
+ mergeCallbacks,
17
+ standardizePrompt,
18
+ validateApprovedToolApprovals
19
+ } from "ai/internal";
20
+
21
+ // src/create-language-model-tool-result-output.ts
22
+ import {
23
+ createDefaultDownloadFunction,
24
+ createToolModelOutput,
25
+ downloadAssets,
26
+ mapToolResultOutput
27
+ } from "ai/internal";
28
+ async function createLanguageModelToolResultOutput({
29
+ toolCallId,
30
+ toolName,
31
+ input,
32
+ output,
33
+ tool: tool2,
34
+ errorMode,
35
+ supportedUrls,
36
+ download = createDefaultDownloadFunction(),
37
+ provider
38
+ }) {
39
+ const modelOutput = await createToolModelOutput({
40
+ toolCallId,
41
+ input,
42
+ output,
43
+ tool: tool2,
44
+ errorMode
45
+ });
46
+ const downloadedAssets = modelOutput.type === "content" ? await downloadAssets(
47
+ [
48
+ {
49
+ role: "tool",
50
+ content: [
51
+ {
52
+ type: "tool-result",
53
+ toolCallId,
54
+ toolName,
55
+ output: modelOutput
56
+ }
57
+ ]
58
+ }
59
+ ],
60
+ download,
61
+ supportedUrls
62
+ ) : {};
63
+ return mapToolResultOutput({
64
+ output: modelOutput,
65
+ provider,
66
+ downloadedAssets
67
+ });
68
+ }
69
+
70
+ // src/stream-text-iterator.ts
71
+ import {
72
+ experimental_filterActiveTools as filterActiveTools
73
+ } from "ai";
74
+ import { createRestrictedTelemetryDispatcher } from "ai/internal";
75
+
76
+ // src/do-stream-step.ts
77
+ import {
78
+ experimental_streamLanguageModelCall as streamModelCall,
79
+ gateway
80
+ } from "ai";
81
+
82
+ // src/serializable-schema.ts
83
+ import { asSchema, jsonSchema } from "@ai-sdk/provider-utils";
84
+ import { tool } from "ai";
85
+ import Ajv from "ajv";
86
+ function serializeToolSet(tools) {
87
+ return Object.fromEntries(
88
+ Object.entries(tools).map(([name, t]) => {
89
+ var _a;
90
+ const def = {
91
+ description: t.description,
92
+ // TODO support tools with function descriptions
93
+ inputSchema: asSchema(t.inputSchema).jsonSchema
94
+ };
95
+ if (t.type === "provider") {
96
+ def.type = "provider";
97
+ def.isProviderExecuted = (_a = t.isProviderExecuted) != null ? _a : false;
98
+ def.id = t.id;
99
+ def.args = t.args;
100
+ }
101
+ return [name, def];
102
+ })
103
+ );
104
+ }
105
+ function resolveSerializableTools(tools) {
106
+ const ajv = new Ajv();
107
+ return Object.fromEntries(
108
+ Object.entries(tools).map(([name, t]) => {
109
+ var _a, _b;
110
+ if (t.type === "provider") {
111
+ return [
112
+ name,
113
+ tool({
114
+ type: "provider",
115
+ id: t.id,
116
+ args: (_a = t.args) != null ? _a : {},
117
+ isProviderExecuted: (_b = t.isProviderExecuted) != null ? _b : false,
118
+ inputSchema: jsonSchema(t.inputSchema)
119
+ })
120
+ ];
121
+ }
122
+ const validateFn = ajv.compile(t.inputSchema);
123
+ return [
124
+ name,
125
+ tool({
126
+ description: t.description,
127
+ inputSchema: jsonSchema(t.inputSchema, {
128
+ validate: (value) => {
129
+ if (validateFn(value)) {
130
+ return { success: true, value };
131
+ }
132
+ return {
133
+ success: false,
134
+ error: new Error(ajv.errorsText(validateFn.errors))
135
+ };
136
+ }
137
+ })
138
+ })
139
+ ];
140
+ })
141
+ );
142
+ }
143
+
144
+ // src/do-stream-step.ts
145
+ async function doStreamStep(conversationPrompt, modelInit, writable, serializedTools, options) {
146
+ "use step";
147
+ const model = typeof modelInit === "string" ? gateway.languageModel(modelInit) : modelInit;
148
+ const tools = serializedTools ? resolveSerializableTools(serializedTools) : void 0;
149
+ const { stream: modelStream } = await streamModelCall({
150
+ model,
151
+ // streamModelCall expects Prompt (ModelMessage[]) but we pass the
152
+ // pre-converted LanguageModelV4Prompt. standardizePrompt inside
153
+ // streamModelCall handles both formats.
154
+ messages: conversationPrompt,
155
+ allowSystemInMessages: true,
156
+ tools,
157
+ toolChoice: options == null ? void 0 : options.toolChoice,
158
+ includeRawChunks: options == null ? void 0 : options.includeRawChunks,
159
+ providerOptions: options == null ? void 0 : options.providerOptions,
160
+ abortSignal: options == null ? void 0 : options.abortSignal,
161
+ headers: options == null ? void 0 : options.headers,
162
+ reasoning: options == null ? void 0 : options.reasoning,
163
+ maxOutputTokens: options == null ? void 0 : options.maxOutputTokens,
164
+ temperature: options == null ? void 0 : options.temperature,
165
+ topP: options == null ? void 0 : options.topP,
166
+ topK: options == null ? void 0 : options.topK,
167
+ presencePenalty: options == null ? void 0 : options.presencePenalty,
168
+ frequencyPenalty: options == null ? void 0 : options.frequencyPenalty,
169
+ stopSequences: options == null ? void 0 : options.stopSequences,
170
+ seed: options == null ? void 0 : options.seed,
171
+ repairToolCall: options == null ? void 0 : options.repairToolCall
172
+ });
173
+ const toolCalls = [];
174
+ const providerExecutedToolResults = /* @__PURE__ */ new Map();
175
+ let finish;
176
+ let text = "";
177
+ const reasoningParts = [];
178
+ let responseMetadata;
179
+ let warnings;
180
+ const writer = writable == null ? void 0 : writable.getWriter();
181
+ try {
182
+ for await (const part of modelStream) {
183
+ switch (part.type) {
184
+ case "text-delta":
185
+ text += part.text;
186
+ break;
187
+ case "reasoning-delta":
188
+ reasoningParts.push({ text: part.text });
189
+ break;
190
+ case "tool-call": {
191
+ const toolCallPart = part;
192
+ toolCalls.push({
193
+ type: "tool-call",
194
+ toolCallId: toolCallPart.toolCallId,
195
+ toolName: toolCallPart.toolName,
196
+ input: toolCallPart.input,
197
+ providerExecuted: toolCallPart.providerExecuted,
198
+ providerMetadata: toolCallPart.providerMetadata,
199
+ dynamic: toolCallPart.dynamic,
200
+ invalid: toolCallPart.invalid,
201
+ error: toolCallPart.error
202
+ });
203
+ break;
204
+ }
205
+ case "tool-result":
206
+ if (part.providerExecuted) {
207
+ providerExecutedToolResults.set(part.toolCallId, {
208
+ toolCallId: part.toolCallId,
209
+ toolName: part.toolName,
210
+ result: part.output,
211
+ isError: false
212
+ });
213
+ }
214
+ break;
215
+ case "tool-error": {
216
+ const errorPart = part;
217
+ if (errorPart.providerExecuted) {
218
+ providerExecutedToolResults.set(errorPart.toolCallId, {
219
+ toolCallId: errorPart.toolCallId,
220
+ toolName: errorPart.toolName,
221
+ result: errorPart.error,
222
+ isError: true
223
+ });
224
+ }
225
+ break;
226
+ }
227
+ case "model-call-end":
228
+ finish = {
229
+ finishReason: part.finishReason,
230
+ rawFinishReason: part.rawFinishReason,
231
+ usage: part.usage,
232
+ providerMetadata: part.providerMetadata
233
+ };
234
+ break;
235
+ case "model-call-start":
236
+ warnings = part.warnings;
237
+ break;
238
+ case "model-call-response-metadata":
239
+ responseMetadata = part;
240
+ break;
241
+ }
242
+ if (writer) {
243
+ await writer.write(part);
244
+ }
245
+ }
246
+ } finally {
247
+ writer == null ? void 0 : writer.releaseLock();
248
+ }
249
+ return {
250
+ toolCalls,
251
+ finish,
252
+ raw: {
253
+ text,
254
+ reasoning: reasoningParts,
255
+ responseMetadata,
256
+ warnings
257
+ },
258
+ providerExecutedToolResults
259
+ };
260
+ }
261
+
262
+ // src/stream-text-iterator.ts
263
+ async function* streamTextIterator({
264
+ prompt,
265
+ tools = {},
266
+ writable,
267
+ model,
268
+ stopConditions,
269
+ onStepEnd,
270
+ onStepFinish,
271
+ onStepStart,
272
+ onError,
273
+ prepareStep,
274
+ generationSettings,
275
+ toolChoice,
276
+ runtimeContext,
277
+ toolsContext,
278
+ telemetry,
279
+ includeRawChunks = false,
280
+ repairToolCall,
281
+ responseFormat,
282
+ experimental_sandbox: sandbox
283
+ }) {
284
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
285
+ let conversationPrompt = [...prompt];
286
+ let currentModel = model;
287
+ let currentGenerationSettings = generationSettings != null ? generationSettings : {};
288
+ let currentToolChoice = toolChoice;
289
+ let currentRuntimeContext = runtimeContext != null ? runtimeContext : {};
290
+ let currentToolsContext = toolsContext != null ? toolsContext : {};
291
+ let currentActiveTools;
292
+ const steps = [];
293
+ let done = false;
294
+ let _isFirstIteration = true;
295
+ let stepNumber = 0;
296
+ let lastStep;
297
+ let lastStepWasToolCalls = false;
298
+ const telemetryDispatcher = createRestrictedTelemetryDispatcher({
299
+ telemetry,
300
+ includeRuntimeContext: telemetry == null ? void 0 : telemetry.includeRuntimeContext,
301
+ includeToolsContext: telemetry == null ? void 0 : telemetry.includeToolsContext
302
+ });
303
+ while (!done) {
304
+ if ((_a = currentGenerationSettings.abortSignal) == null ? void 0 : _a.aborted) {
305
+ break;
306
+ }
307
+ let stepSandbox = sandbox;
308
+ if (prepareStep) {
309
+ const prepareResult = await prepareStep({
310
+ model: currentModel,
311
+ stepNumber,
312
+ steps,
313
+ messages: conversationPrompt,
314
+ runtimeContext: currentRuntimeContext,
315
+ toolsContext: currentToolsContext,
316
+ experimental_sandbox: sandbox
317
+ });
318
+ stepSandbox = (_b = prepareResult == null ? void 0 : prepareResult.experimental_sandbox) != null ? _b : sandbox;
319
+ if ((prepareResult == null ? void 0 : prepareResult.model) !== void 0) {
320
+ currentModel = prepareResult.model;
321
+ }
322
+ if ((prepareResult == null ? void 0 : prepareResult.messages) !== void 0) {
323
+ conversationPrompt = [...prepareResult.messages];
324
+ }
325
+ if ((prepareResult == null ? void 0 : prepareResult.system) !== void 0) {
326
+ if (conversationPrompt.length > 0 && conversationPrompt[0].role === "system") {
327
+ conversationPrompt[0] = {
328
+ role: "system",
329
+ content: prepareResult.system
330
+ };
331
+ } else {
332
+ conversationPrompt.unshift({
333
+ role: "system",
334
+ content: prepareResult.system
335
+ });
336
+ }
337
+ }
338
+ if ((prepareResult == null ? void 0 : prepareResult.runtimeContext) !== void 0) {
339
+ currentRuntimeContext = prepareResult.runtimeContext;
340
+ }
341
+ if ((prepareResult == null ? void 0 : prepareResult.toolsContext) !== void 0) {
342
+ currentToolsContext = prepareResult.toolsContext;
343
+ }
344
+ if ((prepareResult == null ? void 0 : prepareResult.activeTools) !== void 0) {
345
+ currentActiveTools = prepareResult.activeTools;
346
+ }
347
+ if ((prepareResult == null ? void 0 : prepareResult.maxOutputTokens) !== void 0) {
348
+ currentGenerationSettings = {
349
+ ...currentGenerationSettings,
350
+ maxOutputTokens: prepareResult.maxOutputTokens
351
+ };
352
+ }
353
+ if ((prepareResult == null ? void 0 : prepareResult.temperature) !== void 0) {
354
+ currentGenerationSettings = {
355
+ ...currentGenerationSettings,
356
+ temperature: prepareResult.temperature
357
+ };
358
+ }
359
+ if ((prepareResult == null ? void 0 : prepareResult.topP) !== void 0) {
360
+ currentGenerationSettings = {
361
+ ...currentGenerationSettings,
362
+ topP: prepareResult.topP
363
+ };
364
+ }
365
+ if ((prepareResult == null ? void 0 : prepareResult.topK) !== void 0) {
366
+ currentGenerationSettings = {
367
+ ...currentGenerationSettings,
368
+ topK: prepareResult.topK
369
+ };
370
+ }
371
+ if ((prepareResult == null ? void 0 : prepareResult.presencePenalty) !== void 0) {
372
+ currentGenerationSettings = {
373
+ ...currentGenerationSettings,
374
+ presencePenalty: prepareResult.presencePenalty
375
+ };
376
+ }
377
+ if ((prepareResult == null ? void 0 : prepareResult.frequencyPenalty) !== void 0) {
378
+ currentGenerationSettings = {
379
+ ...currentGenerationSettings,
380
+ frequencyPenalty: prepareResult.frequencyPenalty
381
+ };
382
+ }
383
+ if ((prepareResult == null ? void 0 : prepareResult.stopSequences) !== void 0) {
384
+ currentGenerationSettings = {
385
+ ...currentGenerationSettings,
386
+ stopSequences: prepareResult.stopSequences
387
+ };
388
+ }
389
+ if ((prepareResult == null ? void 0 : prepareResult.seed) !== void 0) {
390
+ currentGenerationSettings = {
391
+ ...currentGenerationSettings,
392
+ seed: prepareResult.seed
393
+ };
394
+ }
395
+ if ((prepareResult == null ? void 0 : prepareResult.maxRetries) !== void 0) {
396
+ currentGenerationSettings = {
397
+ ...currentGenerationSettings,
398
+ maxRetries: prepareResult.maxRetries
399
+ };
400
+ }
401
+ if ((prepareResult == null ? void 0 : prepareResult.headers) !== void 0) {
402
+ currentGenerationSettings = {
403
+ ...currentGenerationSettings,
404
+ headers: prepareResult.headers
405
+ };
406
+ }
407
+ if ((prepareResult == null ? void 0 : prepareResult.reasoning) !== void 0) {
408
+ currentGenerationSettings = {
409
+ ...currentGenerationSettings,
410
+ reasoning: prepareResult.reasoning
411
+ };
412
+ }
413
+ if ((prepareResult == null ? void 0 : prepareResult.providerOptions) !== void 0) {
414
+ currentGenerationSettings = {
415
+ ...currentGenerationSettings,
416
+ providerOptions: prepareResult.providerOptions
417
+ };
418
+ }
419
+ if ((prepareResult == null ? void 0 : prepareResult.toolChoice) !== void 0) {
420
+ currentToolChoice = prepareResult.toolChoice;
421
+ }
422
+ }
423
+ if (onStepStart) {
424
+ await onStepStart({
425
+ stepNumber,
426
+ model: currentModel,
427
+ messages: conversationPrompt,
428
+ steps: [...steps],
429
+ runtimeContext: currentRuntimeContext,
430
+ toolsContext: currentToolsContext
431
+ });
432
+ }
433
+ const stepStartModelInfo = getModelInfo(currentModel);
434
+ await ((_c = telemetryDispatcher.onStepStart) == null ? void 0 : _c.call(telemetryDispatcher, {
435
+ callId: "workflow-agent",
436
+ provider: stepStartModelInfo.provider,
437
+ modelId: stepStartModelInfo.modelId,
438
+ stepNumber,
439
+ system: void 0,
440
+ messages: conversationPrompt,
441
+ tools,
442
+ toolChoice: currentToolChoice,
443
+ activeTools: currentActiveTools,
444
+ steps: steps.map(normalizeStepForTelemetry),
445
+ providerOptions: currentGenerationSettings.providerOptions,
446
+ output: void 0,
447
+ runtimeContext: currentRuntimeContext,
448
+ toolsContext: currentToolsContext
449
+ }));
450
+ try {
451
+ const effectiveTools = currentActiveTools && currentActiveTools.length > 0 ? (_d = filterActiveTools({
452
+ tools,
453
+ activeTools: currentActiveTools
454
+ })) != null ? _d : tools : tools;
455
+ const serializedTools = serializeToolSet(effectiveTools);
456
+ const modelCallInfo = getModelInfo(currentModel);
457
+ await ((_e = telemetryDispatcher.onLanguageModelCallStart) == null ? void 0 : _e.call(telemetryDispatcher, {
458
+ callId: "workflow-agent",
459
+ provider: modelCallInfo.provider,
460
+ modelId: modelCallInfo.modelId,
461
+ system: void 0,
462
+ messages: conversationPrompt,
463
+ tools: serializedTools == null ? void 0 : Object.values(serializedTools).map((tool2) => ({ ...tool2 })),
464
+ maxOutputTokens: currentGenerationSettings.maxOutputTokens,
465
+ temperature: currentGenerationSettings.temperature,
466
+ topP: currentGenerationSettings.topP,
467
+ topK: currentGenerationSettings.topK,
468
+ presencePenalty: currentGenerationSettings.presencePenalty,
469
+ frequencyPenalty: currentGenerationSettings.frequencyPenalty,
470
+ stopSequences: currentGenerationSettings.stopSequences,
471
+ seed: currentGenerationSettings.seed,
472
+ reasoning: currentGenerationSettings.reasoning,
473
+ providerOptions: currentGenerationSettings.providerOptions,
474
+ headers: currentGenerationSettings.headers
475
+ }));
476
+ const { toolCalls, finish, raw, providerExecutedToolResults } = await doStreamStep(
477
+ conversationPrompt,
478
+ currentModel,
479
+ writable,
480
+ serializedTools,
481
+ {
482
+ ...currentGenerationSettings,
483
+ toolChoice: currentToolChoice,
484
+ includeRawChunks,
485
+ repairToolCall,
486
+ responseFormat
487
+ }
488
+ );
489
+ const step = buildStepResult(raw, toolCalls, finish, {
490
+ stepNumber,
491
+ runtimeContext: currentRuntimeContext,
492
+ toolsContext: currentToolsContext
493
+ });
494
+ await ((_j = telemetryDispatcher.onLanguageModelCallEnd) == null ? void 0 : _j.call(telemetryDispatcher, {
495
+ callId: step.callId,
496
+ provider: (_g = (_f = step.model) == null ? void 0 : _f.provider) != null ? _g : "unknown",
497
+ modelId: (_i = (_h = step.model) == null ? void 0 : _h.modelId) != null ? _i : "unknown",
498
+ finishReason: step.finishReason,
499
+ usage: step.usage,
500
+ content: step.content,
501
+ responseId: step.response.id
502
+ }));
503
+ _isFirstIteration = false;
504
+ stepNumber++;
505
+ steps.push(step);
506
+ lastStep = step;
507
+ lastStepWasToolCalls = false;
508
+ const finishReason = finish == null ? void 0 : finish.finishReason;
509
+ if (finishReason === "tool-calls") {
510
+ lastStepWasToolCalls = true;
511
+ const textContent = step.content.filter(
512
+ (item) => item.type === "text"
513
+ );
514
+ conversationPrompt.push({
515
+ role: "assistant",
516
+ content: [
517
+ ...textContent,
518
+ ...toolCalls.map((toolCall) => {
519
+ const sanitizedMetadata = sanitizeProviderMetadataForToolCall(
520
+ toolCall.providerMetadata
521
+ );
522
+ return {
523
+ type: "tool-call",
524
+ toolCallId: toolCall.toolCallId,
525
+ toolName: toolCall.toolName,
526
+ input: toolCall.input,
527
+ ...sanitizedMetadata != null ? {
528
+ providerOptions: sanitizedMetadata
529
+ } : {}
530
+ };
531
+ })
532
+ ]
533
+ });
534
+ const toolResults = yield {
535
+ toolCalls,
536
+ messages: conversationPrompt,
537
+ step,
538
+ runtimeContext: currentRuntimeContext,
539
+ toolsContext: currentToolsContext,
540
+ experimental_sandbox: stepSandbox,
541
+ providerExecutedToolResults
542
+ };
543
+ conversationPrompt.push({
544
+ role: "tool",
545
+ content: toolResults
546
+ });
547
+ if (stopConditions) {
548
+ const stopConditionList = Array.isArray(stopConditions) ? stopConditions : [stopConditions];
549
+ if (stopConditionList.some((test) => test({ steps }))) {
550
+ done = true;
551
+ }
552
+ }
553
+ } else if (finishReason === "stop") {
554
+ const textContent = step.content.filter(
555
+ (item) => item.type === "text"
556
+ );
557
+ if (textContent.length > 0) {
558
+ conversationPrompt.push({
559
+ role: "assistant",
560
+ content: textContent
561
+ });
562
+ }
563
+ done = true;
564
+ } else if (finishReason === "length") {
565
+ done = true;
566
+ } else if (finishReason === "content-filter") {
567
+ done = true;
568
+ } else if (finishReason === "error") {
569
+ done = true;
570
+ } else if (finishReason === "other") {
571
+ done = true;
572
+ } else if (finishReason === "unknown") {
573
+ done = true;
574
+ } else if (!finishReason) {
575
+ done = true;
576
+ } else {
577
+ throw new Error(
578
+ `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}`
579
+ );
580
+ }
581
+ const resolvedOnStepEnd = onStepEnd != null ? onStepEnd : onStepFinish;
582
+ if (resolvedOnStepEnd) {
583
+ await resolvedOnStepEnd(step);
584
+ }
585
+ await ((_k = telemetryDispatcher.onStepEnd) == null ? void 0 : _k.call(telemetryDispatcher, normalizeStepForTelemetry(step)));
586
+ } catch (error) {
587
+ if (onError) {
588
+ await onError({ error });
589
+ }
590
+ throw error;
591
+ }
592
+ }
593
+ if (lastStep && !lastStepWasToolCalls) {
594
+ yield {
595
+ toolCalls: [],
596
+ messages: conversationPrompt,
597
+ step: lastStep,
598
+ runtimeContext: currentRuntimeContext,
599
+ toolsContext: currentToolsContext,
600
+ experimental_sandbox: sandbox
601
+ };
602
+ }
603
+ return conversationPrompt;
604
+ }
605
+ function getModelInfo(model) {
606
+ var _a;
607
+ return typeof model === "string" ? { provider: (_a = model.split("/")[0]) != null ? _a : "gateway", modelId: model } : { provider: model.provider, modelId: model.modelId };
608
+ }
609
+ function normalizeStepForTelemetry(step) {
610
+ var _a;
611
+ return {
612
+ ...step,
613
+ model: (_a = step.model) != null ? _a : { provider: "unknown", modelId: "unknown" }
614
+ };
615
+ }
616
+ function buildStepResult(raw, toolCalls, finish, opts) {
617
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
618
+ const { text, reasoning: reasoningParts, responseMetadata, warnings } = raw;
619
+ const reasoningText = reasoningParts.map((r) => r.text).join("") || void 0;
620
+ const validToolCalls = toolCalls.filter((tc) => !tc.invalid).map((tc) => ({
621
+ type: "tool-call",
622
+ toolCallId: tc.toolCallId,
623
+ toolName: tc.toolName,
624
+ input: tc.input,
625
+ ...tc.dynamic ? { dynamic: true } : {}
626
+ }));
627
+ return {
628
+ callId: "workflow-agent",
629
+ stepNumber: opts.stepNumber,
630
+ model: {
631
+ provider: (_b = (_a = responseMetadata == null ? void 0 : responseMetadata.modelId) == null ? void 0 : _a.split(":")[0]) != null ? _b : "unknown",
632
+ modelId: (_c = responseMetadata == null ? void 0 : responseMetadata.modelId) != null ? _c : "unknown"
633
+ },
634
+ functionId: void 0,
635
+ metadata: void 0,
636
+ runtimeContext: (_d = opts.runtimeContext) != null ? _d : {},
637
+ toolsContext: (_e = opts.toolsContext) != null ? _e : {},
638
+ content: [
639
+ ...text ? [{ type: "text", text }] : [],
640
+ ...validToolCalls
641
+ ],
642
+ text,
643
+ reasoning: reasoningParts.map((r) => ({
644
+ type: "reasoning",
645
+ text: r.text
646
+ })),
647
+ reasoningText,
648
+ files: [],
649
+ sources: [],
650
+ toolCalls: validToolCalls,
651
+ staticToolCalls: [],
652
+ dynamicToolCalls: validToolCalls.filter((tc) => tc.dynamic),
653
+ toolResults: [],
654
+ staticToolResults: [],
655
+ dynamicToolResults: [],
656
+ finishReason: (_f = finish == null ? void 0 : finish.finishReason) != null ? _f : "other",
657
+ rawFinishReason: finish == null ? void 0 : finish.rawFinishReason,
658
+ usage: (_g = finish == null ? void 0 : finish.usage) != null ? _g : {
659
+ inputTokens: 0,
660
+ inputTokenDetails: {
661
+ noCacheTokens: void 0,
662
+ cacheReadTokens: void 0,
663
+ cacheWriteTokens: void 0
664
+ },
665
+ outputTokens: 0,
666
+ outputTokenDetails: {
667
+ textTokens: void 0,
668
+ reasoningTokens: void 0
669
+ },
670
+ totalTokens: 0
671
+ },
672
+ performance: {
673
+ effectiveOutputTokensPerSecond: 0,
674
+ outputTokensPerSecond: void 0,
675
+ inputTokensPerSecond: void 0,
676
+ effectiveTotalTokensPerSecond: 0,
677
+ stepTimeMs: 0,
678
+ responseTimeMs: 0,
679
+ toolExecutionMs: {},
680
+ timeToFirstOutputMs: void 0
681
+ },
682
+ warnings,
683
+ request: {
684
+ body: "",
685
+ messages: []
686
+ // TODO implement step request messages
687
+ },
688
+ response: {
689
+ id: (_h = responseMetadata == null ? void 0 : responseMetadata.id) != null ? _h : "unknown",
690
+ timestamp: (_i = responseMetadata == null ? void 0 : responseMetadata.timestamp) != null ? _i : /* @__PURE__ */ new Date(),
691
+ modelId: (_j = responseMetadata == null ? void 0 : responseMetadata.modelId) != null ? _j : "unknown",
692
+ messages: []
693
+ },
694
+ providerMetadata: (_k = finish == null ? void 0 : finish.providerMetadata) != null ? _k : {}
695
+ };
696
+ }
697
+ function sanitizeProviderMetadataForToolCall(metadata) {
698
+ if (metadata == null) return void 0;
699
+ const meta = metadata;
700
+ if ("openai" in meta && meta.openai != null) {
701
+ const { openai, ...restProviders } = meta;
702
+ const openaiMeta = openai;
703
+ const { itemId: _itemId, ...restOpenai } = openaiMeta;
704
+ const hasOtherOpenaiFields = Object.keys(restOpenai).length > 0;
705
+ const hasOtherProviders = Object.keys(restProviders).length > 0;
706
+ if (hasOtherOpenaiFields && hasOtherProviders) {
707
+ return { ...restProviders, openai: restOpenai };
708
+ } else if (hasOtherOpenaiFields) {
709
+ return { openai: restOpenai };
710
+ } else if (hasOtherProviders) {
711
+ return restProviders;
712
+ }
713
+ return void 0;
714
+ }
715
+ return meta;
716
+ }
717
+
718
+ // src/workflow-agent.ts
719
+ var WorkflowAgent = class {
720
+ constructor(options) {
721
+ var _a, _b, _c, _d, _e;
722
+ this.id = options.id;
723
+ this.model = options.model;
724
+ this.tools = (_a = options.tools) != null ? _a : {};
725
+ this.instructions = (_b = options.instructions) != null ? _b : options.system;
726
+ this.toolChoice = options.toolChoice;
727
+ this.telemetry = options.telemetry;
728
+ this.runtimeContext = options.runtimeContext;
729
+ this.toolsContext = options.toolsContext;
730
+ this.stopWhen = options.stopWhen;
731
+ this.activeTools = options.activeTools;
732
+ this.output = options.output;
733
+ this.repairToolCall = (_c = options.repairToolCall) != null ? _c : options.experimental_repairToolCall;
734
+ this.experimentalDownload = options.experimental_download;
735
+ this.experimentalSandbox = options.experimental_sandbox;
736
+ this.prepareStep = options.prepareStep;
737
+ this.constructorOnStepEnd = (_d = options.onStepEnd) != null ? _d : options.onStepFinish;
738
+ const { onFinish, onEnd = onFinish } = options;
739
+ this.constructorOnEnd = onEnd;
740
+ this.constructorOnStart = options.experimental_onStart;
741
+ this.constructorOnStepStart = options.experimental_onStepStart;
742
+ this.constructorOnToolExecutionStart = options.onToolExecutionStart;
743
+ this.constructorOnToolExecutionEnd = options.onToolExecutionEnd;
744
+ this.prepareCall = options.prepareCall;
745
+ this.allowSystemInMessages = (_e = options.allowSystemInMessages) != null ? _e : false;
746
+ this.generationSettings = {
747
+ maxOutputTokens: options.maxOutputTokens,
748
+ temperature: options.temperature,
749
+ topP: options.topP,
750
+ topK: options.topK,
751
+ presencePenalty: options.presencePenalty,
752
+ frequencyPenalty: options.frequencyPenalty,
753
+ stopSequences: options.stopSequences,
754
+ seed: options.seed,
755
+ maxRetries: options.maxRetries,
756
+ abortSignal: options.abortSignal,
757
+ headers: options.headers,
758
+ reasoning: options.reasoning,
759
+ providerOptions: options.providerOptions
760
+ };
761
+ }
762
+ generate() {
763
+ throw new Error("Not implemented");
764
+ }
765
+ async stream(options) {
766
+ 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, _Q, _R, _S;
767
+ const { onFinish, onEnd = onFinish } = options;
768
+ let effectiveModel = this.model;
769
+ let effectiveInstructions = (_a = options.system) != null ? _a : this.instructions;
770
+ let effectivePrompt = options.prompt;
771
+ let effectiveMessages = options.messages;
772
+ let effectiveGenerationSettings = { ...this.generationSettings };
773
+ let effectiveRuntimeContext = (_c = (_b = options.runtimeContext) != null ? _b : this.runtimeContext) != null ? _c : {};
774
+ let effectiveToolsContext = (_e = (_d = options.toolsContext) != null ? _d : this.toolsContext) != null ? _e : {};
775
+ let effectiveToolChoiceFromPrepare = (_f = options.toolChoice) != null ? _f : this.toolChoice;
776
+ let effectiveTelemetryFromPrepare = (_g = options.telemetry) != null ? _g : this.telemetry;
777
+ const resolvedMessagesForPrepareCall = (_h = effectiveMessages != null ? effectiveMessages : typeof effectivePrompt === "string" ? [{ role: "user", content: effectivePrompt }] : effectivePrompt) != null ? _h : [];
778
+ if (this.prepareCall) {
779
+ const prepared = await this.prepareCall({
780
+ model: effectiveModel,
781
+ tools: this.tools,
782
+ instructions: effectiveInstructions,
783
+ toolChoice: effectiveToolChoiceFromPrepare,
784
+ telemetry: effectiveTelemetryFromPrepare,
785
+ runtimeContext: effectiveRuntimeContext,
786
+ toolsContext: effectiveToolsContext,
787
+ messages: resolvedMessagesForPrepareCall,
788
+ ...effectiveGenerationSettings
789
+ });
790
+ if (prepared.model !== void 0) effectiveModel = prepared.model;
791
+ if (prepared.instructions !== void 0)
792
+ effectiveInstructions = prepared.instructions;
793
+ if (prepared.messages !== void 0) {
794
+ effectiveMessages = prepared.messages;
795
+ effectivePrompt = void 0;
796
+ }
797
+ if (prepared.runtimeContext !== void 0)
798
+ effectiveRuntimeContext = prepared.runtimeContext;
799
+ if (prepared.toolsContext !== void 0)
800
+ effectiveToolsContext = prepared.toolsContext;
801
+ if (prepared.toolChoice !== void 0)
802
+ effectiveToolChoiceFromPrepare = prepared.toolChoice;
803
+ if (prepared.telemetry !== void 0)
804
+ effectiveTelemetryFromPrepare = prepared.telemetry;
805
+ if (prepared.maxOutputTokens !== void 0)
806
+ effectiveGenerationSettings.maxOutputTokens = prepared.maxOutputTokens;
807
+ if (prepared.temperature !== void 0)
808
+ effectiveGenerationSettings.temperature = prepared.temperature;
809
+ if (prepared.topP !== void 0)
810
+ effectiveGenerationSettings.topP = prepared.topP;
811
+ if (prepared.topK !== void 0)
812
+ effectiveGenerationSettings.topK = prepared.topK;
813
+ if (prepared.presencePenalty !== void 0)
814
+ effectiveGenerationSettings.presencePenalty = prepared.presencePenalty;
815
+ if (prepared.frequencyPenalty !== void 0)
816
+ effectiveGenerationSettings.frequencyPenalty = prepared.frequencyPenalty;
817
+ if (prepared.stopSequences !== void 0)
818
+ effectiveGenerationSettings.stopSequences = prepared.stopSequences;
819
+ if (prepared.seed !== void 0)
820
+ effectiveGenerationSettings.seed = prepared.seed;
821
+ if (prepared.headers !== void 0)
822
+ effectiveGenerationSettings.headers = prepared.headers;
823
+ if (prepared.reasoning !== void 0)
824
+ effectiveGenerationSettings.reasoning = prepared.reasoning;
825
+ if (prepared.providerOptions !== void 0)
826
+ effectiveGenerationSettings.providerOptions = prepared.providerOptions;
827
+ }
828
+ const effectiveTelemetry = effectiveTelemetryFromPrepare;
829
+ const telemetryDispatcher = createRestrictedTelemetryDispatcher2({
830
+ telemetry: effectiveTelemetry,
831
+ includeRuntimeContext: effectiveTelemetry == null ? void 0 : effectiveTelemetry.includeRuntimeContext,
832
+ includeToolsContext: effectiveTelemetry == null ? void 0 : effectiveTelemetry.includeToolsContext
833
+ });
834
+ const prompt = await standardizePrompt({
835
+ system: effectiveInstructions,
836
+ allowSystemInMessages: this.allowSystemInMessages,
837
+ ...effectivePrompt != null ? { prompt: effectivePrompt } : { messages: effectiveMessages }
838
+ });
839
+ const download = (_i = options.experimental_download) != null ? _i : this.experimentalDownload;
840
+ const sandbox = (_j = options.experimental_sandbox) != null ? _j : this.experimentalSandbox;
841
+ const collectedApprovals = collectToolApprovals({
842
+ messages: prompt.messages
843
+ });
844
+ const approvedToolApprovals = collectedApprovals.approvedToolApprovals.map(
845
+ (collected) => ({
846
+ toolCallId: collected.toolCall.toolCallId,
847
+ toolName: collected.toolCall.toolName,
848
+ input: collected.toolCall.input,
849
+ reason: collected.approvalResponse.reason,
850
+ providerExecuted: collected.toolCall.providerExecuted === true,
851
+ collected
852
+ })
853
+ );
854
+ const deniedToolApprovals = collectedApprovals.deniedToolApprovals.map(
855
+ (collected) => ({
856
+ toolCallId: collected.toolCall.toolCallId,
857
+ toolName: collected.toolCall.toolName,
858
+ input: collected.toolCall.input,
859
+ reason: collected.approvalResponse.reason,
860
+ providerExecuted: collected.toolCall.providerExecuted === true
861
+ })
862
+ );
863
+ const providerExecutedApprovalIds = new Set(
864
+ [
865
+ ...collectedApprovals.approvedToolApprovals,
866
+ ...collectedApprovals.deniedToolApprovals
867
+ ].filter((collected) => collected.toolCall.providerExecuted === true).map((collected) => collected.approvalResponse.approvalId)
868
+ );
869
+ if (approvedToolApprovals.length > 0 || deniedToolApprovals.length > 0) {
870
+ const _toolResultMessages = [];
871
+ const toolResultContent = [];
872
+ const approvedRawResults = [];
873
+ for (const approval of approvedToolApprovals) {
874
+ if (approval.providerExecuted) {
875
+ continue;
876
+ }
877
+ const tool2 = this.tools[approval.toolName];
878
+ if (tool2 && typeof tool2.execute === "function") {
879
+ if (!tool2.needsApproval) {
880
+ const reason = `Tool "${approval.toolName}" does not require approval`;
881
+ toolResultContent.push({
882
+ type: "tool-result",
883
+ toolCallId: approval.toolCallId,
884
+ toolName: approval.toolName,
885
+ output: await createLanguageModelToolResultOutput({
886
+ toolCallId: approval.toolCallId,
887
+ toolName: approval.toolName,
888
+ input: approval.input,
889
+ output: reason,
890
+ tool: tool2,
891
+ errorMode: "text",
892
+ supportedUrls: {},
893
+ download
894
+ })
895
+ });
896
+ continue;
897
+ }
898
+ let revalidationReason;
899
+ try {
900
+ const { deniedToolApprovals: policyDenied } = await validateApprovedToolApprovals({
901
+ approvedToolApprovals: [approval.collected],
902
+ tools: this.tools,
903
+ toolApproval: void 0,
904
+ messages: prompt.messages,
905
+ toolsContext: effectiveToolsContext,
906
+ runtimeContext: effectiveRuntimeContext
907
+ });
908
+ if (policyDenied.length > 0) {
909
+ revalidationReason = (_k = policyDenied[0].approvalResponse.reason) != null ? _k : "Tool approval denied";
910
+ }
911
+ } catch (error) {
912
+ revalidationReason = getErrorMessage(error);
913
+ }
914
+ if (revalidationReason != null) {
915
+ toolResultContent.push({
916
+ type: "tool-result",
917
+ toolCallId: approval.toolCallId,
918
+ toolName: approval.toolName,
919
+ output: await createLanguageModelToolResultOutput({
920
+ toolCallId: approval.toolCallId,
921
+ toolName: approval.toolName,
922
+ input: approval.input,
923
+ output: revalidationReason,
924
+ tool: tool2,
925
+ errorMode: "text",
926
+ supportedUrls: {},
927
+ download
928
+ })
929
+ });
930
+ continue;
931
+ }
932
+ try {
933
+ const { execute } = tool2;
934
+ const resolvedContext = await resolveToolContext({
935
+ toolName: approval.toolName,
936
+ tool: tool2,
937
+ toolsContext: effectiveToolsContext
938
+ });
939
+ const toolCallEvent = {
940
+ type: "tool-call",
941
+ toolCallId: approval.toolCallId,
942
+ toolName: approval.toolName,
943
+ input: approval.input
944
+ };
945
+ const messages2 = prompt.messages;
946
+ await ((_l = telemetryDispatcher.onToolExecutionStart) == null ? void 0 : _l.call(telemetryDispatcher, {
947
+ toolCall: toolCallEvent,
948
+ stepNumber: 0,
949
+ messages: messages2,
950
+ toolContext: resolvedContext
951
+ }));
952
+ const startTime = Date.now();
953
+ const executeApprovedTool = () => execute(approval.input, {
954
+ toolCallId: approval.toolCallId,
955
+ messages: [],
956
+ context: resolvedContext,
957
+ experimental_sandbox: sandbox
958
+ });
959
+ const toolResult = telemetryDispatcher.executeTool != null ? await telemetryDispatcher.executeTool({
960
+ callId: "workflow-agent",
961
+ toolCallId: approval.toolCallId,
962
+ execute: executeApprovedTool
963
+ }) : await executeApprovedTool();
964
+ await ((_m = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _m.call(telemetryDispatcher, {
965
+ toolCall: toolCallEvent,
966
+ stepNumber: 0,
967
+ durationMs: Date.now() - startTime,
968
+ messages: messages2,
969
+ toolContext: resolvedContext,
970
+ success: true,
971
+ output: toolResult
972
+ }));
973
+ toolResultContent.push({
974
+ type: "tool-result",
975
+ toolCallId: approval.toolCallId,
976
+ toolName: approval.toolName,
977
+ output: await createLanguageModelToolResultOutput({
978
+ toolCallId: approval.toolCallId,
979
+ toolName: approval.toolName,
980
+ input: approval.input,
981
+ output: toolResult,
982
+ tool: tool2,
983
+ errorMode: "none",
984
+ supportedUrls: {},
985
+ download
986
+ })
987
+ });
988
+ approvedRawResults.push({
989
+ toolCallId: approval.toolCallId,
990
+ toolName: approval.toolName,
991
+ input: approval.input,
992
+ output: toolResult
993
+ });
994
+ } catch (error) {
995
+ const errorMessage = getErrorMessage(error);
996
+ await ((_n = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _n.call(telemetryDispatcher, {
997
+ toolCall: {
998
+ type: "tool-call",
999
+ toolCallId: approval.toolCallId,
1000
+ toolName: approval.toolName,
1001
+ input: approval.input
1002
+ },
1003
+ stepNumber: 0,
1004
+ durationMs: 0,
1005
+ messages: prompt.messages,
1006
+ toolContext: void 0,
1007
+ success: false,
1008
+ error
1009
+ }));
1010
+ toolResultContent.push({
1011
+ type: "tool-result",
1012
+ toolCallId: approval.toolCallId,
1013
+ toolName: approval.toolName,
1014
+ output: await createLanguageModelToolResultOutput({
1015
+ toolCallId: approval.toolCallId,
1016
+ toolName: approval.toolName,
1017
+ input: approval.input,
1018
+ output: errorMessage,
1019
+ tool: tool2,
1020
+ errorMode: "text",
1021
+ supportedUrls: {},
1022
+ download
1023
+ })
1024
+ });
1025
+ approvedRawResults.push({
1026
+ toolCallId: approval.toolCallId,
1027
+ toolName: approval.toolName,
1028
+ input: approval.input,
1029
+ output: errorMessage
1030
+ });
1031
+ }
1032
+ }
1033
+ }
1034
+ for (const denial of deniedToolApprovals) {
1035
+ if (denial.providerExecuted) {
1036
+ continue;
1037
+ }
1038
+ toolResultContent.push({
1039
+ type: "tool-result",
1040
+ toolCallId: denial.toolCallId,
1041
+ toolName: denial.toolName,
1042
+ output: {
1043
+ type: "execution-denied",
1044
+ reason: denial.reason
1045
+ }
1046
+ });
1047
+ }
1048
+ const cleanedMessages = [];
1049
+ for (const msg of prompt.messages) {
1050
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
1051
+ const filtered = msg.content.filter(
1052
+ (p) => p.type !== "tool-approval-request" || providerExecutedApprovalIds.has(p.approvalId)
1053
+ );
1054
+ if (filtered.length > 0) {
1055
+ cleanedMessages.push({ ...msg, content: filtered });
1056
+ }
1057
+ } else if (msg.role === "tool") {
1058
+ const filtered = msg.content.flatMap((p) => {
1059
+ if (p.type !== "tool-approval-response") {
1060
+ return [p];
1061
+ }
1062
+ if (!providerExecutedApprovalIds.has(p.approvalId)) {
1063
+ return [];
1064
+ }
1065
+ return [{ ...p, providerExecuted: true }];
1066
+ });
1067
+ if (filtered.length > 0) {
1068
+ cleanedMessages.push({ ...msg, content: filtered });
1069
+ }
1070
+ } else {
1071
+ cleanedMessages.push(msg);
1072
+ }
1073
+ }
1074
+ if (toolResultContent.length > 0) {
1075
+ cleanedMessages.push({
1076
+ role: "tool",
1077
+ content: toolResultContent
1078
+ });
1079
+ }
1080
+ prompt.messages = cleanedMessages;
1081
+ if (options.writable && toolResultContent.length > 0) {
1082
+ const deniedResults = toolResultContent.filter((r) => r.output.type === "execution-denied").map((r) => ({ toolCallId: r.toolCallId }));
1083
+ await writeApprovalToolResults(
1084
+ options.writable,
1085
+ approvedRawResults,
1086
+ deniedResults
1087
+ );
1088
+ }
1089
+ }
1090
+ const modelPrompt = await convertToLanguageModelPrompt({
1091
+ prompt,
1092
+ supportedUrls: {},
1093
+ download
1094
+ });
1095
+ const effectiveAbortSignal = mergeAbortSignals(
1096
+ (_o = options.abortSignal) != null ? _o : effectiveGenerationSettings.abortSignal,
1097
+ options.timeout
1098
+ );
1099
+ const mergedGenerationSettings = {
1100
+ ...effectiveGenerationSettings,
1101
+ ...options.maxOutputTokens !== void 0 && {
1102
+ maxOutputTokens: options.maxOutputTokens
1103
+ },
1104
+ ...options.temperature !== void 0 && {
1105
+ temperature: options.temperature
1106
+ },
1107
+ ...options.topP !== void 0 && { topP: options.topP },
1108
+ ...options.topK !== void 0 && { topK: options.topK },
1109
+ ...options.presencePenalty !== void 0 && {
1110
+ presencePenalty: options.presencePenalty
1111
+ },
1112
+ ...options.frequencyPenalty !== void 0 && {
1113
+ frequencyPenalty: options.frequencyPenalty
1114
+ },
1115
+ ...options.stopSequences !== void 0 && {
1116
+ stopSequences: options.stopSequences
1117
+ },
1118
+ ...options.seed !== void 0 && { seed: options.seed },
1119
+ ...options.maxRetries !== void 0 && {
1120
+ maxRetries: options.maxRetries
1121
+ },
1122
+ ...effectiveAbortSignal !== void 0 && {
1123
+ abortSignal: effectiveAbortSignal
1124
+ },
1125
+ ...options.headers !== void 0 && { headers: options.headers },
1126
+ ...options.reasoning !== void 0 && { reasoning: options.reasoning },
1127
+ ...options.providerOptions !== void 0 && {
1128
+ providerOptions: options.providerOptions
1129
+ }
1130
+ };
1131
+ mergedGenerationSettings.headers = withUserAgentSuffix(
1132
+ (_p = mergedGenerationSettings.headers) != null ? _p : {},
1133
+ "ai-sdk-agent/workflow"
1134
+ );
1135
+ const mergedOnStepEnd = mergeCallbacks(
1136
+ this.constructorOnStepEnd,
1137
+ (_q = options.onStepEnd) != null ? _q : options.onStepFinish
1138
+ );
1139
+ const mergedOnEnd = mergeCallbacks(
1140
+ this.constructorOnEnd,
1141
+ onEnd
1142
+ );
1143
+ const mergedOnStart = mergeCallbacks(
1144
+ this.constructorOnStart,
1145
+ options.experimental_onStart
1146
+ );
1147
+ const mergedOnStepStart = mergeCallbacks(
1148
+ this.constructorOnStepStart,
1149
+ options.experimental_onStepStart
1150
+ );
1151
+ const mergedOnToolExecutionStart = mergeCallbacks(
1152
+ this.constructorOnToolExecutionStart,
1153
+ options.onToolExecutionStart
1154
+ );
1155
+ const mergedOnToolExecutionEnd = mergeCallbacks(
1156
+ this.constructorOnToolExecutionEnd,
1157
+ options.onToolExecutionEnd
1158
+ );
1159
+ const effectiveToolChoice = effectiveToolChoiceFromPrepare;
1160
+ const effectiveActiveTools = (_r = options.activeTools) != null ? _r : this.activeTools;
1161
+ const effectiveTools = effectiveActiveTools && effectiveActiveTools.length > 0 ? (_s = filterActiveTools2({
1162
+ tools: this.tools,
1163
+ activeTools: effectiveActiveTools
1164
+ })) != null ? _s : this.tools : this.tools;
1165
+ const effectiveModelInfo = getModelInfo2(effectiveModel);
1166
+ let runtimeContext = effectiveRuntimeContext;
1167
+ let toolsContext = effectiveToolsContext;
1168
+ const steps = [];
1169
+ let lastStepToolCalls = [];
1170
+ let lastStepToolResults = [];
1171
+ if (mergedOnStart) {
1172
+ await mergedOnStart({
1173
+ model: effectiveModel,
1174
+ messages: prompt.messages,
1175
+ runtimeContext,
1176
+ toolsContext
1177
+ });
1178
+ }
1179
+ await ((_v = telemetryDispatcher.onStart) == null ? void 0 : _v.call(telemetryDispatcher, {
1180
+ callId: "workflow-agent",
1181
+ operationId: "ai.workflowAgent.stream",
1182
+ provider: effectiveModelInfo.provider,
1183
+ modelId: effectiveModelInfo.modelId,
1184
+ system: void 0,
1185
+ messages: prompt.messages,
1186
+ tools: effectiveTools,
1187
+ toolChoice: effectiveToolChoice,
1188
+ activeTools: effectiveActiveTools,
1189
+ maxOutputTokens: mergedGenerationSettings.maxOutputTokens,
1190
+ temperature: mergedGenerationSettings.temperature,
1191
+ topP: mergedGenerationSettings.topP,
1192
+ topK: mergedGenerationSettings.topK,
1193
+ presencePenalty: mergedGenerationSettings.presencePenalty,
1194
+ frequencyPenalty: mergedGenerationSettings.frequencyPenalty,
1195
+ stopSequences: mergedGenerationSettings.stopSequences,
1196
+ seed: mergedGenerationSettings.seed,
1197
+ maxRetries: (_t = mergedGenerationSettings.maxRetries) != null ? _t : 2,
1198
+ timeout: void 0,
1199
+ headers: mergedGenerationSettings.headers,
1200
+ reasoning: mergedGenerationSettings.reasoning,
1201
+ providerOptions: mergedGenerationSettings.providerOptions,
1202
+ output: (_u = options.output) != null ? _u : this.output,
1203
+ runtimeContext,
1204
+ toolsContext
1205
+ }));
1206
+ const executeToolWithCallbacks = async (toolCall, tools, messages2, perToolContexts, currentStepNumber = 0, stepSandbox) => {
1207
+ var _a2, _b2, _c2, _d2;
1208
+ const toolCallEvent = {
1209
+ type: "tool-call",
1210
+ toolCallId: toolCall.toolCallId,
1211
+ toolName: toolCall.toolName,
1212
+ input: toolCall.input
1213
+ };
1214
+ const tool2 = tools[toolCall.toolName];
1215
+ const resolvedContext = tool2 ? await resolveToolContext({
1216
+ toolName: toolCall.toolName,
1217
+ tool: tool2,
1218
+ toolsContext: perToolContexts
1219
+ }) : void 0;
1220
+ const modelMessages = getToolCallbackMessages(messages2);
1221
+ if (mergedOnToolExecutionStart) {
1222
+ await mergedOnToolExecutionStart({
1223
+ toolCall: toolCallEvent,
1224
+ stepNumber: currentStepNumber,
1225
+ messages: modelMessages,
1226
+ toolContext: resolvedContext
1227
+ });
1228
+ }
1229
+ await ((_a2 = telemetryDispatcher.onToolExecutionStart) == null ? void 0 : _a2.call(telemetryDispatcher, {
1230
+ toolCall: toolCallEvent,
1231
+ stepNumber: currentStepNumber,
1232
+ messages: modelMessages,
1233
+ toolContext: resolvedContext
1234
+ }));
1235
+ const startTime = Date.now();
1236
+ let result;
1237
+ try {
1238
+ const execute = () => executeTool(
1239
+ toolCall,
1240
+ tools,
1241
+ messages2,
1242
+ resolvedContext,
1243
+ download,
1244
+ stepSandbox
1245
+ );
1246
+ result = telemetryDispatcher.executeTool != null ? await telemetryDispatcher.executeTool({
1247
+ callId: "workflow-agent",
1248
+ toolCallId: toolCall.toolCallId,
1249
+ execute
1250
+ }) : await execute();
1251
+ } catch (err) {
1252
+ const durationMs2 = Date.now() - startTime;
1253
+ if (mergedOnToolExecutionEnd) {
1254
+ await mergedOnToolExecutionEnd({
1255
+ toolCall: toolCallEvent,
1256
+ stepNumber: currentStepNumber,
1257
+ durationMs: durationMs2,
1258
+ messages: modelMessages,
1259
+ toolContext: resolvedContext,
1260
+ success: false,
1261
+ error: err
1262
+ });
1263
+ }
1264
+ await ((_b2 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _b2.call(telemetryDispatcher, {
1265
+ toolCall: toolCallEvent,
1266
+ stepNumber: currentStepNumber,
1267
+ durationMs: durationMs2,
1268
+ messages: modelMessages,
1269
+ toolContext: resolvedContext,
1270
+ success: false,
1271
+ error: err
1272
+ }));
1273
+ throw err;
1274
+ }
1275
+ const durationMs = Date.now() - startTime;
1276
+ if (mergedOnToolExecutionEnd) {
1277
+ if (result.isError) {
1278
+ await mergedOnToolExecutionEnd({
1279
+ toolCall: toolCallEvent,
1280
+ stepNumber: currentStepNumber,
1281
+ durationMs,
1282
+ messages: modelMessages,
1283
+ toolContext: resolvedContext,
1284
+ success: false,
1285
+ error: result.rawOutput
1286
+ });
1287
+ } else {
1288
+ await mergedOnToolExecutionEnd({
1289
+ toolCall: toolCallEvent,
1290
+ stepNumber: currentStepNumber,
1291
+ durationMs,
1292
+ messages: modelMessages,
1293
+ toolContext: resolvedContext,
1294
+ success: true,
1295
+ output: result.rawOutput
1296
+ });
1297
+ }
1298
+ }
1299
+ if (result.isError) {
1300
+ await ((_c2 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _c2.call(telemetryDispatcher, {
1301
+ toolCall: toolCallEvent,
1302
+ stepNumber: currentStepNumber,
1303
+ durationMs,
1304
+ messages: modelMessages,
1305
+ toolContext: resolvedContext,
1306
+ success: false,
1307
+ error: result.rawOutput
1308
+ }));
1309
+ } else {
1310
+ await ((_d2 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _d2.call(telemetryDispatcher, {
1311
+ toolCall: toolCallEvent,
1312
+ stepNumber: currentStepNumber,
1313
+ durationMs,
1314
+ messages: modelMessages,
1315
+ toolContext: resolvedContext,
1316
+ success: true,
1317
+ output: result.rawOutput
1318
+ }));
1319
+ }
1320
+ return result;
1321
+ };
1322
+ const recordProviderExecutedToolTelemetry = async (toolCall, result, messages2, currentStepNumber) => {
1323
+ var _a2, _b2;
1324
+ const toolCallEvent = {
1325
+ type: "tool-call",
1326
+ toolCallId: toolCall.toolCallId,
1327
+ toolName: toolCall.toolName,
1328
+ input: toolCall.input
1329
+ };
1330
+ const modelMessages = getToolCallbackMessages(messages2);
1331
+ await ((_a2 = telemetryDispatcher.onToolExecutionStart) == null ? void 0 : _a2.call(telemetryDispatcher, {
1332
+ toolCall: toolCallEvent,
1333
+ stepNumber: currentStepNumber,
1334
+ messages: modelMessages,
1335
+ toolContext: void 0
1336
+ }));
1337
+ await ((_b2 = telemetryDispatcher.onToolExecutionEnd) == null ? void 0 : _b2.call(telemetryDispatcher, {
1338
+ toolCall: toolCallEvent,
1339
+ stepNumber: currentStepNumber,
1340
+ durationMs: 0,
1341
+ messages: modelMessages,
1342
+ toolContext: void 0,
1343
+ ...result.isError ? {
1344
+ success: false,
1345
+ error: result.rawOutput
1346
+ } : {
1347
+ success: true,
1348
+ output: result.rawOutput
1349
+ }
1350
+ }));
1351
+ };
1352
+ if ((_w = mergedGenerationSettings.abortSignal) == null ? void 0 : _w.aborted) {
1353
+ if (options.onAbort) {
1354
+ await options.onAbort({ steps });
1355
+ }
1356
+ return {
1357
+ messages: prompt.messages,
1358
+ steps,
1359
+ toolCalls: [],
1360
+ toolResults: [],
1361
+ finishReason: "other",
1362
+ totalUsage: aggregateUsage(steps),
1363
+ output: void 0
1364
+ };
1365
+ }
1366
+ const iterator = streamTextIterator({
1367
+ model: effectiveModel,
1368
+ tools: effectiveTools,
1369
+ writable: options.writable,
1370
+ prompt: modelPrompt,
1371
+ stopConditions: (_x = options.stopWhen) != null ? _x : this.stopWhen,
1372
+ onStepEnd: mergedOnStepEnd,
1373
+ onStepStart: mergedOnStepStart,
1374
+ onError: options.onError,
1375
+ prepareStep: (_y = options.prepareStep) != null ? _y : this.prepareStep,
1376
+ generationSettings: mergedGenerationSettings,
1377
+ toolChoice: effectiveToolChoice,
1378
+ runtimeContext,
1379
+ toolsContext,
1380
+ telemetry: effectiveTelemetry,
1381
+ includeRawChunks: (_z = options.includeRawChunks) != null ? _z : false,
1382
+ repairToolCall: (_B = (_A = options.repairToolCall) != null ? _A : options.experimental_repairToolCall) != null ? _B : this.repairToolCall,
1383
+ responseFormat: await ((_D = (_C = options.output) != null ? _C : this.output) == null ? void 0 : _D.responseFormat),
1384
+ experimental_sandbox: sandbox
1385
+ });
1386
+ let finalMessages;
1387
+ let encounteredError;
1388
+ let wasAborted = false;
1389
+ try {
1390
+ let result = await iterator.next();
1391
+ while (!result.done) {
1392
+ if ((_E = mergedGenerationSettings.abortSignal) == null ? void 0 : _E.aborted) {
1393
+ wasAborted = true;
1394
+ if (options.onAbort) {
1395
+ await options.onAbort({ steps });
1396
+ }
1397
+ break;
1398
+ }
1399
+ const {
1400
+ toolCalls,
1401
+ messages: iterMessages,
1402
+ step,
1403
+ runtimeContext: yieldedRuntimeContext,
1404
+ toolsContext: yieldedToolsContext,
1405
+ experimental_sandbox: stepSandbox,
1406
+ providerExecutedToolResults
1407
+ } = result.value;
1408
+ const toolExecutionSandbox = stepSandbox != null ? stepSandbox : sandbox;
1409
+ const currentStepNumber = steps.length;
1410
+ if (step) {
1411
+ steps.push(step);
1412
+ }
1413
+ if (yieldedRuntimeContext !== void 0) {
1414
+ runtimeContext = yieldedRuntimeContext;
1415
+ }
1416
+ if (yieldedToolsContext !== void 0) {
1417
+ toolsContext = yieldedToolsContext;
1418
+ }
1419
+ if (toolCalls.length > 0) {
1420
+ const invalidToolCalls = toolCalls.filter((tc) => tc.invalid === true);
1421
+ const validToolCalls = toolCalls.filter((tc) => tc.invalid !== true);
1422
+ const nonProviderToolCalls = validToolCalls.filter(
1423
+ (tc) => !tc.providerExecuted
1424
+ );
1425
+ const providerToolCalls = validToolCalls.filter(
1426
+ (tc) => tc.providerExecuted
1427
+ );
1428
+ const approvalNeeded = await Promise.all(
1429
+ nonProviderToolCalls.map(async (tc) => {
1430
+ const tool2 = effectiveTools[tc.toolName];
1431
+ if (!tool2) return false;
1432
+ if (tool2.needsApproval == null) return false;
1433
+ if (typeof tool2.needsApproval === "boolean")
1434
+ return tool2.needsApproval;
1435
+ const resolvedContext = await resolveToolContext({
1436
+ toolName: tc.toolName,
1437
+ tool: tool2,
1438
+ toolsContext
1439
+ });
1440
+ return tool2.needsApproval(tc.input, {
1441
+ toolCallId: tc.toolCallId,
1442
+ messages: iterMessages,
1443
+ context: resolvedContext
1444
+ });
1445
+ })
1446
+ );
1447
+ const executableToolCalls = nonProviderToolCalls.filter((tc, i) => {
1448
+ const tool2 = effectiveTools[tc.toolName];
1449
+ return (!tool2 || typeof tool2.execute === "function") && !approvalNeeded[i];
1450
+ });
1451
+ const pausedToolCalls = nonProviderToolCalls.filter((tc, i) => {
1452
+ const tool2 = effectiveTools[tc.toolName];
1453
+ return tool2 && typeof tool2.execute !== "function" || approvalNeeded[i];
1454
+ });
1455
+ if (pausedToolCalls.length > 0) {
1456
+ const executableResults = await Promise.all(
1457
+ executableToolCalls.map(
1458
+ (toolCall) => executeToolWithCallbacks(
1459
+ toolCall,
1460
+ effectiveTools,
1461
+ iterMessages,
1462
+ toolsContext,
1463
+ currentStepNumber,
1464
+ toolExecutionSandbox
1465
+ )
1466
+ )
1467
+ );
1468
+ const providerResults = await Promise.all(
1469
+ providerToolCalls.map(
1470
+ (toolCall) => resolveProviderToolResult(
1471
+ toolCall,
1472
+ providerExecutedToolResults,
1473
+ effectiveTools,
1474
+ download
1475
+ )
1476
+ )
1477
+ );
1478
+ await Promise.all(
1479
+ providerToolCalls.map(
1480
+ (toolCall, index) => recordProviderExecutedToolTelemetry(
1481
+ toolCall,
1482
+ providerResults[index],
1483
+ iterMessages,
1484
+ currentStepNumber
1485
+ )
1486
+ )
1487
+ );
1488
+ const continuationInvalidResults = invalidToolCalls.map(
1489
+ createInvalidToolResult
1490
+ );
1491
+ const resolvedResults = [
1492
+ ...executableResults.map((result2) => result2.modelResult),
1493
+ ...providerResults.map((result2) => result2.modelResult),
1494
+ ...continuationInvalidResults
1495
+ ];
1496
+ const executedResults = [...executableResults, ...providerResults];
1497
+ const allToolCalls = toolCalls.map((tc) => ({
1498
+ type: "tool-call",
1499
+ toolCallId: tc.toolCallId,
1500
+ toolName: tc.toolName,
1501
+ input: tc.input
1502
+ }));
1503
+ const allToolResults = executedResults.map((r) => {
1504
+ var _a2;
1505
+ return {
1506
+ type: "tool-result",
1507
+ toolCallId: r.modelResult.toolCallId,
1508
+ toolName: r.modelResult.toolName,
1509
+ input: (_a2 = toolCalls.find(
1510
+ (tc) => tc.toolCallId === r.modelResult.toolCallId
1511
+ )) == null ? void 0 : _a2.input,
1512
+ output: r.rawOutput
1513
+ };
1514
+ });
1515
+ if (resolvedResults.length > 0) {
1516
+ iterMessages.push({
1517
+ role: "tool",
1518
+ content: resolvedResults
1519
+ });
1520
+ }
1521
+ const messages2 = iterMessages;
1522
+ const lastStep2 = steps[steps.length - 1];
1523
+ const totalUsage2 = aggregateUsage(steps);
1524
+ const finishReason2 = (_F = lastStep2 == null ? void 0 : lastStep2.finishReason) != null ? _F : "other";
1525
+ if (mergedOnEnd && !wasAborted) {
1526
+ await mergedOnEnd({
1527
+ steps,
1528
+ messages: messages2,
1529
+ text: (_G = lastStep2 == null ? void 0 : lastStep2.text) != null ? _G : "",
1530
+ finishReason: finishReason2,
1531
+ usage: totalUsage2,
1532
+ totalUsage: totalUsage2,
1533
+ runtimeContext,
1534
+ toolsContext,
1535
+ output: void 0
1536
+ });
1537
+ }
1538
+ if (!wasAborted && steps.length > 0) {
1539
+ const telemetrySteps = steps.map(normalizeStepForTelemetry2);
1540
+ const lastTelemetryStep = telemetrySteps[telemetrySteps.length - 1];
1541
+ await ((_H = telemetryDispatcher.onEnd) == null ? void 0 : _H.call(telemetryDispatcher, {
1542
+ ...lastTelemetryStep,
1543
+ steps: telemetrySteps,
1544
+ usage: totalUsage2,
1545
+ totalUsage: totalUsage2
1546
+ }));
1547
+ }
1548
+ if (options.writable) {
1549
+ const approvalToolCalls = pausedToolCalls.filter((_, i) => {
1550
+ const tcIndex = nonProviderToolCalls.indexOf(
1551
+ pausedToolCalls[i]
1552
+ );
1553
+ return approvalNeeded[tcIndex];
1554
+ });
1555
+ if (approvalToolCalls.length > 0) {
1556
+ await writeApprovalRequests(
1557
+ options.writable,
1558
+ approvalToolCalls.map((tc) => ({
1559
+ toolCallId: tc.toolCallId,
1560
+ toolName: tc.toolName
1561
+ }))
1562
+ );
1563
+ }
1564
+ }
1565
+ if (options.writable) {
1566
+ const sendFinish = (_I = options.sendFinish) != null ? _I : true;
1567
+ const preventClose = (_J = options.preventClose) != null ? _J : false;
1568
+ if (sendFinish || !preventClose) {
1569
+ await closeStream(options.writable, preventClose, sendFinish);
1570
+ }
1571
+ }
1572
+ return {
1573
+ messages: messages2,
1574
+ steps,
1575
+ toolCalls: allToolCalls,
1576
+ toolResults: allToolResults,
1577
+ finishReason: finishReason2,
1578
+ totalUsage: totalUsage2,
1579
+ output: void 0
1580
+ };
1581
+ }
1582
+ const clientToolResults = await Promise.all(
1583
+ nonProviderToolCalls.map(
1584
+ (toolCall) => executeToolWithCallbacks(
1585
+ toolCall,
1586
+ effectiveTools,
1587
+ iterMessages,
1588
+ toolsContext,
1589
+ currentStepNumber,
1590
+ toolExecutionSandbox
1591
+ )
1592
+ )
1593
+ );
1594
+ const providerToolResults = await Promise.all(
1595
+ providerToolCalls.map(
1596
+ (toolCall) => resolveProviderToolResult(
1597
+ toolCall,
1598
+ providerExecutedToolResults,
1599
+ effectiveTools,
1600
+ download
1601
+ )
1602
+ )
1603
+ );
1604
+ await Promise.all(
1605
+ providerToolCalls.map(
1606
+ (toolCall, index) => recordProviderExecutedToolTelemetry(
1607
+ toolCall,
1608
+ providerToolResults[index],
1609
+ iterMessages,
1610
+ currentStepNumber
1611
+ )
1612
+ )
1613
+ );
1614
+ const continuationInvalidToolResults = invalidToolCalls.map(
1615
+ createInvalidToolResult
1616
+ );
1617
+ const executedToolResults = toolCalls.flatMap((tc) => {
1618
+ const clientResult = clientToolResults.find(
1619
+ (r) => r.modelResult.toolCallId === tc.toolCallId
1620
+ );
1621
+ if (clientResult) return [clientResult];
1622
+ const providerResult = providerToolResults.find(
1623
+ (r) => r.modelResult.toolCallId === tc.toolCallId
1624
+ );
1625
+ if (providerResult) return [providerResult];
1626
+ return [];
1627
+ });
1628
+ const continuationToolResults = toolCalls.flatMap((tc) => {
1629
+ const invalidResult = continuationInvalidToolResults.find(
1630
+ (r) => r.toolCallId === tc.toolCallId
1631
+ );
1632
+ if (invalidResult) return [invalidResult];
1633
+ const executedResult = executedToolResults.find(
1634
+ (r) => r.modelResult.toolCallId === tc.toolCallId
1635
+ );
1636
+ if (executedResult) return [executedResult.modelResult];
1637
+ return [];
1638
+ });
1639
+ if (options.writable) {
1640
+ await writeToolResultsWithStepBoundary(
1641
+ options.writable,
1642
+ executedToolResults.map((r) => {
1643
+ var _a2;
1644
+ return {
1645
+ toolCallId: r.modelResult.toolCallId,
1646
+ toolName: r.modelResult.toolName,
1647
+ input: (_a2 = toolCalls.find(
1648
+ (tc) => tc.toolCallId === r.modelResult.toolCallId
1649
+ )) == null ? void 0 : _a2.input,
1650
+ output: r.rawOutput
1651
+ };
1652
+ })
1653
+ );
1654
+ }
1655
+ lastStepToolCalls = toolCalls.map((tc) => ({
1656
+ type: "tool-call",
1657
+ toolCallId: tc.toolCallId,
1658
+ toolName: tc.toolName,
1659
+ input: tc.input
1660
+ }));
1661
+ lastStepToolResults = executedToolResults.map((r) => {
1662
+ var _a2;
1663
+ return {
1664
+ type: "tool-result",
1665
+ toolCallId: r.modelResult.toolCallId,
1666
+ toolName: r.modelResult.toolName,
1667
+ input: (_a2 = toolCalls.find(
1668
+ (tc) => tc.toolCallId === r.modelResult.toolCallId
1669
+ )) == null ? void 0 : _a2.input,
1670
+ output: r.rawOutput
1671
+ };
1672
+ });
1673
+ result = await iterator.next(continuationToolResults);
1674
+ } else {
1675
+ lastStepToolCalls = [];
1676
+ lastStepToolResults = [];
1677
+ result = await iterator.next([]);
1678
+ }
1679
+ }
1680
+ if (result.done) {
1681
+ finalMessages = result.value;
1682
+ }
1683
+ } catch (error) {
1684
+ encounteredError = error;
1685
+ if (error instanceof Error && error.name === "AbortError") {
1686
+ wasAborted = true;
1687
+ if (options.onAbort) {
1688
+ await options.onAbort({ steps });
1689
+ }
1690
+ } else if (options.onError) {
1691
+ await options.onError({ error });
1692
+ }
1693
+ await ((_K = telemetryDispatcher.onError) == null ? void 0 : _K.call(telemetryDispatcher, error));
1694
+ }
1695
+ const messages = finalMessages != null ? finalMessages : prompt.messages;
1696
+ const effectiveOutput = (_L = options.output) != null ? _L : this.output;
1697
+ let experimentalOutput = void 0;
1698
+ if (effectiveOutput && steps.length > 0) {
1699
+ const lastStep2 = steps[steps.length - 1];
1700
+ const text = lastStep2.text;
1701
+ if (text) {
1702
+ try {
1703
+ experimentalOutput = await effectiveOutput.parseCompleteOutput(
1704
+ { text },
1705
+ {
1706
+ response: lastStep2.response,
1707
+ usage: lastStep2.usage,
1708
+ finishReason: lastStep2.finishReason
1709
+ }
1710
+ );
1711
+ } catch (parseError) {
1712
+ if (!encounteredError) {
1713
+ encounteredError = parseError;
1714
+ }
1715
+ }
1716
+ }
1717
+ }
1718
+ const lastStep = steps[steps.length - 1];
1719
+ const totalUsage = aggregateUsage(steps);
1720
+ const finishReason = (_M = lastStep == null ? void 0 : lastStep.finishReason) != null ? _M : "other";
1721
+ if (mergedOnEnd && !wasAborted) {
1722
+ await mergedOnEnd({
1723
+ steps,
1724
+ messages,
1725
+ text: (_N = lastStep == null ? void 0 : lastStep.text) != null ? _N : "",
1726
+ finishReason,
1727
+ usage: totalUsage,
1728
+ totalUsage,
1729
+ runtimeContext,
1730
+ toolsContext,
1731
+ output: experimentalOutput
1732
+ });
1733
+ }
1734
+ if (!wasAborted && steps.length > 0) {
1735
+ const telemetrySteps = steps.map(normalizeStepForTelemetry2);
1736
+ const lastTelemetryStep = telemetrySteps[telemetrySteps.length - 1];
1737
+ await ((_O = telemetryDispatcher.onEnd) == null ? void 0 : _O.call(telemetryDispatcher, {
1738
+ ...lastTelemetryStep,
1739
+ steps: telemetrySteps,
1740
+ usage: totalUsage,
1741
+ totalUsage
1742
+ }));
1743
+ }
1744
+ if (encounteredError) {
1745
+ if (options.writable) {
1746
+ const sendFinish = (_P = options.sendFinish) != null ? _P : true;
1747
+ const preventClose = (_Q = options.preventClose) != null ? _Q : false;
1748
+ if (sendFinish || !preventClose) {
1749
+ await closeStream(options.writable, preventClose, sendFinish);
1750
+ }
1751
+ }
1752
+ throw encounteredError;
1753
+ }
1754
+ if (options.writable) {
1755
+ const sendFinish = (_R = options.sendFinish) != null ? _R : true;
1756
+ const preventClose = (_S = options.preventClose) != null ? _S : false;
1757
+ if (sendFinish || !preventClose) {
1758
+ await closeStream(options.writable, preventClose, sendFinish);
1759
+ }
1760
+ }
1761
+ return {
1762
+ messages,
1763
+ steps,
1764
+ toolCalls: lastStepToolCalls,
1765
+ toolResults: lastStepToolResults,
1766
+ finishReason,
1767
+ totalUsage,
1768
+ output: experimentalOutput
1769
+ };
1770
+ }
1771
+ };
1772
+ function getModelInfo2(model) {
1773
+ var _a;
1774
+ return typeof model === "string" ? { provider: (_a = model.split("/")[0]) != null ? _a : "gateway", modelId: model } : { provider: model.provider, modelId: model.modelId };
1775
+ }
1776
+ function normalizeStepForTelemetry2(step) {
1777
+ var _a;
1778
+ return {
1779
+ ...step,
1780
+ model: (_a = step.model) != null ? _a : { provider: "unknown", modelId: "unknown" }
1781
+ };
1782
+ }
1783
+ async function closeStream(writable, preventClose, sendFinish) {
1784
+ "use step";
1785
+ if (sendFinish) {
1786
+ const writer = writable.getWriter();
1787
+ try {
1788
+ await writer.write({ type: "finish" });
1789
+ } finally {
1790
+ writer.releaseLock();
1791
+ }
1792
+ }
1793
+ if (!preventClose) {
1794
+ await writable.close();
1795
+ }
1796
+ }
1797
+ async function writeApprovalRequests(writable, toolCalls) {
1798
+ "use step";
1799
+ const writer = writable.getWriter();
1800
+ try {
1801
+ for (const tc of toolCalls) {
1802
+ await writer.write({
1803
+ type: "tool-approval-request",
1804
+ approvalId: `approval-${tc.toolCallId}`,
1805
+ toolCallId: tc.toolCallId
1806
+ });
1807
+ }
1808
+ } finally {
1809
+ writer.releaseLock();
1810
+ }
1811
+ }
1812
+ async function writeToolResultsWithStepBoundary(writable, results) {
1813
+ "use step";
1814
+ const writer = writable.getWriter();
1815
+ try {
1816
+ for (const r of results) {
1817
+ await writer.write({
1818
+ type: "tool-result",
1819
+ toolCallId: r.toolCallId,
1820
+ toolName: r.toolName,
1821
+ input: r.input,
1822
+ output: r.output
1823
+ });
1824
+ }
1825
+ await writer.write({ type: "finish-step" });
1826
+ await writer.write({ type: "start-step" });
1827
+ } finally {
1828
+ writer.releaseLock();
1829
+ }
1830
+ }
1831
+ async function writeApprovalToolResults(writable, approvedResults, deniedResults) {
1832
+ "use step";
1833
+ const writer = writable.getWriter();
1834
+ try {
1835
+ for (const r of approvedResults) {
1836
+ await writer.write({
1837
+ type: "tool-result",
1838
+ toolCallId: r.toolCallId,
1839
+ toolName: r.toolName,
1840
+ input: r.input,
1841
+ output: r.output
1842
+ });
1843
+ }
1844
+ for (const r of deniedResults) {
1845
+ await writer.write({
1846
+ type: "tool-output-denied",
1847
+ toolCallId: r.toolCallId
1848
+ });
1849
+ }
1850
+ await writer.write({ type: "finish-step" });
1851
+ await writer.write({ type: "start-step" });
1852
+ } finally {
1853
+ writer.releaseLock();
1854
+ }
1855
+ }
1856
+ async function resolveToolContext({
1857
+ toolName,
1858
+ tool: tool2,
1859
+ toolsContext
1860
+ }) {
1861
+ const contextSchema = tool2.contextSchema;
1862
+ const entry = toolsContext == null ? void 0 : toolsContext[toolName];
1863
+ if (contextSchema == null) {
1864
+ return entry;
1865
+ }
1866
+ return await validateTypes({
1867
+ value: entry,
1868
+ schema: contextSchema,
1869
+ context: { field: "tool context", entityName: toolName }
1870
+ });
1871
+ }
1872
+ function aggregateUsage(steps) {
1873
+ var _a, _b, _c, _d;
1874
+ let inputTokens = 0;
1875
+ let outputTokens = 0;
1876
+ for (const step of steps) {
1877
+ inputTokens += (_b = (_a = step.usage) == null ? void 0 : _a.inputTokens) != null ? _b : 0;
1878
+ outputTokens += (_d = (_c = step.usage) == null ? void 0 : _c.outputTokens) != null ? _d : 0;
1879
+ }
1880
+ return {
1881
+ inputTokens,
1882
+ outputTokens,
1883
+ totalTokens: inputTokens + outputTokens
1884
+ };
1885
+ }
1886
+ async function resolveProviderToolResult(toolCall, providerExecutedToolResults, tools, download) {
1887
+ const streamResult = providerExecutedToolResults == null ? void 0 : providerExecutedToolResults.get(toolCall.toolCallId);
1888
+ if (!streamResult) {
1889
+ console.warn(
1890
+ `[WorkflowAgent] Provider-executed tool "${toolCall.toolName}" (${toolCall.toolCallId}) did not receive a result from the stream. This may indicate a provider issue.`
1891
+ );
1892
+ return {
1893
+ modelResult: {
1894
+ type: "tool-result",
1895
+ toolCallId: toolCall.toolCallId,
1896
+ toolName: toolCall.toolName,
1897
+ output: {
1898
+ type: "text",
1899
+ value: ""
1900
+ }
1901
+ },
1902
+ rawOutput: "",
1903
+ isError: false
1904
+ };
1905
+ }
1906
+ const result = streamResult.result;
1907
+ const errorMode = streamResult.isError ? typeof result === "string" ? "text" : "json" : "none";
1908
+ return {
1909
+ modelResult: {
1910
+ type: "tool-result",
1911
+ toolCallId: toolCall.toolCallId,
1912
+ toolName: toolCall.toolName,
1913
+ output: await createLanguageModelToolResultOutput({
1914
+ toolCallId: toolCall.toolCallId,
1915
+ toolName: toolCall.toolName,
1916
+ input: toolCall.input,
1917
+ output: result,
1918
+ tool: tools == null ? void 0 : tools[toolCall.toolName],
1919
+ errorMode,
1920
+ supportedUrls: {},
1921
+ download
1922
+ })
1923
+ },
1924
+ rawOutput: result,
1925
+ isError: streamResult.isError === true
1926
+ };
1927
+ }
1928
+ function createInvalidToolResult(toolCall) {
1929
+ return {
1930
+ type: "tool-result",
1931
+ toolCallId: toolCall.toolCallId,
1932
+ toolName: toolCall.toolName,
1933
+ output: {
1934
+ type: "error-text",
1935
+ value: getErrorMessage(toolCall.error)
1936
+ }
1937
+ };
1938
+ }
1939
+ function getToolCallbackMessages(messages) {
1940
+ var _a;
1941
+ const withoutAssistantToolCall = ((_a = messages.at(-1)) == null ? void 0 : _a.role) === "assistant" ? messages.slice(0, -1) : messages;
1942
+ return withoutAssistantToolCall;
1943
+ }
1944
+ async function executeTool(toolCall, tools, messages, context, download, sandbox) {
1945
+ const tool2 = tools[toolCall.toolName];
1946
+ if (!tool2) throw new Error(`Tool "${toolCall.toolName}" not found`);
1947
+ if (typeof tool2.execute !== "function") {
1948
+ throw new Error(
1949
+ `Tool "${toolCall.toolName}" does not have an execute function. Client-side tools should be filtered before calling executeTool.`
1950
+ );
1951
+ }
1952
+ const parsedInput = toolCall.input;
1953
+ let toolResult;
1954
+ try {
1955
+ const { execute } = tool2;
1956
+ toolResult = await execute(parsedInput, {
1957
+ toolCallId: toolCall.toolCallId,
1958
+ // Pass the conversation messages to the tool so it has context about the conversation
1959
+ messages,
1960
+ // Pass per-tool context to the tool (resolved from `toolsContext`)
1961
+ context,
1962
+ experimental_sandbox: sandbox
1963
+ });
1964
+ } catch (error) {
1965
+ const errorMessage = getErrorMessage(error);
1966
+ return {
1967
+ modelResult: {
1968
+ type: "tool-result",
1969
+ toolCallId: toolCall.toolCallId,
1970
+ toolName: toolCall.toolName,
1971
+ output: await createLanguageModelToolResultOutput({
1972
+ toolCallId: toolCall.toolCallId,
1973
+ toolName: toolCall.toolName,
1974
+ input: parsedInput,
1975
+ output: errorMessage,
1976
+ tool: tool2,
1977
+ errorMode: "text",
1978
+ supportedUrls: {},
1979
+ download
1980
+ })
1981
+ },
1982
+ rawOutput: errorMessage,
1983
+ isError: true
1984
+ };
1985
+ }
1986
+ return {
1987
+ modelResult: {
1988
+ type: "tool-result",
1989
+ toolCallId: toolCall.toolCallId,
1990
+ toolName: toolCall.toolName,
1991
+ output: await createLanguageModelToolResultOutput({
1992
+ toolCallId: toolCall.toolCallId,
1993
+ toolName: toolCall.toolName,
1994
+ input: parsedInput,
1995
+ output: toolResult,
1996
+ tool: tool2,
1997
+ errorMode: "none",
1998
+ supportedUrls: {},
1999
+ download
2000
+ })
2001
+ },
2002
+ rawOutput: toolResult,
2003
+ isError: false
2004
+ };
2005
+ }
2006
+
2007
+ // src/to-ui-message-chunk.ts
2008
+ function toUIMessageChunk(part) {
2009
+ var _a;
2010
+ switch (part.type) {
2011
+ case "text-start":
2012
+ return {
2013
+ type: "text-start",
2014
+ id: part.id,
2015
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2016
+ };
2017
+ case "text-delta":
2018
+ return {
2019
+ type: "text-delta",
2020
+ id: part.id,
2021
+ delta: part.text,
2022
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2023
+ };
2024
+ case "text-end":
2025
+ return {
2026
+ type: "text-end",
2027
+ id: part.id,
2028
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2029
+ };
2030
+ case "reasoning-start":
2031
+ return {
2032
+ type: "reasoning-start",
2033
+ id: part.id,
2034
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2035
+ };
2036
+ case "reasoning-delta":
2037
+ return {
2038
+ type: "reasoning-delta",
2039
+ id: part.id,
2040
+ delta: part.text,
2041
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2042
+ };
2043
+ case "reasoning-end":
2044
+ return {
2045
+ type: "reasoning-end",
2046
+ id: part.id,
2047
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2048
+ };
2049
+ case "file": {
2050
+ const file = part.file;
2051
+ return {
2052
+ type: "file",
2053
+ mediaType: file.mediaType,
2054
+ url: `data:${file.mediaType};base64,${file.base64}`
2055
+ };
2056
+ }
2057
+ case "source": {
2058
+ if (part.sourceType === "url") {
2059
+ return {
2060
+ type: "source-url",
2061
+ sourceId: part.id,
2062
+ url: part.url,
2063
+ title: part.title,
2064
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2065
+ };
2066
+ }
2067
+ if (part.sourceType === "document") {
2068
+ return {
2069
+ type: "source-document",
2070
+ sourceId: part.id,
2071
+ mediaType: part.mediaType,
2072
+ title: part.title,
2073
+ filename: part.filename,
2074
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2075
+ };
2076
+ }
2077
+ return void 0;
2078
+ }
2079
+ case "tool-input-start":
2080
+ return {
2081
+ type: "tool-input-start",
2082
+ toolCallId: part.id,
2083
+ toolName: part.toolName,
2084
+ ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}
2085
+ };
2086
+ case "tool-input-delta":
2087
+ return {
2088
+ type: "tool-input-delta",
2089
+ toolCallId: part.id,
2090
+ inputTextDelta: part.delta
2091
+ };
2092
+ case "tool-call": {
2093
+ const toolCallPart = part;
2094
+ if (toolCallPart.invalid) {
2095
+ return {
2096
+ type: "tool-input-error",
2097
+ toolCallId: toolCallPart.toolCallId,
2098
+ toolName: toolCallPart.toolName,
2099
+ input: toolCallPart.input,
2100
+ errorText: toolCallPart.error instanceof Error ? toolCallPart.error.message : String((_a = toolCallPart.error) != null ? _a : "Invalid tool call")
2101
+ };
2102
+ }
2103
+ return {
2104
+ type: "tool-input-available",
2105
+ toolCallId: part.toolCallId,
2106
+ toolName: part.toolName,
2107
+ input: part.input,
2108
+ ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
2109
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
2110
+ };
2111
+ }
2112
+ case "tool-result":
2113
+ return {
2114
+ type: "tool-output-available",
2115
+ toolCallId: part.toolCallId,
2116
+ output: part.output
2117
+ };
2118
+ case "tool-error":
2119
+ return {
2120
+ type: "tool-output-error",
2121
+ toolCallId: part.toolCallId,
2122
+ errorText: part.error instanceof Error ? part.error.message : String(part.error)
2123
+ };
2124
+ case "error": {
2125
+ const error = part.error;
2126
+ return {
2127
+ type: "error",
2128
+ errorText: error instanceof Error ? error.message : String(error)
2129
+ };
2130
+ }
2131
+ // These don't produce UI chunks
2132
+ case "tool-input-end":
2133
+ case "model-call-start":
2134
+ case "model-call-response-metadata":
2135
+ case "model-call-end":
2136
+ case "raw":
2137
+ return void 0;
2138
+ default: {
2139
+ const passthroughPart = part;
2140
+ if (passthroughPart.type === "tool-approval-request") {
2141
+ return {
2142
+ type: "tool-approval-request",
2143
+ approvalId: passthroughPart.approvalId,
2144
+ toolCallId: passthroughPart.toolCallId
2145
+ };
2146
+ }
2147
+ if (passthroughPart.type === "finish-step" || passthroughPart.type === "start-step" || passthroughPart.type === "tool-output-denied") {
2148
+ return passthroughPart;
2149
+ }
2150
+ return void 0;
2151
+ }
2152
+ }
2153
+ }
2154
+ function createModelCallToUIChunkTransform() {
2155
+ return new TransformStream({
2156
+ start: (controller) => {
2157
+ controller.enqueue({ type: "start" });
2158
+ controller.enqueue({ type: "start-step" });
2159
+ },
2160
+ flush: (controller) => {
2161
+ controller.enqueue({ type: "finish-step" });
2162
+ controller.enqueue({ type: "finish" });
2163
+ },
2164
+ transform: (part, controller) => {
2165
+ const uiChunk = toUIMessageChunk(part);
2166
+ if (uiChunk) {
2167
+ controller.enqueue(uiChunk);
2168
+ }
2169
+ }
2170
+ });
2171
+ }
2172
+
2173
+ // src/workflow-chat-transport.ts
2174
+ import {
2175
+ parseJsonEventStream,
2176
+ uiMessageChunkSchema
2177
+ } from "ai";
2178
+ import {
2179
+ convertAsyncIteratorToReadableStream,
2180
+ getErrorMessage as getErrorMessage2
2181
+ } from "@ai-sdk/provider-utils";
2182
+ import { createAsyncIterableStream } from "ai/internal";
2183
+
2184
+ // src/normalize-ui-message-stream.ts
2185
+ var newPartFrameState = () => ({
2186
+ open: /* @__PURE__ */ new Set(),
2187
+ ended: /* @__PURE__ */ new Set()
2188
+ });
2189
+ function* repairPart(kind, id, chunk, state, startType) {
2190
+ if (kind === "start") {
2191
+ if (state.open.has(id) || state.ended.has(id)) {
2192
+ return;
2193
+ }
2194
+ state.open.add(id);
2195
+ yield chunk;
2196
+ return;
2197
+ }
2198
+ if (state.ended.has(id)) {
2199
+ return;
2200
+ }
2201
+ if (!state.open.has(id)) {
2202
+ state.open.add(id);
2203
+ yield { type: startType, id };
2204
+ }
2205
+ if (kind === "end") {
2206
+ state.open.delete(id);
2207
+ state.ended.add(id);
2208
+ }
2209
+ yield chunk;
2210
+ }
2211
+ async function* normalizeUIMessageStreamParts(source) {
2212
+ const text = newPartFrameState();
2213
+ const reasoning = newPartFrameState();
2214
+ for await (const chunk of source) {
2215
+ switch (chunk.type) {
2216
+ case "finish-step":
2217
+ text.open.clear();
2218
+ text.ended.clear();
2219
+ reasoning.open.clear();
2220
+ reasoning.ended.clear();
2221
+ yield chunk;
2222
+ break;
2223
+ case "text-start":
2224
+ yield* repairPart("start", chunk.id, chunk, text, "text-start");
2225
+ break;
2226
+ case "text-delta":
2227
+ yield* repairPart("delta", chunk.id, chunk, text, "text-start");
2228
+ break;
2229
+ case "text-end":
2230
+ yield* repairPart("end", chunk.id, chunk, text, "text-start");
2231
+ break;
2232
+ case "reasoning-start":
2233
+ yield* repairPart(
2234
+ "start",
2235
+ chunk.id,
2236
+ chunk,
2237
+ reasoning,
2238
+ "reasoning-start"
2239
+ );
2240
+ break;
2241
+ case "reasoning-delta":
2242
+ yield* repairPart(
2243
+ "delta",
2244
+ chunk.id,
2245
+ chunk,
2246
+ reasoning,
2247
+ "reasoning-start"
2248
+ );
2249
+ break;
2250
+ case "reasoning-end":
2251
+ yield* repairPart("end", chunk.id, chunk, reasoning, "reasoning-start");
2252
+ break;
2253
+ default:
2254
+ yield chunk;
2255
+ }
2256
+ }
2257
+ }
2258
+
2259
+ // src/workflow-chat-transport.ts
2260
+ function createOrphanFilter() {
2261
+ const seenStartedIds = /* @__PURE__ */ new Set();
2262
+ const seenStartedToolCallIds = /* @__PURE__ */ new Set();
2263
+ let warnedOnce = false;
2264
+ function warnOnce(orphanKind, orphanRef) {
2265
+ if (warnedOnce) return;
2266
+ warnedOnce = true;
2267
+ console.warn(
2268
+ `[WorkflowChatTransport] Dropping orphan UI chunk (${orphanKind} for id "${orphanRef}") on resume \u2014 the resume position landed mid-part. The dropped chunk(s) reference a part whose start chunk wasn't in the resumed window. To preserve the full message, configure your stream endpoint to rewind to a step boundary before returning the readable. See: https://workflow.dev/docs/ai/resumable-streams#mid-part-resumes`
2269
+ );
2270
+ }
2271
+ function shouldDrop(chunk) {
2272
+ switch (chunk.type) {
2273
+ case "text-start":
2274
+ case "reasoning-start":
2275
+ seenStartedIds.add(chunk.id);
2276
+ return false;
2277
+ case "tool-input-start":
2278
+ // `tool-input-available` / `tool-input-error` are self-contained: the
2279
+ // AI SDK creates the tool part from them directly (non-streamed tool
2280
+ // calls are emitted as a bare `tool-input-available`), so they must
2281
+ // never be dropped. They also carry the full input, so they recover a
2282
+ // tool call whose `tool-input-start` fell outside the resumed window.
2283
+ case "tool-input-available":
2284
+ case "tool-input-error":
2285
+ seenStartedToolCallIds.add(chunk.toolCallId);
2286
+ return false;
2287
+ case "text-delta":
2288
+ case "text-end":
2289
+ case "reasoning-delta":
2290
+ case "reasoning-end":
2291
+ if (seenStartedIds.has(chunk.id)) return false;
2292
+ warnOnce(chunk.type, chunk.id);
2293
+ return true;
2294
+ case "tool-input-delta":
2295
+ case "tool-approval-request":
2296
+ case "tool-output-available":
2297
+ case "tool-output-error":
2298
+ case "tool-output-denied":
2299
+ if (seenStartedToolCallIds.has(chunk.toolCallId)) return false;
2300
+ warnOnce(chunk.type, chunk.toolCallId);
2301
+ return true;
2302
+ default:
2303
+ return false;
2304
+ }
2305
+ }
2306
+ return { shouldDrop };
2307
+ }
2308
+ var WorkflowChatTransport = class {
2309
+ /**
2310
+ * Creates a new WorkflowChatTransport instance.
2311
+ *
2312
+ * @param options - Configuration options for the transport
2313
+ * @param options.api - API endpoint for chat requests (defaults to '/api/chat')
2314
+ * @param options.fetch - Custom fetch implementation (defaults to global fetch)
2315
+ * @param options.onChatSendMessage - Callback after sending messages
2316
+ * @param options.onChatEnd - Callback when chat stream ends
2317
+ * @param options.maxConsecutiveErrors - Maximum consecutive errors for reconnection
2318
+ * @param options.prepareSendMessagesRequest - Function to prepare send messages request
2319
+ * @param options.prepareReconnectToStreamRequest - Function to prepare reconnect request
2320
+ */
2321
+ constructor(options = {}) {
2322
+ var _a, _b, _c, _d;
2323
+ this.api = (_a = options.api) != null ? _a : "/api/chat";
2324
+ this.fetch = (_b = options.fetch) != null ? _b : fetch.bind(globalThis);
2325
+ this.onChatSendMessage = options.onChatSendMessage;
2326
+ this.onChatEnd = options.onChatEnd;
2327
+ this.maxConsecutiveErrors = (_c = options.maxConsecutiveErrors) != null ? _c : 3;
2328
+ this.initialStartIndex = (_d = options.initialStartIndex) != null ? _d : 0;
2329
+ this.prepareSendMessagesRequest = options.prepareSendMessagesRequest;
2330
+ this.prepareReconnectToStreamRequest = options.prepareReconnectToStreamRequest;
2331
+ }
2332
+ /**
2333
+ * Sends messages to the chat endpoint and returns a stream of response chunks.
2334
+ *
2335
+ * This method handles the entire chat lifecycle including:
2336
+ * - Sending messages to the /api/chat endpoint
2337
+ * - Streaming response chunks
2338
+ * - Automatic reconnection if the stream is interrupted
2339
+ *
2340
+ * @param options - Options for sending messages
2341
+ * @param options.trigger - The type of message submission ('submit-message' or 'regenerate-message')
2342
+ * @param options.chatId - Unique identifier for this chat session
2343
+ * @param options.messageId - Optional message ID for tracking specific messages
2344
+ * @param options.messages - Array of UI messages to send
2345
+ * @param options.abortSignal - Optional AbortSignal to cancel the request
2346
+ *
2347
+ * @returns A ReadableStream of UIMessageChunk objects containing the response
2348
+ * @throws Error if the fetch request fails or returns a non-OK status
2349
+ */
2350
+ async sendMessages(options) {
2351
+ return convertAsyncIteratorToReadableStream(
2352
+ normalizeUIMessageStreamParts(this.sendMessagesIterator(options))
2353
+ );
2354
+ }
2355
+ async *sendMessagesIterator(options) {
2356
+ var _a, _b, _c;
2357
+ const { chatId, messages, abortSignal, trigger, messageId } = options;
2358
+ let gotFinish = false;
2359
+ let chunkIndex = 0;
2360
+ const requestConfig = this.prepareSendMessagesRequest ? await this.prepareSendMessagesRequest({
2361
+ id: chatId,
2362
+ messages,
2363
+ requestMetadata: options.metadata,
2364
+ body: options.body,
2365
+ credentials: void 0,
2366
+ headers: options.headers,
2367
+ api: this.api,
2368
+ trigger,
2369
+ messageId
2370
+ }) : void 0;
2371
+ const url = (_a = requestConfig == null ? void 0 : requestConfig.api) != null ? _a : this.api;
2372
+ const response = await this.fetch(url, {
2373
+ method: "POST",
2374
+ body: JSON.stringify(
2375
+ (_b = requestConfig == null ? void 0 : requestConfig.body) != null ? _b : { messages, ...options.body }
2376
+ ),
2377
+ headers: requestConfig == null ? void 0 : requestConfig.headers,
2378
+ credentials: requestConfig == null ? void 0 : requestConfig.credentials,
2379
+ signal: abortSignal
2380
+ });
2381
+ if (!response.ok || !response.body) {
2382
+ throw new Error(
2383
+ `Failed to fetch chat: ${response.status} ${await response.text()}`
2384
+ );
2385
+ }
2386
+ const workflowRunId = response.headers.get("x-workflow-run-id");
2387
+ if (!workflowRunId) {
2388
+ throw new Error(
2389
+ 'Workflow run ID not found in "x-workflow-run-id" response header'
2390
+ );
2391
+ }
2392
+ await ((_c = this.onChatSendMessage) == null ? void 0 : _c.call(this, response, options));
2393
+ try {
2394
+ const chunkStream = parseJsonEventStream({
2395
+ stream: response.body,
2396
+ schema: uiMessageChunkSchema
2397
+ });
2398
+ for await (const chunk of createAsyncIterableStream(chunkStream)) {
2399
+ if (!chunk.success) {
2400
+ throw chunk.error;
2401
+ }
2402
+ chunkIndex++;
2403
+ yield chunk.value;
2404
+ if (chunk.value.type === "finish") {
2405
+ gotFinish = true;
2406
+ }
2407
+ }
2408
+ } catch (error) {
2409
+ console.error("Error in chat POST stream", error);
2410
+ }
2411
+ if (gotFinish) {
2412
+ await this.onFinish(gotFinish, { chatId, chunkIndex });
2413
+ } else {
2414
+ yield* this.reconnectToStreamIterator(options, workflowRunId, chunkIndex);
2415
+ }
2416
+ }
2417
+ /**
2418
+ * Reconnects to an existing chat stream that was previously interrupted.
2419
+ *
2420
+ * This method is useful for resuming a chat session after network issues,
2421
+ * page refreshes, or Vercel Function timeouts.
2422
+ *
2423
+ * @param options - Options for reconnecting to the stream
2424
+ * @param options.chatId - The chat ID to reconnect to
2425
+ *
2426
+ * @returns A ReadableStream of UIMessageChunk objects
2427
+ * @throws Error if the reconnection request fails or returns a non-OK status
2428
+ */
2429
+ async reconnectToStream(options) {
2430
+ const reconnectIterator = normalizeUIMessageStreamParts(
2431
+ this.reconnectToStreamIterator(options)
2432
+ );
2433
+ return convertAsyncIteratorToReadableStream(reconnectIterator);
2434
+ }
2435
+ async *reconnectToStreamIterator(options, workflowRunId, initialChunkIndex = 0) {
2436
+ var _a, _b;
2437
+ let chunkIndex = initialChunkIndex;
2438
+ const explicitStartIndex = (_a = options.startIndex) != null ? _a : this.initialStartIndex;
2439
+ let useExplicitStartIndex = initialChunkIndex === 0 && explicitStartIndex !== 0;
2440
+ const defaultApi = `${this.api}/${encodeURIComponent(workflowRunId != null ? workflowRunId : options.chatId)}/stream`;
2441
+ const requestConfig = this.prepareReconnectToStreamRequest ? await this.prepareReconnectToStreamRequest({
2442
+ id: options.chatId,
2443
+ requestMetadata: options.metadata,
2444
+ body: void 0,
2445
+ credentials: void 0,
2446
+ headers: void 0,
2447
+ api: defaultApi
2448
+ }) : void 0;
2449
+ const baseUrl = (_b = requestConfig == null ? void 0 : requestConfig.api) != null ? _b : defaultApi;
2450
+ let gotFinish = false;
2451
+ let consecutiveErrors = 0;
2452
+ let replayFromStart = false;
2453
+ const orphanFilter = useExplicitStartIndex && explicitStartIndex < 0 ? createOrphanFilter() : null;
2454
+ while (!gotFinish) {
2455
+ const startIndex = useExplicitStartIndex ? explicitStartIndex : replayFromStart ? 0 : chunkIndex;
2456
+ const url = `${baseUrl}?startIndex=${startIndex}`;
2457
+ const response = await this.fetch(url, {
2458
+ headers: requestConfig == null ? void 0 : requestConfig.headers,
2459
+ credentials: requestConfig == null ? void 0 : requestConfig.credentials,
2460
+ signal: options.abortSignal
2461
+ });
2462
+ if (!response.ok || !response.body) {
2463
+ throw new Error(
2464
+ `Failed to fetch chat: ${response.status} ${await response.text()}`
2465
+ );
2466
+ }
2467
+ if (useExplicitStartIndex && explicitStartIndex > 0) {
2468
+ chunkIndex = explicitStartIndex;
2469
+ } else if (useExplicitStartIndex && explicitStartIndex < 0) {
2470
+ const tailIndexHeader = response.headers.get(
2471
+ "x-workflow-stream-tail-index"
2472
+ );
2473
+ const tailIndex = tailIndexHeader !== null ? parseInt(tailIndexHeader, 10) : NaN;
2474
+ if (!Number.isNaN(tailIndex)) {
2475
+ chunkIndex = Math.max(0, tailIndex + 1 + explicitStartIndex);
2476
+ } else {
2477
+ console.warn(
2478
+ `[WorkflowChatTransport] Negative initialStartIndex is configured (${explicitStartIndex}) but the reconnection endpoint did not return a valid "x-workflow-stream-tail-index" header. Retries will replay the stream from the beginning. See: https://workflow.dev/docs/ai/resumable-streams#resuming-from-the-end-of-the-stream`
2479
+ );
2480
+ replayFromStart = true;
2481
+ }
2482
+ }
2483
+ useExplicitStartIndex = false;
2484
+ try {
2485
+ const chunkStream = parseJsonEventStream({
2486
+ stream: response.body,
2487
+ schema: uiMessageChunkSchema
2488
+ });
2489
+ for await (const chunk of createAsyncIterableStream(chunkStream)) {
2490
+ if (!chunk.success) {
2491
+ throw chunk.error;
2492
+ }
2493
+ chunkIndex++;
2494
+ if (orphanFilter == null ? void 0 : orphanFilter.shouldDrop(chunk.value)) continue;
2495
+ yield chunk.value;
2496
+ if (chunk.value.type === "finish") {
2497
+ gotFinish = true;
2498
+ }
2499
+ }
2500
+ consecutiveErrors = 0;
2501
+ } catch (error) {
2502
+ console.error("Error in chat GET reconnectToStream", error);
2503
+ consecutiveErrors++;
2504
+ if (consecutiveErrors >= this.maxConsecutiveErrors) {
2505
+ throw new Error(
2506
+ `Failed to reconnect after ${this.maxConsecutiveErrors} consecutive errors. Last error: ${getErrorMessage2(error)}`
2507
+ );
2508
+ }
2509
+ }
2510
+ }
2511
+ await this.onFinish(gotFinish, { chatId: options.chatId, chunkIndex });
2512
+ }
2513
+ async onFinish(gotFinish, { chatId, chunkIndex }) {
2514
+ var _a;
2515
+ if (gotFinish) {
2516
+ await ((_a = this.onChatEnd) == null ? void 0 : _a.call(this, { chatId, chunkIndex }));
2517
+ } else {
2518
+ throw new Error("No finish chunk received");
2519
+ }
2520
+ }
2521
+ };
2522
+ export {
2523
+ Output,
2524
+ WorkflowAgent,
2525
+ WorkflowChatTransport,
2526
+ createModelCallToUIChunkTransform,
2527
+ normalizeUIMessageStreamParts,
2528
+ toUIMessageChunk
2529
+ };
2530
+ //# sourceMappingURL=index.js.map