@mastra/ai-sdk 0.0.0-toolOptionTypes-20250917085558 → 0.0.0-top-level-fix-20251211111608
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 +821 -3
- package/README.md +125 -1
- package/dist/__tests__/__fixtures__/network.stream.d.ts +2329 -0
- package/dist/__tests__/__fixtures__/network.stream.d.ts.map +1 -0
- package/dist/chat-route.d.ts +101 -0
- package/dist/chat-route.d.ts.map +1 -0
- package/dist/convert-messages.d.ts +10 -0
- package/dist/convert-messages.d.ts.map +1 -0
- package/dist/convert-streams.d.ts +81 -0
- package/dist/convert-streams.d.ts.map +1 -0
- package/dist/helpers.d.ts +43 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/index.cjs +2029 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2022 -12
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +157 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/network-route.d.ts +75 -0
- package/dist/network-route.d.ts.map +1 -0
- package/dist/to-ai-sdk-format.d.ts +16 -0
- package/dist/to-ai-sdk-format.d.ts.map +1 -0
- package/dist/transformers.d.ts +259 -0
- package/dist/transformers.d.ts.map +1 -0
- package/dist/ui.cjs +16 -0
- package/dist/ui.cjs.map +1 -0
- package/dist/ui.d.ts +2 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +13 -0
- package/dist/ui.js.map +1 -0
- package/dist/utils.d.ts +11 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/workflow-route.d.ts +77 -0
- package/dist/workflow-route.d.ts.map +1 -0
- package/package.json +28 -8
package/dist/index.js
CHANGED
|
@@ -1,10 +1,1329 @@
|
|
|
1
1
|
import { registerApiRoute } from '@mastra/core/server';
|
|
2
|
+
import { createUIMessageStream, createUIMessageStreamResponse, wrapLanguageModel } from 'ai';
|
|
3
|
+
import { convertFullStreamChunkToMastra, DefaultGeneratedFile, DefaultGeneratedFileWithType } from '@mastra/core/stream';
|
|
4
|
+
import { TripWire, MessageList } from '@mastra/core/agent';
|
|
5
|
+
import { RequestContext } from '@mastra/core/di';
|
|
6
|
+
import { WorkingMemory, MessageHistory, SemanticRecall } from '@mastra/core/processors';
|
|
2
7
|
|
|
3
|
-
// src/
|
|
8
|
+
// src/chat-route.ts
|
|
9
|
+
|
|
10
|
+
// src/utils.ts
|
|
11
|
+
var isDataChunkType = (chunk) => {
|
|
12
|
+
return chunk && typeof chunk === "object" && "type" in chunk && chunk.type?.startsWith("data-");
|
|
13
|
+
};
|
|
14
|
+
var isMastraTextStreamChunk = (chunk) => {
|
|
15
|
+
return chunk && typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string" && [
|
|
16
|
+
"text-start",
|
|
17
|
+
"text-delta",
|
|
18
|
+
"text-end",
|
|
19
|
+
"reasoning-start",
|
|
20
|
+
"reasoning-delta",
|
|
21
|
+
"reasoning-end",
|
|
22
|
+
"file",
|
|
23
|
+
"source",
|
|
24
|
+
"tool-input-start",
|
|
25
|
+
"tool-input-delta",
|
|
26
|
+
"tool-call-approval",
|
|
27
|
+
"tool-call-suspended",
|
|
28
|
+
"tool-call",
|
|
29
|
+
"tool-result",
|
|
30
|
+
"tool-error",
|
|
31
|
+
"error",
|
|
32
|
+
"start-step",
|
|
33
|
+
"finish-step",
|
|
34
|
+
"start",
|
|
35
|
+
"finish",
|
|
36
|
+
"abort",
|
|
37
|
+
"tool-input-end",
|
|
38
|
+
"object",
|
|
39
|
+
"tripwire",
|
|
40
|
+
"raw"
|
|
41
|
+
].includes(chunk.type);
|
|
42
|
+
};
|
|
43
|
+
function safeParseErrorObject(obj) {
|
|
44
|
+
if (typeof obj !== "object" || obj === null) {
|
|
45
|
+
return String(obj);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const stringified = JSON.stringify(obj);
|
|
49
|
+
if (stringified === "{}") {
|
|
50
|
+
return String(obj);
|
|
51
|
+
}
|
|
52
|
+
return stringified;
|
|
53
|
+
} catch {
|
|
54
|
+
return String(obj);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
var isAgentExecutionDataChunkType = (chunk) => {
|
|
58
|
+
return chunk && typeof chunk === "object" && "type" in chunk && chunk.type?.startsWith("agent-execution-event-") && "payload" in chunk && typeof chunk.payload === "object" && "type" in chunk.payload && chunk.payload.type?.startsWith("data-");
|
|
59
|
+
};
|
|
60
|
+
var isWorkflowExecutionDataChunkType = (chunk) => {
|
|
61
|
+
return chunk && typeof chunk === "object" && "type" in chunk && chunk.type?.startsWith("workflow-execution-event-") && "payload" in chunk && typeof chunk.payload === "object" && "type" in chunk.payload && chunk.payload.type?.startsWith("data-");
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// src/helpers.ts
|
|
65
|
+
function toAISDKFinishReason(reason) {
|
|
66
|
+
if (reason === "tripwire" || reason === "retry") {
|
|
67
|
+
return "other";
|
|
68
|
+
}
|
|
69
|
+
return reason;
|
|
70
|
+
}
|
|
71
|
+
function convertMastraChunkToAISDKv5({
|
|
72
|
+
chunk,
|
|
73
|
+
mode = "stream"
|
|
74
|
+
}) {
|
|
75
|
+
switch (chunk.type) {
|
|
76
|
+
case "start":
|
|
77
|
+
return {
|
|
78
|
+
type: "start"
|
|
79
|
+
};
|
|
80
|
+
case "step-start":
|
|
81
|
+
const { messageId: _messageId, ...rest } = chunk.payload;
|
|
82
|
+
return {
|
|
83
|
+
type: "start-step",
|
|
84
|
+
request: rest.request,
|
|
85
|
+
warnings: rest.warnings || []
|
|
86
|
+
};
|
|
87
|
+
case "raw":
|
|
88
|
+
return {
|
|
89
|
+
type: "raw",
|
|
90
|
+
rawValue: chunk.payload
|
|
91
|
+
};
|
|
92
|
+
case "finish": {
|
|
93
|
+
return {
|
|
94
|
+
type: "finish",
|
|
95
|
+
finishReason: toAISDKFinishReason(chunk.payload.stepResult.reason),
|
|
96
|
+
totalUsage: chunk.payload.output.usage
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
case "reasoning-start":
|
|
100
|
+
return {
|
|
101
|
+
type: "reasoning-start",
|
|
102
|
+
id: chunk.payload.id,
|
|
103
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
104
|
+
};
|
|
105
|
+
case "reasoning-delta":
|
|
106
|
+
return {
|
|
107
|
+
type: "reasoning-delta",
|
|
108
|
+
id: chunk.payload.id,
|
|
109
|
+
text: chunk.payload.text,
|
|
110
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
111
|
+
};
|
|
112
|
+
case "reasoning-signature":
|
|
113
|
+
throw new Error('AISDKv5 chunk type "reasoning-signature" not supported');
|
|
114
|
+
// return {
|
|
115
|
+
// type: 'reasoning-signature' as const,
|
|
116
|
+
// id: chunk.payload.id,
|
|
117
|
+
// signature: chunk.payload.signature,
|
|
118
|
+
// };
|
|
119
|
+
case "redacted-reasoning":
|
|
120
|
+
throw new Error('AISDKv5 chunk type "redacted-reasoning" not supported');
|
|
121
|
+
// return {
|
|
122
|
+
// type: 'redacted-reasoning',
|
|
123
|
+
// id: chunk.payload.id,
|
|
124
|
+
// data: chunk.payload.data,
|
|
125
|
+
// };
|
|
126
|
+
case "reasoning-end":
|
|
127
|
+
return {
|
|
128
|
+
type: "reasoning-end",
|
|
129
|
+
id: chunk.payload.id,
|
|
130
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
131
|
+
};
|
|
132
|
+
case "source":
|
|
133
|
+
if (chunk.payload.sourceType === "url") {
|
|
134
|
+
return {
|
|
135
|
+
type: "source",
|
|
136
|
+
sourceType: "url",
|
|
137
|
+
id: chunk.payload.id,
|
|
138
|
+
url: chunk.payload.url,
|
|
139
|
+
title: chunk.payload.title,
|
|
140
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
141
|
+
};
|
|
142
|
+
} else {
|
|
143
|
+
return {
|
|
144
|
+
type: "source",
|
|
145
|
+
sourceType: "document",
|
|
146
|
+
id: chunk.payload.id,
|
|
147
|
+
mediaType: chunk.payload.mimeType,
|
|
148
|
+
title: chunk.payload.title,
|
|
149
|
+
filename: chunk.payload.filename,
|
|
150
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
case "file":
|
|
154
|
+
if (mode === "generate") {
|
|
155
|
+
return {
|
|
156
|
+
type: "file",
|
|
157
|
+
file: new DefaultGeneratedFile({
|
|
158
|
+
data: chunk.payload.data,
|
|
159
|
+
mediaType: chunk.payload.mimeType
|
|
160
|
+
})
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
type: "file",
|
|
165
|
+
file: new DefaultGeneratedFileWithType({
|
|
166
|
+
data: chunk.payload.data,
|
|
167
|
+
mediaType: chunk.payload.mimeType
|
|
168
|
+
})
|
|
169
|
+
};
|
|
170
|
+
case "tool-call":
|
|
171
|
+
return {
|
|
172
|
+
type: "tool-call",
|
|
173
|
+
toolCallId: chunk.payload.toolCallId,
|
|
174
|
+
providerMetadata: chunk.payload.providerMetadata,
|
|
175
|
+
providerExecuted: chunk.payload.providerExecuted,
|
|
176
|
+
toolName: chunk.payload.toolName,
|
|
177
|
+
input: chunk.payload.args
|
|
178
|
+
};
|
|
179
|
+
case "tool-call-approval":
|
|
180
|
+
return {
|
|
181
|
+
type: "data-tool-call-approval",
|
|
182
|
+
id: chunk.payload.toolCallId,
|
|
183
|
+
data: {
|
|
184
|
+
runId: chunk.runId,
|
|
185
|
+
toolCallId: chunk.payload.toolCallId,
|
|
186
|
+
toolName: chunk.payload.toolName,
|
|
187
|
+
args: chunk.payload.args
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
case "tool-call-suspended":
|
|
191
|
+
return {
|
|
192
|
+
type: "data-tool-call-suspended",
|
|
193
|
+
id: chunk.payload.toolCallId,
|
|
194
|
+
data: {
|
|
195
|
+
runId: chunk.runId,
|
|
196
|
+
toolCallId: chunk.payload.toolCallId,
|
|
197
|
+
toolName: chunk.payload.toolName,
|
|
198
|
+
suspendPayload: chunk.payload.suspendPayload
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
case "tool-call-input-streaming-start":
|
|
202
|
+
return {
|
|
203
|
+
type: "tool-input-start",
|
|
204
|
+
id: chunk.payload.toolCallId,
|
|
205
|
+
toolName: chunk.payload.toolName,
|
|
206
|
+
dynamic: !!chunk.payload.dynamic,
|
|
207
|
+
providerMetadata: chunk.payload.providerMetadata,
|
|
208
|
+
providerExecuted: chunk.payload.providerExecuted
|
|
209
|
+
};
|
|
210
|
+
case "tool-call-input-streaming-end":
|
|
211
|
+
return {
|
|
212
|
+
type: "tool-input-end",
|
|
213
|
+
id: chunk.payload.toolCallId,
|
|
214
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
215
|
+
};
|
|
216
|
+
case "tool-call-delta":
|
|
217
|
+
return {
|
|
218
|
+
type: "tool-input-delta",
|
|
219
|
+
id: chunk.payload.toolCallId,
|
|
220
|
+
delta: chunk.payload.argsTextDelta,
|
|
221
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
222
|
+
};
|
|
223
|
+
case "step-finish": {
|
|
224
|
+
const { request: _request, providerMetadata, ...rest2 } = chunk.payload.metadata;
|
|
225
|
+
return {
|
|
226
|
+
type: "finish-step",
|
|
227
|
+
response: {
|
|
228
|
+
id: chunk.payload.id || "",
|
|
229
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
230
|
+
modelId: rest2.modelId || "",
|
|
231
|
+
...rest2
|
|
232
|
+
},
|
|
233
|
+
usage: chunk.payload.output.usage,
|
|
234
|
+
finishReason: toAISDKFinishReason(chunk.payload.stepResult.reason),
|
|
235
|
+
providerMetadata
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
case "text-delta":
|
|
239
|
+
return {
|
|
240
|
+
type: "text-delta",
|
|
241
|
+
id: chunk.payload.id,
|
|
242
|
+
text: chunk.payload.text,
|
|
243
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
244
|
+
};
|
|
245
|
+
case "text-end":
|
|
246
|
+
return {
|
|
247
|
+
type: "text-end",
|
|
248
|
+
id: chunk.payload.id,
|
|
249
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
250
|
+
};
|
|
251
|
+
case "text-start":
|
|
252
|
+
return {
|
|
253
|
+
type: "text-start",
|
|
254
|
+
id: chunk.payload.id,
|
|
255
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
256
|
+
};
|
|
257
|
+
case "tool-result":
|
|
258
|
+
return {
|
|
259
|
+
type: "tool-result",
|
|
260
|
+
input: chunk.payload.args,
|
|
261
|
+
toolCallId: chunk.payload.toolCallId,
|
|
262
|
+
providerExecuted: chunk.payload.providerExecuted,
|
|
263
|
+
toolName: chunk.payload.toolName,
|
|
264
|
+
output: chunk.payload.result
|
|
265
|
+
// providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this?
|
|
266
|
+
};
|
|
267
|
+
case "tool-error":
|
|
268
|
+
return {
|
|
269
|
+
type: "tool-error",
|
|
270
|
+
error: chunk.payload.error,
|
|
271
|
+
input: chunk.payload.args,
|
|
272
|
+
toolCallId: chunk.payload.toolCallId,
|
|
273
|
+
providerExecuted: chunk.payload.providerExecuted,
|
|
274
|
+
toolName: chunk.payload.toolName
|
|
275
|
+
// providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this?
|
|
276
|
+
};
|
|
277
|
+
case "abort":
|
|
278
|
+
return {
|
|
279
|
+
type: "abort"
|
|
280
|
+
};
|
|
281
|
+
case "error":
|
|
282
|
+
return {
|
|
283
|
+
type: "error",
|
|
284
|
+
error: chunk.payload.error
|
|
285
|
+
};
|
|
286
|
+
case "object":
|
|
287
|
+
return {
|
|
288
|
+
type: "object",
|
|
289
|
+
object: chunk.object
|
|
290
|
+
};
|
|
291
|
+
case "tripwire":
|
|
292
|
+
return {
|
|
293
|
+
type: "data-tripwire",
|
|
294
|
+
data: {
|
|
295
|
+
reason: chunk.payload.reason,
|
|
296
|
+
retry: chunk.payload.retry,
|
|
297
|
+
metadata: chunk.payload.metadata,
|
|
298
|
+
processorId: chunk.payload.processorId
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
default:
|
|
302
|
+
if (chunk.type && "payload" in chunk && chunk.payload) {
|
|
303
|
+
return {
|
|
304
|
+
type: chunk.type,
|
|
305
|
+
...chunk.payload || {}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
if ("type" in chunk && chunk.type?.startsWith("data-")) {
|
|
309
|
+
return chunk;
|
|
310
|
+
}
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function convertFullStreamChunkToUIMessageStream({
|
|
315
|
+
part,
|
|
316
|
+
messageMetadataValue,
|
|
317
|
+
sendReasoning,
|
|
318
|
+
sendSources,
|
|
319
|
+
onError,
|
|
320
|
+
sendStart,
|
|
321
|
+
sendFinish,
|
|
322
|
+
responseMessageId
|
|
323
|
+
}) {
|
|
324
|
+
const partType = part?.type;
|
|
325
|
+
switch (partType) {
|
|
326
|
+
case "text-start": {
|
|
327
|
+
return {
|
|
328
|
+
type: "text-start",
|
|
329
|
+
id: part.id,
|
|
330
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
case "text-delta": {
|
|
334
|
+
return {
|
|
335
|
+
type: "text-delta",
|
|
336
|
+
id: part.id,
|
|
337
|
+
delta: part.text,
|
|
338
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
case "text-end": {
|
|
342
|
+
return {
|
|
343
|
+
type: "text-end",
|
|
344
|
+
id: part.id,
|
|
345
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
case "reasoning-start": {
|
|
349
|
+
return {
|
|
350
|
+
type: "reasoning-start",
|
|
351
|
+
id: part.id,
|
|
352
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
case "reasoning-delta": {
|
|
356
|
+
if (sendReasoning) {
|
|
357
|
+
return {
|
|
358
|
+
type: "reasoning-delta",
|
|
359
|
+
id: part.id,
|
|
360
|
+
delta: part.text,
|
|
361
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
case "reasoning-end": {
|
|
367
|
+
return {
|
|
368
|
+
type: "reasoning-end",
|
|
369
|
+
id: part.id,
|
|
370
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
case "file": {
|
|
374
|
+
return {
|
|
375
|
+
type: "file",
|
|
376
|
+
mediaType: part.file.mediaType,
|
|
377
|
+
url: `data:${part.file.mediaType};base64,${part.file.base64}`
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
case "source": {
|
|
381
|
+
if (sendSources && part.sourceType === "url") {
|
|
382
|
+
return {
|
|
383
|
+
type: "source-url",
|
|
384
|
+
sourceId: part.id,
|
|
385
|
+
url: part.url,
|
|
386
|
+
title: part.title,
|
|
387
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
if (sendSources && part.sourceType === "document") {
|
|
391
|
+
return {
|
|
392
|
+
type: "source-document",
|
|
393
|
+
sourceId: part.id,
|
|
394
|
+
mediaType: part.mediaType,
|
|
395
|
+
title: part.title,
|
|
396
|
+
filename: part.filename,
|
|
397
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
case "tool-input-start": {
|
|
403
|
+
return {
|
|
404
|
+
type: "tool-input-start",
|
|
405
|
+
toolCallId: part.id,
|
|
406
|
+
toolName: part.toolName,
|
|
407
|
+
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
408
|
+
...part.dynamic != null ? { dynamic: part.dynamic } : {}
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
case "tool-input-delta": {
|
|
412
|
+
return {
|
|
413
|
+
type: "tool-input-delta",
|
|
414
|
+
toolCallId: part.id,
|
|
415
|
+
inputTextDelta: part.delta
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
case "tool-call": {
|
|
419
|
+
return {
|
|
420
|
+
type: "tool-input-available",
|
|
421
|
+
toolCallId: part.toolCallId,
|
|
422
|
+
toolName: part.toolName,
|
|
423
|
+
input: part.input,
|
|
424
|
+
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
425
|
+
...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
|
|
426
|
+
...part.dynamic != null ? { dynamic: part.dynamic } : {}
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
case "tool-result": {
|
|
430
|
+
return {
|
|
431
|
+
type: "tool-output-available",
|
|
432
|
+
toolCallId: part.toolCallId,
|
|
433
|
+
output: part.output,
|
|
434
|
+
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
435
|
+
...part.dynamic != null ? { dynamic: part.dynamic } : {}
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
case "tool-output": {
|
|
439
|
+
if (part.output.from === "AGENT") {
|
|
440
|
+
return {
|
|
441
|
+
type: "tool-agent",
|
|
442
|
+
toolCallId: part.toolCallId,
|
|
443
|
+
payload: part.output
|
|
444
|
+
};
|
|
445
|
+
} else if (part.output.from === "WORKFLOW") {
|
|
446
|
+
return {
|
|
447
|
+
type: "tool-workflow",
|
|
448
|
+
toolCallId: part.toolCallId,
|
|
449
|
+
payload: part.output
|
|
450
|
+
};
|
|
451
|
+
} else if (part.output.from === "NETWORK") {
|
|
452
|
+
return {
|
|
453
|
+
type: "tool-network",
|
|
454
|
+
toolCallId: part.toolCallId,
|
|
455
|
+
payload: part.output
|
|
456
|
+
};
|
|
457
|
+
} else if (isDataChunkType(part.output)) {
|
|
458
|
+
if (!("data" in part.output)) {
|
|
459
|
+
throw new Error(
|
|
460
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
461
|
+
${JSON.stringify(part)}`
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
return part.output;
|
|
465
|
+
}
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
case "tool-error": {
|
|
469
|
+
return {
|
|
470
|
+
type: "tool-output-error",
|
|
471
|
+
toolCallId: part.toolCallId,
|
|
472
|
+
errorText: onError(part.error),
|
|
473
|
+
...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
|
|
474
|
+
...part.dynamic != null ? { dynamic: part.dynamic } : {}
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
case "error": {
|
|
478
|
+
return {
|
|
479
|
+
type: "error",
|
|
480
|
+
errorText: onError(part.error)
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
case "start-step": {
|
|
484
|
+
return { type: "start-step" };
|
|
485
|
+
}
|
|
486
|
+
case "finish-step": {
|
|
487
|
+
return { type: "finish-step" };
|
|
488
|
+
}
|
|
489
|
+
case "start": {
|
|
490
|
+
if (sendStart) {
|
|
491
|
+
return {
|
|
492
|
+
type: "start",
|
|
493
|
+
...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {},
|
|
494
|
+
...responseMessageId != null ? { messageId: responseMessageId } : {}
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
case "finish": {
|
|
500
|
+
if (sendFinish) {
|
|
501
|
+
return {
|
|
502
|
+
type: "finish",
|
|
503
|
+
...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
case "abort": {
|
|
509
|
+
return part;
|
|
510
|
+
}
|
|
511
|
+
case "tool-input-end": {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
case "raw": {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
default: {
|
|
518
|
+
if (isDataChunkType(part)) {
|
|
519
|
+
if (!("data" in part)) {
|
|
520
|
+
throw new Error(
|
|
521
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
522
|
+
${JSON.stringify(part)}`
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
return part;
|
|
526
|
+
}
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// src/transformers.ts
|
|
533
|
+
var PRIMITIVE_CACHE_SYMBOL = Symbol("primitive-cache");
|
|
534
|
+
function WorkflowStreamToAISDKTransformer({
|
|
535
|
+
includeTextStreamParts
|
|
536
|
+
} = {}) {
|
|
537
|
+
const bufferedWorkflows = /* @__PURE__ */ new Map();
|
|
538
|
+
return new TransformStream({
|
|
539
|
+
start(controller) {
|
|
540
|
+
controller.enqueue({
|
|
541
|
+
type: "start"
|
|
542
|
+
});
|
|
543
|
+
},
|
|
544
|
+
flush(controller) {
|
|
545
|
+
controller.enqueue({
|
|
546
|
+
type: "finish"
|
|
547
|
+
});
|
|
548
|
+
},
|
|
549
|
+
transform(chunk, controller) {
|
|
550
|
+
const transformed = transformWorkflow(chunk, bufferedWorkflows, false, includeTextStreamParts);
|
|
551
|
+
if (transformed) controller.enqueue(transformed);
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
function AgentNetworkToAISDKTransformer() {
|
|
556
|
+
const bufferedNetworks = /* @__PURE__ */ new Map();
|
|
557
|
+
return new TransformStream({
|
|
558
|
+
start(controller) {
|
|
559
|
+
controller.enqueue({
|
|
560
|
+
type: "start"
|
|
561
|
+
});
|
|
562
|
+
},
|
|
563
|
+
flush(controller) {
|
|
564
|
+
controller.enqueue({
|
|
565
|
+
type: "finish"
|
|
566
|
+
});
|
|
567
|
+
},
|
|
568
|
+
transform(chunk, controller) {
|
|
569
|
+
const transformed = transformNetwork(chunk, bufferedNetworks);
|
|
570
|
+
if (transformed) controller.enqueue(transformed);
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
function AgentStreamToAISDKTransformer({
|
|
575
|
+
lastMessageId,
|
|
576
|
+
sendStart,
|
|
577
|
+
sendFinish,
|
|
578
|
+
sendReasoning,
|
|
579
|
+
sendSources,
|
|
580
|
+
messageMetadata,
|
|
581
|
+
onError
|
|
582
|
+
}) {
|
|
583
|
+
let bufferedSteps = /* @__PURE__ */ new Map();
|
|
584
|
+
let tripwireOccurred = false;
|
|
585
|
+
let finishEventSent = false;
|
|
586
|
+
return new TransformStream({
|
|
587
|
+
transform(chunk, controller) {
|
|
588
|
+
if (chunk.type === "tripwire") {
|
|
589
|
+
tripwireOccurred = true;
|
|
590
|
+
}
|
|
591
|
+
if (chunk.type === "finish") {
|
|
592
|
+
finishEventSent = true;
|
|
593
|
+
}
|
|
594
|
+
const part = convertMastraChunkToAISDKv5({ chunk, mode: "stream" });
|
|
595
|
+
const transformedChunk = convertFullStreamChunkToUIMessageStream({
|
|
596
|
+
part,
|
|
597
|
+
sendReasoning,
|
|
598
|
+
sendSources,
|
|
599
|
+
messageMetadataValue: messageMetadata?.({ part }),
|
|
600
|
+
sendStart,
|
|
601
|
+
sendFinish,
|
|
602
|
+
responseMessageId: lastMessageId,
|
|
603
|
+
onError(error) {
|
|
604
|
+
return onError ? onError(error) : safeParseErrorObject(error);
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
if (transformedChunk) {
|
|
608
|
+
if (transformedChunk.type === "tool-agent") {
|
|
609
|
+
const payload = transformedChunk.payload;
|
|
610
|
+
const agentTransformed = transformAgent(payload, bufferedSteps);
|
|
611
|
+
if (agentTransformed) controller.enqueue(agentTransformed);
|
|
612
|
+
} else if (transformedChunk.type === "tool-workflow") {
|
|
613
|
+
const payload = transformedChunk.payload;
|
|
614
|
+
const workflowChunk = transformWorkflow(payload, bufferedSteps, true);
|
|
615
|
+
if (workflowChunk) controller.enqueue(workflowChunk);
|
|
616
|
+
} else if (transformedChunk.type === "tool-network") {
|
|
617
|
+
const payload = transformedChunk.payload;
|
|
618
|
+
const networkChunk = transformNetwork(payload, bufferedSteps, true);
|
|
619
|
+
if (networkChunk) controller.enqueue(networkChunk);
|
|
620
|
+
} else {
|
|
621
|
+
controller.enqueue(transformedChunk);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
flush(controller) {
|
|
626
|
+
if (tripwireOccurred && !finishEventSent && sendFinish) {
|
|
627
|
+
controller.enqueue({
|
|
628
|
+
type: "finish",
|
|
629
|
+
finishReason: "other"
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
function transformAgent(payload, bufferedSteps) {
|
|
636
|
+
let hasChanged = false;
|
|
637
|
+
switch (payload.type) {
|
|
638
|
+
case "start":
|
|
639
|
+
bufferedSteps.set(payload.runId, {
|
|
640
|
+
id: payload.payload.id,
|
|
641
|
+
object: null,
|
|
642
|
+
finishReason: null,
|
|
643
|
+
usage: null,
|
|
644
|
+
warnings: [],
|
|
645
|
+
text: "",
|
|
646
|
+
reasoning: [],
|
|
647
|
+
sources: [],
|
|
648
|
+
files: [],
|
|
649
|
+
toolCalls: [],
|
|
650
|
+
toolResults: [],
|
|
651
|
+
request: {},
|
|
652
|
+
response: {
|
|
653
|
+
id: "",
|
|
654
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
655
|
+
modelId: "",
|
|
656
|
+
messages: []
|
|
657
|
+
},
|
|
658
|
+
providerMetadata: void 0,
|
|
659
|
+
steps: [],
|
|
660
|
+
status: "running"
|
|
661
|
+
});
|
|
662
|
+
hasChanged = true;
|
|
663
|
+
break;
|
|
664
|
+
case "finish":
|
|
665
|
+
bufferedSteps.set(payload.runId, {
|
|
666
|
+
...bufferedSteps.get(payload.runId),
|
|
667
|
+
finishReason: payload.payload.stepResult.reason,
|
|
668
|
+
usage: payload.payload?.output?.usage,
|
|
669
|
+
warnings: payload.payload?.stepResult?.warnings,
|
|
670
|
+
steps: bufferedSteps.get(payload.runId).steps,
|
|
671
|
+
status: "finished"
|
|
672
|
+
});
|
|
673
|
+
hasChanged = true;
|
|
674
|
+
break;
|
|
675
|
+
case "text-delta":
|
|
676
|
+
const prevData = bufferedSteps.get(payload.runId);
|
|
677
|
+
bufferedSteps.set(payload.runId, {
|
|
678
|
+
...prevData,
|
|
679
|
+
text: `${prevData.text}${payload.payload.text}`
|
|
680
|
+
});
|
|
681
|
+
hasChanged = true;
|
|
682
|
+
break;
|
|
683
|
+
case "reasoning-delta":
|
|
684
|
+
bufferedSteps.set(payload.runId, {
|
|
685
|
+
...bufferedSteps.get(payload.runId),
|
|
686
|
+
reasoning: [...bufferedSteps.get(payload.runId).reasoning, payload.payload.text]
|
|
687
|
+
});
|
|
688
|
+
hasChanged = true;
|
|
689
|
+
break;
|
|
690
|
+
case "source":
|
|
691
|
+
bufferedSteps.set(payload.runId, {
|
|
692
|
+
...bufferedSteps.get(payload.runId),
|
|
693
|
+
sources: [...bufferedSteps.get(payload.runId).sources, payload.payload]
|
|
694
|
+
});
|
|
695
|
+
hasChanged = true;
|
|
696
|
+
break;
|
|
697
|
+
case "file":
|
|
698
|
+
bufferedSteps.set(payload.runId, {
|
|
699
|
+
...bufferedSteps.get(payload.runId),
|
|
700
|
+
files: [...bufferedSteps.get(payload.runId).files, payload.payload]
|
|
701
|
+
});
|
|
702
|
+
hasChanged = true;
|
|
703
|
+
break;
|
|
704
|
+
case "tool-call":
|
|
705
|
+
bufferedSteps.set(payload.runId, {
|
|
706
|
+
...bufferedSteps.get(payload.runId),
|
|
707
|
+
toolCalls: [...bufferedSteps.get(payload.runId).toolCalls, payload.payload]
|
|
708
|
+
});
|
|
709
|
+
hasChanged = true;
|
|
710
|
+
break;
|
|
711
|
+
case "tool-result":
|
|
712
|
+
bufferedSteps.set(payload.runId, {
|
|
713
|
+
...bufferedSteps.get(payload.runId),
|
|
714
|
+
toolResults: [...bufferedSteps.get(payload.runId).toolResults, payload.payload]
|
|
715
|
+
});
|
|
716
|
+
hasChanged = true;
|
|
717
|
+
break;
|
|
718
|
+
case "object-result":
|
|
719
|
+
bufferedSteps.set(payload.runId, {
|
|
720
|
+
...bufferedSteps.get(payload.runId),
|
|
721
|
+
object: payload.object
|
|
722
|
+
});
|
|
723
|
+
hasChanged = true;
|
|
724
|
+
break;
|
|
725
|
+
case "object":
|
|
726
|
+
bufferedSteps.set(payload.runId, {
|
|
727
|
+
...bufferedSteps.get(payload.runId),
|
|
728
|
+
object: payload.object
|
|
729
|
+
});
|
|
730
|
+
hasChanged = true;
|
|
731
|
+
break;
|
|
732
|
+
case "step-finish":
|
|
733
|
+
const currentRun = bufferedSteps.get(payload.runId);
|
|
734
|
+
const stepResult = {
|
|
735
|
+
...bufferedSteps.get(payload.runId),
|
|
736
|
+
stepType: currentRun.steps.length === 0 ? "initial" : "tool-result",
|
|
737
|
+
reasoningText: bufferedSteps.get(payload.runId).reasoning.join(""),
|
|
738
|
+
staticToolCalls: bufferedSteps.get(payload.runId).toolCalls.filter((part) => part.type === "tool-call" && part.payload?.dynamic === false),
|
|
739
|
+
dynamicToolCalls: bufferedSteps.get(payload.runId).toolCalls.filter((part) => part.type === "tool-call" && part.payload?.dynamic === true),
|
|
740
|
+
staticToolResults: bufferedSteps.get(payload.runId).toolResults.filter((part) => part.type === "tool-result" && part.payload?.dynamic === false),
|
|
741
|
+
dynamicToolResults: bufferedSteps.get(payload.runId).toolResults.filter((part) => part.type === "tool-result" && part.payload?.dynamic === true),
|
|
742
|
+
finishReason: payload.payload.stepResult.reason,
|
|
743
|
+
usage: payload.payload.output.usage,
|
|
744
|
+
warnings: payload.payload.stepResult.warnings || [],
|
|
745
|
+
response: {
|
|
746
|
+
id: payload.payload.id || "",
|
|
747
|
+
timestamp: payload.payload.metadata?.timestamp || /* @__PURE__ */ new Date(),
|
|
748
|
+
modelId: payload.payload.metadata?.modelId || payload.payload.metadata?.model || "",
|
|
749
|
+
...bufferedSteps.get(payload.runId).response,
|
|
750
|
+
messages: bufferedSteps.get(payload.runId).response.messages || []
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
bufferedSteps.set(payload.runId, {
|
|
754
|
+
...bufferedSteps.get(payload.runId),
|
|
755
|
+
usage: payload.payload.output.usage,
|
|
756
|
+
warnings: payload.payload.stepResult.warnings || [],
|
|
757
|
+
steps: [...bufferedSteps.get(payload.runId).steps, stepResult]
|
|
758
|
+
});
|
|
759
|
+
hasChanged = true;
|
|
760
|
+
break;
|
|
761
|
+
}
|
|
762
|
+
if (hasChanged) {
|
|
763
|
+
return {
|
|
764
|
+
type: "data-tool-agent",
|
|
765
|
+
id: payload.runId,
|
|
766
|
+
data: bufferedSteps.get(payload.runId)
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStreamParts) {
|
|
772
|
+
switch (payload.type) {
|
|
773
|
+
case "workflow-start":
|
|
774
|
+
bufferedWorkflows.set(payload.runId, {
|
|
775
|
+
name: payload.payload.workflowId,
|
|
776
|
+
steps: {}
|
|
777
|
+
});
|
|
778
|
+
return {
|
|
779
|
+
type: isNested ? "data-tool-workflow" : "data-workflow",
|
|
780
|
+
id: payload.runId,
|
|
781
|
+
data: {
|
|
782
|
+
name: bufferedWorkflows.get(payload.runId).name,
|
|
783
|
+
status: "running",
|
|
784
|
+
steps: bufferedWorkflows.get(payload.runId).steps,
|
|
785
|
+
output: null
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
case "workflow-step-start": {
|
|
789
|
+
const current = bufferedWorkflows.get(payload.runId) || { name: "", steps: {} };
|
|
790
|
+
current.steps[payload.payload.id] = {
|
|
791
|
+
name: payload.payload.id,
|
|
792
|
+
status: payload.payload.status,
|
|
793
|
+
input: payload.payload.payload ?? null,
|
|
794
|
+
output: null,
|
|
795
|
+
suspendPayload: null,
|
|
796
|
+
resumePayload: null
|
|
797
|
+
};
|
|
798
|
+
bufferedWorkflows.set(payload.runId, current);
|
|
799
|
+
return {
|
|
800
|
+
type: isNested ? "data-tool-workflow" : "data-workflow",
|
|
801
|
+
id: payload.runId,
|
|
802
|
+
data: {
|
|
803
|
+
name: current.name,
|
|
804
|
+
status: "running",
|
|
805
|
+
steps: current.steps,
|
|
806
|
+
output: null
|
|
807
|
+
}
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
case "workflow-step-result": {
|
|
811
|
+
const current = bufferedWorkflows.get(payload.runId);
|
|
812
|
+
if (!current) return null;
|
|
813
|
+
current.steps[payload.payload.id] = {
|
|
814
|
+
...current.steps[payload.payload.id],
|
|
815
|
+
status: payload.payload.status,
|
|
816
|
+
output: payload.payload.output ?? null
|
|
817
|
+
};
|
|
818
|
+
return {
|
|
819
|
+
type: isNested ? "data-tool-workflow" : "data-workflow",
|
|
820
|
+
id: payload.runId,
|
|
821
|
+
data: {
|
|
822
|
+
name: current.name,
|
|
823
|
+
status: "running",
|
|
824
|
+
steps: current.steps,
|
|
825
|
+
output: null
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
case "workflow-step-suspended": {
|
|
830
|
+
const current = bufferedWorkflows.get(payload.runId);
|
|
831
|
+
if (!current) return null;
|
|
832
|
+
current.steps[payload.payload.id] = {
|
|
833
|
+
...current.steps[payload.payload.id],
|
|
834
|
+
status: payload.payload.status,
|
|
835
|
+
suspendPayload: payload.payload.suspendPayload ?? null,
|
|
836
|
+
resumePayload: payload.payload.resumePayload ?? null,
|
|
837
|
+
output: null
|
|
838
|
+
};
|
|
839
|
+
return {
|
|
840
|
+
type: isNested ? "data-tool-workflow" : "data-workflow",
|
|
841
|
+
id: payload.runId,
|
|
842
|
+
data: {
|
|
843
|
+
name: current.name,
|
|
844
|
+
status: "suspended",
|
|
845
|
+
steps: current.steps,
|
|
846
|
+
output: null
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
case "workflow-finish": {
|
|
851
|
+
const current = bufferedWorkflows.get(payload.runId);
|
|
852
|
+
if (!current) return null;
|
|
853
|
+
return {
|
|
854
|
+
type: isNested ? "data-tool-workflow" : "data-workflow",
|
|
855
|
+
id: payload.runId,
|
|
856
|
+
data: {
|
|
857
|
+
name: current.name,
|
|
858
|
+
steps: current.steps,
|
|
859
|
+
output: payload.payload.output ?? null,
|
|
860
|
+
status: payload.payload.workflowStatus
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
case "workflow-step-output": {
|
|
865
|
+
const output = payload.payload.output;
|
|
866
|
+
if (includeTextStreamParts && output && isMastraTextStreamChunk(output)) {
|
|
867
|
+
const part = convertMastraChunkToAISDKv5({ chunk: output, mode: "stream" });
|
|
868
|
+
const transformedChunk = convertFullStreamChunkToUIMessageStream({
|
|
869
|
+
part,
|
|
870
|
+
onError(error) {
|
|
871
|
+
return safeParseErrorObject(error);
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
return transformedChunk;
|
|
875
|
+
}
|
|
876
|
+
if (output && isDataChunkType(output)) {
|
|
877
|
+
if (!("data" in output)) {
|
|
878
|
+
throw new Error(
|
|
879
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
880
|
+
${JSON.stringify(output)}`
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
return output;
|
|
884
|
+
}
|
|
885
|
+
return null;
|
|
886
|
+
}
|
|
887
|
+
default: {
|
|
888
|
+
if (isDataChunkType(payload)) {
|
|
889
|
+
if (!("data" in payload)) {
|
|
890
|
+
throw new Error(
|
|
891
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
892
|
+
${JSON.stringify(payload)}`
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
return payload;
|
|
896
|
+
}
|
|
897
|
+
return null;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
902
|
+
switch (payload.type) {
|
|
903
|
+
case "routing-agent-start": {
|
|
904
|
+
if (!bufferedNetworks.has(payload.runId)) {
|
|
905
|
+
bufferedNetworks.set(payload.runId, {
|
|
906
|
+
name: payload.payload.networkId,
|
|
907
|
+
steps: [],
|
|
908
|
+
usage: null,
|
|
909
|
+
output: null
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
913
|
+
current.steps.push({
|
|
914
|
+
id: payload.payload.runId,
|
|
915
|
+
name: payload.payload.agentId,
|
|
916
|
+
status: "running",
|
|
917
|
+
iteration: payload.payload.inputData.iteration,
|
|
918
|
+
input: {
|
|
919
|
+
task: payload.payload.inputData.task,
|
|
920
|
+
threadId: payload.payload.inputData.threadId,
|
|
921
|
+
threadResourceId: payload.payload.inputData.threadResourceId
|
|
922
|
+
},
|
|
923
|
+
output: "",
|
|
924
|
+
task: null,
|
|
925
|
+
suspendPayload: null,
|
|
926
|
+
resumePayload: null,
|
|
927
|
+
[PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
|
|
928
|
+
});
|
|
929
|
+
return {
|
|
930
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
931
|
+
id: payload.runId,
|
|
932
|
+
data: {
|
|
933
|
+
name: bufferedNetworks.get(payload.runId).name,
|
|
934
|
+
status: "running",
|
|
935
|
+
usage: null,
|
|
936
|
+
steps: bufferedNetworks.get(payload.runId).steps,
|
|
937
|
+
output: null
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
case "routing-agent-text-start": {
|
|
942
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
943
|
+
if (!current) return null;
|
|
944
|
+
return {
|
|
945
|
+
type: "text-start",
|
|
946
|
+
id: payload.runId
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
case "routing-agent-text-delta": {
|
|
950
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
951
|
+
if (!current) return null;
|
|
952
|
+
return {
|
|
953
|
+
type: "text-delta",
|
|
954
|
+
id: payload.runId,
|
|
955
|
+
delta: payload.payload.text
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
case "agent-execution-start": {
|
|
959
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
960
|
+
if (!current) return null;
|
|
961
|
+
current.steps.push({
|
|
962
|
+
id: payload.payload.runId,
|
|
963
|
+
name: payload.payload.agentId,
|
|
964
|
+
status: "running",
|
|
965
|
+
iteration: payload.payload.args?.iteration ?? 0,
|
|
966
|
+
input: { prompt: payload.payload.args?.prompt ?? "" },
|
|
967
|
+
output: null,
|
|
968
|
+
task: null,
|
|
969
|
+
suspendPayload: null,
|
|
970
|
+
resumePayload: null,
|
|
971
|
+
[PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
|
|
972
|
+
});
|
|
973
|
+
bufferedNetworks.set(payload.runId, current);
|
|
974
|
+
return {
|
|
975
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
976
|
+
id: payload.runId,
|
|
977
|
+
data: {
|
|
978
|
+
...current,
|
|
979
|
+
status: "running"
|
|
980
|
+
}
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
case "workflow-execution-start": {
|
|
984
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
985
|
+
if (!current) return null;
|
|
986
|
+
current.steps.push({
|
|
987
|
+
id: payload.payload.runId,
|
|
988
|
+
name: payload.payload.workflowId,
|
|
989
|
+
status: "running",
|
|
990
|
+
iteration: payload.payload.args?.iteration ?? 0,
|
|
991
|
+
input: { prompt: payload.payload.args?.prompt ?? "" },
|
|
992
|
+
output: null,
|
|
993
|
+
task: null,
|
|
994
|
+
suspendPayload: null,
|
|
995
|
+
resumePayload: null,
|
|
996
|
+
[PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
|
|
997
|
+
});
|
|
998
|
+
bufferedNetworks.set(payload.runId, current);
|
|
999
|
+
return {
|
|
1000
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1001
|
+
id: payload.runId,
|
|
1002
|
+
data: {
|
|
1003
|
+
...current,
|
|
1004
|
+
status: "running"
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
case "tool-execution-start": {
|
|
1009
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1010
|
+
if (!current) return null;
|
|
1011
|
+
current.steps.push({
|
|
1012
|
+
id: payload.payload.args.toolCallId,
|
|
1013
|
+
name: payload.payload.args?.toolName,
|
|
1014
|
+
status: "running",
|
|
1015
|
+
iteration: payload.payload.args?.iteration ? Number(payload.payload.args.iteration) : 0,
|
|
1016
|
+
task: {
|
|
1017
|
+
id: payload.payload.args?.toolName
|
|
1018
|
+
},
|
|
1019
|
+
input: payload.payload.args?.args || null,
|
|
1020
|
+
output: null,
|
|
1021
|
+
suspendPayload: null,
|
|
1022
|
+
resumePayload: null,
|
|
1023
|
+
[PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
|
|
1024
|
+
});
|
|
1025
|
+
bufferedNetworks.set(payload.runId, current);
|
|
1026
|
+
return {
|
|
1027
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1028
|
+
id: payload.runId,
|
|
1029
|
+
data: {
|
|
1030
|
+
...current,
|
|
1031
|
+
status: "running"
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
case "agent-execution-end": {
|
|
1036
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1037
|
+
if (!current) return null;
|
|
1038
|
+
const stepId = payload.payload.runId;
|
|
1039
|
+
const step = current.steps.find((step2) => step2.id === stepId);
|
|
1040
|
+
if (!step) {
|
|
1041
|
+
return null;
|
|
1042
|
+
}
|
|
1043
|
+
step.status = "success";
|
|
1044
|
+
step.output = payload.payload.result;
|
|
1045
|
+
return {
|
|
1046
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1047
|
+
id: payload.runId,
|
|
1048
|
+
data: {
|
|
1049
|
+
...current,
|
|
1050
|
+
usage: payload.payload?.usage ?? current.usage,
|
|
1051
|
+
status: "running",
|
|
1052
|
+
output: payload.payload.result ?? current.output
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
case "tool-execution-end": {
|
|
1057
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1058
|
+
if (!current) return null;
|
|
1059
|
+
const stepId = payload.payload.toolCallId;
|
|
1060
|
+
const step = current.steps.find((step2) => step2.id === stepId);
|
|
1061
|
+
if (!step) {
|
|
1062
|
+
return null;
|
|
1063
|
+
}
|
|
1064
|
+
step.status = "success";
|
|
1065
|
+
step.output = payload.payload.result;
|
|
1066
|
+
return {
|
|
1067
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1068
|
+
id: payload.runId,
|
|
1069
|
+
data: {
|
|
1070
|
+
...current,
|
|
1071
|
+
status: "running",
|
|
1072
|
+
output: payload.payload.result ?? current.output
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
case "workflow-execution-end": {
|
|
1077
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1078
|
+
if (!current) return null;
|
|
1079
|
+
const stepId = payload.payload.runId;
|
|
1080
|
+
const step = current.steps.find((step2) => step2.id === stepId);
|
|
1081
|
+
if (!step) {
|
|
1082
|
+
return null;
|
|
1083
|
+
}
|
|
1084
|
+
step.status = "success";
|
|
1085
|
+
step.output = payload.payload.result;
|
|
1086
|
+
return {
|
|
1087
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1088
|
+
id: payload.runId,
|
|
1089
|
+
data: {
|
|
1090
|
+
...current,
|
|
1091
|
+
usage: payload.payload?.usage ?? current.usage,
|
|
1092
|
+
status: "running",
|
|
1093
|
+
output: payload.payload.result ?? current.output
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
case "routing-agent-end": {
|
|
1098
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1099
|
+
if (!current) return null;
|
|
1100
|
+
const stepId = payload.payload.runId;
|
|
1101
|
+
const step = current.steps.find((step2) => step2.id === stepId);
|
|
1102
|
+
if (!step) {
|
|
1103
|
+
return null;
|
|
1104
|
+
}
|
|
1105
|
+
step.status = "success";
|
|
1106
|
+
step.task = {
|
|
1107
|
+
id: payload.payload.primitiveId,
|
|
1108
|
+
type: payload.payload.primitiveType,
|
|
1109
|
+
name: payload.payload.task,
|
|
1110
|
+
reason: payload.payload.selectionReason
|
|
1111
|
+
};
|
|
1112
|
+
step.output = payload.payload.result;
|
|
1113
|
+
return {
|
|
1114
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1115
|
+
id: payload.runId,
|
|
1116
|
+
data: {
|
|
1117
|
+
...current,
|
|
1118
|
+
usage: payload.payload?.usage ?? current.usage,
|
|
1119
|
+
output: payload.payload?.result ?? current.output
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
case "network-execution-event-step-finish": {
|
|
1124
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1125
|
+
if (!current) return null;
|
|
1126
|
+
return {
|
|
1127
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1128
|
+
id: payload.runId,
|
|
1129
|
+
data: {
|
|
1130
|
+
...current,
|
|
1131
|
+
status: "finished",
|
|
1132
|
+
output: payload.payload?.result ?? current.output
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
case "network-execution-event-finish": {
|
|
1137
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1138
|
+
if (!current) return null;
|
|
1139
|
+
return {
|
|
1140
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1141
|
+
id: payload.runId,
|
|
1142
|
+
data: {
|
|
1143
|
+
...current,
|
|
1144
|
+
usage: payload.payload?.usage ?? current.usage,
|
|
1145
|
+
status: "finished",
|
|
1146
|
+
output: payload.payload?.result ?? current.output
|
|
1147
|
+
}
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
default: {
|
|
1151
|
+
if (isAgentExecutionDataChunkType(payload)) {
|
|
1152
|
+
if (!("data" in payload.payload)) {
|
|
1153
|
+
throw new Error(
|
|
1154
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
1155
|
+
${JSON.stringify(payload)}`
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
const { type, data } = payload.payload;
|
|
1159
|
+
return { type, data };
|
|
1160
|
+
}
|
|
1161
|
+
if (isWorkflowExecutionDataChunkType(payload)) {
|
|
1162
|
+
if (!("data" in payload.payload)) {
|
|
1163
|
+
throw new Error(
|
|
1164
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
1165
|
+
${JSON.stringify(payload)}`
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
const { type, data } = payload.payload;
|
|
1169
|
+
return { type, data };
|
|
1170
|
+
}
|
|
1171
|
+
if (payload.type.startsWith("agent-execution-event-")) {
|
|
1172
|
+
const stepId = payload.payload.runId;
|
|
1173
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1174
|
+
if (!current) return null;
|
|
1175
|
+
const step = current.steps.find((step2) => step2.id === stepId);
|
|
1176
|
+
if (!step) {
|
|
1177
|
+
return null;
|
|
1178
|
+
}
|
|
1179
|
+
step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
|
|
1180
|
+
const result = transformAgent(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
|
|
1181
|
+
if (result) {
|
|
1182
|
+
const { request, response, ...data } = result.data;
|
|
1183
|
+
step.task = data;
|
|
1184
|
+
}
|
|
1185
|
+
bufferedNetworks.set(payload.runId, current);
|
|
1186
|
+
return {
|
|
1187
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1188
|
+
id: payload.runId,
|
|
1189
|
+
data: {
|
|
1190
|
+
...current,
|
|
1191
|
+
status: "running"
|
|
1192
|
+
}
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
if (payload.type.startsWith("workflow-execution-event-")) {
|
|
1196
|
+
const stepId = payload.payload.runId;
|
|
1197
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
1198
|
+
if (!current) return null;
|
|
1199
|
+
const step = current.steps.find((step2) => step2.id === stepId);
|
|
1200
|
+
if (!step) {
|
|
1201
|
+
return null;
|
|
1202
|
+
}
|
|
1203
|
+
step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
|
|
1204
|
+
const result = transformWorkflow(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
|
|
1205
|
+
if (result && "data" in result) {
|
|
1206
|
+
const data = result.data;
|
|
1207
|
+
step.task = data;
|
|
1208
|
+
if (data.name && step.task) {
|
|
1209
|
+
step.task.id = data.name;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
bufferedNetworks.set(payload.runId, current);
|
|
1213
|
+
return {
|
|
1214
|
+
type: isNested ? "data-tool-network" : "data-network",
|
|
1215
|
+
id: payload.runId,
|
|
1216
|
+
data: {
|
|
1217
|
+
...current,
|
|
1218
|
+
status: "running"
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
if (isDataChunkType(payload)) {
|
|
1223
|
+
if (!("data" in payload)) {
|
|
1224
|
+
throw new Error(
|
|
1225
|
+
`UI Messages require a data property when using data- prefixed chunks
|
|
1226
|
+
${JSON.stringify(payload)}`
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
const { type, data } = payload;
|
|
1230
|
+
return { type, data };
|
|
1231
|
+
}
|
|
1232
|
+
return null;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
// src/convert-streams.ts
|
|
1238
|
+
function toAISdkV5Stream(stream, options = {
|
|
1239
|
+
from: "agent",
|
|
1240
|
+
sendStart: true,
|
|
1241
|
+
sendFinish: true
|
|
1242
|
+
}) {
|
|
1243
|
+
const from = options?.from;
|
|
1244
|
+
if (from === "workflow") {
|
|
1245
|
+
const includeTextStreamParts = options?.includeTextStreamParts ?? true;
|
|
1246
|
+
return stream.pipeThrough(
|
|
1247
|
+
WorkflowStreamToAISDKTransformer({ includeTextStreamParts })
|
|
1248
|
+
);
|
|
1249
|
+
}
|
|
1250
|
+
if (from === "network") {
|
|
1251
|
+
return stream.pipeThrough(AgentNetworkToAISDKTransformer());
|
|
1252
|
+
}
|
|
1253
|
+
const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
|
|
1254
|
+
return agentReadable.pipeThrough(
|
|
1255
|
+
AgentStreamToAISDKTransformer({
|
|
1256
|
+
lastMessageId: options?.lastMessageId,
|
|
1257
|
+
sendStart: options?.sendStart,
|
|
1258
|
+
sendFinish: options?.sendFinish,
|
|
1259
|
+
sendReasoning: options?.sendReasoning,
|
|
1260
|
+
sendSources: options?.sendSources,
|
|
1261
|
+
messageMetadata: options?.messageMetadata,
|
|
1262
|
+
onError: options?.onError
|
|
1263
|
+
})
|
|
1264
|
+
);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// src/chat-route.ts
|
|
1268
|
+
async function handleChatStream({
|
|
1269
|
+
mastra,
|
|
1270
|
+
agentId,
|
|
1271
|
+
params,
|
|
1272
|
+
defaultOptions,
|
|
1273
|
+
sendStart = true,
|
|
1274
|
+
sendFinish = true,
|
|
1275
|
+
sendReasoning = false,
|
|
1276
|
+
sendSources = false
|
|
1277
|
+
}) {
|
|
1278
|
+
const { messages, resumeData, runId, requestContext, ...rest } = params;
|
|
1279
|
+
if (resumeData && !runId) {
|
|
1280
|
+
throw new Error("runId is required when resumeData is provided");
|
|
1281
|
+
}
|
|
1282
|
+
const agentObj = mastra.getAgentById(agentId);
|
|
1283
|
+
if (!agentObj) {
|
|
1284
|
+
throw new Error(`Agent ${agentId} not found`);
|
|
1285
|
+
}
|
|
1286
|
+
if (!Array.isArray(messages)) {
|
|
1287
|
+
throw new Error("Messages must be an array of UIMessage objects");
|
|
1288
|
+
}
|
|
1289
|
+
const mergedOptions = {
|
|
1290
|
+
...defaultOptions,
|
|
1291
|
+
...rest,
|
|
1292
|
+
...runId && { runId },
|
|
1293
|
+
requestContext: requestContext || defaultOptions?.requestContext
|
|
1294
|
+
};
|
|
1295
|
+
const result = resumeData ? await agentObj.resumeStream(resumeData, mergedOptions) : await agentObj.stream(messages, mergedOptions);
|
|
1296
|
+
let lastMessageId;
|
|
1297
|
+
if (messages.length) {
|
|
1298
|
+
const lastMessage = messages[messages.length - 1];
|
|
1299
|
+
if (lastMessage?.role === "assistant") {
|
|
1300
|
+
lastMessageId = lastMessage.id;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
return createUIMessageStream({
|
|
1304
|
+
originalMessages: messages,
|
|
1305
|
+
execute: async ({ writer }) => {
|
|
1306
|
+
for await (const part of toAISdkV5Stream(result, {
|
|
1307
|
+
from: "agent",
|
|
1308
|
+
lastMessageId,
|
|
1309
|
+
sendStart,
|
|
1310
|
+
sendFinish,
|
|
1311
|
+
sendReasoning,
|
|
1312
|
+
sendSources
|
|
1313
|
+
})) {
|
|
1314
|
+
writer.write(part);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
4
1319
|
function chatRoute({
|
|
5
1320
|
path = "/chat/:agentId",
|
|
6
1321
|
agent,
|
|
7
|
-
defaultOptions
|
|
1322
|
+
defaultOptions,
|
|
1323
|
+
sendStart = true,
|
|
1324
|
+
sendFinish = true,
|
|
1325
|
+
sendReasoning = false,
|
|
1326
|
+
sendSources = false
|
|
8
1327
|
}) {
|
|
9
1328
|
if (!agent && !path.includes("/:agentId")) {
|
|
10
1329
|
throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
|
|
@@ -33,6 +1352,14 @@ function chatRoute({
|
|
|
33
1352
|
schema: {
|
|
34
1353
|
type: "object",
|
|
35
1354
|
properties: {
|
|
1355
|
+
resumeData: {
|
|
1356
|
+
type: "object",
|
|
1357
|
+
description: "Resume data for the agent"
|
|
1358
|
+
},
|
|
1359
|
+
runId: {
|
|
1360
|
+
type: "string",
|
|
1361
|
+
description: "The run ID required when resuming an agent execution"
|
|
1362
|
+
},
|
|
36
1363
|
messages: {
|
|
37
1364
|
type: "array",
|
|
38
1365
|
description: "Array of messages in the conversation",
|
|
@@ -103,8 +1430,9 @@ function chatRoute({
|
|
|
103
1430
|
}
|
|
104
1431
|
},
|
|
105
1432
|
handler: async (c) => {
|
|
106
|
-
const
|
|
1433
|
+
const params = await c.req.json();
|
|
107
1434
|
const mastra = c.get("mastra");
|
|
1435
|
+
const contextRequestContext = c.get("requestContext");
|
|
108
1436
|
let agentToUse = agent;
|
|
109
1437
|
if (!agent) {
|
|
110
1438
|
const agentId = c.req.param("agentId");
|
|
@@ -115,23 +1443,705 @@ function chatRoute({
|
|
|
115
1443
|
`Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
|
|
116
1444
|
);
|
|
117
1445
|
}
|
|
1446
|
+
if (contextRequestContext && defaultOptions?.requestContext) {
|
|
1447
|
+
mastra.getLogger()?.warn(`"requestContext" set in the route options will be overridden by the request's "requestContext".`);
|
|
1448
|
+
}
|
|
118
1449
|
if (!agentToUse) {
|
|
119
1450
|
throw new Error("Agent ID is required");
|
|
120
1451
|
}
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
1452
|
+
const uiMessageStream = await handleChatStream({
|
|
1453
|
+
mastra,
|
|
1454
|
+
agentId: agentToUse,
|
|
1455
|
+
params: {
|
|
1456
|
+
...params,
|
|
1457
|
+
requestContext: contextRequestContext || params.requestContext
|
|
1458
|
+
},
|
|
1459
|
+
defaultOptions,
|
|
1460
|
+
sendStart,
|
|
1461
|
+
sendFinish,
|
|
1462
|
+
sendReasoning,
|
|
1463
|
+
sendSources
|
|
1464
|
+
});
|
|
1465
|
+
return createUIMessageStreamResponse({
|
|
1466
|
+
stream: uiMessageStream
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1471
|
+
async function handleWorkflowStream({
|
|
1472
|
+
mastra,
|
|
1473
|
+
workflowId,
|
|
1474
|
+
params,
|
|
1475
|
+
includeTextStreamParts = true
|
|
1476
|
+
}) {
|
|
1477
|
+
const { runId, resourceId, inputData, resumeData, requestContext, ...rest } = params;
|
|
1478
|
+
const workflowObj = mastra.getWorkflowById(workflowId);
|
|
1479
|
+
if (!workflowObj) {
|
|
1480
|
+
throw new Error(`Workflow ${workflowId} not found`);
|
|
1481
|
+
}
|
|
1482
|
+
const run = await workflowObj.createRun({ runId, resourceId, ...rest });
|
|
1483
|
+
const stream = resumeData ? run.resumeStream({ resumeData, ...rest, requestContext }) : run.stream({ inputData, ...rest, requestContext });
|
|
1484
|
+
return createUIMessageStream({
|
|
1485
|
+
execute: async ({ writer }) => {
|
|
1486
|
+
for await (const part of toAISdkV5Stream(stream, { from: "workflow", includeTextStreamParts })) {
|
|
1487
|
+
writer.write(part);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
function workflowRoute({
|
|
1493
|
+
path = "/api/workflows/:workflowId/stream",
|
|
1494
|
+
workflow,
|
|
1495
|
+
includeTextStreamParts = true
|
|
1496
|
+
}) {
|
|
1497
|
+
if (!workflow && !path.includes("/:workflowId")) {
|
|
1498
|
+
throw new Error("Path must include :workflowId to route to the correct workflow or pass the workflow explicitly");
|
|
1499
|
+
}
|
|
1500
|
+
return registerApiRoute(path, {
|
|
1501
|
+
method: "POST",
|
|
1502
|
+
openapi: {
|
|
1503
|
+
summary: "Stream a workflow in AI SDK format",
|
|
1504
|
+
description: "Starts a workflow run and streams events as AI SDK UIMessage chunks",
|
|
1505
|
+
tags: ["ai-sdk"],
|
|
1506
|
+
parameters: [
|
|
1507
|
+
{
|
|
1508
|
+
name: "workflowId",
|
|
1509
|
+
in: "path",
|
|
1510
|
+
required: true,
|
|
1511
|
+
description: "The ID of the workflow to stream",
|
|
1512
|
+
schema: { type: "string" }
|
|
1513
|
+
}
|
|
1514
|
+
],
|
|
1515
|
+
requestBody: {
|
|
1516
|
+
required: true,
|
|
1517
|
+
content: {
|
|
1518
|
+
"application/json": {
|
|
1519
|
+
schema: {
|
|
1520
|
+
type: "object",
|
|
1521
|
+
properties: {
|
|
1522
|
+
runId: { type: "string" },
|
|
1523
|
+
resourceId: { type: "string" },
|
|
1524
|
+
inputData: { type: "object", additionalProperties: true },
|
|
1525
|
+
resumeData: { type: "object", additionalProperties: true },
|
|
1526
|
+
requestContext: { type: "object", additionalProperties: true },
|
|
1527
|
+
tracingOptions: { type: "object", additionalProperties: true },
|
|
1528
|
+
step: { type: "string" }
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
},
|
|
1534
|
+
responses: {
|
|
1535
|
+
"200": {
|
|
1536
|
+
description: "Workflow UIMessage event stream",
|
|
1537
|
+
content: {
|
|
1538
|
+
"text/plain": {
|
|
1539
|
+
schema: { type: "string", description: "SSE stream" }
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
},
|
|
1545
|
+
handler: async (c) => {
|
|
1546
|
+
const params = await c.req.json();
|
|
1547
|
+
const mastra = c.get("mastra");
|
|
1548
|
+
const contextRequestContext = c.get("requestContext");
|
|
1549
|
+
let workflowToUse = workflow;
|
|
1550
|
+
if (!workflow) {
|
|
1551
|
+
const workflowId = c.req.param("workflowId");
|
|
1552
|
+
workflowToUse = workflowId;
|
|
124
1553
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
1554
|
+
if (c.req.param("workflowId") && workflow) {
|
|
1555
|
+
mastra.getLogger()?.warn(
|
|
1556
|
+
`Fixed workflow ID was set together with a workflowId path parameter. This can lead to unexpected behavior.`
|
|
1557
|
+
);
|
|
1558
|
+
}
|
|
1559
|
+
if (!workflowToUse) {
|
|
1560
|
+
throw new Error("Workflow ID is required");
|
|
1561
|
+
}
|
|
1562
|
+
if (contextRequestContext && params.requestContext) {
|
|
1563
|
+
mastra.getLogger()?.warn(
|
|
1564
|
+
`"requestContext" from the request body will be ignored because "requestContext" is already set in the route options.`
|
|
1565
|
+
);
|
|
1566
|
+
}
|
|
1567
|
+
const uiMessageStream = await handleWorkflowStream({
|
|
1568
|
+
mastra,
|
|
1569
|
+
workflowId: workflowToUse,
|
|
1570
|
+
params: {
|
|
1571
|
+
...params,
|
|
1572
|
+
requestContext: contextRequestContext || params.requestContext
|
|
1573
|
+
},
|
|
1574
|
+
includeTextStreamParts
|
|
129
1575
|
});
|
|
130
|
-
return
|
|
1576
|
+
return createUIMessageStreamResponse({ stream: uiMessageStream });
|
|
1577
|
+
}
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
async function handleNetworkStream({
|
|
1581
|
+
mastra,
|
|
1582
|
+
agentId,
|
|
1583
|
+
params,
|
|
1584
|
+
defaultOptions
|
|
1585
|
+
}) {
|
|
1586
|
+
const { messages, ...rest } = params;
|
|
1587
|
+
const agentObj = mastra.getAgentById(agentId);
|
|
1588
|
+
if (!agentObj) {
|
|
1589
|
+
throw new Error(`Agent ${agentId} not found`);
|
|
1590
|
+
}
|
|
1591
|
+
const result = await agentObj.network(messages, {
|
|
1592
|
+
...defaultOptions,
|
|
1593
|
+
...rest
|
|
1594
|
+
});
|
|
1595
|
+
return createUIMessageStream({
|
|
1596
|
+
execute: async ({ writer }) => {
|
|
1597
|
+
for await (const part of toAISdkV5Stream(result, { from: "network" })) {
|
|
1598
|
+
writer.write(part);
|
|
1599
|
+
}
|
|
131
1600
|
}
|
|
132
1601
|
});
|
|
133
1602
|
}
|
|
1603
|
+
function networkRoute({
|
|
1604
|
+
path = "/network/:agentId",
|
|
1605
|
+
agent,
|
|
1606
|
+
defaultOptions
|
|
1607
|
+
}) {
|
|
1608
|
+
if (!agent && !path.includes("/:agentId")) {
|
|
1609
|
+
throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
|
|
1610
|
+
}
|
|
1611
|
+
return registerApiRoute(path, {
|
|
1612
|
+
method: "POST",
|
|
1613
|
+
openapi: {
|
|
1614
|
+
summary: "Execute an agent network and stream AI SDK events",
|
|
1615
|
+
description: "Routes a request to an agent network and streams UIMessage chunks in AI SDK format",
|
|
1616
|
+
tags: ["ai-sdk"],
|
|
1617
|
+
parameters: [
|
|
1618
|
+
{
|
|
1619
|
+
name: "agentId",
|
|
1620
|
+
in: "path",
|
|
1621
|
+
required: true,
|
|
1622
|
+
description: "The ID of the routing agent to execute as a network",
|
|
1623
|
+
schema: { type: "string" }
|
|
1624
|
+
}
|
|
1625
|
+
],
|
|
1626
|
+
requestBody: {
|
|
1627
|
+
required: true,
|
|
1628
|
+
content: {
|
|
1629
|
+
"application/json": {
|
|
1630
|
+
schema: {
|
|
1631
|
+
type: "object",
|
|
1632
|
+
properties: {
|
|
1633
|
+
messages: { type: "array", items: { type: "object" } },
|
|
1634
|
+
requestContext: { type: "object", additionalProperties: true },
|
|
1635
|
+
runId: { type: "string" },
|
|
1636
|
+
maxSteps: { type: "number" },
|
|
1637
|
+
threadId: { type: "string" },
|
|
1638
|
+
resourceId: { type: "string" },
|
|
1639
|
+
modelSettings: { type: "object", additionalProperties: true },
|
|
1640
|
+
tools: { type: "array", items: { type: "object" } }
|
|
1641
|
+
},
|
|
1642
|
+
required: ["messages"]
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
},
|
|
1647
|
+
responses: {
|
|
1648
|
+
"200": {
|
|
1649
|
+
description: "Streaming AI SDK UIMessage event stream for the agent network",
|
|
1650
|
+
content: { "text/plain": { schema: { type: "string", description: "SSE stream" } } }
|
|
1651
|
+
},
|
|
1652
|
+
"404": {
|
|
1653
|
+
description: "Agent not found",
|
|
1654
|
+
content: {
|
|
1655
|
+
"application/json": {
|
|
1656
|
+
schema: { type: "object", properties: { error: { type: "string" } } }
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
},
|
|
1662
|
+
handler: async (c) => {
|
|
1663
|
+
const params = await c.req.json();
|
|
1664
|
+
const mastra = c.get("mastra");
|
|
1665
|
+
let agentToUse = agent;
|
|
1666
|
+
if (!agent) {
|
|
1667
|
+
const agentId = c.req.param("agentId");
|
|
1668
|
+
agentToUse = agentId;
|
|
1669
|
+
}
|
|
1670
|
+
if (c.req.param("agentId") && agent) {
|
|
1671
|
+
mastra.getLogger()?.warn(
|
|
1672
|
+
`Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
if (!agentToUse) {
|
|
1676
|
+
throw new Error("Agent ID is required");
|
|
1677
|
+
}
|
|
1678
|
+
const uiMessageStream = await handleNetworkStream({
|
|
1679
|
+
mastra,
|
|
1680
|
+
agentId: agentToUse,
|
|
1681
|
+
params,
|
|
1682
|
+
defaultOptions
|
|
1683
|
+
});
|
|
1684
|
+
return createUIMessageStreamResponse({ stream: uiMessageStream });
|
|
1685
|
+
}
|
|
1686
|
+
});
|
|
1687
|
+
}
|
|
1688
|
+
function withMastra(model, options = {}) {
|
|
1689
|
+
const { memory, inputProcessors = [], outputProcessors = [] } = options;
|
|
1690
|
+
const allInputProcessors = [...inputProcessors];
|
|
1691
|
+
const allOutputProcessors = [...outputProcessors];
|
|
1692
|
+
if (memory) {
|
|
1693
|
+
const { storage, lastMessages, semanticRecall, workingMemory } = memory;
|
|
1694
|
+
const isWorkingMemoryEnabled = typeof workingMemory === "object" && workingMemory.enabled !== false;
|
|
1695
|
+
if (isWorkingMemoryEnabled && typeof workingMemory === "object") {
|
|
1696
|
+
let template;
|
|
1697
|
+
if (workingMemory.template) {
|
|
1698
|
+
template = {
|
|
1699
|
+
format: "markdown",
|
|
1700
|
+
content: workingMemory.template
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
const workingMemoryProcessor = new WorkingMemory({
|
|
1704
|
+
storage,
|
|
1705
|
+
template,
|
|
1706
|
+
scope: workingMemory.scope,
|
|
1707
|
+
useVNext: "version" in workingMemory && workingMemory.version === "vnext"
|
|
1708
|
+
});
|
|
1709
|
+
allInputProcessors.push(workingMemoryProcessor);
|
|
1710
|
+
}
|
|
1711
|
+
if (lastMessages !== false && lastMessages !== void 0) {
|
|
1712
|
+
const messageHistory = new MessageHistory({
|
|
1713
|
+
storage,
|
|
1714
|
+
lastMessages: typeof lastMessages === "number" ? lastMessages : void 0
|
|
1715
|
+
});
|
|
1716
|
+
allInputProcessors.push(messageHistory);
|
|
1717
|
+
allOutputProcessors.push(messageHistory);
|
|
1718
|
+
}
|
|
1719
|
+
if (semanticRecall) {
|
|
1720
|
+
const { vector, embedder, indexName, ...semanticConfig } = semanticRecall;
|
|
1721
|
+
const semanticRecallProcessor = new SemanticRecall({
|
|
1722
|
+
storage,
|
|
1723
|
+
vector,
|
|
1724
|
+
embedder,
|
|
1725
|
+
indexName: indexName || "memory_messages",
|
|
1726
|
+
...semanticConfig
|
|
1727
|
+
});
|
|
1728
|
+
allInputProcessors.push(semanticRecallProcessor);
|
|
1729
|
+
allOutputProcessors.push(semanticRecallProcessor);
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
return wrapLanguageModel({
|
|
1733
|
+
model,
|
|
1734
|
+
middleware: createProcessorMiddleware({
|
|
1735
|
+
inputProcessors: allInputProcessors,
|
|
1736
|
+
outputProcessors: allOutputProcessors,
|
|
1737
|
+
memory: memory ? {
|
|
1738
|
+
threadId: memory.threadId,
|
|
1739
|
+
resourceId: memory.resourceId
|
|
1740
|
+
} : void 0
|
|
1741
|
+
})
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
function createProcessorMiddleware(options) {
|
|
1745
|
+
const { inputProcessors = [], outputProcessors = [], memory } = options;
|
|
1746
|
+
const requestContext = new RequestContext();
|
|
1747
|
+
if (memory) {
|
|
1748
|
+
requestContext.set("MastraMemory", {
|
|
1749
|
+
thread: memory.threadId ? { id: memory.threadId } : void 0,
|
|
1750
|
+
resourceId: memory.resourceId,
|
|
1751
|
+
memoryConfig: memory.config
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1754
|
+
return {
|
|
1755
|
+
middlewareVersion: "v2",
|
|
1756
|
+
/**
|
|
1757
|
+
* Transform params runs input processors (processInput)
|
|
1758
|
+
*/
|
|
1759
|
+
async transformParams({ params }) {
|
|
1760
|
+
const messageList = new MessageList({
|
|
1761
|
+
threadId: memory?.threadId,
|
|
1762
|
+
resourceId: memory?.resourceId
|
|
1763
|
+
});
|
|
1764
|
+
for (const msg of params.prompt) {
|
|
1765
|
+
if (msg.role === "system") {
|
|
1766
|
+
messageList.addSystem(msg.content);
|
|
1767
|
+
} else {
|
|
1768
|
+
messageList.add(msg, "input");
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
for (const processor of inputProcessors) {
|
|
1772
|
+
if (processor.processInput) {
|
|
1773
|
+
try {
|
|
1774
|
+
await processor.processInput({
|
|
1775
|
+
messages: messageList.get.input.db(),
|
|
1776
|
+
systemMessages: messageList.getAllSystemMessages(),
|
|
1777
|
+
messageList,
|
|
1778
|
+
requestContext,
|
|
1779
|
+
abort: (reason) => {
|
|
1780
|
+
throw new TripWire(reason || "Aborted by processor");
|
|
1781
|
+
}
|
|
1782
|
+
});
|
|
1783
|
+
} catch (error) {
|
|
1784
|
+
if (error instanceof TripWire) {
|
|
1785
|
+
return {
|
|
1786
|
+
...params,
|
|
1787
|
+
providerOptions: {
|
|
1788
|
+
...params.providerOptions,
|
|
1789
|
+
mastraProcessors: {
|
|
1790
|
+
tripwire: true,
|
|
1791
|
+
reason: error.message
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
};
|
|
1795
|
+
}
|
|
1796
|
+
throw error;
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
const newPrompt = messageList.get.all.aiV5.prompt().map(MessageList.aiV5ModelMessageToV2PromptMessage);
|
|
1801
|
+
return {
|
|
1802
|
+
...params,
|
|
1803
|
+
prompt: newPrompt
|
|
1804
|
+
};
|
|
1805
|
+
},
|
|
1806
|
+
/**
|
|
1807
|
+
* Wrap generate for non-streaming output processing
|
|
1808
|
+
*/
|
|
1809
|
+
async wrapGenerate({ doGenerate, params }) {
|
|
1810
|
+
const processorState = params.providerOptions?.mastraProcessors;
|
|
1811
|
+
if (processorState?.tripwire) {
|
|
1812
|
+
const reason = processorState.reason || "Blocked by processor";
|
|
1813
|
+
return {
|
|
1814
|
+
content: [{ type: "text", text: reason }],
|
|
1815
|
+
finishReason: "stop",
|
|
1816
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
1817
|
+
warnings: [{ type: "other", message: `Tripwire: ${reason}` }]
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1820
|
+
const result = await doGenerate();
|
|
1821
|
+
if (!outputProcessors.length) return result;
|
|
1822
|
+
const messageList = new MessageList({
|
|
1823
|
+
threadId: memory?.threadId,
|
|
1824
|
+
resourceId: memory?.resourceId
|
|
1825
|
+
});
|
|
1826
|
+
for (const msg of params.prompt) {
|
|
1827
|
+
if (msg.role === "system") {
|
|
1828
|
+
messageList.addSystem(msg.content);
|
|
1829
|
+
} else {
|
|
1830
|
+
messageList.add(msg, "input");
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
const textContent = result.content.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
1834
|
+
const responseMessage = {
|
|
1835
|
+
id: crypto.randomUUID(),
|
|
1836
|
+
role: "assistant",
|
|
1837
|
+
content: {
|
|
1838
|
+
format: 2,
|
|
1839
|
+
parts: [{ type: "text", text: textContent }]
|
|
1840
|
+
},
|
|
1841
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1842
|
+
...memory?.threadId && { threadId: memory.threadId },
|
|
1843
|
+
...memory?.resourceId && { resourceId: memory.resourceId }
|
|
1844
|
+
};
|
|
1845
|
+
messageList.add(responseMessage, "response");
|
|
1846
|
+
for (const processor of outputProcessors) {
|
|
1847
|
+
if (processor.processOutputResult) {
|
|
1848
|
+
try {
|
|
1849
|
+
await processor.processOutputResult({
|
|
1850
|
+
messages: messageList.get.all.db(),
|
|
1851
|
+
messageList,
|
|
1852
|
+
requestContext,
|
|
1853
|
+
abort: (reason) => {
|
|
1854
|
+
throw new TripWire(reason || "Aborted by processor");
|
|
1855
|
+
}
|
|
1856
|
+
});
|
|
1857
|
+
} catch (error) {
|
|
1858
|
+
if (error instanceof TripWire) {
|
|
1859
|
+
return {
|
|
1860
|
+
content: [{ type: "text", text: error.message }],
|
|
1861
|
+
finishReason: "stop",
|
|
1862
|
+
usage: result.usage,
|
|
1863
|
+
warnings: [{ type: "other", message: `Output blocked: ${error.message}` }]
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
throw error;
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
const processedText = messageList.get.response.db().map((m) => extractTextFromMastraMessage(m)).join("");
|
|
1871
|
+
return {
|
|
1872
|
+
...result,
|
|
1873
|
+
content: [{ type: "text", text: processedText }]
|
|
1874
|
+
};
|
|
1875
|
+
},
|
|
1876
|
+
/**
|
|
1877
|
+
* Wrap stream for streaming output processing
|
|
1878
|
+
*/
|
|
1879
|
+
async wrapStream({ doStream, params }) {
|
|
1880
|
+
const processorState = params.providerOptions?.mastraProcessors;
|
|
1881
|
+
if (processorState?.tripwire) {
|
|
1882
|
+
const reason = processorState.reason || "Blocked by processor";
|
|
1883
|
+
return {
|
|
1884
|
+
stream: createBlockedStream(reason)
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1887
|
+
const { stream, ...rest } = await doStream();
|
|
1888
|
+
if (!outputProcessors.length) return { stream, ...rest };
|
|
1889
|
+
const processorStates = /* @__PURE__ */ new Map();
|
|
1890
|
+
const runId = crypto.randomUUID();
|
|
1891
|
+
const transformedStream = stream.pipeThrough(
|
|
1892
|
+
new TransformStream({
|
|
1893
|
+
async transform(chunk, controller) {
|
|
1894
|
+
let mastraChunk = convertFullStreamChunkToMastra(
|
|
1895
|
+
chunk,
|
|
1896
|
+
{ runId }
|
|
1897
|
+
);
|
|
1898
|
+
if (!mastraChunk) {
|
|
1899
|
+
controller.enqueue(chunk);
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1902
|
+
for (const processor of outputProcessors) {
|
|
1903
|
+
if (processor.processOutputStream && mastraChunk) {
|
|
1904
|
+
let state = processorStates.get(processor.id);
|
|
1905
|
+
if (!state) {
|
|
1906
|
+
state = { streamParts: [], customState: {} };
|
|
1907
|
+
processorStates.set(processor.id, state);
|
|
1908
|
+
}
|
|
1909
|
+
state.streamParts.push(mastraChunk);
|
|
1910
|
+
try {
|
|
1911
|
+
const result = await processor.processOutputStream({
|
|
1912
|
+
part: mastraChunk,
|
|
1913
|
+
streamParts: state.streamParts,
|
|
1914
|
+
state: state.customState,
|
|
1915
|
+
requestContext,
|
|
1916
|
+
abort: (reason) => {
|
|
1917
|
+
throw new TripWire(reason || "Aborted by processor");
|
|
1918
|
+
}
|
|
1919
|
+
});
|
|
1920
|
+
if (result === null || result === void 0) {
|
|
1921
|
+
mastraChunk = void 0;
|
|
1922
|
+
} else {
|
|
1923
|
+
mastraChunk = result;
|
|
1924
|
+
}
|
|
1925
|
+
} catch (error) {
|
|
1926
|
+
if (error instanceof TripWire) {
|
|
1927
|
+
controller.enqueue({
|
|
1928
|
+
type: "error",
|
|
1929
|
+
error: new Error(error.message)
|
|
1930
|
+
});
|
|
1931
|
+
controller.terminate();
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
throw error;
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
if (mastraChunk) {
|
|
1939
|
+
const aiChunk = convertMastraChunkToAISDKStreamPart(mastraChunk);
|
|
1940
|
+
if (aiChunk) {
|
|
1941
|
+
controller.enqueue(aiChunk);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
})
|
|
1946
|
+
);
|
|
1947
|
+
return { stream: transformedStream, ...rest };
|
|
1948
|
+
}
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
function createBlockedStream(reason) {
|
|
1952
|
+
return new ReadableStream({
|
|
1953
|
+
start(controller) {
|
|
1954
|
+
const id = crypto.randomUUID();
|
|
1955
|
+
controller.enqueue({
|
|
1956
|
+
type: "text-start",
|
|
1957
|
+
id
|
|
1958
|
+
});
|
|
1959
|
+
controller.enqueue({
|
|
1960
|
+
type: "text-delta",
|
|
1961
|
+
id,
|
|
1962
|
+
delta: reason
|
|
1963
|
+
});
|
|
1964
|
+
controller.enqueue({
|
|
1965
|
+
type: "text-end",
|
|
1966
|
+
id
|
|
1967
|
+
});
|
|
1968
|
+
controller.enqueue({
|
|
1969
|
+
type: "finish",
|
|
1970
|
+
finishReason: "stop",
|
|
1971
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 }
|
|
1972
|
+
});
|
|
1973
|
+
controller.close();
|
|
1974
|
+
}
|
|
1975
|
+
});
|
|
1976
|
+
}
|
|
1977
|
+
function extractTextFromMastraMessage(msg) {
|
|
1978
|
+
const content = msg.content;
|
|
1979
|
+
if (typeof content === "string") {
|
|
1980
|
+
return content;
|
|
1981
|
+
}
|
|
1982
|
+
if (content?.parts) {
|
|
1983
|
+
return content.parts.filter((p) => p.type === "text" && "text" in p).map((p) => p.text).join("");
|
|
1984
|
+
}
|
|
1985
|
+
return "";
|
|
1986
|
+
}
|
|
1987
|
+
function convertMastraChunkToAISDKStreamPart(chunk) {
|
|
1988
|
+
switch (chunk.type) {
|
|
1989
|
+
// Text streaming
|
|
1990
|
+
case "text-start":
|
|
1991
|
+
return {
|
|
1992
|
+
type: "text-start",
|
|
1993
|
+
id: chunk.payload.id || crypto.randomUUID(),
|
|
1994
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
1995
|
+
};
|
|
1996
|
+
case "text-delta":
|
|
1997
|
+
return {
|
|
1998
|
+
type: "text-delta",
|
|
1999
|
+
id: chunk.payload.id || crypto.randomUUID(),
|
|
2000
|
+
delta: chunk.payload.text,
|
|
2001
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2002
|
+
};
|
|
2003
|
+
case "text-end":
|
|
2004
|
+
return {
|
|
2005
|
+
type: "text-end",
|
|
2006
|
+
id: chunk.payload.id || crypto.randomUUID(),
|
|
2007
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2008
|
+
};
|
|
2009
|
+
// Reasoning streaming
|
|
2010
|
+
case "reasoning-start":
|
|
2011
|
+
return {
|
|
2012
|
+
type: "reasoning-start",
|
|
2013
|
+
id: chunk.payload.id || crypto.randomUUID(),
|
|
2014
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2015
|
+
};
|
|
2016
|
+
case "reasoning-delta":
|
|
2017
|
+
return {
|
|
2018
|
+
type: "reasoning-delta",
|
|
2019
|
+
id: chunk.payload.id || crypto.randomUUID(),
|
|
2020
|
+
delta: chunk.payload.text,
|
|
2021
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2022
|
+
};
|
|
2023
|
+
case "reasoning-end":
|
|
2024
|
+
return {
|
|
2025
|
+
type: "reasoning-end",
|
|
2026
|
+
id: chunk.payload.id || crypto.randomUUID(),
|
|
2027
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2028
|
+
};
|
|
2029
|
+
// Tool call (complete)
|
|
2030
|
+
case "tool-call":
|
|
2031
|
+
return {
|
|
2032
|
+
type: "tool-call",
|
|
2033
|
+
toolCallId: chunk.payload.toolCallId,
|
|
2034
|
+
toolName: chunk.payload.toolName,
|
|
2035
|
+
input: JSON.stringify(chunk.payload.args),
|
|
2036
|
+
providerExecuted: chunk.payload.providerExecuted,
|
|
2037
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2038
|
+
};
|
|
2039
|
+
// Tool call input streaming
|
|
2040
|
+
case "tool-call-input-streaming-start":
|
|
2041
|
+
return {
|
|
2042
|
+
type: "tool-input-start",
|
|
2043
|
+
id: chunk.payload.toolCallId,
|
|
2044
|
+
toolName: chunk.payload.toolName,
|
|
2045
|
+
providerExecuted: chunk.payload.providerExecuted,
|
|
2046
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2047
|
+
};
|
|
2048
|
+
case "tool-call-delta":
|
|
2049
|
+
return {
|
|
2050
|
+
type: "tool-input-delta",
|
|
2051
|
+
id: chunk.payload.toolCallId,
|
|
2052
|
+
delta: chunk.payload.argsTextDelta,
|
|
2053
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2054
|
+
};
|
|
2055
|
+
case "tool-call-input-streaming-end":
|
|
2056
|
+
return {
|
|
2057
|
+
type: "tool-input-end",
|
|
2058
|
+
id: chunk.payload.toolCallId,
|
|
2059
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2060
|
+
};
|
|
2061
|
+
// Tool result
|
|
2062
|
+
case "tool-result":
|
|
2063
|
+
return {
|
|
2064
|
+
type: "tool-result",
|
|
2065
|
+
toolCallId: chunk.payload.toolCallId,
|
|
2066
|
+
toolName: chunk.payload.toolName,
|
|
2067
|
+
result: { type: "json", value: chunk.payload.result },
|
|
2068
|
+
isError: chunk.payload.isError,
|
|
2069
|
+
providerExecuted: chunk.payload.providerExecuted,
|
|
2070
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2071
|
+
};
|
|
2072
|
+
// Source (citations)
|
|
2073
|
+
case "source":
|
|
2074
|
+
if (chunk.payload.sourceType === "url") {
|
|
2075
|
+
return {
|
|
2076
|
+
type: "source",
|
|
2077
|
+
sourceType: "url",
|
|
2078
|
+
id: chunk.payload.id,
|
|
2079
|
+
url: chunk.payload.url,
|
|
2080
|
+
title: chunk.payload.title,
|
|
2081
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2082
|
+
};
|
|
2083
|
+
} else {
|
|
2084
|
+
return {
|
|
2085
|
+
type: "source",
|
|
2086
|
+
sourceType: "document",
|
|
2087
|
+
id: chunk.payload.id,
|
|
2088
|
+
mediaType: chunk.payload.mimeType,
|
|
2089
|
+
title: chunk.payload.title,
|
|
2090
|
+
filename: chunk.payload.filename,
|
|
2091
|
+
providerMetadata: chunk.payload.providerMetadata
|
|
2092
|
+
};
|
|
2093
|
+
}
|
|
2094
|
+
// File output
|
|
2095
|
+
case "file":
|
|
2096
|
+
return {
|
|
2097
|
+
type: "file",
|
|
2098
|
+
data: chunk.payload.data || chunk.payload.base64,
|
|
2099
|
+
mediaType: chunk.payload.mimeType
|
|
2100
|
+
};
|
|
2101
|
+
// Response metadata
|
|
2102
|
+
case "response-metadata":
|
|
2103
|
+
return {
|
|
2104
|
+
type: "response-metadata",
|
|
2105
|
+
...chunk.payload
|
|
2106
|
+
};
|
|
2107
|
+
// Raw provider data
|
|
2108
|
+
case "raw":
|
|
2109
|
+
return {
|
|
2110
|
+
type: "raw",
|
|
2111
|
+
rawValue: chunk.payload
|
|
2112
|
+
};
|
|
2113
|
+
// Finish
|
|
2114
|
+
case "finish": {
|
|
2115
|
+
const usage = chunk.payload.output?.usage;
|
|
2116
|
+
return {
|
|
2117
|
+
type: "finish",
|
|
2118
|
+
finishReason: toAISDKFinishReason(chunk.payload.stepResult?.reason || "stop"),
|
|
2119
|
+
usage: usage ? {
|
|
2120
|
+
inputTokens: usage.inputTokens || 0,
|
|
2121
|
+
outputTokens: usage.outputTokens || 0,
|
|
2122
|
+
totalTokens: usage.totalTokens || 0
|
|
2123
|
+
} : { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
2124
|
+
providerMetadata: chunk.payload.metadata?.providerMetadata
|
|
2125
|
+
};
|
|
2126
|
+
}
|
|
2127
|
+
// Error
|
|
2128
|
+
case "error":
|
|
2129
|
+
return {
|
|
2130
|
+
type: "error",
|
|
2131
|
+
error: chunk.payload.error || chunk.payload
|
|
2132
|
+
};
|
|
2133
|
+
default:
|
|
2134
|
+
return null;
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
// src/to-ai-sdk-format.ts
|
|
2139
|
+
function toAISdkFormat() {
|
|
2140
|
+
throw new Error(
|
|
2141
|
+
'toAISdkFormat() has been deprecated. Please use toAISdkStream() instead.\n\nMigration:\n import { toAISdkFormat } from "@mastra/ai-sdk";\n // Change to:\n import { toAISdkStream } from "@mastra/ai-sdk";\n\nThe function signature remains the same.'
|
|
2142
|
+
);
|
|
2143
|
+
}
|
|
134
2144
|
|
|
135
|
-
export { chatRoute };
|
|
2145
|
+
export { chatRoute, handleChatStream, handleNetworkStream, handleWorkflowStream, networkRoute, toAISdkFormat, toAISdkV5Stream as toAISdkStream, withMastra, workflowRoute };
|
|
136
2146
|
//# sourceMappingURL=index.js.map
|
|
137
2147
|
//# sourceMappingURL=index.js.map
|