@ai-sdk/workflow 2.0.17 → 2.0.19
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 +24 -0
- package/dist/index.d.ts +27 -3
- package/dist/index.js +105 -156
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/stream-text-iterator.ts +3 -2
- package/src/workflow-agent.ts +114 -137
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/workflow",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "WorkflowAgent for building AI agents with AI SDK",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ai-sdk/provider": "4.0.
|
|
35
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
36
|
-
"ai": "7.0.
|
|
34
|
+
"@ai-sdk/provider": "4.0.10",
|
|
35
|
+
"@ai-sdk/provider-utils": "5.0.35",
|
|
36
|
+
"ai": "7.0.89",
|
|
37
37
|
"ajv": "^8.20.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
import type { Context } from '@ai-sdk/provider-utils';
|
|
8
8
|
import {
|
|
9
9
|
experimental_filterActiveTools as filterActiveTools,
|
|
10
|
+
type ActiveTools,
|
|
10
11
|
type Experimental_SandboxSession as SandboxSession,
|
|
11
12
|
type Instructions,
|
|
12
13
|
type LanguageModel,
|
|
@@ -164,7 +165,7 @@ export async function* streamTextIterator({
|
|
|
164
165
|
let currentRuntimeContext: Context = runtimeContext ?? {};
|
|
165
166
|
let currentToolsContext: Record<string, Context | undefined> =
|
|
166
167
|
toolsContext ?? {};
|
|
167
|
-
let currentActiveTools:
|
|
168
|
+
let currentActiveTools: ActiveTools<ToolSet>;
|
|
168
169
|
|
|
169
170
|
const steps: StepResult<any, any>[] = [];
|
|
170
171
|
let done = false;
|
|
@@ -297,7 +298,7 @@ export async function* streamTextIterator({
|
|
|
297
298
|
try {
|
|
298
299
|
// Filter tools if activeTools is specified
|
|
299
300
|
const effectiveTools =
|
|
300
|
-
currentActiveTools
|
|
301
|
+
currentActiveTools !== undefined
|
|
301
302
|
? (filterActiveTools({
|
|
302
303
|
tools,
|
|
303
304
|
activeTools: currentActiveTools,
|
package/src/workflow-agent.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
type ToolCallRepairFunction,
|
|
29
29
|
type ToolChoice,
|
|
30
30
|
type ToolSet,
|
|
31
|
+
type InferUITools,
|
|
31
32
|
type UIMessage,
|
|
32
33
|
type LanguageModel,
|
|
33
34
|
type Prompt,
|
|
@@ -40,6 +41,7 @@ import {
|
|
|
40
41
|
createRestrictedTelemetryDispatcher,
|
|
41
42
|
collectToolApprovals,
|
|
42
43
|
convertToLanguageModelPrompt,
|
|
44
|
+
mergeAbortSignals,
|
|
43
45
|
mergeCallbacks,
|
|
44
46
|
signToolApproval,
|
|
45
47
|
standardizePrompt,
|
|
@@ -84,9 +86,13 @@ export type InferWorkflowAgentTools<WORKFLOW_AGENT> =
|
|
|
84
86
|
* Infer the UI message type of a workflow agent.
|
|
85
87
|
*/
|
|
86
88
|
export type InferWorkflowAgentUIMessage<
|
|
87
|
-
|
|
89
|
+
WORKFLOW_AGENT,
|
|
88
90
|
MESSAGE_METADATA = unknown,
|
|
89
|
-
> = UIMessage<
|
|
91
|
+
> = UIMessage<
|
|
92
|
+
MESSAGE_METADATA,
|
|
93
|
+
never,
|
|
94
|
+
InferUITools<InferWorkflowAgentTools<WORKFLOW_AGENT>>
|
|
95
|
+
>;
|
|
90
96
|
|
|
91
97
|
/**
|
|
92
98
|
* Re-export the Output helper for structured output specifications.
|
|
@@ -349,7 +355,7 @@ export interface PrepareStepResult<
|
|
|
349
355
|
* Override the active tools for this step.
|
|
350
356
|
* Limits the tools that are available for the model to call.
|
|
351
357
|
*/
|
|
352
|
-
activeTools?:
|
|
358
|
+
activeTools?: ActiveTools<NoInfer<TTools>>;
|
|
353
359
|
|
|
354
360
|
/**
|
|
355
361
|
* Updated runtime context for the current and subsequent steps.
|
|
@@ -605,6 +611,13 @@ export type WorkflowAgentOptions<
|
|
|
605
611
|
/**
|
|
606
612
|
* Callback called when the agent starts streaming, before any LLM calls.
|
|
607
613
|
*/
|
|
614
|
+
onStart?: WorkflowAgentOnStartCallback<TTools, TRuntimeContext>;
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Callback called when the agent starts streaming, before any LLM calls.
|
|
618
|
+
*
|
|
619
|
+
* @deprecated Use `onStart` instead.
|
|
620
|
+
*/
|
|
608
621
|
experimental_onStart?: WorkflowAgentOnStartCallback<
|
|
609
622
|
TTools,
|
|
610
623
|
TRuntimeContext
|
|
@@ -613,6 +626,13 @@ export type WorkflowAgentOptions<
|
|
|
613
626
|
/**
|
|
614
627
|
* Callback called before each step (LLM call) begins.
|
|
615
628
|
*/
|
|
629
|
+
onStepStart?: WorkflowAgentOnStepStartCallback<TTools, TRuntimeContext>;
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Callback called before each step (LLM call) begins.
|
|
633
|
+
*
|
|
634
|
+
* @deprecated Use `onStepStart` instead.
|
|
635
|
+
*/
|
|
616
636
|
experimental_onStepStart?: WorkflowAgentOnStepStartCallback<
|
|
617
637
|
TTools,
|
|
618
638
|
TRuntimeContext
|
|
@@ -1080,6 +1100,13 @@ export type WorkflowAgentStreamOptions<
|
|
|
1080
1100
|
/**
|
|
1081
1101
|
* Callback called when the agent starts streaming, before any LLM calls.
|
|
1082
1102
|
*/
|
|
1103
|
+
onStart?: WorkflowAgentOnStartCallback<TTools, TRuntimeContext>;
|
|
1104
|
+
|
|
1105
|
+
/**
|
|
1106
|
+
* Callback called when the agent starts streaming, before any LLM calls.
|
|
1107
|
+
*
|
|
1108
|
+
* @deprecated Use `onStart` instead.
|
|
1109
|
+
*/
|
|
1083
1110
|
experimental_onStart?: WorkflowAgentOnStartCallback<
|
|
1084
1111
|
TTools,
|
|
1085
1112
|
TRuntimeContext
|
|
@@ -1088,6 +1115,13 @@ export type WorkflowAgentStreamOptions<
|
|
|
1088
1115
|
/**
|
|
1089
1116
|
* Callback called before each step (LLM call) begins.
|
|
1090
1117
|
*/
|
|
1118
|
+
onStepStart?: WorkflowAgentOnStepStartCallback<TTools, TRuntimeContext>;
|
|
1119
|
+
|
|
1120
|
+
/**
|
|
1121
|
+
* Callback called before each step (LLM call) begins.
|
|
1122
|
+
*
|
|
1123
|
+
* @deprecated Use `onStepStart` instead.
|
|
1124
|
+
*/
|
|
1091
1125
|
experimental_onStepStart?: WorkflowAgentOnStepStartCallback<
|
|
1092
1126
|
TTools,
|
|
1093
1127
|
TRuntimeContext
|
|
@@ -1350,8 +1384,9 @@ export class WorkflowAgent<
|
|
|
1350
1384
|
this.constructorOnStepEnd = options.onStepEnd ?? options.onStepFinish;
|
|
1351
1385
|
const { onFinish, onEnd = onFinish } = options;
|
|
1352
1386
|
this.constructorOnEnd = onEnd;
|
|
1353
|
-
this.constructorOnStart = options.experimental_onStart;
|
|
1354
|
-
this.constructorOnStepStart =
|
|
1387
|
+
this.constructorOnStart = options.onStart ?? options.experimental_onStart;
|
|
1388
|
+
this.constructorOnStepStart =
|
|
1389
|
+
options.onStepStart ?? options.experimental_onStepStart;
|
|
1355
1390
|
this.constructorOnToolExecutionStart = options.onToolExecutionStart;
|
|
1356
1391
|
this.constructorOnToolExecutionEnd = options.onToolExecutionEnd;
|
|
1357
1392
|
this.prepareCall = options.prepareCall;
|
|
@@ -1518,6 +1553,20 @@ export class WorkflowAgent<
|
|
|
1518
1553
|
} as Prompt);
|
|
1519
1554
|
const download = effectiveDownloadFromPrepare;
|
|
1520
1555
|
const sandbox = options.experimental_sandbox ?? this.experimentalSandbox;
|
|
1556
|
+
const effectiveAbortSignal = mergeAbortSignals(
|
|
1557
|
+
options.abortSignal ?? effectiveGenerationSettings.abortSignal,
|
|
1558
|
+
options.timeout,
|
|
1559
|
+
);
|
|
1560
|
+
const timeoutAt =
|
|
1561
|
+
options.timeout == null ? undefined : Date.now() + options.timeout;
|
|
1562
|
+
const mergedOnToolExecutionStart = mergeCallbacks(
|
|
1563
|
+
this.constructorOnToolExecutionStart,
|
|
1564
|
+
options.onToolExecutionStart,
|
|
1565
|
+
);
|
|
1566
|
+
const mergedOnToolExecutionEnd = mergeCallbacks(
|
|
1567
|
+
this.constructorOnToolExecutionEnd,
|
|
1568
|
+
options.onToolExecutionEnd,
|
|
1569
|
+
);
|
|
1521
1570
|
|
|
1522
1571
|
// Process tool approval responses before starting the agent loop.
|
|
1523
1572
|
// This mirrors how stream-text.ts handles tool-approval-response parts:
|
|
@@ -1663,110 +1712,25 @@ export class WorkflowAgent<
|
|
|
1663
1712
|
continue;
|
|
1664
1713
|
}
|
|
1665
1714
|
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
const resolvedContext = await resolveToolContext({
|
|
1669
|
-
toolName: approval.toolName,
|
|
1670
|
-
tool,
|
|
1671
|
-
toolsContext: effectiveToolsContext,
|
|
1672
|
-
});
|
|
1673
|
-
const toolCallEvent: ToolCall = {
|
|
1674
|
-
type: 'tool-call',
|
|
1675
|
-
toolCallId: approval.toolCallId,
|
|
1676
|
-
toolName: approval.toolName,
|
|
1677
|
-
input: approval.input,
|
|
1678
|
-
};
|
|
1679
|
-
const messages = prompt.messages as unknown as ModelMessage[];
|
|
1680
|
-
await telemetryDispatcher.onToolExecutionStart?.({
|
|
1681
|
-
toolCall: toolCallEvent,
|
|
1682
|
-
stepNumber: 0,
|
|
1683
|
-
messages,
|
|
1684
|
-
toolContext: resolvedContext,
|
|
1685
|
-
});
|
|
1686
|
-
const startTime = Date.now();
|
|
1687
|
-
const executeApprovedTool = () =>
|
|
1688
|
-
execute(approval.input, {
|
|
1689
|
-
toolCallId: approval.toolCallId,
|
|
1690
|
-
messages: [],
|
|
1691
|
-
context: resolvedContext,
|
|
1692
|
-
experimental_sandbox: sandbox,
|
|
1693
|
-
});
|
|
1694
|
-
const toolResult =
|
|
1695
|
-
telemetryDispatcher.executeTool != null
|
|
1696
|
-
? await telemetryDispatcher.executeTool({
|
|
1697
|
-
callId: 'workflow-agent',
|
|
1698
|
-
toolCallId: approval.toolCallId,
|
|
1699
|
-
execute: executeApprovedTool,
|
|
1700
|
-
})
|
|
1701
|
-
: await executeApprovedTool();
|
|
1702
|
-
await telemetryDispatcher.onToolExecutionEnd?.({
|
|
1703
|
-
toolCall: toolCallEvent,
|
|
1704
|
-
stepNumber: 0,
|
|
1705
|
-
durationMs: Date.now() - startTime,
|
|
1706
|
-
messages,
|
|
1707
|
-
toolContext: resolvedContext,
|
|
1708
|
-
success: true,
|
|
1709
|
-
output: toolResult,
|
|
1710
|
-
});
|
|
1711
|
-
toolResultContent.push({
|
|
1712
|
-
type: 'tool-result' as const,
|
|
1713
|
-
toolCallId: approval.toolCallId,
|
|
1714
|
-
toolName: approval.toolName,
|
|
1715
|
-
output: await createLanguageModelToolResultOutput({
|
|
1716
|
-
toolCallId: approval.toolCallId,
|
|
1717
|
-
toolName: approval.toolName,
|
|
1718
|
-
input: approval.input,
|
|
1719
|
-
output: toolResult,
|
|
1720
|
-
tool,
|
|
1721
|
-
errorMode: 'none',
|
|
1722
|
-
supportedUrls: {},
|
|
1723
|
-
download,
|
|
1724
|
-
}),
|
|
1725
|
-
});
|
|
1726
|
-
approvedRawResults.push({
|
|
1727
|
-
toolCallId: approval.toolCallId,
|
|
1728
|
-
toolName: approval.toolName,
|
|
1729
|
-
input: approval.input,
|
|
1730
|
-
output: toolResult,
|
|
1731
|
-
});
|
|
1732
|
-
} catch (error) {
|
|
1733
|
-
const errorMessage = getErrorMessage(error);
|
|
1734
|
-
await telemetryDispatcher.onToolExecutionEnd?.({
|
|
1735
|
-
toolCall: {
|
|
1736
|
-
type: 'tool-call',
|
|
1737
|
-
toolCallId: approval.toolCallId,
|
|
1738
|
-
toolName: approval.toolName,
|
|
1739
|
-
input: approval.input,
|
|
1740
|
-
},
|
|
1741
|
-
stepNumber: 0,
|
|
1742
|
-
durationMs: 0,
|
|
1743
|
-
messages: prompt.messages as unknown as ModelMessage[],
|
|
1744
|
-
toolContext: undefined,
|
|
1745
|
-
success: false,
|
|
1746
|
-
error,
|
|
1747
|
-
});
|
|
1748
|
-
toolResultContent.push({
|
|
1749
|
-
type: 'tool-result' as const,
|
|
1750
|
-
toolCallId: approval.toolCallId,
|
|
1751
|
-
toolName: approval.toolName,
|
|
1752
|
-
output: await createLanguageModelToolResultOutput({
|
|
1753
|
-
toolCallId: approval.toolCallId,
|
|
1754
|
-
toolName: approval.toolName,
|
|
1755
|
-
input: approval.input,
|
|
1756
|
-
output: errorMessage,
|
|
1757
|
-
tool,
|
|
1758
|
-
errorMode: 'text',
|
|
1759
|
-
supportedUrls: {},
|
|
1760
|
-
download,
|
|
1761
|
-
}),
|
|
1762
|
-
});
|
|
1763
|
-
approvedRawResults.push({
|
|
1715
|
+
const result = await executeToolWithCallbacks(
|
|
1716
|
+
{
|
|
1764
1717
|
toolCallId: approval.toolCallId,
|
|
1765
1718
|
toolName: approval.toolName,
|
|
1766
1719
|
input: approval.input,
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1720
|
+
},
|
|
1721
|
+
this.tools as ToolSet,
|
|
1722
|
+
prompt.messages as unknown as LanguageModelV4Prompt,
|
|
1723
|
+
effectiveToolsContext,
|
|
1724
|
+
0,
|
|
1725
|
+
sandbox,
|
|
1726
|
+
);
|
|
1727
|
+
toolResultContent.push(result.modelResult);
|
|
1728
|
+
approvedRawResults.push({
|
|
1729
|
+
toolCallId: approval.toolCallId,
|
|
1730
|
+
toolName: approval.toolName,
|
|
1731
|
+
input: approval.input,
|
|
1732
|
+
output: result.rawOutput,
|
|
1733
|
+
});
|
|
1770
1734
|
}
|
|
1771
1735
|
}
|
|
1772
1736
|
|
|
@@ -1854,11 +1818,6 @@ export class WorkflowAgent<
|
|
|
1854
1818
|
download,
|
|
1855
1819
|
});
|
|
1856
1820
|
|
|
1857
|
-
const effectiveAbortSignal =
|
|
1858
|
-
options.abortSignal ?? effectiveGenerationSettings.abortSignal;
|
|
1859
|
-
const timeoutAt =
|
|
1860
|
-
options.timeout == null ? undefined : Date.now() + options.timeout;
|
|
1861
|
-
|
|
1862
1821
|
// Merge generation settings: constructor defaults < prepareCall < stream options
|
|
1863
1822
|
const mergedGenerationSettings: GenerationSettings = {
|
|
1864
1823
|
...effectiveGenerationSettings,
|
|
@@ -1918,30 +1877,21 @@ export class WorkflowAgent<
|
|
|
1918
1877
|
this.constructorOnStart as
|
|
1919
1878
|
| WorkflowAgentOnStartCallback<TTools, TRuntimeContext>
|
|
1920
1879
|
| undefined,
|
|
1921
|
-
options.experimental_onStart,
|
|
1880
|
+
options.onStart ?? options.experimental_onStart,
|
|
1922
1881
|
);
|
|
1923
1882
|
const mergedOnStepStart = mergeCallbacks(
|
|
1924
1883
|
this.constructorOnStepStart as
|
|
1925
1884
|
| WorkflowAgentOnStepStartCallback<TTools, TRuntimeContext>
|
|
1926
1885
|
| undefined,
|
|
1927
|
-
options.experimental_onStepStart,
|
|
1886
|
+
options.onStepStart ?? options.experimental_onStepStart,
|
|
1928
1887
|
);
|
|
1929
|
-
const mergedOnToolExecutionStart = mergeCallbacks(
|
|
1930
|
-
this.constructorOnToolExecutionStart,
|
|
1931
|
-
options.onToolExecutionStart,
|
|
1932
|
-
);
|
|
1933
|
-
const mergedOnToolExecutionEnd = mergeCallbacks(
|
|
1934
|
-
this.constructorOnToolExecutionEnd,
|
|
1935
|
-
options.onToolExecutionEnd,
|
|
1936
|
-
);
|
|
1937
|
-
|
|
1938
1888
|
// Determine effective tool choice
|
|
1939
1889
|
const effectiveToolChoice = effectiveToolChoiceFromPrepare;
|
|
1940
1890
|
|
|
1941
1891
|
// Filter tools if activeTools is specified (stream-level overrides constructor default)
|
|
1942
1892
|
const effectiveActiveTools = effectiveActiveToolsFromPrepare;
|
|
1943
1893
|
const effectiveTools =
|
|
1944
|
-
effectiveActiveTools
|
|
1894
|
+
effectiveActiveTools !== undefined
|
|
1945
1895
|
? (filterActiveTools({
|
|
1946
1896
|
tools: this.tools,
|
|
1947
1897
|
activeTools: effectiveActiveTools,
|
|
@@ -1998,14 +1948,14 @@ export class WorkflowAgent<
|
|
|
1998
1948
|
});
|
|
1999
1949
|
|
|
2000
1950
|
// Helper to wrap executeTool with onToolExecutionStart/onToolExecutionEnd callbacks
|
|
2001
|
-
|
|
1951
|
+
async function executeToolWithCallbacks(
|
|
2002
1952
|
toolCall: { toolCallId: string; toolName: string; input: unknown },
|
|
2003
1953
|
tools: ToolSet,
|
|
2004
1954
|
messages: LanguageModelV4Prompt,
|
|
2005
1955
|
perToolContexts: Record<string, Context | undefined>,
|
|
2006
1956
|
currentStepNumber: number = 0,
|
|
2007
1957
|
stepSandbox?: SandboxSession,
|
|
2008
|
-
): Promise<WorkflowToolExecutionResult>
|
|
1958
|
+
): Promise<WorkflowToolExecutionResult> {
|
|
2009
1959
|
const toolCallEvent: ToolCall = {
|
|
2010
1960
|
type: 'tool-call',
|
|
2011
1961
|
toolCallId: toolCall.toolCallId,
|
|
@@ -2051,6 +2001,7 @@ export class WorkflowAgent<
|
|
|
2051
2001
|
tools,
|
|
2052
2002
|
messages,
|
|
2053
2003
|
resolvedContext,
|
|
2004
|
+
effectiveAbortSignal,
|
|
2054
2005
|
download,
|
|
2055
2006
|
stepSandbox,
|
|
2056
2007
|
);
|
|
@@ -2145,7 +2096,7 @@ export class WorkflowAgent<
|
|
|
2145
2096
|
});
|
|
2146
2097
|
}
|
|
2147
2098
|
return result;
|
|
2148
|
-
}
|
|
2099
|
+
}
|
|
2149
2100
|
|
|
2150
2101
|
const recordProviderExecutedToolTelemetry = async (
|
|
2151
2102
|
toolCall: { toolCallId: string; toolName: string; input: unknown },
|
|
@@ -2437,7 +2388,18 @@ export class WorkflowAgent<
|
|
|
2437
2388
|
// so useChat can show the approval UI
|
|
2438
2389
|
if (options.writable) {
|
|
2439
2390
|
if (allToolResults.length > 0) {
|
|
2440
|
-
await writeToolResults(
|
|
2391
|
+
await writeToolResults(
|
|
2392
|
+
options.writable,
|
|
2393
|
+
executedResults.map(r => ({
|
|
2394
|
+
toolCallId: r.modelResult.toolCallId,
|
|
2395
|
+
toolName: r.modelResult.toolName,
|
|
2396
|
+
input: toolCalls.find(
|
|
2397
|
+
tc => tc.toolCallId === r.modelResult.toolCallId,
|
|
2398
|
+
)?.input,
|
|
2399
|
+
output: r.rawOutput,
|
|
2400
|
+
isError: r.isError,
|
|
2401
|
+
})),
|
|
2402
|
+
);
|
|
2441
2403
|
}
|
|
2442
2404
|
|
|
2443
2405
|
const approvalToolCalls = pausedToolCalls.filter((_, i) => {
|
|
@@ -2562,9 +2524,9 @@ export class WorkflowAgent<
|
|
|
2562
2524
|
return [];
|
|
2563
2525
|
});
|
|
2564
2526
|
|
|
2565
|
-
// Write tool results and step boundaries to the stream so the
|
|
2566
|
-
//
|
|
2567
|
-
//
|
|
2527
|
+
// Write tool results and step boundaries to the stream so the UI can
|
|
2528
|
+
// transition tool parts to the appropriate output state and properly
|
|
2529
|
+
// separate multi-step model calls in the message history.
|
|
2568
2530
|
if (options.writable) {
|
|
2569
2531
|
await writeToolResults(
|
|
2570
2532
|
options.writable,
|
|
@@ -2575,6 +2537,7 @@ export class WorkflowAgent<
|
|
|
2575
2537
|
tc => tc.toolCallId === r.modelResult.toolCallId,
|
|
2576
2538
|
)?.input,
|
|
2577
2539
|
output: r.rawOutput,
|
|
2540
|
+
isError: r.isError,
|
|
2578
2541
|
})),
|
|
2579
2542
|
true,
|
|
2580
2543
|
);
|
|
@@ -2937,6 +2900,7 @@ async function writeToolResults(
|
|
|
2937
2900
|
toolName: string;
|
|
2938
2901
|
input: unknown;
|
|
2939
2902
|
output: unknown;
|
|
2903
|
+
isError: boolean;
|
|
2940
2904
|
}>,
|
|
2941
2905
|
writeStepBoundary = false,
|
|
2942
2906
|
) {
|
|
@@ -2944,13 +2908,23 @@ async function writeToolResults(
|
|
|
2944
2908
|
const writer = writable.getWriter();
|
|
2945
2909
|
try {
|
|
2946
2910
|
for (const r of results) {
|
|
2947
|
-
await writer.write(
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2911
|
+
await writer.write(
|
|
2912
|
+
r.isError
|
|
2913
|
+
? {
|
|
2914
|
+
type: 'tool-error',
|
|
2915
|
+
toolCallId: r.toolCallId,
|
|
2916
|
+
toolName: r.toolName,
|
|
2917
|
+
input: r.input,
|
|
2918
|
+
error: r.output,
|
|
2919
|
+
}
|
|
2920
|
+
: {
|
|
2921
|
+
type: 'tool-result',
|
|
2922
|
+
toolCallId: r.toolCallId,
|
|
2923
|
+
toolName: r.toolName,
|
|
2924
|
+
input: r.input,
|
|
2925
|
+
output: r.output,
|
|
2926
|
+
},
|
|
2927
|
+
);
|
|
2954
2928
|
}
|
|
2955
2929
|
if (writeStepBoundary) {
|
|
2956
2930
|
// Emit step boundaries so the UI message history properly separates
|
|
@@ -3128,6 +3102,7 @@ async function executeTool(
|
|
|
3128
3102
|
tools: ToolSet,
|
|
3129
3103
|
messages: LanguageModelV4Prompt,
|
|
3130
3104
|
context?: unknown,
|
|
3105
|
+
abortSignal?: AbortSignal,
|
|
3131
3106
|
download?: DownloadFunction,
|
|
3132
3107
|
sandbox?: SandboxSession,
|
|
3133
3108
|
): Promise<WorkflowToolExecutionResult> {
|
|
@@ -3154,6 +3129,8 @@ async function executeTool(
|
|
|
3154
3129
|
toolCallId: toolCall.toolCallId,
|
|
3155
3130
|
// Pass the conversation messages to the tool so it has context about the conversation
|
|
3156
3131
|
messages,
|
|
3132
|
+
// Pass the effective agent signal so in-flight tool work can cooperatively cancel
|
|
3133
|
+
abortSignal,
|
|
3157
3134
|
// Pass per-tool context to the tool (resolved from `toolsContext`)
|
|
3158
3135
|
context,
|
|
3159
3136
|
experimental_sandbox: sandbox,
|