@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/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/index.ts
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 { messages, ...rest } = await c.req.json();
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 agentObj = mastra.getAgent(agentToUse);
122
- if (!agentObj) {
123
- throw new Error(`Agent ${agentToUse} not found`);
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
- const result = await agentObj.streamVNext(messages, {
126
- ...defaultOptions,
127
- ...rest,
128
- format: "aisdk"
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 result.toUIMessageStreamResponse();
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