@ai-sdk/workflow 0.0.0-bf6e4b15-20260402200305

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1261 @@
1
+ // src/workflow-agent.ts
2
+ import {
3
+ Output
4
+ } from "ai";
5
+ import {
6
+ convertToLanguageModelPrompt,
7
+ mergeAbortSignals,
8
+ standardizePrompt
9
+ } from "ai/internal";
10
+ import { mergeCallbacks } from "ai/internal";
11
+
12
+ // src/do-stream-step.ts
13
+ import {
14
+ experimental_streamModelCall as streamModelCall
15
+ } from "ai";
16
+ import { gateway } from "ai";
17
+
18
+ // src/serializable-schema.ts
19
+ import { asSchema, jsonSchema } from "@ai-sdk/provider-utils";
20
+ import { tool } from "ai";
21
+ import Ajv from "ajv";
22
+ function serializeToolSet(tools) {
23
+ return Object.fromEntries(
24
+ Object.entries(tools).map(([name, t]) => [
25
+ name,
26
+ {
27
+ description: t.description,
28
+ inputSchema: asSchema(t.inputSchema).jsonSchema
29
+ }
30
+ ])
31
+ );
32
+ }
33
+ function resolveSerializableTools(tools) {
34
+ const ajv = new Ajv();
35
+ return Object.fromEntries(
36
+ Object.entries(tools).map(([name, t]) => {
37
+ const validateFn = ajv.compile(t.inputSchema);
38
+ return [
39
+ name,
40
+ tool({
41
+ description: t.description,
42
+ inputSchema: jsonSchema(t.inputSchema, {
43
+ validate: (value) => {
44
+ if (validateFn(value)) {
45
+ return { success: true, value };
46
+ }
47
+ return {
48
+ success: false,
49
+ error: new Error(ajv.errorsText(validateFn.errors))
50
+ };
51
+ }
52
+ })
53
+ })
54
+ ];
55
+ })
56
+ );
57
+ }
58
+
59
+ // src/do-stream-step.ts
60
+ async function doStreamStep(conversationPrompt, modelInit, writable, serializedTools, options) {
61
+ "use step";
62
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
63
+ let model;
64
+ if (typeof modelInit === "string") {
65
+ model = gateway.languageModel(modelInit);
66
+ } else if (typeof modelInit === "function") {
67
+ model = await modelInit();
68
+ } else {
69
+ throw new Error(
70
+ 'Invalid "model initialization" argument. Must be a string or a function that returns a LanguageModel instance.'
71
+ );
72
+ }
73
+ const tools = serializedTools ? resolveSerializableTools(serializedTools) : void 0;
74
+ const { stream: modelStream } = await streamModelCall({
75
+ model,
76
+ // streamModelCall expects Prompt (ModelMessage[]) but we pass the
77
+ // pre-converted LanguageModelV4Prompt. standardizePrompt inside
78
+ // streamModelCall handles both formats.
79
+ messages: conversationPrompt,
80
+ tools,
81
+ toolChoice: options == null ? void 0 : options.toolChoice,
82
+ includeRawChunks: options == null ? void 0 : options.includeRawChunks,
83
+ providerOptions: options == null ? void 0 : options.providerOptions,
84
+ abortSignal: options == null ? void 0 : options.abortSignal,
85
+ headers: options == null ? void 0 : options.headers,
86
+ maxOutputTokens: options == null ? void 0 : options.maxOutputTokens,
87
+ temperature: options == null ? void 0 : options.temperature,
88
+ topP: options == null ? void 0 : options.topP,
89
+ topK: options == null ? void 0 : options.topK,
90
+ presencePenalty: options == null ? void 0 : options.presencePenalty,
91
+ frequencyPenalty: options == null ? void 0 : options.frequencyPenalty,
92
+ stopSequences: options == null ? void 0 : options.stopSequences,
93
+ seed: options == null ? void 0 : options.seed,
94
+ repairToolCall: options == null ? void 0 : options.repairToolCall
95
+ });
96
+ const toolCalls = [];
97
+ const providerExecutedToolResults = /* @__PURE__ */ new Map();
98
+ let finish;
99
+ let text = "";
100
+ const reasoningParts = [];
101
+ let responseMetadata;
102
+ let warnings;
103
+ const writer = writable == null ? void 0 : writable.getWriter();
104
+ try {
105
+ for await (const part of modelStream) {
106
+ switch (part.type) {
107
+ case "text-delta":
108
+ text += part.text;
109
+ break;
110
+ case "reasoning-delta":
111
+ reasoningParts.push({ text: part.text });
112
+ break;
113
+ case "tool-call": {
114
+ const toolCallPart = part;
115
+ toolCalls.push({
116
+ type: "tool-call",
117
+ toolCallId: toolCallPart.toolCallId,
118
+ toolName: toolCallPart.toolName,
119
+ input: toolCallPart.input,
120
+ providerExecuted: toolCallPart.providerExecuted,
121
+ providerMetadata: toolCallPart.providerMetadata,
122
+ dynamic: toolCallPart.dynamic,
123
+ invalid: toolCallPart.invalid,
124
+ error: toolCallPart.error
125
+ });
126
+ break;
127
+ }
128
+ case "tool-result":
129
+ if (part.providerExecuted) {
130
+ providerExecutedToolResults.set(part.toolCallId, {
131
+ toolCallId: part.toolCallId,
132
+ toolName: part.toolName,
133
+ result: part.output,
134
+ isError: false
135
+ });
136
+ }
137
+ break;
138
+ case "tool-error": {
139
+ const errorPart = part;
140
+ if (errorPart.providerExecuted) {
141
+ providerExecutedToolResults.set(errorPart.toolCallId, {
142
+ toolCallId: errorPart.toolCallId,
143
+ toolName: errorPart.toolName,
144
+ result: errorPart.error,
145
+ isError: true
146
+ });
147
+ }
148
+ break;
149
+ }
150
+ case "model-call-end":
151
+ finish = {
152
+ finishReason: part.finishReason,
153
+ rawFinishReason: part.rawFinishReason,
154
+ usage: part.usage,
155
+ providerMetadata: part.providerMetadata
156
+ };
157
+ break;
158
+ case "model-call-start":
159
+ warnings = part.warnings;
160
+ break;
161
+ case "model-call-response-metadata":
162
+ responseMetadata = part;
163
+ break;
164
+ }
165
+ if (writer) {
166
+ await writer.write(part);
167
+ }
168
+ }
169
+ } finally {
170
+ writer == null ? void 0 : writer.releaseLock();
171
+ }
172
+ const reasoningText = reasoningParts.map((r) => r.text).join("") || void 0;
173
+ const step = {
174
+ callId: "workflow-agent",
175
+ stepNumber: 0,
176
+ model: {
177
+ provider: (_b = (_a = responseMetadata == null ? void 0 : responseMetadata.modelId) == null ? void 0 : _a.split(":")[0]) != null ? _b : "unknown",
178
+ modelId: (_c = responseMetadata == null ? void 0 : responseMetadata.modelId) != null ? _c : "unknown"
179
+ },
180
+ functionId: void 0,
181
+ metadata: void 0,
182
+ experimental_context: void 0,
183
+ content: [
184
+ ...text ? [{ type: "text", text }] : [],
185
+ ...toolCalls.filter((tc) => !tc.invalid).map((tc) => ({
186
+ type: "tool-call",
187
+ toolCallId: tc.toolCallId,
188
+ toolName: tc.toolName,
189
+ input: tc.input,
190
+ ...tc.dynamic ? { dynamic: true } : {}
191
+ }))
192
+ ],
193
+ text,
194
+ reasoning: reasoningParts.map((r) => ({
195
+ type: "reasoning",
196
+ text: r.text
197
+ })),
198
+ reasoningText,
199
+ files: [],
200
+ sources: [],
201
+ toolCalls: toolCalls.filter((tc) => !tc.invalid).map((tc) => ({
202
+ type: "tool-call",
203
+ toolCallId: tc.toolCallId,
204
+ toolName: tc.toolName,
205
+ input: tc.input,
206
+ ...tc.dynamic ? { dynamic: true } : {}
207
+ })),
208
+ staticToolCalls: [],
209
+ dynamicToolCalls: toolCalls.filter((tc) => !tc.invalid && tc.dynamic).map((tc) => ({
210
+ type: "tool-call",
211
+ toolCallId: tc.toolCallId,
212
+ toolName: tc.toolName,
213
+ input: tc.input,
214
+ dynamic: true
215
+ })),
216
+ toolResults: [],
217
+ staticToolResults: [],
218
+ dynamicToolResults: [],
219
+ finishReason: (_d = finish == null ? void 0 : finish.finishReason) != null ? _d : "other",
220
+ rawFinishReason: finish == null ? void 0 : finish.rawFinishReason,
221
+ usage: (_e = finish == null ? void 0 : finish.usage) != null ? _e : {
222
+ inputTokens: 0,
223
+ inputTokenDetails: {
224
+ noCacheTokens: void 0,
225
+ cacheReadTokens: void 0,
226
+ cacheWriteTokens: void 0
227
+ },
228
+ outputTokens: 0,
229
+ outputTokenDetails: {
230
+ textTokens: void 0,
231
+ reasoningTokens: void 0
232
+ },
233
+ totalTokens: 0
234
+ },
235
+ warnings,
236
+ request: { body: "" },
237
+ response: {
238
+ id: (_f = responseMetadata == null ? void 0 : responseMetadata.id) != null ? _f : "unknown",
239
+ timestamp: (_g = responseMetadata == null ? void 0 : responseMetadata.timestamp) != null ? _g : /* @__PURE__ */ new Date(),
240
+ modelId: (_h = responseMetadata == null ? void 0 : responseMetadata.modelId) != null ? _h : "unknown",
241
+ messages: []
242
+ },
243
+ providerMetadata: (_i = finish == null ? void 0 : finish.providerMetadata) != null ? _i : {}
244
+ };
245
+ return {
246
+ toolCalls,
247
+ finish,
248
+ step,
249
+ providerExecutedToolResults
250
+ };
251
+ }
252
+
253
+ // src/stream-text-iterator.ts
254
+ async function* streamTextIterator({
255
+ prompt,
256
+ tools = {},
257
+ writable,
258
+ model,
259
+ stopConditions,
260
+ maxSteps,
261
+ onStepFinish,
262
+ onStepStart,
263
+ onError,
264
+ prepareStep,
265
+ generationSettings,
266
+ toolChoice,
267
+ experimental_context,
268
+ experimental_telemetry,
269
+ includeRawChunks = false,
270
+ repairToolCall,
271
+ responseFormat
272
+ }) {
273
+ var _a;
274
+ let conversationPrompt = [...prompt];
275
+ let currentModel = model;
276
+ let currentGenerationSettings = generationSettings != null ? generationSettings : {};
277
+ let currentToolChoice = toolChoice;
278
+ let currentContext = experimental_context;
279
+ let currentActiveTools;
280
+ const steps = [];
281
+ let done = false;
282
+ let isFirstIteration = true;
283
+ let stepNumber = 0;
284
+ let lastStep;
285
+ let lastStepWasToolCalls = false;
286
+ const effectiveMaxSteps = maxSteps != null ? maxSteps : Infinity;
287
+ while (!done) {
288
+ if (stepNumber >= effectiveMaxSteps) {
289
+ break;
290
+ }
291
+ if ((_a = currentGenerationSettings.abortSignal) == null ? void 0 : _a.aborted) {
292
+ break;
293
+ }
294
+ if (prepareStep) {
295
+ const prepareResult = await prepareStep({
296
+ model: currentModel,
297
+ stepNumber,
298
+ steps,
299
+ messages: conversationPrompt,
300
+ experimental_context: currentContext
301
+ });
302
+ if (prepareResult.model !== void 0) {
303
+ currentModel = prepareResult.model;
304
+ }
305
+ if (prepareResult.messages !== void 0) {
306
+ conversationPrompt = [...prepareResult.messages];
307
+ }
308
+ if (prepareResult.system !== void 0) {
309
+ if (conversationPrompt.length > 0 && conversationPrompt[0].role === "system") {
310
+ conversationPrompt[0] = {
311
+ role: "system",
312
+ content: prepareResult.system
313
+ };
314
+ } else {
315
+ conversationPrompt.unshift({
316
+ role: "system",
317
+ content: prepareResult.system
318
+ });
319
+ }
320
+ }
321
+ if (prepareResult.experimental_context !== void 0) {
322
+ currentContext = prepareResult.experimental_context;
323
+ }
324
+ if (prepareResult.activeTools !== void 0) {
325
+ currentActiveTools = prepareResult.activeTools;
326
+ }
327
+ if (prepareResult.maxOutputTokens !== void 0) {
328
+ currentGenerationSettings = {
329
+ ...currentGenerationSettings,
330
+ maxOutputTokens: prepareResult.maxOutputTokens
331
+ };
332
+ }
333
+ if (prepareResult.temperature !== void 0) {
334
+ currentGenerationSettings = {
335
+ ...currentGenerationSettings,
336
+ temperature: prepareResult.temperature
337
+ };
338
+ }
339
+ if (prepareResult.topP !== void 0) {
340
+ currentGenerationSettings = {
341
+ ...currentGenerationSettings,
342
+ topP: prepareResult.topP
343
+ };
344
+ }
345
+ if (prepareResult.topK !== void 0) {
346
+ currentGenerationSettings = {
347
+ ...currentGenerationSettings,
348
+ topK: prepareResult.topK
349
+ };
350
+ }
351
+ if (prepareResult.presencePenalty !== void 0) {
352
+ currentGenerationSettings = {
353
+ ...currentGenerationSettings,
354
+ presencePenalty: prepareResult.presencePenalty
355
+ };
356
+ }
357
+ if (prepareResult.frequencyPenalty !== void 0) {
358
+ currentGenerationSettings = {
359
+ ...currentGenerationSettings,
360
+ frequencyPenalty: prepareResult.frequencyPenalty
361
+ };
362
+ }
363
+ if (prepareResult.stopSequences !== void 0) {
364
+ currentGenerationSettings = {
365
+ ...currentGenerationSettings,
366
+ stopSequences: prepareResult.stopSequences
367
+ };
368
+ }
369
+ if (prepareResult.seed !== void 0) {
370
+ currentGenerationSettings = {
371
+ ...currentGenerationSettings,
372
+ seed: prepareResult.seed
373
+ };
374
+ }
375
+ if (prepareResult.maxRetries !== void 0) {
376
+ currentGenerationSettings = {
377
+ ...currentGenerationSettings,
378
+ maxRetries: prepareResult.maxRetries
379
+ };
380
+ }
381
+ if (prepareResult.headers !== void 0) {
382
+ currentGenerationSettings = {
383
+ ...currentGenerationSettings,
384
+ headers: prepareResult.headers
385
+ };
386
+ }
387
+ if (prepareResult.providerOptions !== void 0) {
388
+ currentGenerationSettings = {
389
+ ...currentGenerationSettings,
390
+ providerOptions: prepareResult.providerOptions
391
+ };
392
+ }
393
+ if (prepareResult.toolChoice !== void 0) {
394
+ currentToolChoice = prepareResult.toolChoice;
395
+ }
396
+ }
397
+ if (onStepStart) {
398
+ await onStepStart({
399
+ stepNumber,
400
+ model: currentModel,
401
+ messages: conversationPrompt
402
+ });
403
+ }
404
+ try {
405
+ const effectiveTools = currentActiveTools && currentActiveTools.length > 0 ? filterToolSet(tools, currentActiveTools) : tools;
406
+ const serializedTools = serializeToolSet(effectiveTools);
407
+ const { toolCalls, finish, step, providerExecutedToolResults } = await doStreamStep(
408
+ conversationPrompt,
409
+ currentModel,
410
+ writable,
411
+ serializedTools,
412
+ {
413
+ ...currentGenerationSettings,
414
+ toolChoice: currentToolChoice,
415
+ includeRawChunks,
416
+ experimental_telemetry,
417
+ repairToolCall,
418
+ responseFormat
419
+ }
420
+ );
421
+ isFirstIteration = false;
422
+ stepNumber++;
423
+ steps.push(step);
424
+ lastStep = step;
425
+ lastStepWasToolCalls = false;
426
+ const finishReason = finish == null ? void 0 : finish.finishReason;
427
+ if (finishReason === "tool-calls") {
428
+ lastStepWasToolCalls = true;
429
+ conversationPrompt.push({
430
+ role: "assistant",
431
+ content: toolCalls.map((toolCall) => {
432
+ const sanitizedMetadata = sanitizeProviderMetadataForToolCall(
433
+ toolCall.providerMetadata
434
+ );
435
+ return {
436
+ type: "tool-call",
437
+ toolCallId: toolCall.toolCallId,
438
+ toolName: toolCall.toolName,
439
+ input: toolCall.input,
440
+ ...sanitizedMetadata != null ? { providerOptions: sanitizedMetadata } : {}
441
+ };
442
+ })
443
+ });
444
+ const toolResults = yield {
445
+ toolCalls,
446
+ messages: conversationPrompt,
447
+ step,
448
+ context: currentContext,
449
+ providerExecutedToolResults
450
+ };
451
+ conversationPrompt.push({
452
+ role: "tool",
453
+ content: toolResults
454
+ });
455
+ if (stopConditions) {
456
+ const stopConditionList = Array.isArray(stopConditions) ? stopConditions : [stopConditions];
457
+ if (stopConditionList.some((test) => test({ steps }))) {
458
+ done = true;
459
+ }
460
+ }
461
+ } else if (finishReason === "stop") {
462
+ const textContent = step.content.filter(
463
+ (item) => item.type === "text"
464
+ );
465
+ if (textContent.length > 0) {
466
+ conversationPrompt.push({
467
+ role: "assistant",
468
+ content: textContent
469
+ });
470
+ }
471
+ done = true;
472
+ } else if (finishReason === "length") {
473
+ done = true;
474
+ } else if (finishReason === "content-filter") {
475
+ done = true;
476
+ } else if (finishReason === "error") {
477
+ done = true;
478
+ } else if (finishReason === "other") {
479
+ done = true;
480
+ } else if (finishReason === "unknown") {
481
+ done = true;
482
+ } else if (!finishReason) {
483
+ done = true;
484
+ } else {
485
+ throw new Error(
486
+ `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}`
487
+ );
488
+ }
489
+ if (onStepFinish) {
490
+ await onStepFinish(step);
491
+ }
492
+ } catch (error) {
493
+ if (onError) {
494
+ await onError({ error });
495
+ }
496
+ throw error;
497
+ }
498
+ }
499
+ if (lastStep && !lastStepWasToolCalls) {
500
+ yield {
501
+ toolCalls: [],
502
+ messages: conversationPrompt,
503
+ step: lastStep,
504
+ context: currentContext
505
+ };
506
+ }
507
+ return conversationPrompt;
508
+ }
509
+ function filterToolSet(tools, activeTools) {
510
+ const filtered = {};
511
+ for (const toolName of activeTools) {
512
+ if (toolName in tools) {
513
+ filtered[toolName] = tools[toolName];
514
+ }
515
+ }
516
+ return filtered;
517
+ }
518
+ function sanitizeProviderMetadataForToolCall(metadata) {
519
+ if (metadata == null) return void 0;
520
+ const meta = metadata;
521
+ if ("openai" in meta && meta.openai != null) {
522
+ const { openai, ...restProviders } = meta;
523
+ const openaiMeta = openai;
524
+ const { itemId: _itemId, ...restOpenai } = openaiMeta;
525
+ const hasOtherOpenaiFields = Object.keys(restOpenai).length > 0;
526
+ const hasOtherProviders = Object.keys(restProviders).length > 0;
527
+ if (hasOtherOpenaiFields && hasOtherProviders) {
528
+ return { ...restProviders, openai: restOpenai };
529
+ } else if (hasOtherOpenaiFields) {
530
+ return { openai: restOpenai };
531
+ } else if (hasOtherProviders) {
532
+ return restProviders;
533
+ }
534
+ return void 0;
535
+ }
536
+ return meta;
537
+ }
538
+
539
+ // src/workflow-agent.ts
540
+ var WorkflowAgent = class {
541
+ constructor(options) {
542
+ var _a, _b;
543
+ this.model = options.model;
544
+ this.tools = (_a = options.tools) != null ? _a : {};
545
+ this.instructions = (_b = options.instructions) != null ? _b : options.system;
546
+ this.toolChoice = options.toolChoice;
547
+ this.telemetry = options.experimental_telemetry;
548
+ this.experimentalContext = options.experimental_context;
549
+ this.prepareStep = options.prepareStep;
550
+ this.constructorOnStepFinish = options.onStepFinish;
551
+ this.constructorOnFinish = options.onFinish;
552
+ this.constructorOnStart = options.experimental_onStart;
553
+ this.constructorOnStepStart = options.experimental_onStepStart;
554
+ this.constructorOnToolCallStart = options.experimental_onToolCallStart;
555
+ this.constructorOnToolCallFinish = options.experimental_onToolCallFinish;
556
+ this.prepareCall = options.prepareCall;
557
+ this.generationSettings = {
558
+ maxOutputTokens: options.maxOutputTokens,
559
+ temperature: options.temperature,
560
+ topP: options.topP,
561
+ topK: options.topK,
562
+ presencePenalty: options.presencePenalty,
563
+ frequencyPenalty: options.frequencyPenalty,
564
+ stopSequences: options.stopSequences,
565
+ seed: options.seed,
566
+ maxRetries: options.maxRetries,
567
+ abortSignal: options.abortSignal,
568
+ headers: options.headers,
569
+ providerOptions: options.providerOptions
570
+ };
571
+ }
572
+ generate() {
573
+ throw new Error("Not implemented");
574
+ }
575
+ async stream(options) {
576
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
577
+ let effectiveModel = this.model;
578
+ let effectiveInstructions = (_a = options.system) != null ? _a : this.instructions;
579
+ let effectiveMessages = options.messages;
580
+ let effectiveGenerationSettings = { ...this.generationSettings };
581
+ let effectiveExperimentalContext = (_b = options.experimental_context) != null ? _b : this.experimentalContext;
582
+ let effectiveToolChoiceFromPrepare = (_c = options.toolChoice) != null ? _c : this.toolChoice;
583
+ let effectiveTelemetryFromPrepare = (_d = options.experimental_telemetry) != null ? _d : this.telemetry;
584
+ if (this.prepareCall) {
585
+ const prepared = await this.prepareCall({
586
+ model: effectiveModel,
587
+ tools: this.tools,
588
+ instructions: effectiveInstructions,
589
+ toolChoice: effectiveToolChoiceFromPrepare,
590
+ experimental_telemetry: effectiveTelemetryFromPrepare,
591
+ experimental_context: effectiveExperimentalContext,
592
+ messages: effectiveMessages,
593
+ ...effectiveGenerationSettings
594
+ });
595
+ if (prepared.model !== void 0) effectiveModel = prepared.model;
596
+ if (prepared.instructions !== void 0)
597
+ effectiveInstructions = prepared.instructions;
598
+ if (prepared.messages !== void 0)
599
+ effectiveMessages = prepared.messages;
600
+ if (prepared.experimental_context !== void 0)
601
+ effectiveExperimentalContext = prepared.experimental_context;
602
+ if (prepared.toolChoice !== void 0)
603
+ effectiveToolChoiceFromPrepare = prepared.toolChoice;
604
+ if (prepared.experimental_telemetry !== void 0)
605
+ effectiveTelemetryFromPrepare = prepared.experimental_telemetry;
606
+ if (prepared.maxOutputTokens !== void 0)
607
+ effectiveGenerationSettings.maxOutputTokens = prepared.maxOutputTokens;
608
+ if (prepared.temperature !== void 0)
609
+ effectiveGenerationSettings.temperature = prepared.temperature;
610
+ if (prepared.topP !== void 0)
611
+ effectiveGenerationSettings.topP = prepared.topP;
612
+ if (prepared.topK !== void 0)
613
+ effectiveGenerationSettings.topK = prepared.topK;
614
+ if (prepared.presencePenalty !== void 0)
615
+ effectiveGenerationSettings.presencePenalty = prepared.presencePenalty;
616
+ if (prepared.frequencyPenalty !== void 0)
617
+ effectiveGenerationSettings.frequencyPenalty = prepared.frequencyPenalty;
618
+ if (prepared.stopSequences !== void 0)
619
+ effectiveGenerationSettings.stopSequences = prepared.stopSequences;
620
+ if (prepared.seed !== void 0)
621
+ effectiveGenerationSettings.seed = prepared.seed;
622
+ if (prepared.headers !== void 0)
623
+ effectiveGenerationSettings.headers = prepared.headers;
624
+ if (prepared.providerOptions !== void 0)
625
+ effectiveGenerationSettings.providerOptions = prepared.providerOptions;
626
+ }
627
+ const prompt = await standardizePrompt({
628
+ system: effectiveInstructions,
629
+ messages: effectiveMessages
630
+ });
631
+ const modelPrompt = await convertToLanguageModelPrompt({
632
+ prompt,
633
+ supportedUrls: {},
634
+ download: options.experimental_download
635
+ });
636
+ const effectiveAbortSignal = mergeAbortSignals(
637
+ (_e = options.abortSignal) != null ? _e : effectiveGenerationSettings.abortSignal,
638
+ options.timeout != null ? AbortSignal.timeout(options.timeout) : void 0
639
+ );
640
+ const mergedGenerationSettings = {
641
+ ...effectiveGenerationSettings,
642
+ ...options.maxOutputTokens !== void 0 && {
643
+ maxOutputTokens: options.maxOutputTokens
644
+ },
645
+ ...options.temperature !== void 0 && {
646
+ temperature: options.temperature
647
+ },
648
+ ...options.topP !== void 0 && { topP: options.topP },
649
+ ...options.topK !== void 0 && { topK: options.topK },
650
+ ...options.presencePenalty !== void 0 && {
651
+ presencePenalty: options.presencePenalty
652
+ },
653
+ ...options.frequencyPenalty !== void 0 && {
654
+ frequencyPenalty: options.frequencyPenalty
655
+ },
656
+ ...options.stopSequences !== void 0 && {
657
+ stopSequences: options.stopSequences
658
+ },
659
+ ...options.seed !== void 0 && { seed: options.seed },
660
+ ...options.maxRetries !== void 0 && {
661
+ maxRetries: options.maxRetries
662
+ },
663
+ ...effectiveAbortSignal !== void 0 && {
664
+ abortSignal: effectiveAbortSignal
665
+ },
666
+ ...options.headers !== void 0 && { headers: options.headers },
667
+ ...options.providerOptions !== void 0 && {
668
+ providerOptions: options.providerOptions
669
+ }
670
+ };
671
+ const mergedOnStepFinish = mergeCallbacks(
672
+ this.constructorOnStepFinish,
673
+ options.onStepFinish
674
+ );
675
+ const mergedOnFinish = mergeCallbacks(
676
+ this.constructorOnFinish,
677
+ options.onFinish
678
+ );
679
+ const mergedOnStart = mergeCallbacks(
680
+ this.constructorOnStart,
681
+ options.experimental_onStart
682
+ );
683
+ const mergedOnStepStart = mergeCallbacks(
684
+ this.constructorOnStepStart,
685
+ options.experimental_onStepStart
686
+ );
687
+ const mergedOnToolCallStart = mergeCallbacks(
688
+ this.constructorOnToolCallStart,
689
+ options.experimental_onToolCallStart
690
+ );
691
+ const mergedOnToolCallFinish = mergeCallbacks(
692
+ this.constructorOnToolCallFinish,
693
+ options.experimental_onToolCallFinish
694
+ );
695
+ const effectiveToolChoice = effectiveToolChoiceFromPrepare;
696
+ const effectiveTelemetry = effectiveTelemetryFromPrepare;
697
+ const effectiveTools = options.activeTools && options.activeTools.length > 0 ? filterTools(this.tools, options.activeTools) : this.tools;
698
+ let experimentalContext = effectiveExperimentalContext;
699
+ const steps = [];
700
+ let lastStepToolCalls = [];
701
+ let lastStepToolResults = [];
702
+ if (mergedOnStart) {
703
+ await mergedOnStart({
704
+ model: effectiveModel,
705
+ messages: effectiveMessages
706
+ });
707
+ }
708
+ const executeToolWithCallbacks = async (toolCall, tools, messages2, context) => {
709
+ if (mergedOnToolCallStart) {
710
+ await mergedOnToolCallStart({
711
+ toolCall: {
712
+ type: "tool-call",
713
+ toolCallId: toolCall.toolCallId,
714
+ toolName: toolCall.toolName,
715
+ input: toolCall.input
716
+ }
717
+ });
718
+ }
719
+ let result;
720
+ try {
721
+ result = await executeTool(toolCall, tools, messages2, context);
722
+ } catch (err) {
723
+ if (mergedOnToolCallFinish) {
724
+ await mergedOnToolCallFinish({
725
+ toolCall: {
726
+ type: "tool-call",
727
+ toolCallId: toolCall.toolCallId,
728
+ toolName: toolCall.toolName,
729
+ input: toolCall.input
730
+ },
731
+ error: err
732
+ });
733
+ }
734
+ throw err;
735
+ }
736
+ if (mergedOnToolCallFinish) {
737
+ const isError = result.output && "type" in result.output && (result.output.type === "error-text" || result.output.type === "error-json");
738
+ await mergedOnToolCallFinish({
739
+ toolCall: {
740
+ type: "tool-call",
741
+ toolCallId: toolCall.toolCallId,
742
+ toolName: toolCall.toolName,
743
+ input: toolCall.input
744
+ },
745
+ ...isError ? {
746
+ error: "value" in result.output ? result.output.value : void 0
747
+ } : {
748
+ result: result.output && "value" in result.output ? result.output.value : void 0
749
+ }
750
+ });
751
+ }
752
+ return result;
753
+ };
754
+ if ((_f = mergedGenerationSettings.abortSignal) == null ? void 0 : _f.aborted) {
755
+ if (options.onAbort) {
756
+ await options.onAbort({ steps });
757
+ }
758
+ return {
759
+ messages: options.messages,
760
+ steps,
761
+ toolCalls: [],
762
+ toolResults: [],
763
+ experimental_output: void 0
764
+ };
765
+ }
766
+ const iterator = streamTextIterator({
767
+ model: effectiveModel,
768
+ tools: effectiveTools,
769
+ writable: options.writable,
770
+ prompt: modelPrompt,
771
+ stopConditions: options.stopWhen,
772
+ maxSteps: options.maxSteps,
773
+ onStepFinish: mergedOnStepFinish,
774
+ onStepStart: mergedOnStepStart,
775
+ onError: options.onError,
776
+ prepareStep: (_g = options.prepareStep) != null ? _g : this.prepareStep,
777
+ generationSettings: mergedGenerationSettings,
778
+ toolChoice: effectiveToolChoice,
779
+ experimental_context: experimentalContext,
780
+ experimental_telemetry: effectiveTelemetry,
781
+ includeRawChunks: (_h = options.includeRawChunks) != null ? _h : false,
782
+ repairToolCall: options.experimental_repairToolCall,
783
+ responseFormat: await ((_i = options.experimental_output) == null ? void 0 : _i.responseFormat)
784
+ });
785
+ let finalMessages;
786
+ let encounteredError;
787
+ let wasAborted = false;
788
+ try {
789
+ let result = await iterator.next();
790
+ while (!result.done) {
791
+ if ((_j = mergedGenerationSettings.abortSignal) == null ? void 0 : _j.aborted) {
792
+ wasAborted = true;
793
+ if (options.onAbort) {
794
+ await options.onAbort({ steps });
795
+ }
796
+ break;
797
+ }
798
+ const {
799
+ toolCalls,
800
+ messages: iterMessages,
801
+ step,
802
+ context,
803
+ providerExecutedToolResults
804
+ } = result.value;
805
+ if (step) {
806
+ steps.push(step);
807
+ }
808
+ if (context !== void 0) {
809
+ experimentalContext = context;
810
+ }
811
+ if (toolCalls.length > 0) {
812
+ const nonProviderToolCalls = toolCalls.filter(
813
+ (tc) => !tc.providerExecuted
814
+ );
815
+ const providerToolCalls = toolCalls.filter((tc) => tc.providerExecuted);
816
+ const executableToolCalls = nonProviderToolCalls.filter((tc) => {
817
+ const tool2 = effectiveTools[tc.toolName];
818
+ return !tool2 || typeof tool2.execute === "function";
819
+ });
820
+ const clientSideToolCalls = nonProviderToolCalls.filter((tc) => {
821
+ const tool2 = effectiveTools[tc.toolName];
822
+ return tool2 && typeof tool2.execute !== "function";
823
+ });
824
+ if (clientSideToolCalls.length > 0) {
825
+ const executableResults = await Promise.all(
826
+ executableToolCalls.map(
827
+ (toolCall) => executeToolWithCallbacks(
828
+ toolCall,
829
+ effectiveTools,
830
+ iterMessages,
831
+ experimentalContext
832
+ )
833
+ )
834
+ );
835
+ const providerResults = providerToolCalls.map(
836
+ (toolCall) => resolveProviderToolResult(
837
+ toolCall,
838
+ providerExecutedToolResults
839
+ )
840
+ );
841
+ const resolvedResults = [...executableResults, ...providerResults];
842
+ const allToolCalls = toolCalls.map((tc) => ({
843
+ type: "tool-call",
844
+ toolCallId: tc.toolCallId,
845
+ toolName: tc.toolName,
846
+ input: tc.input
847
+ }));
848
+ const allToolResults = resolvedResults.map((r) => {
849
+ var _a2;
850
+ return {
851
+ type: "tool-result",
852
+ toolCallId: r.toolCallId,
853
+ toolName: r.toolName,
854
+ input: (_a2 = toolCalls.find((tc) => tc.toolCallId === r.toolCallId)) == null ? void 0 : _a2.input,
855
+ output: "value" in r.output ? r.output.value : void 0
856
+ };
857
+ });
858
+ if (resolvedResults.length > 0) {
859
+ iterMessages.push({
860
+ role: "tool",
861
+ content: resolvedResults
862
+ });
863
+ }
864
+ const messages2 = iterMessages;
865
+ if (mergedOnFinish && !wasAborted) {
866
+ const lastStep = steps[steps.length - 1];
867
+ await mergedOnFinish({
868
+ steps,
869
+ messages: messages2,
870
+ text: (_k = lastStep == null ? void 0 : lastStep.text) != null ? _k : "",
871
+ finishReason: (_l = lastStep == null ? void 0 : lastStep.finishReason) != null ? _l : "other",
872
+ totalUsage: aggregateUsage(steps),
873
+ experimental_context: experimentalContext,
874
+ experimental_output: void 0
875
+ });
876
+ }
877
+ return {
878
+ messages: messages2,
879
+ steps,
880
+ toolCalls: allToolCalls,
881
+ toolResults: allToolResults,
882
+ experimental_output: void 0
883
+ };
884
+ }
885
+ const clientToolResults = await Promise.all(
886
+ nonProviderToolCalls.map(
887
+ (toolCall) => executeToolWithCallbacks(
888
+ toolCall,
889
+ effectiveTools,
890
+ iterMessages,
891
+ experimentalContext
892
+ )
893
+ )
894
+ );
895
+ const providerToolResults = providerToolCalls.map(
896
+ (toolCall) => resolveProviderToolResult(toolCall, providerExecutedToolResults)
897
+ );
898
+ const toolResults = toolCalls.map((tc) => {
899
+ const clientResult = clientToolResults.find(
900
+ (r) => r.toolCallId === tc.toolCallId
901
+ );
902
+ if (clientResult) return clientResult;
903
+ const providerResult = providerToolResults.find(
904
+ (r) => r.toolCallId === tc.toolCallId
905
+ );
906
+ if (providerResult) return providerResult;
907
+ return {
908
+ type: "tool-result",
909
+ toolCallId: tc.toolCallId,
910
+ toolName: tc.toolName,
911
+ output: { type: "text", value: "" }
912
+ };
913
+ });
914
+ lastStepToolCalls = toolCalls.map((tc) => ({
915
+ type: "tool-call",
916
+ toolCallId: tc.toolCallId,
917
+ toolName: tc.toolName,
918
+ input: tc.input
919
+ }));
920
+ lastStepToolResults = toolResults.map((r) => {
921
+ var _a2;
922
+ return {
923
+ type: "tool-result",
924
+ toolCallId: r.toolCallId,
925
+ toolName: r.toolName,
926
+ input: (_a2 = toolCalls.find((tc) => tc.toolCallId === r.toolCallId)) == null ? void 0 : _a2.input,
927
+ output: "value" in r.output ? r.output.value : void 0
928
+ };
929
+ });
930
+ result = await iterator.next(toolResults);
931
+ } else {
932
+ lastStepToolCalls = [];
933
+ lastStepToolResults = [];
934
+ result = await iterator.next([]);
935
+ }
936
+ }
937
+ if (result.done) {
938
+ finalMessages = result.value;
939
+ }
940
+ } catch (error) {
941
+ encounteredError = error;
942
+ if (error instanceof Error && error.name === "AbortError") {
943
+ wasAborted = true;
944
+ if (options.onAbort) {
945
+ await options.onAbort({ steps });
946
+ }
947
+ } else if (options.onError) {
948
+ await options.onError({ error });
949
+ }
950
+ }
951
+ const messages = finalMessages != null ? finalMessages : options.messages;
952
+ let experimentalOutput = void 0;
953
+ if (options.experimental_output && steps.length > 0) {
954
+ const lastStep = steps[steps.length - 1];
955
+ const text = lastStep.text;
956
+ if (text) {
957
+ try {
958
+ experimentalOutput = await options.experimental_output.parseCompleteOutput(
959
+ { text },
960
+ {
961
+ response: lastStep.response,
962
+ usage: lastStep.usage,
963
+ finishReason: lastStep.finishReason
964
+ }
965
+ );
966
+ } catch (parseError) {
967
+ if (!encounteredError) {
968
+ encounteredError = parseError;
969
+ }
970
+ }
971
+ }
972
+ }
973
+ if (mergedOnFinish && !wasAborted) {
974
+ const lastStep = steps[steps.length - 1];
975
+ await mergedOnFinish({
976
+ steps,
977
+ messages,
978
+ text: (_m = lastStep == null ? void 0 : lastStep.text) != null ? _m : "",
979
+ finishReason: (_n = lastStep == null ? void 0 : lastStep.finishReason) != null ? _n : "other",
980
+ totalUsage: aggregateUsage(steps),
981
+ experimental_context: experimentalContext,
982
+ experimental_output: experimentalOutput
983
+ });
984
+ }
985
+ if (encounteredError) {
986
+ throw encounteredError;
987
+ }
988
+ return {
989
+ messages,
990
+ steps,
991
+ toolCalls: lastStepToolCalls,
992
+ toolResults: lastStepToolResults,
993
+ experimental_output: experimentalOutput
994
+ };
995
+ }
996
+ };
997
+ function aggregateUsage(steps) {
998
+ var _a, _b, _c, _d;
999
+ let inputTokens = 0;
1000
+ let outputTokens = 0;
1001
+ for (const step of steps) {
1002
+ inputTokens += (_b = (_a = step.usage) == null ? void 0 : _a.inputTokens) != null ? _b : 0;
1003
+ outputTokens += (_d = (_c = step.usage) == null ? void 0 : _c.outputTokens) != null ? _d : 0;
1004
+ }
1005
+ return {
1006
+ inputTokens,
1007
+ outputTokens,
1008
+ totalTokens: inputTokens + outputTokens
1009
+ };
1010
+ }
1011
+ function filterTools(tools, activeTools) {
1012
+ const filtered = {};
1013
+ for (const toolName of activeTools) {
1014
+ if (toolName in tools) {
1015
+ filtered[toolName] = tools[toolName];
1016
+ }
1017
+ }
1018
+ return filtered;
1019
+ }
1020
+ function getErrorMessage(error) {
1021
+ if (error == null) {
1022
+ return "unknown error";
1023
+ }
1024
+ if (typeof error === "string") {
1025
+ return error;
1026
+ }
1027
+ if (error instanceof Error) {
1028
+ return error.message;
1029
+ }
1030
+ return JSON.stringify(error);
1031
+ }
1032
+ function resolveProviderToolResult(toolCall, providerExecutedToolResults) {
1033
+ const streamResult = providerExecutedToolResults == null ? void 0 : providerExecutedToolResults.get(toolCall.toolCallId);
1034
+ if (!streamResult) {
1035
+ console.warn(
1036
+ `[WorkflowAgent] Provider-executed tool "${toolCall.toolName}" (${toolCall.toolCallId}) did not receive a result from the stream. This may indicate a provider issue.`
1037
+ );
1038
+ return {
1039
+ type: "tool-result",
1040
+ toolCallId: toolCall.toolCallId,
1041
+ toolName: toolCall.toolName,
1042
+ output: {
1043
+ type: "text",
1044
+ value: ""
1045
+ }
1046
+ };
1047
+ }
1048
+ const result = streamResult.result;
1049
+ const isString = typeof result === "string";
1050
+ return {
1051
+ type: "tool-result",
1052
+ toolCallId: toolCall.toolCallId,
1053
+ toolName: toolCall.toolName,
1054
+ output: isString ? streamResult.isError ? { type: "error-text", value: result } : { type: "text", value: result } : streamResult.isError ? {
1055
+ type: "error-json",
1056
+ value: result
1057
+ } : {
1058
+ type: "json",
1059
+ value: result
1060
+ }
1061
+ };
1062
+ }
1063
+ async function executeTool(toolCall, tools, messages, experimentalContext) {
1064
+ const tool2 = tools[toolCall.toolName];
1065
+ if (!tool2) throw new Error(`Tool "${toolCall.toolName}" not found`);
1066
+ if (typeof tool2.execute !== "function") {
1067
+ throw new Error(
1068
+ `Tool "${toolCall.toolName}" does not have an execute function. Client-side tools should be filtered before calling executeTool.`
1069
+ );
1070
+ }
1071
+ const parsedInput = toolCall.input;
1072
+ try {
1073
+ const { execute } = tool2;
1074
+ const toolResult = await execute(parsedInput, {
1075
+ toolCallId: toolCall.toolCallId,
1076
+ // Pass the conversation messages to the tool so it has context about the conversation
1077
+ messages,
1078
+ // Pass experimental context to the tool
1079
+ experimental_context: experimentalContext
1080
+ });
1081
+ const output = typeof toolResult === "string" ? { type: "text", value: toolResult } : { type: "json", value: toolResult };
1082
+ return {
1083
+ type: "tool-result",
1084
+ toolCallId: toolCall.toolCallId,
1085
+ toolName: toolCall.toolName,
1086
+ output
1087
+ };
1088
+ } catch (error) {
1089
+ return {
1090
+ type: "tool-result",
1091
+ toolCallId: toolCall.toolCallId,
1092
+ toolName: toolCall.toolName,
1093
+ output: {
1094
+ type: "error-text",
1095
+ value: getErrorMessage(error)
1096
+ }
1097
+ };
1098
+ }
1099
+ }
1100
+
1101
+ // src/to-ui-message-chunk.ts
1102
+ import { generateId } from "ai";
1103
+ function toUIMessageChunk(part) {
1104
+ var _a;
1105
+ switch (part.type) {
1106
+ case "text-start":
1107
+ return {
1108
+ type: "text-start",
1109
+ id: part.id,
1110
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1111
+ };
1112
+ case "text-delta":
1113
+ return {
1114
+ type: "text-delta",
1115
+ id: part.id,
1116
+ delta: part.text,
1117
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1118
+ };
1119
+ case "text-end":
1120
+ return {
1121
+ type: "text-end",
1122
+ id: part.id,
1123
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1124
+ };
1125
+ case "reasoning-start":
1126
+ return {
1127
+ type: "reasoning-start",
1128
+ id: part.id,
1129
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1130
+ };
1131
+ case "reasoning-delta":
1132
+ return {
1133
+ type: "reasoning-delta",
1134
+ id: part.id,
1135
+ delta: part.text,
1136
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1137
+ };
1138
+ case "reasoning-end":
1139
+ return {
1140
+ type: "reasoning-end",
1141
+ id: part.id,
1142
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1143
+ };
1144
+ case "file": {
1145
+ const file = part.file;
1146
+ return {
1147
+ type: "file",
1148
+ mediaType: file.mediaType,
1149
+ url: `data:${file.mediaType};base64,${file.base64}`
1150
+ };
1151
+ }
1152
+ case "source": {
1153
+ if (part.sourceType === "url") {
1154
+ return {
1155
+ type: "source-url",
1156
+ sourceId: part.id,
1157
+ url: part.url,
1158
+ title: part.title,
1159
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1160
+ };
1161
+ }
1162
+ if (part.sourceType === "document") {
1163
+ return {
1164
+ type: "source-document",
1165
+ sourceId: part.id,
1166
+ mediaType: part.mediaType,
1167
+ title: part.title,
1168
+ filename: part.filename,
1169
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1170
+ };
1171
+ }
1172
+ return void 0;
1173
+ }
1174
+ case "tool-input-start":
1175
+ return {
1176
+ type: "tool-input-start",
1177
+ toolCallId: part.id,
1178
+ toolName: part.toolName,
1179
+ ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}
1180
+ };
1181
+ case "tool-input-delta":
1182
+ return {
1183
+ type: "tool-input-delta",
1184
+ toolCallId: part.id,
1185
+ inputTextDelta: part.delta
1186
+ };
1187
+ case "tool-call": {
1188
+ const toolCallPart = part;
1189
+ if (toolCallPart.invalid) {
1190
+ return {
1191
+ type: "tool-input-error",
1192
+ toolCallId: toolCallPart.toolCallId,
1193
+ toolName: toolCallPart.toolName,
1194
+ input: toolCallPart.input,
1195
+ errorText: toolCallPart.error instanceof Error ? toolCallPart.error.message : String((_a = toolCallPart.error) != null ? _a : "Invalid tool call")
1196
+ };
1197
+ }
1198
+ return {
1199
+ type: "tool-input-available",
1200
+ toolCallId: part.toolCallId,
1201
+ toolName: part.toolName,
1202
+ input: part.input,
1203
+ ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
1204
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
1205
+ };
1206
+ }
1207
+ case "tool-result":
1208
+ return {
1209
+ type: "tool-output-available",
1210
+ toolCallId: part.toolCallId,
1211
+ output: part.output
1212
+ };
1213
+ case "tool-error":
1214
+ return {
1215
+ type: "tool-output-error",
1216
+ toolCallId: part.toolCallId,
1217
+ errorText: part.error instanceof Error ? part.error.message : String(part.error)
1218
+ };
1219
+ case "error": {
1220
+ const error = part.error;
1221
+ return {
1222
+ type: "error",
1223
+ errorText: error instanceof Error ? error.message : String(error)
1224
+ };
1225
+ }
1226
+ // These don't produce UI chunks
1227
+ case "tool-input-end":
1228
+ case "model-call-start":
1229
+ case "model-call-response-metadata":
1230
+ case "model-call-end":
1231
+ case "raw":
1232
+ return void 0;
1233
+ default:
1234
+ return void 0;
1235
+ }
1236
+ }
1237
+ function createModelCallToUIChunkTransform() {
1238
+ return new TransformStream({
1239
+ start: (controller) => {
1240
+ controller.enqueue({ type: "start", messageId: generateId() });
1241
+ controller.enqueue({ type: "start-step" });
1242
+ },
1243
+ flush: (controller) => {
1244
+ controller.enqueue({ type: "finish-step" });
1245
+ controller.enqueue({ type: "finish" });
1246
+ },
1247
+ transform: (part, controller) => {
1248
+ const uiChunk = toUIMessageChunk(part);
1249
+ if (uiChunk) {
1250
+ controller.enqueue(uiChunk);
1251
+ }
1252
+ }
1253
+ });
1254
+ }
1255
+ export {
1256
+ Output,
1257
+ WorkflowAgent,
1258
+ createModelCallToUIChunkTransform,
1259
+ toUIMessageChunk
1260
+ };
1261
+ //# sourceMappingURL=index.mjs.map