@ai-sdk/workflow 0.0.0-6b196531-20260710185421

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