@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/CHANGELOG.md +52 -0
- package/LICENSE +13 -0
- package/README.md +62 -0
- package/dist/index.d.mts +739 -0
- package/dist/index.mjs +1261 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +77 -0
- package/src/do-stream-step.ts +329 -0
- package/src/index.ts +37 -0
- package/src/providers/mock-function-wrapper.ts +11 -0
- package/src/providers/mock.ts +123 -0
- package/src/serializable-schema.ts +81 -0
- package/src/stream-iterator.ts +46 -0
- package/src/stream-text-iterator.ts +444 -0
- package/src/telemetry.ts +199 -0
- package/src/test/agent-e2e-workflows.ts +507 -0
- package/src/test/calculate-workflow.ts +19 -0
- package/src/to-ui-message-chunk.ts +214 -0
- package/src/types.ts +11 -0
- package/src/workflow-agent.ts +1647 -0
- package/src/workflow-chat-transport.ts +359 -0
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
|