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