agents 0.11.8 → 0.12.0
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/README.md +37 -1
- package/dist/{index-DSwOzhhd.d.ts → agent-tool-types-tBGRsPm0.d.ts} +584 -99
- package/dist/agent-tool-types.d.ts +34 -0
- package/dist/agent-tool-types.js +1 -0
- package/dist/agent-tools-BAdX1vdI.js +425 -0
- package/dist/agent-tools-BAdX1vdI.js.map +1 -0
- package/dist/agent-tools-CIO14miM.d.ts +14 -0
- package/dist/agent-tools.d.ts +68 -0
- package/dist/agent-tools.js +51 -0
- package/dist/agent-tools.js.map +1 -0
- package/dist/browser/ai.d.ts +1 -1
- package/dist/browser/ai.js +2 -2
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/tanstack-ai.d.ts +1 -1
- package/dist/browser/tanstack-ai.js +1 -1
- package/dist/chat/index.d.ts +27 -1
- package/dist/chat/index.js +3 -263
- package/dist/chat/index.js.map +1 -1
- package/dist/client.d.ts +2 -2
- package/dist/{compaction-helpers-C_cN3z55.js → compaction-helpers-CSaqCmdE.js} +1 -1
- package/dist/{compaction-helpers-C_cN3z55.js.map → compaction-helpers-CSaqCmdE.js.map} +1 -1
- package/dist/{compaction-helpers-YzCLvunJ.d.ts → compaction-helpers-D92Ipstp.d.ts} +1 -1
- package/dist/experimental/memory/session/index.d.ts +1 -1
- package/dist/experimental/memory/session/index.js +1 -1
- package/dist/experimental/memory/utils/index.d.ts +1 -1
- package/dist/experimental/memory/utils/index.js +1 -1
- package/dist/index.d.ts +74 -42
- package/dist/index.js +1393 -296
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/react.d.ts +16 -2
- package/dist/react.js +42 -1
- package/dist/react.js.map +1 -1
- package/dist/{serializable-Bg8ARWlN.d.ts → serializable-Brg7fRds.d.ts} +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{shared-mfBbxjS1.js → shared-C6l4ZKRN.js} +1 -1
- package/dist/{shared-mfBbxjS1.js.map → shared-C6l4ZKRN.js.map} +1 -1
- package/dist/{shared-BUHZFGTk.d.ts → shared-Ch9slKdI.d.ts} +1 -1
- package/dist/sub-routing.d.ts +6 -6
- package/dist/workflows.d.ts +1 -1
- package/package.json +9 -4
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
a as AgentToolEventState,
|
|
3
|
+
c as AgentToolRunInspection,
|
|
4
|
+
d as AgentToolStoredChunk,
|
|
5
|
+
f as AgentToolTerminalStatus,
|
|
6
|
+
h as RunAgentToolResult,
|
|
7
|
+
i as AgentToolEventMessage,
|
|
8
|
+
l as AgentToolRunState,
|
|
9
|
+
m as RunAgentToolOptions,
|
|
10
|
+
n as AgentToolDisplayMetadata,
|
|
11
|
+
o as AgentToolLifecycleResult,
|
|
12
|
+
p as ChatCapableAgentClass,
|
|
13
|
+
r as AgentToolEvent,
|
|
14
|
+
s as AgentToolRunInfo,
|
|
15
|
+
t as AgentToolChildAdapter,
|
|
16
|
+
u as AgentToolRunStatus
|
|
17
|
+
} from "./agent-tool-types-tBGRsPm0.js";
|
|
18
|
+
export {
|
|
19
|
+
AgentToolChildAdapter,
|
|
20
|
+
AgentToolDisplayMetadata,
|
|
21
|
+
AgentToolEvent,
|
|
22
|
+
AgentToolEventMessage,
|
|
23
|
+
AgentToolEventState,
|
|
24
|
+
AgentToolLifecycleResult,
|
|
25
|
+
AgentToolRunInfo,
|
|
26
|
+
AgentToolRunInspection,
|
|
27
|
+
AgentToolRunState,
|
|
28
|
+
AgentToolRunStatus,
|
|
29
|
+
AgentToolStoredChunk,
|
|
30
|
+
AgentToolTerminalStatus,
|
|
31
|
+
ChatCapableAgentClass,
|
|
32
|
+
RunAgentToolOptions,
|
|
33
|
+
RunAgentToolResult
|
|
34
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
//#region src/chat/message-builder.ts
|
|
2
|
+
/**
|
|
3
|
+
* Applies a stream chunk to a mutable parts array, building up the message
|
|
4
|
+
* incrementally. Returns true if the chunk was handled, false if it was
|
|
5
|
+
* an unrecognized type (caller may handle it with additional logic).
|
|
6
|
+
*
|
|
7
|
+
* Handles all common chunk types that both server and client need:
|
|
8
|
+
* - text-start / text-delta / text-end
|
|
9
|
+
* - reasoning-start / reasoning-delta / reasoning-end
|
|
10
|
+
* - file
|
|
11
|
+
* - source-url / source-document
|
|
12
|
+
* - tool-input-start / tool-input-delta / tool-input-available / tool-input-error
|
|
13
|
+
* - tool-output-available / tool-output-error
|
|
14
|
+
* - step-start (aliased from start-step)
|
|
15
|
+
* - data-* (developer-defined typed JSON blobs)
|
|
16
|
+
*
|
|
17
|
+
* @param parts - The mutable parts array to update
|
|
18
|
+
* @param chunk - The parsed stream chunk data
|
|
19
|
+
* @returns true if handled, false if the chunk type is not recognized
|
|
20
|
+
*/
|
|
21
|
+
function applyChunkToParts(parts, chunk) {
|
|
22
|
+
switch (chunk.type) {
|
|
23
|
+
case "text-start":
|
|
24
|
+
parts.push({
|
|
25
|
+
type: "text",
|
|
26
|
+
text: "",
|
|
27
|
+
state: "streaming"
|
|
28
|
+
});
|
|
29
|
+
return true;
|
|
30
|
+
case "text-delta": {
|
|
31
|
+
const lastTextPart = findLastPartByType(parts, "text");
|
|
32
|
+
if (lastTextPart && lastTextPart.type === "text") lastTextPart.text += chunk.delta ?? "";
|
|
33
|
+
else parts.push({
|
|
34
|
+
type: "text",
|
|
35
|
+
text: chunk.delta ?? "",
|
|
36
|
+
state: "streaming"
|
|
37
|
+
});
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
case "text-end": {
|
|
41
|
+
const lastTextPart = findLastPartByType(parts, "text");
|
|
42
|
+
if (lastTextPart && "state" in lastTextPart) lastTextPart.state = "done";
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
case "reasoning-start":
|
|
46
|
+
parts.push({
|
|
47
|
+
type: "reasoning",
|
|
48
|
+
text: "",
|
|
49
|
+
state: "streaming"
|
|
50
|
+
});
|
|
51
|
+
return true;
|
|
52
|
+
case "reasoning-delta": {
|
|
53
|
+
const lastReasoningPart = findLastPartByType(parts, "reasoning");
|
|
54
|
+
if (lastReasoningPart && lastReasoningPart.type === "reasoning") {
|
|
55
|
+
lastReasoningPart.text += chunk.delta ?? "";
|
|
56
|
+
mergeProviderMetadata(lastReasoningPart, chunk.providerMetadata);
|
|
57
|
+
} else parts.push({
|
|
58
|
+
type: "reasoning",
|
|
59
|
+
text: chunk.delta ?? "",
|
|
60
|
+
state: "streaming",
|
|
61
|
+
...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
|
|
62
|
+
});
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
case "reasoning-end": {
|
|
66
|
+
const lastReasoningPart = findLastPartByType(parts, "reasoning");
|
|
67
|
+
if (lastReasoningPart && "state" in lastReasoningPart) {
|
|
68
|
+
lastReasoningPart.state = "done";
|
|
69
|
+
mergeProviderMetadata(lastReasoningPart, chunk.providerMetadata);
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
case "file":
|
|
74
|
+
parts.push({
|
|
75
|
+
type: "file",
|
|
76
|
+
mediaType: chunk.mediaType,
|
|
77
|
+
url: chunk.url
|
|
78
|
+
});
|
|
79
|
+
return true;
|
|
80
|
+
case "source-url":
|
|
81
|
+
parts.push({
|
|
82
|
+
type: "source-url",
|
|
83
|
+
sourceId: chunk.sourceId,
|
|
84
|
+
url: chunk.url,
|
|
85
|
+
title: chunk.title,
|
|
86
|
+
providerMetadata: chunk.providerMetadata
|
|
87
|
+
});
|
|
88
|
+
return true;
|
|
89
|
+
case "source-document":
|
|
90
|
+
parts.push({
|
|
91
|
+
type: "source-document",
|
|
92
|
+
sourceId: chunk.sourceId,
|
|
93
|
+
mediaType: chunk.mediaType,
|
|
94
|
+
title: chunk.title,
|
|
95
|
+
filename: chunk.filename,
|
|
96
|
+
providerMetadata: chunk.providerMetadata
|
|
97
|
+
});
|
|
98
|
+
return true;
|
|
99
|
+
case "tool-input-start":
|
|
100
|
+
if (findToolPartByCallId(parts, chunk.toolCallId)) return true;
|
|
101
|
+
parts.push({
|
|
102
|
+
type: `tool-${chunk.toolName}`,
|
|
103
|
+
toolCallId: chunk.toolCallId,
|
|
104
|
+
toolName: chunk.toolName,
|
|
105
|
+
state: "input-streaming",
|
|
106
|
+
input: void 0,
|
|
107
|
+
...chunk.providerExecuted != null ? { providerExecuted: chunk.providerExecuted } : {},
|
|
108
|
+
...chunk.providerMetadata != null ? { callProviderMetadata: chunk.providerMetadata } : {},
|
|
109
|
+
...chunk.title != null ? { title: chunk.title } : {}
|
|
110
|
+
});
|
|
111
|
+
return true;
|
|
112
|
+
case "tool-input-delta": {
|
|
113
|
+
const toolPart = findToolPartByCallId(parts, chunk.toolCallId);
|
|
114
|
+
if (toolPart && toolPart.state === "input-streaming") toolPart.input = chunk.input;
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
case "tool-input-available": {
|
|
118
|
+
const existing = findToolPartByCallId(parts, chunk.toolCallId);
|
|
119
|
+
if (existing) {
|
|
120
|
+
const p = existing;
|
|
121
|
+
if (p.state === "input-streaming") {
|
|
122
|
+
p.state = "input-available";
|
|
123
|
+
p.input = chunk.input;
|
|
124
|
+
if (chunk.providerExecuted != null) p.providerExecuted = chunk.providerExecuted;
|
|
125
|
+
if (chunk.providerMetadata != null) p.callProviderMetadata = chunk.providerMetadata;
|
|
126
|
+
if (chunk.title != null) p.title = chunk.title;
|
|
127
|
+
}
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
parts.push({
|
|
131
|
+
type: `tool-${chunk.toolName}`,
|
|
132
|
+
toolCallId: chunk.toolCallId,
|
|
133
|
+
toolName: chunk.toolName,
|
|
134
|
+
state: "input-available",
|
|
135
|
+
input: chunk.input,
|
|
136
|
+
...chunk.providerExecuted != null ? { providerExecuted: chunk.providerExecuted } : {},
|
|
137
|
+
...chunk.providerMetadata != null ? { callProviderMetadata: chunk.providerMetadata } : {},
|
|
138
|
+
...chunk.title != null ? { title: chunk.title } : {}
|
|
139
|
+
});
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
case "tool-input-error": {
|
|
143
|
+
const existing = findToolPartByCallId(parts, chunk.toolCallId);
|
|
144
|
+
if (existing) {
|
|
145
|
+
const p = existing;
|
|
146
|
+
if (p.state === "output-available" || p.state === "output-error" || p.state === "output-denied") return true;
|
|
147
|
+
p.state = "output-error";
|
|
148
|
+
p.errorText = chunk.errorText;
|
|
149
|
+
p.input = chunk.input;
|
|
150
|
+
if (chunk.providerExecuted != null) p.providerExecuted = chunk.providerExecuted;
|
|
151
|
+
if (chunk.providerMetadata != null) p.callProviderMetadata = chunk.providerMetadata;
|
|
152
|
+
} else parts.push({
|
|
153
|
+
type: `tool-${chunk.toolName}`,
|
|
154
|
+
toolCallId: chunk.toolCallId,
|
|
155
|
+
toolName: chunk.toolName,
|
|
156
|
+
state: "output-error",
|
|
157
|
+
input: chunk.input,
|
|
158
|
+
errorText: chunk.errorText,
|
|
159
|
+
...chunk.providerExecuted != null ? { providerExecuted: chunk.providerExecuted } : {},
|
|
160
|
+
...chunk.providerMetadata != null ? { callProviderMetadata: chunk.providerMetadata } : {}
|
|
161
|
+
});
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
case "tool-approval-request": {
|
|
165
|
+
const toolPart = findToolPartByCallId(parts, chunk.toolCallId);
|
|
166
|
+
if (toolPart) {
|
|
167
|
+
const p = toolPart;
|
|
168
|
+
p.state = "approval-requested";
|
|
169
|
+
p.approval = { id: chunk.approvalId };
|
|
170
|
+
}
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
case "tool-output-denied": {
|
|
174
|
+
const toolPart = findToolPartByCallId(parts, chunk.toolCallId);
|
|
175
|
+
if (toolPart) {
|
|
176
|
+
const p = toolPart;
|
|
177
|
+
p.state = "output-denied";
|
|
178
|
+
}
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
case "tool-output-available": {
|
|
182
|
+
const toolPart = findToolPartByCallId(parts, chunk.toolCallId);
|
|
183
|
+
if (toolPart) {
|
|
184
|
+
const p = toolPart;
|
|
185
|
+
p.state = "output-available";
|
|
186
|
+
p.output = chunk.output;
|
|
187
|
+
if (chunk.preliminary !== void 0) p.preliminary = chunk.preliminary;
|
|
188
|
+
}
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
case "tool-output-error": {
|
|
192
|
+
const toolPart = findToolPartByCallId(parts, chunk.toolCallId);
|
|
193
|
+
if (toolPart) {
|
|
194
|
+
const p = toolPart;
|
|
195
|
+
p.state = "output-error";
|
|
196
|
+
p.errorText = chunk.errorText;
|
|
197
|
+
}
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
case "step-start":
|
|
201
|
+
case "start-step":
|
|
202
|
+
parts.push({ type: "step-start" });
|
|
203
|
+
return true;
|
|
204
|
+
default:
|
|
205
|
+
if (chunk.type.startsWith("data-")) {
|
|
206
|
+
if (chunk.transient) return true;
|
|
207
|
+
if (chunk.id != null) {
|
|
208
|
+
const existing = findDataPartByTypeAndId(parts, chunk.type, chunk.id);
|
|
209
|
+
if (existing) {
|
|
210
|
+
existing.data = chunk.data;
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
parts.push({
|
|
215
|
+
type: chunk.type,
|
|
216
|
+
...chunk.id != null && { id: chunk.id },
|
|
217
|
+
data: chunk.data
|
|
218
|
+
});
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Returns true if `chunk` would be a no-op replay against the already-known
|
|
226
|
+
* `parts` — i.e. some upstream is re-emitting events for a tool call that
|
|
227
|
+
* the message has already advanced past.
|
|
228
|
+
*
|
|
229
|
+
* Used by stream broadcasters to suppress re-broadcasting these chunks to
|
|
230
|
+
* connected clients. AI SDK v6's `updateToolPart` mutates an existing tool
|
|
231
|
+
* part in place when a chunk arrives with a matching `toolCallId`, so a
|
|
232
|
+
* replayed `tool-input-start` would clobber an `output-available` part back
|
|
233
|
+
* to `input-streaming` on the client (issue #1404).
|
|
234
|
+
*
|
|
235
|
+
* Only returns true when re-broadcasting would *visibly regress* state on
|
|
236
|
+
* a v6 client. Safe-by-construction chunk types (e.g. `tool-output-available`
|
|
237
|
+
* carrying the same output the part already has) return false.
|
|
238
|
+
*
|
|
239
|
+
* Conditions:
|
|
240
|
+
* - `tool-input-start` for a `toolCallId` that already exists in `parts`.
|
|
241
|
+
* - `tool-input-delta` for a `toolCallId` whose existing part is no longer
|
|
242
|
+
* `input-streaming`.
|
|
243
|
+
* - `tool-input-available` for a `toolCallId` whose existing part is no
|
|
244
|
+
* longer `input-streaming` (i.e. has already advanced to `input-available`
|
|
245
|
+
* or any terminal state).
|
|
246
|
+
*/
|
|
247
|
+
function isReplayChunk(parts, chunk) {
|
|
248
|
+
if (chunk.type !== "tool-input-start" && chunk.type !== "tool-input-delta" && chunk.type !== "tool-input-available") return false;
|
|
249
|
+
if (!chunk.toolCallId) return false;
|
|
250
|
+
const existing = findToolPartByCallId(parts, chunk.toolCallId);
|
|
251
|
+
if (!existing) return false;
|
|
252
|
+
if (chunk.type === "tool-input-start") return true;
|
|
253
|
+
return existing.state !== "input-streaming";
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Finds the last part in the array matching the given type.
|
|
257
|
+
* Searches from the end for efficiency (the part we want is usually recent).
|
|
258
|
+
*/
|
|
259
|
+
function findLastPartByType(parts, type) {
|
|
260
|
+
for (let i = parts.length - 1; i >= 0; i--) if (parts[i].type === type) return parts[i];
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Finds a tool part by its toolCallId.
|
|
264
|
+
* Searches from the end since the tool part is usually recent.
|
|
265
|
+
*/
|
|
266
|
+
function findToolPartByCallId(parts, toolCallId) {
|
|
267
|
+
if (!toolCallId) return void 0;
|
|
268
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
269
|
+
const p = parts[i];
|
|
270
|
+
if ("toolCallId" in p && p.toolCallId === toolCallId) return p;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Shallow-merges providerMetadata from a chunk onto an existing part.
|
|
275
|
+
* Preserves any metadata already on the part (e.g. from earlier deltas)
|
|
276
|
+
* while adding new keys from the chunk. This is critical for providers
|
|
277
|
+
* like Anthropic that emit the thinking block signature on reasoning-end.
|
|
278
|
+
*/
|
|
279
|
+
function mergeProviderMetadata(part, metadata) {
|
|
280
|
+
if (metadata == null) return;
|
|
281
|
+
const p = part;
|
|
282
|
+
p.providerMetadata = {
|
|
283
|
+
...p.providerMetadata,
|
|
284
|
+
...metadata
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Finds a data part by its type and id for reconciliation.
|
|
289
|
+
* Data parts use type+id as a composite key so when the same combination
|
|
290
|
+
* is seen again, the existing part's data is updated in-place.
|
|
291
|
+
*/
|
|
292
|
+
function findDataPartByTypeAndId(parts, type, id) {
|
|
293
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
294
|
+
const p = parts[i];
|
|
295
|
+
if (p.type === type && "id" in p && p.id === id) return p;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/chat/agent-tools.ts
|
|
300
|
+
function sortRuns(runs) {
|
|
301
|
+
return [...runs].sort((a, b) => {
|
|
302
|
+
if (a.order !== b.order) return a.order - b.order;
|
|
303
|
+
return a.runId.localeCompare(b.runId);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
function rebuildIndexes(runsById) {
|
|
307
|
+
const grouped = {};
|
|
308
|
+
const unboundRuns = [];
|
|
309
|
+
for (const run of Object.values(runsById)) if (run.parentToolCallId) {
|
|
310
|
+
grouped[run.parentToolCallId] = grouped[run.parentToolCallId] ?? [];
|
|
311
|
+
grouped[run.parentToolCallId].push(run);
|
|
312
|
+
} else unboundRuns.push(run);
|
|
313
|
+
for (const [toolCallId, runs] of Object.entries(grouped)) grouped[toolCallId] = sortRuns(runs);
|
|
314
|
+
return {
|
|
315
|
+
runsByToolCallId: grouped,
|
|
316
|
+
unboundRuns: sortRuns(unboundRuns)
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function emptyRun(message) {
|
|
320
|
+
const { event } = message;
|
|
321
|
+
if (event.kind === "started") return {
|
|
322
|
+
runId: event.runId,
|
|
323
|
+
agentType: event.agentType,
|
|
324
|
+
parentToolCallId: message.parentToolCallId,
|
|
325
|
+
inputPreview: event.inputPreview,
|
|
326
|
+
order: event.order,
|
|
327
|
+
display: event.display,
|
|
328
|
+
status: "running",
|
|
329
|
+
parts: [],
|
|
330
|
+
subAgent: {
|
|
331
|
+
agent: event.agentType,
|
|
332
|
+
name: event.runId
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
function applyToRun(prev, message) {
|
|
337
|
+
const seeded = prev ?? emptyRun(message);
|
|
338
|
+
const { event } = message;
|
|
339
|
+
switch (event.kind) {
|
|
340
|
+
case "started":
|
|
341
|
+
if (seeded?.status === "completed" || seeded?.status === "error" || seeded?.status === "aborted" || seeded?.status === "interrupted") return seeded;
|
|
342
|
+
return {
|
|
343
|
+
...seeded,
|
|
344
|
+
runId: event.runId,
|
|
345
|
+
agentType: event.agentType,
|
|
346
|
+
parentToolCallId: message.parentToolCallId,
|
|
347
|
+
inputPreview: event.inputPreview,
|
|
348
|
+
order: event.order,
|
|
349
|
+
display: event.display,
|
|
350
|
+
status: "running",
|
|
351
|
+
parts: seeded?.parts ?? [],
|
|
352
|
+
subAgent: {
|
|
353
|
+
agent: event.agentType,
|
|
354
|
+
name: event.runId
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
case "chunk": {
|
|
358
|
+
if (!seeded) return void 0;
|
|
359
|
+
const parts = [...seeded.parts];
|
|
360
|
+
try {
|
|
361
|
+
applyChunkToParts(parts, JSON.parse(event.body));
|
|
362
|
+
} catch {
|
|
363
|
+
return seeded;
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
...seeded,
|
|
367
|
+
parts
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
case "finished":
|
|
371
|
+
if (!seeded) return void 0;
|
|
372
|
+
return {
|
|
373
|
+
...seeded,
|
|
374
|
+
status: "completed",
|
|
375
|
+
summary: event.summary,
|
|
376
|
+
error: void 0
|
|
377
|
+
};
|
|
378
|
+
case "error":
|
|
379
|
+
if (!seeded) return void 0;
|
|
380
|
+
return {
|
|
381
|
+
...seeded,
|
|
382
|
+
status: "error",
|
|
383
|
+
error: event.error
|
|
384
|
+
};
|
|
385
|
+
case "aborted":
|
|
386
|
+
if (!seeded) return void 0;
|
|
387
|
+
return {
|
|
388
|
+
...seeded,
|
|
389
|
+
status: "aborted",
|
|
390
|
+
error: event.reason
|
|
391
|
+
};
|
|
392
|
+
case "interrupted":
|
|
393
|
+
if (!seeded) return void 0;
|
|
394
|
+
return {
|
|
395
|
+
...seeded,
|
|
396
|
+
status: "interrupted",
|
|
397
|
+
error: event.error
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function createAgentToolEventState() {
|
|
402
|
+
return {
|
|
403
|
+
runsById: {},
|
|
404
|
+
runsByToolCallId: {},
|
|
405
|
+
unboundRuns: []
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
function applyAgentToolEvent(state, message) {
|
|
409
|
+
if (message.type !== "agent-tool-event") return state;
|
|
410
|
+
const runId = message.event.runId;
|
|
411
|
+
const nextRun = applyToRun(state.runsById[runId], message);
|
|
412
|
+
if (!nextRun) return state;
|
|
413
|
+
const runsById = {
|
|
414
|
+
...state.runsById,
|
|
415
|
+
[runId]: nextRun
|
|
416
|
+
};
|
|
417
|
+
return {
|
|
418
|
+
runsById,
|
|
419
|
+
...rebuildIndexes(runsById)
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
//#endregion
|
|
423
|
+
export { isReplayChunk as i, createAgentToolEventState as n, applyChunkToParts as r, applyAgentToolEvent as t };
|
|
424
|
+
|
|
425
|
+
//# sourceMappingURL=agent-tools-BAdX1vdI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-tools-BAdX1vdI.js","names":[],"sources":["../src/chat/message-builder.ts","../src/chat/agent-tools.ts"],"sourcesContent":["/**\n * Shared message builder for reconstructing UIMessage parts from stream chunks.\n *\n * Used by both @cloudflare/ai-chat (server + client) and @cloudflare/think\n * to avoid duplicating the chunk-type switch/case logic.\n *\n * Operates on a mutable parts array for performance (avoids allocating new arrays\n * on every chunk during streaming).\n */\n\nimport type { UIMessage } from \"ai\";\n\n/** The parts array type from UIMessage */\nexport type MessageParts = UIMessage[\"parts\"];\n\n/** A single part from the UIMessage parts array */\nexport type MessagePart = MessageParts[number];\n\n/**\n * Parsed chunk data from an AI SDK stream event.\n * This is the JSON-parsed body of a CF_AGENT_USE_CHAT_RESPONSE message,\n * or the `data:` payload of an SSE line.\n */\nexport type StreamChunkData = {\n type: string;\n id?: string;\n delta?: string;\n text?: string;\n mediaType?: string;\n url?: string;\n sourceId?: string;\n title?: string;\n filename?: string;\n toolCallId?: string;\n toolName?: string;\n input?: unknown;\n inputTextDelta?: string;\n output?: unknown;\n state?: string;\n errorText?: string;\n /** When true, the output is preliminary (may be updated by a later chunk) */\n preliminary?: boolean;\n /** Approval ID for tools with needsApproval */\n approvalId?: string;\n providerMetadata?: Record<string, unknown>;\n /** Whether the tool was executed by the provider (e.g. Gemini code execution) */\n providerExecuted?: boolean;\n /** Payload for data-* parts (developer-defined typed JSON) */\n data?: unknown;\n /** When true, data parts are ephemeral and not persisted to message.parts */\n transient?: boolean;\n /** Message ID assigned by the server at stream start */\n messageId?: string;\n /** Per-message metadata attached by start/finish/message-metadata chunks */\n messageMetadata?: unknown;\n [key: string]: unknown;\n};\n\n/**\n * Applies a stream chunk to a mutable parts array, building up the message\n * incrementally. Returns true if the chunk was handled, false if it was\n * an unrecognized type (caller may handle it with additional logic).\n *\n * Handles all common chunk types that both server and client need:\n * - text-start / text-delta / text-end\n * - reasoning-start / reasoning-delta / reasoning-end\n * - file\n * - source-url / source-document\n * - tool-input-start / tool-input-delta / tool-input-available / tool-input-error\n * - tool-output-available / tool-output-error\n * - step-start (aliased from start-step)\n * - data-* (developer-defined typed JSON blobs)\n *\n * @param parts - The mutable parts array to update\n * @param chunk - The parsed stream chunk data\n * @returns true if handled, false if the chunk type is not recognized\n */\nexport function applyChunkToParts(\n parts: MessagePart[],\n chunk: StreamChunkData\n): boolean {\n switch (chunk.type) {\n case \"text-start\": {\n parts.push({\n type: \"text\",\n text: \"\",\n state: \"streaming\"\n } as MessagePart);\n return true;\n }\n\n case \"text-delta\": {\n const lastTextPart = findLastPartByType(parts, \"text\");\n if (lastTextPart && lastTextPart.type === \"text\") {\n (lastTextPart as { text: string }).text += chunk.delta ?? \"\";\n } else {\n // No text-start received — create a new text part (stream resumption fallback)\n parts.push({\n type: \"text\",\n text: chunk.delta ?? \"\",\n state: \"streaming\"\n } as MessagePart);\n }\n return true;\n }\n\n case \"text-end\": {\n const lastTextPart = findLastPartByType(parts, \"text\");\n if (lastTextPart && \"state\" in lastTextPart) {\n (lastTextPart as { state: string }).state = \"done\";\n }\n return true;\n }\n\n case \"reasoning-start\": {\n parts.push({\n type: \"reasoning\",\n text: \"\",\n state: \"streaming\"\n } as MessagePart);\n return true;\n }\n\n case \"reasoning-delta\": {\n const lastReasoningPart = findLastPartByType(parts, \"reasoning\");\n if (lastReasoningPart && lastReasoningPart.type === \"reasoning\") {\n (lastReasoningPart as { text: string }).text += chunk.delta ?? \"\";\n mergeProviderMetadata(lastReasoningPart, chunk.providerMetadata);\n } else {\n // No reasoning-start received — create a new reasoning part (stream resumption fallback)\n parts.push({\n type: \"reasoning\",\n text: chunk.delta ?? \"\",\n state: \"streaming\",\n ...(chunk.providerMetadata != null\n ? { providerMetadata: chunk.providerMetadata }\n : {})\n } as MessagePart);\n }\n return true;\n }\n\n case \"reasoning-end\": {\n const lastReasoningPart = findLastPartByType(parts, \"reasoning\");\n if (lastReasoningPart && \"state\" in lastReasoningPart) {\n (lastReasoningPart as { state: string }).state = \"done\";\n mergeProviderMetadata(lastReasoningPart, chunk.providerMetadata);\n }\n return true;\n }\n\n case \"file\": {\n parts.push({\n type: \"file\",\n mediaType: chunk.mediaType,\n url: chunk.url\n } as MessagePart);\n return true;\n }\n\n case \"source-url\": {\n parts.push({\n type: \"source-url\",\n sourceId: chunk.sourceId,\n url: chunk.url,\n title: chunk.title,\n providerMetadata: chunk.providerMetadata\n } as MessagePart);\n return true;\n }\n\n case \"source-document\": {\n parts.push({\n type: \"source-document\",\n sourceId: chunk.sourceId,\n mediaType: chunk.mediaType,\n title: chunk.title,\n filename: chunk.filename,\n providerMetadata: chunk.providerMetadata\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-start\": {\n // Idempotent against an existing tool part with the same toolCallId.\n // Some providers (notably the OpenAI Responses API) replay prior\n // tool calls in continuation streams as a fresh `tool-input-start`\n // → `tool-input-delta` → `tool-input-available` →\n // `tool-output-available` sequence carrying the original toolCallId\n // and original output. Without this guard a replay would push a\n // duplicate part into the streaming message *and* clobber the\n // original part's state when the AI SDK's mutate-in-place\n // `updateToolPart` processes the replay on the client (issue #1404).\n // A model that genuinely wants a fresh tool call always emits a\n // new toolCallId, so an existing match is never a legitimate\n // \"start over\".\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n return true;\n }\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"input-streaming\",\n input: undefined,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {}),\n ...(chunk.title != null ? { title: chunk.title } : {})\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-delta\": {\n // Only mutate input while the tool is still actively input-streaming.\n // Deltas arriving after the tool has already advanced (input-available\n // or any terminal state) are provider replay and must not regress\n // a fully-formed input back to a partial one.\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (\n toolPart &&\n (toolPart as Record<string, unknown>).state === \"input-streaming\"\n ) {\n (toolPart as Record<string, unknown>).input = chunk.input;\n }\n return true;\n }\n\n case \"tool-input-available\": {\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n const p = existing as Record<string, unknown>;\n // Only advance from the streaming-input phase. Once the tool is\n // already at input-available or any terminal state\n // (output-available, output-error, output-denied,\n // approval-requested, approval-responded), this chunk is a\n // provider replay and must not regress state or overwrite a\n // resolved input/output. See the comment on tool-input-start.\n if (p.state === \"input-streaming\") {\n p.state = \"input-available\";\n p.input = chunk.input;\n if (chunk.providerExecuted != null) {\n p.providerExecuted = chunk.providerExecuted;\n }\n if (chunk.providerMetadata != null) {\n p.callProviderMetadata = chunk.providerMetadata;\n }\n if (chunk.title != null) {\n p.title = chunk.title;\n }\n }\n return true;\n }\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"input-available\",\n input: chunk.input,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {}),\n ...(chunk.title != null ? { title: chunk.title } : {})\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-error\": {\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n const p = existing as Record<string, unknown>;\n // First-write-wins: a tool that's already terminal must not be\n // regressed (or re-decided as an error) by a later chunk. A\n // tool-input-error here is either provider replay or a confused\n // upstream — preserve the existing terminal state.\n if (\n p.state === \"output-available\" ||\n p.state === \"output-error\" ||\n p.state === \"output-denied\"\n ) {\n return true;\n }\n p.state = \"output-error\";\n p.errorText = chunk.errorText;\n p.input = chunk.input;\n if (chunk.providerExecuted != null) {\n p.providerExecuted = chunk.providerExecuted;\n }\n if (chunk.providerMetadata != null) {\n p.callProviderMetadata = chunk.providerMetadata;\n }\n } else {\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"output-error\",\n input: chunk.input,\n errorText: chunk.errorText,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {})\n } as MessagePart);\n }\n return true;\n }\n\n case \"tool-approval-request\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"approval-requested\";\n p.approval = { id: chunk.approvalId };\n }\n return true;\n }\n\n case \"tool-output-denied\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-denied\";\n }\n return true;\n }\n\n case \"tool-output-available\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-available\";\n p.output = chunk.output;\n if (chunk.preliminary !== undefined) {\n p.preliminary = chunk.preliminary;\n }\n }\n return true;\n }\n\n case \"tool-output-error\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-error\";\n p.errorText = chunk.errorText;\n }\n return true;\n }\n\n // Both \"step-start\" (client convention) and \"start-step\" (server convention)\n case \"step-start\":\n case \"start-step\": {\n parts.push({ type: \"step-start\" } as MessagePart);\n return true;\n }\n\n default: {\n // https://ai-sdk.dev/docs/ai-sdk-ui/streaming-data\n if (chunk.type.startsWith(\"data-\")) {\n // Transient parts are ephemeral — the AI SDK client fires an onData\n // callback instead of adding them to message.parts. On the server we\n // still broadcast them (so connected clients see them in real time)\n // but skip persisting them into the stored message parts.\n if (chunk.transient) {\n return true;\n }\n\n // Reconciliation: if a part with the same type AND id already exists,\n // update its data in-place instead of appending a duplicate.\n if (chunk.id != null) {\n const existing = findDataPartByTypeAndId(parts, chunk.type, chunk.id);\n if (existing) {\n (existing as Record<string, unknown>).data = chunk.data;\n return true;\n }\n }\n\n // Append new data parts to the array directly.\n // Note: `chunk.data` should always be provided — if omitted, the\n // persisted part will have `data: undefined` which JSON.stringify\n // drops, so the part will have no `data` field on reload.\n // The cast is needed because UIMessage[\"parts\"] doesn't include\n // data-* types in its union because they're an open extension point.\n parts.push({\n type: chunk.type,\n ...(chunk.id != null && { id: chunk.id }),\n data: chunk.data\n } as MessagePart);\n return true;\n }\n\n return false;\n }\n }\n}\n\n/**\n * Returns true if `chunk` would be a no-op replay against the already-known\n * `parts` — i.e. some upstream is re-emitting events for a tool call that\n * the message has already advanced past.\n *\n * Used by stream broadcasters to suppress re-broadcasting these chunks to\n * connected clients. AI SDK v6's `updateToolPart` mutates an existing tool\n * part in place when a chunk arrives with a matching `toolCallId`, so a\n * replayed `tool-input-start` would clobber an `output-available` part back\n * to `input-streaming` on the client (issue #1404).\n *\n * Only returns true when re-broadcasting would *visibly regress* state on\n * a v6 client. Safe-by-construction chunk types (e.g. `tool-output-available`\n * carrying the same output the part already has) return false.\n *\n * Conditions:\n * - `tool-input-start` for a `toolCallId` that already exists in `parts`.\n * - `tool-input-delta` for a `toolCallId` whose existing part is no longer\n * `input-streaming`.\n * - `tool-input-available` for a `toolCallId` whose existing part is no\n * longer `input-streaming` (i.e. has already advanced to `input-available`\n * or any terminal state).\n */\nexport function isReplayChunk(\n parts: MessagePart[],\n chunk: StreamChunkData\n): boolean {\n if (\n chunk.type !== \"tool-input-start\" &&\n chunk.type !== \"tool-input-delta\" &&\n chunk.type !== \"tool-input-available\"\n ) {\n return false;\n }\n if (!chunk.toolCallId) return false;\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (!existing) return false;\n if (chunk.type === \"tool-input-start\") return true;\n const state = (existing as Record<string, unknown>).state;\n return state !== \"input-streaming\";\n}\n\n/**\n * Finds the last part in the array matching the given type.\n * Searches from the end for efficiency (the part we want is usually recent).\n */\nfunction findLastPartByType(\n parts: MessagePart[],\n type: string\n): MessagePart | undefined {\n for (let i = parts.length - 1; i >= 0; i--) {\n if (parts[i].type === type) {\n return parts[i];\n }\n }\n return undefined;\n}\n\n/**\n * Finds a tool part by its toolCallId.\n * Searches from the end since the tool part is usually recent.\n */\nfunction findToolPartByCallId(\n parts: MessagePart[],\n toolCallId: string | undefined\n): MessagePart | undefined {\n if (!toolCallId) return undefined;\n for (let i = parts.length - 1; i >= 0; i--) {\n const p = parts[i];\n if (\"toolCallId\" in p && p.toolCallId === toolCallId) {\n return p;\n }\n }\n return undefined;\n}\n\n/**\n * Shallow-merges providerMetadata from a chunk onto an existing part.\n * Preserves any metadata already on the part (e.g. from earlier deltas)\n * while adding new keys from the chunk. This is critical for providers\n * like Anthropic that emit the thinking block signature on reasoning-end.\n */\nfunction mergeProviderMetadata(\n part: MessagePart,\n metadata: Record<string, unknown> | undefined\n): void {\n if (metadata == null) return;\n const p = part as Record<string, unknown>;\n p.providerMetadata = {\n ...(p.providerMetadata as Record<string, unknown> | undefined),\n ...metadata\n };\n}\n\n/**\n * Finds a data part by its type and id for reconciliation.\n * Data parts use type+id as a composite key so when the same combination\n * is seen again, the existing part's data is updated in-place.\n */\nfunction findDataPartByTypeAndId(\n parts: MessagePart[],\n type: string,\n id: string\n): MessagePart | undefined {\n for (let i = parts.length - 1; i >= 0; i--) {\n const p = parts[i];\n if (p.type === type && \"id\" in p && (p as { id: string }).id === id) {\n return p;\n }\n }\n return undefined;\n}\n","import { applyChunkToParts } from \"./message-builder\";\nimport type {\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolRunState\n} from \"../agent-tool-types\";\n\nfunction sortRuns(runs: AgentToolRunState[]): AgentToolRunState[] {\n return [...runs].sort((a, b) => {\n if (a.order !== b.order) return a.order - b.order;\n return a.runId.localeCompare(b.runId);\n });\n}\n\nfunction rebuildIndexes(\n runsById: Record<string, AgentToolRunState>\n): Pick<AgentToolEventState, \"runsByToolCallId\" | \"unboundRuns\"> {\n const grouped: Record<string, AgentToolRunState[]> = {};\n const unboundRuns: AgentToolRunState[] = [];\n for (const run of Object.values(runsById)) {\n if (run.parentToolCallId) {\n grouped[run.parentToolCallId] = grouped[run.parentToolCallId] ?? [];\n grouped[run.parentToolCallId].push(run);\n } else {\n unboundRuns.push(run);\n }\n }\n for (const [toolCallId, runs] of Object.entries(grouped)) {\n grouped[toolCallId] = sortRuns(runs);\n }\n return { runsByToolCallId: grouped, unboundRuns: sortRuns(unboundRuns) };\n}\n\nfunction emptyRun(\n message: AgentToolEventMessage\n): AgentToolRunState | undefined {\n const { event } = message;\n if (event.kind === \"started\") {\n return {\n runId: event.runId,\n agentType: event.agentType,\n parentToolCallId: message.parentToolCallId,\n inputPreview: event.inputPreview,\n order: event.order,\n display: event.display,\n status: \"running\",\n parts: [],\n subAgent: { agent: event.agentType, name: event.runId }\n };\n }\n return undefined;\n}\n\nfunction applyToRun(\n prev: AgentToolRunState | undefined,\n message: AgentToolEventMessage\n): AgentToolRunState | undefined {\n const seeded = prev ?? emptyRun(message);\n const { event } = message;\n\n switch (event.kind) {\n case \"started\":\n if (\n seeded?.status === \"completed\" ||\n seeded?.status === \"error\" ||\n seeded?.status === \"aborted\" ||\n seeded?.status === \"interrupted\"\n ) {\n return seeded;\n }\n return {\n ...seeded,\n runId: event.runId,\n agentType: event.agentType,\n parentToolCallId: message.parentToolCallId,\n inputPreview: event.inputPreview,\n order: event.order,\n display: event.display,\n status: \"running\",\n parts: seeded?.parts ?? [],\n subAgent: { agent: event.agentType, name: event.runId }\n };\n case \"chunk\": {\n if (!seeded) return undefined;\n const parts = [...seeded.parts];\n try {\n applyChunkToParts(parts, JSON.parse(event.body));\n } catch {\n return seeded;\n }\n return { ...seeded, parts };\n }\n case \"finished\":\n if (!seeded) return undefined;\n return {\n ...seeded,\n status: \"completed\",\n summary: event.summary,\n error: undefined\n };\n case \"error\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"error\", error: event.error };\n case \"aborted\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"aborted\", error: event.reason };\n case \"interrupted\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"interrupted\", error: event.error };\n }\n}\n\nexport function createAgentToolEventState(): AgentToolEventState {\n return {\n runsById: {},\n runsByToolCallId: {},\n unboundRuns: []\n };\n}\n\nexport function applyAgentToolEvent(\n state: AgentToolEventState,\n message: AgentToolEventMessage\n): AgentToolEventState {\n if (message.type !== \"agent-tool-event\") return state;\n const runId = message.event.runId;\n const nextRun = applyToRun(state.runsById[runId], message);\n if (!nextRun) return state;\n\n const runsById = { ...state.runsById, [runId]: nextRun };\n return { runsById, ...rebuildIndexes(runsById) };\n}\n\nexport type {\n AgentToolEvent,\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolRunState\n} from \"../agent-tool-types\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
a as AgentToolEventState,
|
|
3
|
+
i as AgentToolEventMessage
|
|
4
|
+
} from "./agent-tool-types-tBGRsPm0.js";
|
|
5
|
+
|
|
6
|
+
//#region src/chat/agent-tools.d.ts
|
|
7
|
+
declare function createAgentToolEventState(): AgentToolEventState;
|
|
8
|
+
declare function applyAgentToolEvent(
|
|
9
|
+
state: AgentToolEventState,
|
|
10
|
+
message: AgentToolEventMessage
|
|
11
|
+
): AgentToolEventState;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { createAgentToolEventState as n, applyAgentToolEvent as t };
|
|
14
|
+
//# sourceMappingURL=agent-tools-CIO14miM.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
a as AgentToolEventState,
|
|
3
|
+
c as AgentToolRunInspection,
|
|
4
|
+
d as AgentToolStoredChunk,
|
|
5
|
+
f as AgentToolTerminalStatus,
|
|
6
|
+
h as RunAgentToolResult,
|
|
7
|
+
i as AgentToolEventMessage,
|
|
8
|
+
l as AgentToolRunState,
|
|
9
|
+
m as RunAgentToolOptions,
|
|
10
|
+
n as AgentToolDisplayMetadata,
|
|
11
|
+
o as AgentToolLifecycleResult,
|
|
12
|
+
p as ChatCapableAgentClass,
|
|
13
|
+
r as AgentToolEvent,
|
|
14
|
+
s as AgentToolRunInfo,
|
|
15
|
+
t as AgentToolChildAdapter,
|
|
16
|
+
u as AgentToolRunStatus
|
|
17
|
+
} from "./agent-tool-types-tBGRsPm0.js";
|
|
18
|
+
import { Tool } from "ai";
|
|
19
|
+
|
|
20
|
+
//#region src/agent-tools.d.ts
|
|
21
|
+
type SchemaLike<T = unknown> = {
|
|
22
|
+
parse(value: unknown): T;
|
|
23
|
+
};
|
|
24
|
+
type AgentToolFactoryOptions<Output = unknown> = {
|
|
25
|
+
description: string;
|
|
26
|
+
inputSchema: unknown;
|
|
27
|
+
outputSchema?: SchemaLike<Output>;
|
|
28
|
+
displayName?: string;
|
|
29
|
+
icon?: string;
|
|
30
|
+
display?: AgentToolDisplayMetadata;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Create an AI SDK tool that dispatches a chat-capable sub-agent through
|
|
34
|
+
* `Agent.runAgentTool`.
|
|
35
|
+
*/
|
|
36
|
+
declare function agentTool<Input = unknown, Output = unknown>(
|
|
37
|
+
cls: ChatCapableAgentClass,
|
|
38
|
+
options: AgentToolFactoryOptions<Output>
|
|
39
|
+
): Tool<
|
|
40
|
+
Input,
|
|
41
|
+
| string
|
|
42
|
+
| Output
|
|
43
|
+
| {
|
|
44
|
+
ok: false;
|
|
45
|
+
error: string;
|
|
46
|
+
}
|
|
47
|
+
>;
|
|
48
|
+
//#endregion
|
|
49
|
+
export {
|
|
50
|
+
type AgentToolChildAdapter,
|
|
51
|
+
type AgentToolDisplayMetadata,
|
|
52
|
+
type AgentToolEvent,
|
|
53
|
+
type AgentToolEventMessage,
|
|
54
|
+
type AgentToolEventState,
|
|
55
|
+
type AgentToolFactoryOptions,
|
|
56
|
+
type AgentToolLifecycleResult,
|
|
57
|
+
type AgentToolRunInfo,
|
|
58
|
+
type AgentToolRunInspection,
|
|
59
|
+
type AgentToolRunState,
|
|
60
|
+
type AgentToolRunStatus,
|
|
61
|
+
type AgentToolStoredChunk,
|
|
62
|
+
type AgentToolTerminalStatus,
|
|
63
|
+
type ChatCapableAgentClass,
|
|
64
|
+
type RunAgentToolOptions,
|
|
65
|
+
type RunAgentToolResult,
|
|
66
|
+
agentTool
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=agent-tools.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { __DO_NOT_USE_WILL_BREAK__agentContext } from "./internal_context.js";
|
|
2
|
+
import { tool } from "ai";
|
|
3
|
+
//#region src/agent-tools.ts
|
|
4
|
+
function currentAgentToolRunner() {
|
|
5
|
+
const agent = __DO_NOT_USE_WILL_BREAK__agentContext.getStore()?.agent;
|
|
6
|
+
if (agent === null || typeof agent !== "object" || typeof agent.runAgentTool !== "function") throw new Error("agentTool() can only run inside an Agent turn. Use it from getTools() on an Agent subclass.");
|
|
7
|
+
return agent;
|
|
8
|
+
}
|
|
9
|
+
function failure(error) {
|
|
10
|
+
return {
|
|
11
|
+
ok: false,
|
|
12
|
+
error
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create an AI SDK tool that dispatches a chat-capable sub-agent through
|
|
17
|
+
* `Agent.runAgentTool`.
|
|
18
|
+
*/
|
|
19
|
+
function agentTool(cls, options) {
|
|
20
|
+
return tool({
|
|
21
|
+
description: options.description,
|
|
22
|
+
inputSchema: options.inputSchema,
|
|
23
|
+
execute: async (input, executeOptions) => {
|
|
24
|
+
const display = options.displayName || options.icon || options.display ? {
|
|
25
|
+
...options.display,
|
|
26
|
+
...options.displayName ? { name: options.displayName } : {},
|
|
27
|
+
...options.icon ? { icon: options.icon } : {}
|
|
28
|
+
} : void 0;
|
|
29
|
+
const result = await currentAgentToolRunner().runAgentTool(cls, {
|
|
30
|
+
input,
|
|
31
|
+
parentToolCallId: executeOptions?.toolCallId,
|
|
32
|
+
signal: executeOptions?.abortSignal,
|
|
33
|
+
display
|
|
34
|
+
});
|
|
35
|
+
if (result.status === "completed") {
|
|
36
|
+
if (options.outputSchema) {
|
|
37
|
+
if (result.output === void 0) return failure("agent tool completed without structured output required by outputSchema");
|
|
38
|
+
return options.outputSchema.parse(result.output);
|
|
39
|
+
}
|
|
40
|
+
return result.summary ?? "";
|
|
41
|
+
}
|
|
42
|
+
if (result.status === "aborted") return failure("agent tool run was cancelled");
|
|
43
|
+
if (result.status === "interrupted") return failure("agent tool run was interrupted; no recoverable output");
|
|
44
|
+
return failure(result.error ?? "agent tool run failed");
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { agentTool };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=agent-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-tools.js","names":["agentContext","createTool"],"sources":["../src/agent-tools.ts"],"sourcesContent":["import { tool, type Tool } from \"ai\";\nimport { __DO_NOT_USE_WILL_BREAK__agentContext as agentContext } from \"./internal_context\";\nimport type {\n ChatCapableAgentClass,\n RunAgentToolOptions,\n RunAgentToolResult,\n AgentToolDisplayMetadata\n} from \"./agent-tool-types\";\n\ntype SchemaLike<T = unknown> = {\n parse(value: unknown): T;\n};\n\ntype AgentToolFactoryOptions<Output = unknown> = {\n description: string;\n inputSchema: unknown;\n outputSchema?: SchemaLike<Output>;\n displayName?: string;\n icon?: string;\n display?: AgentToolDisplayMetadata;\n};\n\ntype ToolExecutionOptions = {\n toolCallId?: string;\n abortSignal?: AbortSignal;\n};\n\ntype AgentToolRunner = {\n runAgentTool<Input, Output>(\n cls: ChatCapableAgentClass,\n options: RunAgentToolOptions<Input>\n ): Promise<RunAgentToolResult<Output>>;\n};\n\nfunction currentAgentToolRunner(): AgentToolRunner {\n const agent = agentContext.getStore()?.agent;\n if (\n agent === null ||\n typeof agent !== \"object\" ||\n typeof (agent as { runAgentTool?: unknown }).runAgentTool !== \"function\"\n ) {\n throw new Error(\n \"agentTool() can only run inside an Agent turn. Use it from getTools() on an Agent subclass.\"\n );\n }\n return agent as AgentToolRunner;\n}\n\nfunction failure(error: string): { ok: false; error: string } {\n return { ok: false, error };\n}\n\n/**\n * Create an AI SDK tool that dispatches a chat-capable sub-agent through\n * `Agent.runAgentTool`.\n */\nexport function agentTool<Input = unknown, Output = unknown>(\n cls: ChatCapableAgentClass,\n options: AgentToolFactoryOptions<Output>\n): Tool<Input, string | Output | { ok: false; error: string }> {\n const createTool = tool as unknown as <I, O>(config: {\n description: string;\n inputSchema: unknown;\n execute: (input: I, options?: ToolExecutionOptions) => Promise<O>;\n }) => Tool<I, O>;\n\n return createTool<Input, string | Output | { ok: false; error: string }>({\n description: options.description,\n inputSchema: options.inputSchema,\n execute: async (input: Input, executeOptions?: ToolExecutionOptions) => {\n const display: AgentToolDisplayMetadata | undefined =\n options.displayName || options.icon || options.display\n ? {\n ...options.display,\n ...(options.displayName ? { name: options.displayName } : {}),\n ...(options.icon ? { icon: options.icon } : {})\n }\n : undefined;\n\n const result = await currentAgentToolRunner().runAgentTool<Input, Output>(\n cls,\n {\n input,\n parentToolCallId: executeOptions?.toolCallId,\n signal: executeOptions?.abortSignal,\n display\n }\n );\n\n if (result.status === \"completed\") {\n if (options.outputSchema) {\n if (result.output === undefined) {\n return failure(\n \"agent tool completed without structured output required by outputSchema\"\n );\n }\n return options.outputSchema.parse(result.output);\n }\n return result.summary ?? \"\";\n }\n\n if (result.status === \"aborted\") {\n return failure(\"agent tool run was cancelled\");\n }\n if (result.status === \"interrupted\") {\n return failure(\"agent tool run was interrupted; no recoverable output\");\n }\n return failure(result.error ?? \"agent tool run failed\");\n }\n });\n}\n\nexport type { AgentToolFactoryOptions };\nexport type {\n AgentToolChildAdapter,\n AgentToolDisplayMetadata,\n AgentToolEvent,\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolLifecycleResult,\n AgentToolRunInfo,\n AgentToolRunInspection,\n AgentToolRunState,\n AgentToolRunStatus,\n AgentToolStoredChunk,\n AgentToolTerminalStatus,\n ChatCapableAgentClass,\n RunAgentToolOptions,\n RunAgentToolResult\n} from \"./agent-tool-types\";\n"],"mappings":";;;AAkCA,SAAS,yBAA0C;CACjD,MAAM,QAAQA,sCAAa,UAAU,EAAE;AACvC,KACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAQ,MAAqC,iBAAiB,WAE9D,OAAM,IAAI,MACR,8FACD;AAEH,QAAO;;AAGT,SAAS,QAAQ,OAA6C;AAC5D,QAAO;EAAE,IAAI;EAAO;EAAO;;;;;;AAO7B,SAAgB,UACd,KACA,SAC6D;AAO7D,QAAOC,KAAkE;EACvE,aAAa,QAAQ;EACrB,aAAa,QAAQ;EACrB,SAAS,OAAO,OAAc,mBAA0C;GACtE,MAAM,UACJ,QAAQ,eAAe,QAAQ,QAAQ,QAAQ,UAC3C;IACE,GAAG,QAAQ;IACX,GAAI,QAAQ,cAAc,EAAE,MAAM,QAAQ,aAAa,GAAG,EAAE;IAC5D,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE;IAC/C,GACD,KAAA;GAEN,MAAM,SAAS,MAAM,wBAAwB,CAAC,aAC5C,KACA;IACE;IACA,kBAAkB,gBAAgB;IAClC,QAAQ,gBAAgB;IACxB;IACD,CACF;AAED,OAAI,OAAO,WAAW,aAAa;AACjC,QAAI,QAAQ,cAAc;AACxB,SAAI,OAAO,WAAW,KAAA,EACpB,QAAO,QACL,0EACD;AAEH,YAAO,QAAQ,aAAa,MAAM,OAAO,OAAO;;AAElD,WAAO,OAAO,WAAW;;AAG3B,OAAI,OAAO,WAAW,UACpB,QAAO,QAAQ,+BAA+B;AAEhD,OAAI,OAAO,WAAW,cACpB,QAAO,QAAQ,wDAAwD;AAEzE,UAAO,QAAQ,OAAO,SAAS,wBAAwB;;EAE1D,CAAC"}
|