@ai-sdk/workflow 2.0.20 → 2.0.22
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 +19 -0
- package/dist/index.d.ts +7 -6
- package/dist/index.js +480 -106
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/do-stream-step.ts +165 -12
- package/src/resolve-tool-context.ts +28 -0
- package/src/serializable-schema.ts +99 -30
- package/src/stream-text-iterator.ts +273 -51
- package/src/workflow-agent.ts +153 -78
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ import "./chunk-UAWBPTDW.js";
|
|
|
4
4
|
import {
|
|
5
5
|
getErrorMessage,
|
|
6
6
|
isAbortError as isAbortError2,
|
|
7
|
-
validateTypes,
|
|
8
7
|
withUserAgentSuffix
|
|
9
8
|
} from "@ai-sdk/provider-utils";
|
|
10
9
|
import {
|
|
@@ -73,8 +72,28 @@ async function createLanguageModelToolResultOutput({
|
|
|
73
72
|
});
|
|
74
73
|
}
|
|
75
74
|
|
|
75
|
+
// src/resolve-tool-context.ts
|
|
76
|
+
import { validateTypes } from "@ai-sdk/provider-utils";
|
|
77
|
+
async function resolveToolContext({
|
|
78
|
+
toolName,
|
|
79
|
+
tool: tool2,
|
|
80
|
+
toolsContext
|
|
81
|
+
}) {
|
|
82
|
+
const contextSchema = tool2.contextSchema;
|
|
83
|
+
const entry = toolsContext == null ? void 0 : toolsContext[toolName];
|
|
84
|
+
if (contextSchema == null) {
|
|
85
|
+
return entry;
|
|
86
|
+
}
|
|
87
|
+
return await validateTypes({
|
|
88
|
+
value: entry,
|
|
89
|
+
schema: contextSchema,
|
|
90
|
+
context: { field: "tool context", entityName: toolName }
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
76
94
|
// src/stream-text-iterator.ts
|
|
77
95
|
import {
|
|
96
|
+
DefaultGeneratedFile,
|
|
78
97
|
experimental_filterActiveTools as filterActiveTools
|
|
79
98
|
} from "ai";
|
|
80
99
|
import { createRestrictedTelemetryDispatcher } from "ai/internal";
|
|
@@ -92,7 +111,7 @@ import {
|
|
|
92
111
|
asSchema,
|
|
93
112
|
jsonSchema
|
|
94
113
|
} from "@ai-sdk/provider-utils";
|
|
95
|
-
import { tool } from "ai";
|
|
114
|
+
import { dynamicTool, tool } from "ai";
|
|
96
115
|
import Ajv from "ajv";
|
|
97
116
|
function serializeToolSet(tools, {
|
|
98
117
|
toolsContext = {},
|
|
@@ -102,6 +121,8 @@ function serializeToolSet(tools, {
|
|
|
102
121
|
Object.entries(tools).map(([name, t]) => {
|
|
103
122
|
var _a;
|
|
104
123
|
const def = {
|
|
124
|
+
title: t.title,
|
|
125
|
+
metadata: t.metadata,
|
|
105
126
|
description: resolveToolDescription({
|
|
106
127
|
tool: t,
|
|
107
128
|
toolName: name,
|
|
@@ -109,12 +130,26 @@ function serializeToolSet(tools, {
|
|
|
109
130
|
experimental_sandbox: sandbox
|
|
110
131
|
}),
|
|
111
132
|
inputSchema: asSchema(t.inputSchema).jsonSchema,
|
|
133
|
+
strict: t.strict,
|
|
112
134
|
inputExamples: t.inputExamples,
|
|
113
135
|
providerOptions: t.providerOptions
|
|
114
136
|
};
|
|
137
|
+
if (t.type === "dynamic") {
|
|
138
|
+
def.type = "dynamic";
|
|
139
|
+
}
|
|
140
|
+
if (t.onInputStart != null) {
|
|
141
|
+
def.hasOnInputStart = true;
|
|
142
|
+
}
|
|
143
|
+
if (t.onInputDelta != null) {
|
|
144
|
+
def.hasOnInputDelta = true;
|
|
145
|
+
}
|
|
146
|
+
if (t.onInputAvailable != null) {
|
|
147
|
+
def.hasOnInputAvailable = true;
|
|
148
|
+
}
|
|
115
149
|
if (t.type === "provider") {
|
|
116
150
|
def.type = "provider";
|
|
117
151
|
def.isProviderExecuted = (_a = t.isProviderExecuted) != null ? _a : false;
|
|
152
|
+
def.supportsDeferredResults = t.supportsDeferredResults;
|
|
118
153
|
def.id = t.id;
|
|
119
154
|
def.args = t.args;
|
|
120
155
|
}
|
|
@@ -137,39 +172,74 @@ function resolveSerializableTools(tools) {
|
|
|
137
172
|
const ajv = new Ajv();
|
|
138
173
|
return Object.fromEntries(
|
|
139
174
|
Object.entries(tools).map(([name, t]) => {
|
|
140
|
-
var _a
|
|
175
|
+
var _a;
|
|
141
176
|
if (t.type === "provider") {
|
|
177
|
+
const providerTool = {
|
|
178
|
+
type: "provider",
|
|
179
|
+
title: t.title,
|
|
180
|
+
metadata: t.metadata,
|
|
181
|
+
id: t.id,
|
|
182
|
+
args: (_a = t.args) != null ? _a : {},
|
|
183
|
+
inputSchema: jsonSchema(t.inputSchema),
|
|
184
|
+
providerOptions: t.providerOptions
|
|
185
|
+
};
|
|
142
186
|
return [
|
|
143
187
|
name,
|
|
144
|
-
tool({
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
188
|
+
t.isProviderExecuted ? tool({
|
|
189
|
+
...providerTool,
|
|
190
|
+
isProviderExecuted: true,
|
|
191
|
+
supportsDeferredResults: t.supportsDeferredResults
|
|
192
|
+
}) : tool({
|
|
193
|
+
...providerTool,
|
|
194
|
+
isProviderExecuted: false
|
|
151
195
|
})
|
|
152
196
|
];
|
|
153
197
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
198
|
+
if (t.type === "dynamic") {
|
|
199
|
+
const validateFn2 = ajv.compile(t.inputSchema);
|
|
200
|
+
return [
|
|
201
|
+
name,
|
|
202
|
+
dynamicTool({
|
|
203
|
+
description: t.description,
|
|
204
|
+
inputExamples: t.inputExamples,
|
|
205
|
+
providerOptions: t.providerOptions,
|
|
206
|
+
inputSchema: jsonSchema(t.inputSchema, {
|
|
207
|
+
validate: (value) => {
|
|
208
|
+
if (validateFn2(value)) {
|
|
209
|
+
return { success: true, value };
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
success: false,
|
|
213
|
+
error: new Error(ajv.errorsText(validateFn2.errors))
|
|
214
|
+
};
|
|
165
215
|
}
|
|
166
|
-
|
|
167
|
-
success: false,
|
|
168
|
-
error: new Error(ajv.errorsText(validateFn.errors))
|
|
169
|
-
};
|
|
170
|
-
}
|
|
216
|
+
})
|
|
171
217
|
})
|
|
218
|
+
];
|
|
219
|
+
}
|
|
220
|
+
const validateFn = ajv.compile(t.inputSchema);
|
|
221
|
+
const functionTool = {
|
|
222
|
+
title: t.title,
|
|
223
|
+
metadata: t.metadata,
|
|
224
|
+
description: t.description,
|
|
225
|
+
strict: t.strict,
|
|
226
|
+
inputExamples: t.inputExamples,
|
|
227
|
+
providerOptions: t.providerOptions,
|
|
228
|
+
inputSchema: jsonSchema(t.inputSchema, {
|
|
229
|
+
validate: (value) => {
|
|
230
|
+
if (validateFn(value)) {
|
|
231
|
+
return { success: true, value };
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
success: false,
|
|
235
|
+
error: new Error(ajv.errorsText(validateFn.errors))
|
|
236
|
+
};
|
|
237
|
+
}
|
|
172
238
|
})
|
|
239
|
+
};
|
|
240
|
+
return [
|
|
241
|
+
name,
|
|
242
|
+
t.type === "dynamic" ? tool({ ...functionTool, type: "dynamic" }) : tool(functionTool)
|
|
173
243
|
];
|
|
174
244
|
})
|
|
175
245
|
);
|
|
@@ -178,13 +248,14 @@ function resolveSerializableTools(tools) {
|
|
|
178
248
|
// src/do-stream-step.ts
|
|
179
249
|
async function doStreamStep(conversationPrompt, modelInit, writable, serializedTools, options) {
|
|
180
250
|
"use step";
|
|
181
|
-
var _a;
|
|
251
|
+
var _a, _b, _c, _d, _e, _f;
|
|
182
252
|
const timeout = (options == null ? void 0 : options.timeoutAt) == null ? void 0 : options.timeoutAt - Date.now();
|
|
183
253
|
if (((_a = options == null ? void 0 : options.abortSignal) == null ? void 0 : _a.aborted) || timeout != null && timeout <= 0) {
|
|
184
254
|
return { aborted: true };
|
|
185
255
|
}
|
|
186
256
|
const abortSignal = timeout == null ? options == null ? void 0 : options.abortSignal : (options == null ? void 0 : options.abortSignal) == null ? AbortSignal.timeout(timeout) : AbortSignal.any([options.abortSignal, AbortSignal.timeout(timeout)]);
|
|
187
257
|
const model = typeof modelInit === "string" ? gateway.languageModel(modelInit) : modelInit;
|
|
258
|
+
const toolInputLifecycleEvents = [];
|
|
188
259
|
const tools = serializedTools ? resolveSerializableTools(serializedTools) : void 0;
|
|
189
260
|
const output = (options == null ? void 0 : options.responseFormat) == null ? void 0 : {
|
|
190
261
|
name: "workflow",
|
|
@@ -248,25 +319,85 @@ async function doStreamStep(conversationPrompt, modelInit, writable, serializedT
|
|
|
248
319
|
const toolCalls = [];
|
|
249
320
|
const providerExecutedToolResults = /* @__PURE__ */ new Map();
|
|
250
321
|
let finish;
|
|
251
|
-
|
|
322
|
+
const content = [];
|
|
323
|
+
const textPartIndexes = /* @__PURE__ */ new Map();
|
|
252
324
|
const reasoningParts = [];
|
|
253
325
|
let responseMetadata;
|
|
254
326
|
let warnings;
|
|
255
327
|
let terminalError;
|
|
256
328
|
let hasTerminalError = false;
|
|
329
|
+
const ongoingToolCallToolNames = /* @__PURE__ */ new Map();
|
|
257
330
|
const writer = writable == null ? void 0 : writable.getWriter();
|
|
258
331
|
try {
|
|
259
332
|
await (writer == null ? void 0 : writer.write({ type: "reset-step" }));
|
|
260
333
|
for await (const part of modelStream) {
|
|
261
334
|
switch (part.type) {
|
|
335
|
+
case "tool-input-start":
|
|
336
|
+
ongoingToolCallToolNames.set(part.id, part.toolName);
|
|
337
|
+
if (((_b = serializedTools == null ? void 0 : serializedTools[part.toolName]) == null ? void 0 : _b.hasOnInputStart) || ((_c = serializedTools == null ? void 0 : serializedTools[part.toolName]) == null ? void 0 : _c.hasOnInputDelta) || ((_d = serializedTools == null ? void 0 : serializedTools[part.toolName]) == null ? void 0 : _d.hasOnInputAvailable)) {
|
|
338
|
+
toolInputLifecycleEvents.push(["start", part.id, part.toolName]);
|
|
339
|
+
}
|
|
340
|
+
break;
|
|
341
|
+
case "tool-input-delta": {
|
|
342
|
+
const toolName = ongoingToolCallToolNames.get(part.id);
|
|
343
|
+
if (toolName != null && ((_e = serializedTools == null ? void 0 : serializedTools[toolName]) == null ? void 0 : _e.hasOnInputDelta)) {
|
|
344
|
+
toolInputLifecycleEvents.push(["delta", part.id, part.delta]);
|
|
345
|
+
}
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
case "text-start":
|
|
349
|
+
upsertTextContentPart({
|
|
350
|
+
content,
|
|
351
|
+
textPartIndexes,
|
|
352
|
+
id: part.id,
|
|
353
|
+
providerMetadata: part.providerMetadata
|
|
354
|
+
});
|
|
355
|
+
break;
|
|
262
356
|
case "text-delta":
|
|
263
|
-
|
|
357
|
+
upsertTextContentPart({
|
|
358
|
+
content,
|
|
359
|
+
textPartIndexes,
|
|
360
|
+
id: part.id,
|
|
361
|
+
textDelta: part.text,
|
|
362
|
+
providerMetadata: part.providerMetadata
|
|
363
|
+
});
|
|
364
|
+
break;
|
|
365
|
+
case "text-end":
|
|
366
|
+
upsertTextContentPart({
|
|
367
|
+
content,
|
|
368
|
+
textPartIndexes,
|
|
369
|
+
id: part.id,
|
|
370
|
+
providerMetadata: part.providerMetadata
|
|
371
|
+
});
|
|
372
|
+
textPartIndexes.delete(part.id);
|
|
264
373
|
break;
|
|
265
374
|
case "reasoning-delta":
|
|
266
375
|
reasoningParts.push({ text: part.text });
|
|
267
376
|
break;
|
|
377
|
+
case "file":
|
|
378
|
+
content.push({
|
|
379
|
+
type: "file",
|
|
380
|
+
data: part.file.base64,
|
|
381
|
+
mediaType: part.file.mediaType,
|
|
382
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
383
|
+
});
|
|
384
|
+
break;
|
|
385
|
+
case "source":
|
|
386
|
+
content.push(part);
|
|
387
|
+
break;
|
|
268
388
|
case "tool-call": {
|
|
269
389
|
const toolCallPart = part;
|
|
390
|
+
const toolCallIndex = toolCalls.length;
|
|
391
|
+
const lifecycleToolName = ongoingToolCallToolNames.get(
|
|
392
|
+
toolCallPart.toolCallId
|
|
393
|
+
);
|
|
394
|
+
ongoingToolCallToolNames.delete(toolCallPart.toolCallId);
|
|
395
|
+
if (lifecycleToolName != null && ((_f = serializedTools == null ? void 0 : serializedTools[lifecycleToolName]) == null ? void 0 : _f.hasOnInputAvailable)) {
|
|
396
|
+
toolInputLifecycleEvents.push([
|
|
397
|
+
"available",
|
|
398
|
+
toolCallPart.toolCallId
|
|
399
|
+
]);
|
|
400
|
+
}
|
|
270
401
|
toolCalls.push({
|
|
271
402
|
type: "tool-call",
|
|
272
403
|
toolCallId: toolCallPart.toolCallId,
|
|
@@ -274,10 +405,13 @@ async function doStreamStep(conversationPrompt, modelInit, writable, serializedT
|
|
|
274
405
|
input: toolCallPart.input,
|
|
275
406
|
providerExecuted: toolCallPart.providerExecuted,
|
|
276
407
|
providerMetadata: toolCallPart.providerMetadata,
|
|
408
|
+
title: toolCallPart.title,
|
|
409
|
+
toolMetadata: toolCallPart.toolMetadata,
|
|
277
410
|
dynamic: toolCallPart.dynamic,
|
|
278
411
|
invalid: toolCallPart.invalid,
|
|
279
412
|
error: toolCallPart.error
|
|
280
413
|
});
|
|
414
|
+
content.push({ type: "tool-call", toolCallIndex });
|
|
281
415
|
break;
|
|
282
416
|
}
|
|
283
417
|
case "tool-result":
|
|
@@ -349,16 +483,44 @@ async function doStreamStep(conversationPrompt, modelInit, writable, serializedT
|
|
|
349
483
|
toolCalls,
|
|
350
484
|
finish,
|
|
351
485
|
raw: {
|
|
352
|
-
|
|
486
|
+
content,
|
|
353
487
|
reasoning: reasoningParts,
|
|
354
488
|
responseMetadata,
|
|
355
489
|
warnings
|
|
356
490
|
},
|
|
357
491
|
providerExecutedToolResults,
|
|
492
|
+
toolInputLifecycleEvents,
|
|
358
493
|
...hasTerminalError ? { terminalError } : {}
|
|
359
494
|
};
|
|
360
495
|
}
|
|
361
496
|
doStreamStep.maxRetries = 0;
|
|
497
|
+
function upsertTextContentPart({
|
|
498
|
+
content,
|
|
499
|
+
textPartIndexes,
|
|
500
|
+
id,
|
|
501
|
+
textDelta,
|
|
502
|
+
providerMetadata
|
|
503
|
+
}) {
|
|
504
|
+
let partIndex = textPartIndexes.get(id);
|
|
505
|
+
if (partIndex == null) {
|
|
506
|
+
partIndex = content.push({
|
|
507
|
+
type: "text",
|
|
508
|
+
text: "",
|
|
509
|
+
...providerMetadata != null ? { providerMetadata } : {}
|
|
510
|
+
}) - 1;
|
|
511
|
+
textPartIndexes.set(id, partIndex);
|
|
512
|
+
}
|
|
513
|
+
const part = content[partIndex];
|
|
514
|
+
if (part.type !== "text") {
|
|
515
|
+
throw new Error(`Expected text content at index ${partIndex}.`);
|
|
516
|
+
}
|
|
517
|
+
if (textDelta != null) {
|
|
518
|
+
part.text += textDelta;
|
|
519
|
+
}
|
|
520
|
+
if (providerMetadata != null) {
|
|
521
|
+
part.providerMetadata = providerMetadata;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
362
524
|
|
|
363
525
|
// src/stream-text-iterator.ts
|
|
364
526
|
var prepareStepGenerationSettingKeys = [
|
|
@@ -540,6 +702,7 @@ async function* streamTextIterator({
|
|
|
540
702
|
providerOptions: currentGenerationSettings.providerOptions,
|
|
541
703
|
headers: currentGenerationSettings.headers
|
|
542
704
|
}));
|
|
705
|
+
const stepInputMessages = conversationPrompt;
|
|
543
706
|
const streamStepResult = await doStreamStep(
|
|
544
707
|
conversationPrompt,
|
|
545
708
|
currentModel,
|
|
@@ -562,7 +725,22 @@ async function* streamTextIterator({
|
|
|
562
725
|
terminalError = streamStepResult.terminalError;
|
|
563
726
|
hasTerminalError = true;
|
|
564
727
|
}
|
|
565
|
-
const {
|
|
728
|
+
const {
|
|
729
|
+
toolCalls,
|
|
730
|
+
finish,
|
|
731
|
+
raw,
|
|
732
|
+
providerExecutedToolResults,
|
|
733
|
+
toolInputLifecycleEvents
|
|
734
|
+
} = streamStepResult;
|
|
735
|
+
await invokeToolInputLifecycleCallbacks({
|
|
736
|
+
events: toolInputLifecycleEvents != null ? toolInputLifecycleEvents : [],
|
|
737
|
+
toolCalls,
|
|
738
|
+
tools: effectiveTools,
|
|
739
|
+
messages: stepInputMessages,
|
|
740
|
+
abortSignal: currentGenerationSettings.abortSignal,
|
|
741
|
+
toolsContext: currentToolsContext,
|
|
742
|
+
experimental_sandbox: stepSandbox
|
|
743
|
+
});
|
|
566
744
|
const step = buildStepResult(raw, toolCalls, finish, {
|
|
567
745
|
stepNumber,
|
|
568
746
|
runtimeContext: currentRuntimeContext,
|
|
@@ -588,27 +766,17 @@ async function* streamTextIterator({
|
|
|
588
766
|
done = true;
|
|
589
767
|
} else if (finishReason === "tool-calls") {
|
|
590
768
|
lastStepWasToolCalls = true;
|
|
591
|
-
const
|
|
592
|
-
|
|
769
|
+
const assistantContent = getAssistantMessageContent(step);
|
|
770
|
+
const includedToolCallIds = new Set(
|
|
771
|
+
assistantContent.flatMap(
|
|
772
|
+
(part) => part.type === "tool-call" ? [part.toolCallId] : []
|
|
773
|
+
)
|
|
593
774
|
);
|
|
594
775
|
conversationPrompt.push({
|
|
595
776
|
role: "assistant",
|
|
596
777
|
content: [
|
|
597
|
-
...
|
|
598
|
-
...toolCalls.
|
|
599
|
-
const sanitizedMetadata = sanitizeProviderMetadataForToolCall(
|
|
600
|
-
toolCall.providerMetadata
|
|
601
|
-
);
|
|
602
|
-
return {
|
|
603
|
-
type: "tool-call",
|
|
604
|
-
toolCallId: toolCall.toolCallId,
|
|
605
|
-
toolName: toolCall.toolName,
|
|
606
|
-
input: toolCall.input,
|
|
607
|
-
...sanitizedMetadata != null ? {
|
|
608
|
-
providerOptions: sanitizedMetadata
|
|
609
|
-
} : {}
|
|
610
|
-
};
|
|
611
|
-
})
|
|
778
|
+
...assistantContent,
|
|
779
|
+
...toolCalls.filter((toolCall) => !includedToolCallIds.has(toolCall.toolCallId)).map(toAssistantToolCallContent)
|
|
612
780
|
]
|
|
613
781
|
});
|
|
614
782
|
const toolResults = yield {
|
|
@@ -631,13 +799,11 @@ async function* streamTextIterator({
|
|
|
631
799
|
}
|
|
632
800
|
}
|
|
633
801
|
} else if (finishReason === "stop") {
|
|
634
|
-
const
|
|
635
|
-
|
|
636
|
-
);
|
|
637
|
-
if (textContent.length > 0) {
|
|
802
|
+
const assistantContent = getAssistantMessageContent(step);
|
|
803
|
+
if (assistantContent.length > 0) {
|
|
638
804
|
conversationPrompt.push({
|
|
639
805
|
role: "assistant",
|
|
640
|
-
content:
|
|
806
|
+
content: assistantContent
|
|
641
807
|
});
|
|
642
808
|
}
|
|
643
809
|
done = true;
|
|
@@ -688,6 +854,74 @@ async function* streamTextIterator({
|
|
|
688
854
|
}
|
|
689
855
|
return conversationPrompt;
|
|
690
856
|
}
|
|
857
|
+
async function invokeToolInputLifecycleCallbacks({
|
|
858
|
+
events,
|
|
859
|
+
toolCalls,
|
|
860
|
+
tools,
|
|
861
|
+
messages,
|
|
862
|
+
abortSignal,
|
|
863
|
+
toolsContext,
|
|
864
|
+
experimental_sandbox
|
|
865
|
+
}) {
|
|
866
|
+
var _a, _b, _c;
|
|
867
|
+
const toolNamesByCallId = /* @__PURE__ */ new Map();
|
|
868
|
+
const toolCallsById = new Map(
|
|
869
|
+
toolCalls.map((toolCall) => [toolCall.toolCallId, toolCall])
|
|
870
|
+
);
|
|
871
|
+
const resolvedContexts = /* @__PURE__ */ new Map();
|
|
872
|
+
for (const event of events) {
|
|
873
|
+
const [type, toolCallId, value] = event;
|
|
874
|
+
if (type === "start") {
|
|
875
|
+
toolNamesByCallId.set(toolCallId, value);
|
|
876
|
+
}
|
|
877
|
+
const toolName = type === "start" ? value : toolNamesByCallId.get(toolCallId);
|
|
878
|
+
if (toolName == null) {
|
|
879
|
+
continue;
|
|
880
|
+
}
|
|
881
|
+
const tool2 = tools[toolName];
|
|
882
|
+
if (tool2 == null) {
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
let resolvedContext = resolvedContexts.get(toolName);
|
|
886
|
+
if (resolvedContext == null) {
|
|
887
|
+
resolvedContext = resolveToolContext({
|
|
888
|
+
toolName,
|
|
889
|
+
tool: tool2,
|
|
890
|
+
toolsContext
|
|
891
|
+
});
|
|
892
|
+
resolvedContexts.set(toolName, resolvedContext);
|
|
893
|
+
}
|
|
894
|
+
const options = {
|
|
895
|
+
toolCallId,
|
|
896
|
+
messages,
|
|
897
|
+
abortSignal,
|
|
898
|
+
context: await resolvedContext,
|
|
899
|
+
experimental_sandbox
|
|
900
|
+
};
|
|
901
|
+
switch (type) {
|
|
902
|
+
case "start":
|
|
903
|
+
await ((_a = tool2.onInputStart) == null ? void 0 : _a.call(tool2, options));
|
|
904
|
+
break;
|
|
905
|
+
case "delta":
|
|
906
|
+
await ((_b = tool2.onInputDelta) == null ? void 0 : _b.call(tool2, {
|
|
907
|
+
...options,
|
|
908
|
+
inputTextDelta: value
|
|
909
|
+
}));
|
|
910
|
+
break;
|
|
911
|
+
case "available": {
|
|
912
|
+
const toolCall = toolCallsById.get(toolCallId);
|
|
913
|
+
if (toolCall == null) {
|
|
914
|
+
break;
|
|
915
|
+
}
|
|
916
|
+
await ((_c = tool2.onInputAvailable) == null ? void 0 : _c.call(tool2, {
|
|
917
|
+
...options,
|
|
918
|
+
input: toolCall.input
|
|
919
|
+
}));
|
|
920
|
+
break;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
691
925
|
function getModelInfo(model) {
|
|
692
926
|
var _a;
|
|
693
927
|
return typeof model === "string" ? { provider: (_a = model.split("/")[0]) != null ? _a : "gateway", modelId: model } : { provider: model.provider, modelId: model.modelId };
|
|
@@ -701,15 +935,76 @@ function normalizeStepForTelemetry(step) {
|
|
|
701
935
|
}
|
|
702
936
|
function buildStepResult(raw, toolCalls, finish, opts) {
|
|
703
937
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
704
|
-
const {
|
|
938
|
+
const {
|
|
939
|
+
content: rawContent,
|
|
940
|
+
reasoning: reasoningParts,
|
|
941
|
+
responseMetadata,
|
|
942
|
+
warnings
|
|
943
|
+
} = raw;
|
|
705
944
|
const reasoningText = reasoningParts.map((r) => r.text).join("") || void 0;
|
|
706
|
-
const
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
945
|
+
const validToolCallsByIndex = new Map(
|
|
946
|
+
toolCalls.flatMap(
|
|
947
|
+
(tc, index) => tc.invalid ? [] : [
|
|
948
|
+
[
|
|
949
|
+
index,
|
|
950
|
+
{
|
|
951
|
+
type: "tool-call",
|
|
952
|
+
toolCallId: tc.toolCallId,
|
|
953
|
+
toolName: tc.toolName,
|
|
954
|
+
input: tc.input,
|
|
955
|
+
...tc.providerExecuted != null ? { providerExecuted: tc.providerExecuted } : {},
|
|
956
|
+
...tc.title != null ? { title: tc.title } : {},
|
|
957
|
+
...tc.toolMetadata != null ? { toolMetadata: tc.toolMetadata } : {},
|
|
958
|
+
...tc.dynamic ? { dynamic: true } : {},
|
|
959
|
+
...tc.providerExecuted ? { providerExecuted: true } : {},
|
|
960
|
+
...tc.providerMetadata != null ? { providerMetadata: tc.providerMetadata } : {}
|
|
961
|
+
}
|
|
962
|
+
]
|
|
963
|
+
]
|
|
964
|
+
)
|
|
965
|
+
);
|
|
966
|
+
const validToolCalls = [...validToolCallsByIndex.values()];
|
|
967
|
+
const content = [];
|
|
968
|
+
const files = [];
|
|
969
|
+
const sources = [];
|
|
970
|
+
let text = "";
|
|
971
|
+
for (const part of rawContent) {
|
|
972
|
+
switch (part.type) {
|
|
973
|
+
case "text":
|
|
974
|
+
text += part.text;
|
|
975
|
+
content.push({
|
|
976
|
+
type: "text",
|
|
977
|
+
text: part.text,
|
|
978
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
979
|
+
});
|
|
980
|
+
break;
|
|
981
|
+
case "file": {
|
|
982
|
+
const file = new DefaultGeneratedFile({
|
|
983
|
+
data: part.data,
|
|
984
|
+
mediaType: part.mediaType,
|
|
985
|
+
providerMetadata: part.providerMetadata
|
|
986
|
+
});
|
|
987
|
+
files.push(file);
|
|
988
|
+
content.push({
|
|
989
|
+
type: "file",
|
|
990
|
+
file,
|
|
991
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
992
|
+
});
|
|
993
|
+
break;
|
|
994
|
+
}
|
|
995
|
+
case "source":
|
|
996
|
+
sources.push(part);
|
|
997
|
+
content.push(part);
|
|
998
|
+
break;
|
|
999
|
+
case "tool-call": {
|
|
1000
|
+
const toolCall = validToolCallsByIndex.get(part.toolCallIndex);
|
|
1001
|
+
if (toolCall != null) {
|
|
1002
|
+
content.push(toolCall);
|
|
1003
|
+
}
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
713
1008
|
return {
|
|
714
1009
|
callId: "workflow-agent",
|
|
715
1010
|
stepNumber: opts.stepNumber,
|
|
@@ -721,20 +1016,17 @@ function buildStepResult(raw, toolCalls, finish, opts) {
|
|
|
721
1016
|
metadata: void 0,
|
|
722
1017
|
runtimeContext: (_d = opts.runtimeContext) != null ? _d : {},
|
|
723
1018
|
toolsContext: (_e = opts.toolsContext) != null ? _e : {},
|
|
724
|
-
content
|
|
725
|
-
...text ? [{ type: "text", text }] : [],
|
|
726
|
-
...validToolCalls
|
|
727
|
-
],
|
|
1019
|
+
content,
|
|
728
1020
|
text,
|
|
729
1021
|
reasoning: reasoningParts.map((r) => ({
|
|
730
1022
|
type: "reasoning",
|
|
731
1023
|
text: r.text
|
|
732
1024
|
})),
|
|
733
1025
|
reasoningText,
|
|
734
|
-
files
|
|
735
|
-
sources
|
|
1026
|
+
files,
|
|
1027
|
+
sources,
|
|
736
1028
|
toolCalls: validToolCalls,
|
|
737
|
-
staticToolCalls:
|
|
1029
|
+
staticToolCalls: validToolCalls.filter((tc) => tc.dynamic !== true),
|
|
738
1030
|
dynamicToolCalls: validToolCalls.filter((tc) => tc.dynamic),
|
|
739
1031
|
toolResults: [],
|
|
740
1032
|
staticToolResults: [],
|
|
@@ -780,6 +1072,47 @@ function buildStepResult(raw, toolCalls, finish, opts) {
|
|
|
780
1072
|
providerMetadata: (_k = finish == null ? void 0 : finish.providerMetadata) != null ? _k : {}
|
|
781
1073
|
};
|
|
782
1074
|
}
|
|
1075
|
+
function getAssistantMessageContent(step) {
|
|
1076
|
+
const content = [];
|
|
1077
|
+
for (const part of step.content) {
|
|
1078
|
+
switch (part.type) {
|
|
1079
|
+
case "text":
|
|
1080
|
+
if (part.text.length > 0) {
|
|
1081
|
+
content.push({ type: "text", text: part.text });
|
|
1082
|
+
}
|
|
1083
|
+
break;
|
|
1084
|
+
case "file":
|
|
1085
|
+
content.push({
|
|
1086
|
+
type: "file",
|
|
1087
|
+
data: { type: "data", data: part.file.base64 },
|
|
1088
|
+
mediaType: part.file.mediaType,
|
|
1089
|
+
...part.providerMetadata != null ? {
|
|
1090
|
+
providerOptions: part.providerMetadata
|
|
1091
|
+
} : {}
|
|
1092
|
+
});
|
|
1093
|
+
break;
|
|
1094
|
+
case "tool-call":
|
|
1095
|
+
content.push(toAssistantToolCallContent(part));
|
|
1096
|
+
break;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
return content;
|
|
1100
|
+
}
|
|
1101
|
+
function toAssistantToolCallContent(toolCall) {
|
|
1102
|
+
const sanitizedMetadata = sanitizeProviderMetadataForToolCall(
|
|
1103
|
+
toolCall.providerMetadata
|
|
1104
|
+
);
|
|
1105
|
+
return {
|
|
1106
|
+
type: "tool-call",
|
|
1107
|
+
toolCallId: toolCall.toolCallId,
|
|
1108
|
+
toolName: toolCall.toolName,
|
|
1109
|
+
input: toolCall.input,
|
|
1110
|
+
...toolCall.providerExecuted != null ? { providerExecuted: toolCall.providerExecuted } : {},
|
|
1111
|
+
...sanitizedMetadata != null ? {
|
|
1112
|
+
providerOptions: sanitizedMetadata
|
|
1113
|
+
} : {}
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
783
1116
|
function sanitizeProviderMetadataForToolCall(metadata) {
|
|
784
1117
|
if (metadata == null) return void 0;
|
|
785
1118
|
const meta = metadata;
|
|
@@ -802,6 +1135,45 @@ function sanitizeProviderMetadataForToolCall(metadata) {
|
|
|
802
1135
|
}
|
|
803
1136
|
|
|
804
1137
|
// src/workflow-agent.ts
|
|
1138
|
+
function addToolResultsToStep(step, executedResults) {
|
|
1139
|
+
if (step == null || executedResults.length === 0) {
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
const toolOutputs = executedResults.map((result) => {
|
|
1143
|
+
const toolCall = step.toolCalls.find(
|
|
1144
|
+
(toolCall2) => toolCall2.toolCallId === result.modelResult.toolCallId
|
|
1145
|
+
);
|
|
1146
|
+
const common = {
|
|
1147
|
+
toolCallId: result.modelResult.toolCallId,
|
|
1148
|
+
toolName: result.modelResult.toolName,
|
|
1149
|
+
input: toolCall == null ? void 0 : toolCall.input,
|
|
1150
|
+
...(toolCall == null ? void 0 : toolCall.dynamic) === true ? { dynamic: true } : {},
|
|
1151
|
+
...(toolCall == null ? void 0 : toolCall.providerExecuted) === true ? { providerExecuted: true } : {}
|
|
1152
|
+
};
|
|
1153
|
+
return result.isError ? {
|
|
1154
|
+
type: "tool-error",
|
|
1155
|
+
...common,
|
|
1156
|
+
error: result.rawOutput
|
|
1157
|
+
} : {
|
|
1158
|
+
type: "tool-result",
|
|
1159
|
+
...common,
|
|
1160
|
+
output: result.rawOutput
|
|
1161
|
+
};
|
|
1162
|
+
});
|
|
1163
|
+
step.content.push(...toolOutputs);
|
|
1164
|
+
const toolResults = toolOutputs.filter(
|
|
1165
|
+
(result) => result.type === "tool-result"
|
|
1166
|
+
);
|
|
1167
|
+
step.toolResults.push(
|
|
1168
|
+
...toolResults
|
|
1169
|
+
);
|
|
1170
|
+
step.staticToolResults.push(
|
|
1171
|
+
...toolResults.filter((result) => result.dynamic !== true)
|
|
1172
|
+
);
|
|
1173
|
+
step.dynamicToolResults.push(
|
|
1174
|
+
...toolResults.filter((result) => result.dynamic === true)
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
805
1177
|
var WorkflowAgent = class {
|
|
806
1178
|
constructor(options) {
|
|
807
1179
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -1507,26 +1879,32 @@ var WorkflowAgent = class {
|
|
|
1507
1879
|
)
|
|
1508
1880
|
)
|
|
1509
1881
|
);
|
|
1510
|
-
const
|
|
1511
|
-
providerToolCalls.map(
|
|
1512
|
-
|
|
1882
|
+
const providerResultEntries = await Promise.all(
|
|
1883
|
+
providerToolCalls.map(async (toolCall) => ({
|
|
1884
|
+
toolCall,
|
|
1885
|
+
result: await resolveProviderToolResult(
|
|
1513
1886
|
toolCall,
|
|
1514
1887
|
providerExecutedToolResults,
|
|
1515
1888
|
effectiveTools,
|
|
1516
1889
|
download
|
|
1517
1890
|
)
|
|
1518
|
-
)
|
|
1891
|
+
}))
|
|
1519
1892
|
);
|
|
1520
1893
|
await Promise.all(
|
|
1521
|
-
|
|
1522
|
-
(toolCall,
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1894
|
+
providerResultEntries.flatMap(
|
|
1895
|
+
({ toolCall, result: result2 }) => result2 == null ? [] : [
|
|
1896
|
+
recordProviderExecutedToolTelemetry(
|
|
1897
|
+
toolCall,
|
|
1898
|
+
result2,
|
|
1899
|
+
iterMessages,
|
|
1900
|
+
currentStepNumber
|
|
1901
|
+
)
|
|
1902
|
+
]
|
|
1528
1903
|
)
|
|
1529
1904
|
);
|
|
1905
|
+
const providerResults = providerResultEntries.flatMap(
|
|
1906
|
+
({ result: result2 }) => result2 == null ? [] : [result2]
|
|
1907
|
+
);
|
|
1530
1908
|
const continuationInvalidResults = invalidToolCalls.map(
|
|
1531
1909
|
createInvalidToolResult
|
|
1532
1910
|
);
|
|
@@ -1554,6 +1932,7 @@ var WorkflowAgent = class {
|
|
|
1554
1932
|
output: r.rawOutput
|
|
1555
1933
|
};
|
|
1556
1934
|
});
|
|
1935
|
+
addToolResultsToStep(step, executedResults);
|
|
1557
1936
|
if (resolvedResults.length > 0) {
|
|
1558
1937
|
iterMessages.push({
|
|
1559
1938
|
role: "tool",
|
|
@@ -1661,26 +2040,32 @@ var WorkflowAgent = class {
|
|
|
1661
2040
|
)
|
|
1662
2041
|
)
|
|
1663
2042
|
);
|
|
1664
|
-
const
|
|
1665
|
-
providerToolCalls.map(
|
|
1666
|
-
|
|
2043
|
+
const providerToolResultEntries = await Promise.all(
|
|
2044
|
+
providerToolCalls.map(async (toolCall) => ({
|
|
2045
|
+
toolCall,
|
|
2046
|
+
result: await resolveProviderToolResult(
|
|
1667
2047
|
toolCall,
|
|
1668
2048
|
providerExecutedToolResults,
|
|
1669
2049
|
effectiveTools,
|
|
1670
2050
|
download
|
|
1671
2051
|
)
|
|
1672
|
-
)
|
|
2052
|
+
}))
|
|
1673
2053
|
);
|
|
1674
2054
|
await Promise.all(
|
|
1675
|
-
|
|
1676
|
-
(toolCall,
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
2055
|
+
providerToolResultEntries.flatMap(
|
|
2056
|
+
({ toolCall, result: result2 }) => result2 == null ? [] : [
|
|
2057
|
+
recordProviderExecutedToolTelemetry(
|
|
2058
|
+
toolCall,
|
|
2059
|
+
result2,
|
|
2060
|
+
iterMessages,
|
|
2061
|
+
currentStepNumber
|
|
2062
|
+
)
|
|
2063
|
+
]
|
|
1682
2064
|
)
|
|
1683
2065
|
);
|
|
2066
|
+
const providerToolResults = providerToolResultEntries.flatMap(
|
|
2067
|
+
({ result: result2 }) => result2 == null ? [] : [result2]
|
|
2068
|
+
);
|
|
1684
2069
|
const continuationInvalidToolResults = invalidToolCalls.map(
|
|
1685
2070
|
createInvalidToolResult
|
|
1686
2071
|
);
|
|
@@ -1742,6 +2127,7 @@ var WorkflowAgent = class {
|
|
|
1742
2127
|
output: r.rawOutput
|
|
1743
2128
|
};
|
|
1744
2129
|
});
|
|
2130
|
+
addToolResultsToStep(step, executedToolResults);
|
|
1745
2131
|
result = await iterator.next(continuationToolResults);
|
|
1746
2132
|
} else {
|
|
1747
2133
|
lastStepToolCalls = [];
|
|
@@ -2036,22 +2422,6 @@ async function writeApprovalToolResults(writable, approvedResults, deniedResults
|
|
|
2036
2422
|
writer.releaseLock();
|
|
2037
2423
|
}
|
|
2038
2424
|
}
|
|
2039
|
-
async function resolveToolContext({
|
|
2040
|
-
toolName,
|
|
2041
|
-
tool: tool2,
|
|
2042
|
-
toolsContext
|
|
2043
|
-
}) {
|
|
2044
|
-
const contextSchema = tool2.contextSchema;
|
|
2045
|
-
const entry = toolsContext == null ? void 0 : toolsContext[toolName];
|
|
2046
|
-
if (contextSchema == null) {
|
|
2047
|
-
return entry;
|
|
2048
|
-
}
|
|
2049
|
-
return await validateTypes({
|
|
2050
|
-
value: entry,
|
|
2051
|
-
schema: contextSchema,
|
|
2052
|
-
context: { field: "tool context", entityName: toolName }
|
|
2053
|
-
});
|
|
2054
|
-
}
|
|
2055
2425
|
function aggregateUsage(steps) {
|
|
2056
2426
|
var _a, _b, _c, _d;
|
|
2057
2427
|
let inputTokens = 0;
|
|
@@ -2069,6 +2439,10 @@ function aggregateUsage(steps) {
|
|
|
2069
2439
|
async function resolveProviderToolResult(toolCall, providerExecutedToolResults, tools, download) {
|
|
2070
2440
|
const streamResult = providerExecutedToolResults == null ? void 0 : providerExecutedToolResults.get(toolCall.toolCallId);
|
|
2071
2441
|
if (!streamResult) {
|
|
2442
|
+
const tool2 = tools == null ? void 0 : tools[toolCall.toolName];
|
|
2443
|
+
if ((tool2 == null ? void 0 : tool2.type) === "provider" && tool2.isProviderExecuted && tool2.supportsDeferredResults) {
|
|
2444
|
+
return void 0;
|
|
2445
|
+
}
|
|
2072
2446
|
console.warn(
|
|
2073
2447
|
`[WorkflowAgent] Provider-executed tool "${toolCall.toolName}" (${toolCall.toolCallId}) did not receive a result from the stream. This may indicate a provider issue.`
|
|
2074
2448
|
);
|