@mastra/ai-sdk 0.0.0-scorers-ui-refactored-20250916094952 → 0.0.0-scorers-logs-20251208093427

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,1297 @@
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');
4
6
 
5
- // src/index.ts
7
+ // src/chat-route.ts
8
+
9
+ // src/utils.ts
10
+ var isDataChunkType = (chunk) => {
11
+ return chunk && typeof chunk === "object" && "type" in chunk && chunk.type?.startsWith("data-");
12
+ };
13
+ var isMastraTextStreamChunk = (chunk) => {
14
+ return chunk && typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string" && [
15
+ "text-start",
16
+ "text-delta",
17
+ "text-end",
18
+ "reasoning-start",
19
+ "reasoning-delta",
20
+ "reasoning-end",
21
+ "file",
22
+ "source",
23
+ "tool-input-start",
24
+ "tool-input-delta",
25
+ "tool-call",
26
+ "tool-result",
27
+ "tool-error",
28
+ "error",
29
+ "start-step",
30
+ "finish-step",
31
+ "start",
32
+ "finish",
33
+ "abort",
34
+ "tool-input-end",
35
+ "raw"
36
+ ].includes(chunk.type);
37
+ };
38
+ function safeParseErrorObject(obj) {
39
+ if (typeof obj !== "object" || obj === null) {
40
+ return String(obj);
41
+ }
42
+ try {
43
+ const stringified = JSON.stringify(obj);
44
+ if (stringified === "{}") {
45
+ return String(obj);
46
+ }
47
+ return stringified;
48
+ } catch {
49
+ return String(obj);
50
+ }
51
+ }
52
+ var isAgentExecutionDataChunkType = (chunk) => {
53
+ 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-");
54
+ };
55
+ var isWorkflowExecutionDataChunkType = (chunk) => {
56
+ 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-");
57
+ };
58
+
59
+ // src/helpers.ts
60
+ function convertMastraChunkToAISDKv5({
61
+ chunk,
62
+ mode = "stream"
63
+ }) {
64
+ switch (chunk.type) {
65
+ case "start":
66
+ return {
67
+ type: "start"
68
+ };
69
+ case "step-start":
70
+ const { messageId: _messageId, ...rest } = chunk.payload;
71
+ return {
72
+ type: "start-step",
73
+ request: rest.request,
74
+ warnings: rest.warnings || []
75
+ };
76
+ case "raw":
77
+ return {
78
+ type: "raw",
79
+ rawValue: chunk.payload
80
+ };
81
+ case "finish": {
82
+ return {
83
+ type: "finish",
84
+ finishReason: chunk.payload.stepResult.reason,
85
+ totalUsage: chunk.payload.output.usage
86
+ };
87
+ }
88
+ case "reasoning-start":
89
+ return {
90
+ type: "reasoning-start",
91
+ id: chunk.payload.id,
92
+ providerMetadata: chunk.payload.providerMetadata
93
+ };
94
+ case "reasoning-delta":
95
+ return {
96
+ type: "reasoning-delta",
97
+ id: chunk.payload.id,
98
+ text: chunk.payload.text,
99
+ providerMetadata: chunk.payload.providerMetadata
100
+ };
101
+ case "reasoning-signature":
102
+ throw new Error('AISDKv5 chunk type "reasoning-signature" not supported');
103
+ // return {
104
+ // type: 'reasoning-signature' as const,
105
+ // id: chunk.payload.id,
106
+ // signature: chunk.payload.signature,
107
+ // };
108
+ case "redacted-reasoning":
109
+ throw new Error('AISDKv5 chunk type "redacted-reasoning" not supported');
110
+ // return {
111
+ // type: 'redacted-reasoning',
112
+ // id: chunk.payload.id,
113
+ // data: chunk.payload.data,
114
+ // };
115
+ case "reasoning-end":
116
+ return {
117
+ type: "reasoning-end",
118
+ id: chunk.payload.id,
119
+ providerMetadata: chunk.payload.providerMetadata
120
+ };
121
+ case "source":
122
+ if (chunk.payload.sourceType === "url") {
123
+ return {
124
+ type: "source",
125
+ sourceType: "url",
126
+ id: chunk.payload.id,
127
+ url: chunk.payload.url,
128
+ title: chunk.payload.title,
129
+ providerMetadata: chunk.payload.providerMetadata
130
+ };
131
+ } else {
132
+ return {
133
+ type: "source",
134
+ sourceType: "document",
135
+ id: chunk.payload.id,
136
+ mediaType: chunk.payload.mimeType,
137
+ title: chunk.payload.title,
138
+ filename: chunk.payload.filename,
139
+ providerMetadata: chunk.payload.providerMetadata
140
+ };
141
+ }
142
+ case "file":
143
+ if (mode === "generate") {
144
+ return {
145
+ type: "file",
146
+ file: new stream.DefaultGeneratedFile({
147
+ data: chunk.payload.data,
148
+ mediaType: chunk.payload.mimeType
149
+ })
150
+ };
151
+ }
152
+ return {
153
+ type: "file",
154
+ file: new stream.DefaultGeneratedFileWithType({
155
+ data: chunk.payload.data,
156
+ mediaType: chunk.payload.mimeType
157
+ })
158
+ };
159
+ case "tool-call":
160
+ return {
161
+ type: "tool-call",
162
+ toolCallId: chunk.payload.toolCallId,
163
+ providerMetadata: chunk.payload.providerMetadata,
164
+ providerExecuted: chunk.payload.providerExecuted,
165
+ toolName: chunk.payload.toolName,
166
+ input: chunk.payload.args
167
+ };
168
+ case "tool-call-approval":
169
+ return {
170
+ type: "data-tool-call-approval",
171
+ id: chunk.payload.toolCallId,
172
+ data: {
173
+ runId: chunk.runId,
174
+ toolCallId: chunk.payload.toolCallId,
175
+ toolName: chunk.payload.toolName,
176
+ args: chunk.payload.args
177
+ }
178
+ };
179
+ case "tool-call-suspended":
180
+ return {
181
+ type: "data-tool-call-suspended",
182
+ id: chunk.payload.toolCallId,
183
+ data: {
184
+ runId: chunk.runId,
185
+ toolCallId: chunk.payload.toolCallId,
186
+ toolName: chunk.payload.toolName,
187
+ suspendPayload: chunk.payload.suspendPayload
188
+ }
189
+ };
190
+ case "tool-call-input-streaming-start":
191
+ return {
192
+ type: "tool-input-start",
193
+ id: chunk.payload.toolCallId,
194
+ toolName: chunk.payload.toolName,
195
+ dynamic: !!chunk.payload.dynamic,
196
+ providerMetadata: chunk.payload.providerMetadata,
197
+ providerExecuted: chunk.payload.providerExecuted
198
+ };
199
+ case "tool-call-input-streaming-end":
200
+ return {
201
+ type: "tool-input-end",
202
+ id: chunk.payload.toolCallId,
203
+ providerMetadata: chunk.payload.providerMetadata
204
+ };
205
+ case "tool-call-delta":
206
+ return {
207
+ type: "tool-input-delta",
208
+ id: chunk.payload.toolCallId,
209
+ delta: chunk.payload.argsTextDelta,
210
+ providerMetadata: chunk.payload.providerMetadata
211
+ };
212
+ case "step-finish": {
213
+ const { request: _request, providerMetadata, ...rest2 } = chunk.payload.metadata;
214
+ return {
215
+ type: "finish-step",
216
+ response: {
217
+ id: chunk.payload.id || "",
218
+ timestamp: /* @__PURE__ */ new Date(),
219
+ modelId: rest2.modelId || "",
220
+ ...rest2
221
+ },
222
+ usage: chunk.payload.output.usage,
223
+ finishReason: chunk.payload.stepResult.reason,
224
+ providerMetadata
225
+ };
226
+ }
227
+ case "text-delta":
228
+ return {
229
+ type: "text-delta",
230
+ id: chunk.payload.id,
231
+ text: chunk.payload.text,
232
+ providerMetadata: chunk.payload.providerMetadata
233
+ };
234
+ case "text-end":
235
+ return {
236
+ type: "text-end",
237
+ id: chunk.payload.id,
238
+ providerMetadata: chunk.payload.providerMetadata
239
+ };
240
+ case "text-start":
241
+ return {
242
+ type: "text-start",
243
+ id: chunk.payload.id,
244
+ providerMetadata: chunk.payload.providerMetadata
245
+ };
246
+ case "tool-result":
247
+ return {
248
+ type: "tool-result",
249
+ input: chunk.payload.args,
250
+ toolCallId: chunk.payload.toolCallId,
251
+ providerExecuted: chunk.payload.providerExecuted,
252
+ toolName: chunk.payload.toolName,
253
+ output: chunk.payload.result
254
+ // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this?
255
+ };
256
+ case "tool-error":
257
+ return {
258
+ type: "tool-error",
259
+ error: chunk.payload.error,
260
+ input: chunk.payload.args,
261
+ toolCallId: chunk.payload.toolCallId,
262
+ providerExecuted: chunk.payload.providerExecuted,
263
+ toolName: chunk.payload.toolName
264
+ // providerMetadata: chunk.payload.providerMetadata, // AI v5 types don't show this?
265
+ };
266
+ case "abort":
267
+ return {
268
+ type: "abort"
269
+ };
270
+ case "error":
271
+ return {
272
+ type: "error",
273
+ error: chunk.payload.error
274
+ };
275
+ case "object":
276
+ return {
277
+ type: "object",
278
+ object: chunk.object
279
+ };
280
+ case "tripwire":
281
+ return {
282
+ type: "data-tripwire",
283
+ data: {
284
+ tripwireReason: chunk.payload.tripwireReason
285
+ }
286
+ };
287
+ default:
288
+ if (chunk.type && "payload" in chunk && chunk.payload) {
289
+ return {
290
+ type: chunk.type,
291
+ ...chunk.payload || {}
292
+ };
293
+ }
294
+ if ("type" in chunk && chunk.type?.startsWith("data-")) {
295
+ return chunk;
296
+ }
297
+ return;
298
+ }
299
+ }
300
+ function convertFullStreamChunkToUIMessageStream({
301
+ part,
302
+ messageMetadataValue,
303
+ sendReasoning,
304
+ sendSources,
305
+ onError,
306
+ sendStart,
307
+ sendFinish,
308
+ responseMessageId
309
+ }) {
310
+ const partType = part?.type;
311
+ switch (partType) {
312
+ case "text-start": {
313
+ return {
314
+ type: "text-start",
315
+ id: part.id,
316
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
317
+ };
318
+ }
319
+ case "text-delta": {
320
+ return {
321
+ type: "text-delta",
322
+ id: part.id,
323
+ delta: part.text,
324
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
325
+ };
326
+ }
327
+ case "text-end": {
328
+ return {
329
+ type: "text-end",
330
+ id: part.id,
331
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
332
+ };
333
+ }
334
+ case "reasoning-start": {
335
+ return {
336
+ type: "reasoning-start",
337
+ id: part.id,
338
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
339
+ };
340
+ }
341
+ case "reasoning-delta": {
342
+ if (sendReasoning) {
343
+ return {
344
+ type: "reasoning-delta",
345
+ id: part.id,
346
+ delta: part.text,
347
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
348
+ };
349
+ }
350
+ return;
351
+ }
352
+ case "reasoning-end": {
353
+ return {
354
+ type: "reasoning-end",
355
+ id: part.id,
356
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
357
+ };
358
+ }
359
+ case "file": {
360
+ return {
361
+ type: "file",
362
+ mediaType: part.file.mediaType,
363
+ url: `data:${part.file.mediaType};base64,${part.file.base64}`
364
+ };
365
+ }
366
+ case "source": {
367
+ if (sendSources && part.sourceType === "url") {
368
+ return {
369
+ type: "source-url",
370
+ sourceId: part.id,
371
+ url: part.url,
372
+ title: part.title,
373
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
374
+ };
375
+ }
376
+ if (sendSources && part.sourceType === "document") {
377
+ return {
378
+ type: "source-document",
379
+ sourceId: part.id,
380
+ mediaType: part.mediaType,
381
+ title: part.title,
382
+ filename: part.filename,
383
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
384
+ };
385
+ }
386
+ return;
387
+ }
388
+ case "tool-input-start": {
389
+ return {
390
+ type: "tool-input-start",
391
+ toolCallId: part.id,
392
+ toolName: part.toolName,
393
+ ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
394
+ ...part.dynamic != null ? { dynamic: part.dynamic } : {}
395
+ };
396
+ }
397
+ case "tool-input-delta": {
398
+ return {
399
+ type: "tool-input-delta",
400
+ toolCallId: part.id,
401
+ inputTextDelta: part.delta
402
+ };
403
+ }
404
+ case "tool-call": {
405
+ return {
406
+ type: "tool-input-available",
407
+ toolCallId: part.toolCallId,
408
+ toolName: part.toolName,
409
+ input: part.input,
410
+ ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
411
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
412
+ ...part.dynamic != null ? { dynamic: part.dynamic } : {}
413
+ };
414
+ }
415
+ case "tool-result": {
416
+ return {
417
+ type: "tool-output-available",
418
+ toolCallId: part.toolCallId,
419
+ output: part.output,
420
+ ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
421
+ ...part.dynamic != null ? { dynamic: part.dynamic } : {}
422
+ };
423
+ }
424
+ case "tool-output": {
425
+ if (part.output.from === "AGENT") {
426
+ return {
427
+ type: "tool-agent",
428
+ toolCallId: part.toolCallId,
429
+ payload: part.output
430
+ };
431
+ } else if (part.output.from === "WORKFLOW") {
432
+ return {
433
+ type: "tool-workflow",
434
+ toolCallId: part.toolCallId,
435
+ payload: part.output
436
+ };
437
+ } else if (part.output.from === "NETWORK") {
438
+ return {
439
+ type: "tool-network",
440
+ toolCallId: part.toolCallId,
441
+ payload: part.output
442
+ };
443
+ } else if (isDataChunkType(part.output)) {
444
+ if (!("data" in part.output)) {
445
+ throw new Error(
446
+ `UI Messages require a data property when using data- prefixed chunks
447
+ ${JSON.stringify(part)}`
448
+ );
449
+ }
450
+ return part.output;
451
+ }
452
+ return;
453
+ }
454
+ case "tool-error": {
455
+ return {
456
+ type: "tool-output-error",
457
+ toolCallId: part.toolCallId,
458
+ errorText: onError(part.error),
459
+ ...part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {},
460
+ ...part.dynamic != null ? { dynamic: part.dynamic } : {}
461
+ };
462
+ }
463
+ case "error": {
464
+ return {
465
+ type: "error",
466
+ errorText: onError(part.error)
467
+ };
468
+ }
469
+ case "start-step": {
470
+ return { type: "start-step" };
471
+ }
472
+ case "finish-step": {
473
+ return { type: "finish-step" };
474
+ }
475
+ case "start": {
476
+ if (sendStart) {
477
+ return {
478
+ type: "start",
479
+ ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {},
480
+ ...responseMessageId != null ? { messageId: responseMessageId } : {}
481
+ };
482
+ }
483
+ return;
484
+ }
485
+ case "finish": {
486
+ if (sendFinish) {
487
+ return {
488
+ type: "finish",
489
+ ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}
490
+ };
491
+ }
492
+ return;
493
+ }
494
+ case "abort": {
495
+ return part;
496
+ }
497
+ case "tool-input-end": {
498
+ return;
499
+ }
500
+ case "raw": {
501
+ return;
502
+ }
503
+ default: {
504
+ if (isDataChunkType(part)) {
505
+ if (!("data" in part)) {
506
+ throw new Error(
507
+ `UI Messages require a data property when using data- prefixed chunks
508
+ ${JSON.stringify(part)}`
509
+ );
510
+ }
511
+ return part;
512
+ }
513
+ return;
514
+ }
515
+ }
516
+ }
517
+
518
+ // src/transformers.ts
519
+ var PRIMITIVE_CACHE_SYMBOL = Symbol("primitive-cache");
520
+ function WorkflowStreamToAISDKTransformer({
521
+ includeTextStreamParts
522
+ } = {}) {
523
+ const bufferedWorkflows = /* @__PURE__ */ new Map();
524
+ return new TransformStream({
525
+ start(controller) {
526
+ controller.enqueue({
527
+ type: "start"
528
+ });
529
+ },
530
+ flush(controller) {
531
+ controller.enqueue({
532
+ type: "finish"
533
+ });
534
+ },
535
+ transform(chunk, controller) {
536
+ const transformed = transformWorkflow(chunk, bufferedWorkflows, false, includeTextStreamParts);
537
+ if (transformed) controller.enqueue(transformed);
538
+ }
539
+ });
540
+ }
541
+ function AgentNetworkToAISDKTransformer() {
542
+ const bufferedNetworks = /* @__PURE__ */ new Map();
543
+ return new TransformStream({
544
+ start(controller) {
545
+ controller.enqueue({
546
+ type: "start"
547
+ });
548
+ },
549
+ flush(controller) {
550
+ controller.enqueue({
551
+ type: "finish"
552
+ });
553
+ },
554
+ transform(chunk, controller) {
555
+ const transformed = transformNetwork(chunk, bufferedNetworks);
556
+ if (transformed) controller.enqueue(transformed);
557
+ }
558
+ });
559
+ }
560
+ function AgentStreamToAISDKTransformer({
561
+ lastMessageId,
562
+ sendStart,
563
+ sendFinish,
564
+ sendReasoning,
565
+ sendSources,
566
+ messageMetadata,
567
+ onError
568
+ }) {
569
+ let bufferedSteps = /* @__PURE__ */ new Map();
570
+ let tripwireOccurred = false;
571
+ let finishEventSent = false;
572
+ return new TransformStream({
573
+ transform(chunk, controller) {
574
+ if (chunk.type === "tripwire") {
575
+ tripwireOccurred = true;
576
+ }
577
+ if (chunk.type === "finish") {
578
+ finishEventSent = true;
579
+ }
580
+ const part = convertMastraChunkToAISDKv5({ chunk, mode: "stream" });
581
+ const transformedChunk = convertFullStreamChunkToUIMessageStream({
582
+ part,
583
+ sendReasoning,
584
+ sendSources,
585
+ messageMetadataValue: messageMetadata?.({ part }),
586
+ sendStart,
587
+ sendFinish,
588
+ responseMessageId: lastMessageId,
589
+ onError(error) {
590
+ return onError ? onError(error) : safeParseErrorObject(error);
591
+ }
592
+ });
593
+ if (transformedChunk) {
594
+ if (transformedChunk.type === "tool-agent") {
595
+ const payload = transformedChunk.payload;
596
+ const agentTransformed = transformAgent(payload, bufferedSteps);
597
+ if (agentTransformed) controller.enqueue(agentTransformed);
598
+ } else if (transformedChunk.type === "tool-workflow") {
599
+ const payload = transformedChunk.payload;
600
+ const workflowChunk = transformWorkflow(payload, bufferedSteps, true);
601
+ if (workflowChunk) controller.enqueue(workflowChunk);
602
+ } else if (transformedChunk.type === "tool-network") {
603
+ const payload = transformedChunk.payload;
604
+ const networkChunk = transformNetwork(payload, bufferedSteps, true);
605
+ if (networkChunk) controller.enqueue(networkChunk);
606
+ } else {
607
+ controller.enqueue(transformedChunk);
608
+ }
609
+ }
610
+ },
611
+ flush(controller) {
612
+ if (tripwireOccurred && !finishEventSent && sendFinish) {
613
+ controller.enqueue({
614
+ type: "finish",
615
+ finishReason: "other"
616
+ });
617
+ }
618
+ }
619
+ });
620
+ }
621
+ function transformAgent(payload, bufferedSteps) {
622
+ let hasChanged = false;
623
+ switch (payload.type) {
624
+ case "start":
625
+ bufferedSteps.set(payload.runId, {
626
+ id: payload.payload.id,
627
+ object: null,
628
+ finishReason: null,
629
+ usage: null,
630
+ warnings: [],
631
+ text: "",
632
+ reasoning: [],
633
+ sources: [],
634
+ files: [],
635
+ toolCalls: [],
636
+ toolResults: [],
637
+ request: {},
638
+ response: {
639
+ id: "",
640
+ timestamp: /* @__PURE__ */ new Date(),
641
+ modelId: "",
642
+ messages: []
643
+ },
644
+ providerMetadata: void 0,
645
+ steps: [],
646
+ status: "running"
647
+ });
648
+ hasChanged = true;
649
+ break;
650
+ case "finish":
651
+ bufferedSteps.set(payload.runId, {
652
+ ...bufferedSteps.get(payload.runId),
653
+ finishReason: payload.payload.stepResult.reason,
654
+ usage: payload.payload?.output?.usage,
655
+ warnings: payload.payload?.stepResult?.warnings,
656
+ steps: bufferedSteps.get(payload.runId).steps,
657
+ status: "finished"
658
+ });
659
+ hasChanged = true;
660
+ break;
661
+ case "text-delta":
662
+ const prevData = bufferedSteps.get(payload.runId);
663
+ bufferedSteps.set(payload.runId, {
664
+ ...prevData,
665
+ text: `${prevData.text}${payload.payload.text}`
666
+ });
667
+ hasChanged = true;
668
+ break;
669
+ case "reasoning-delta":
670
+ bufferedSteps.set(payload.runId, {
671
+ ...bufferedSteps.get(payload.runId),
672
+ reasoning: [...bufferedSteps.get(payload.runId).reasoning, payload.payload.text]
673
+ });
674
+ hasChanged = true;
675
+ break;
676
+ case "source":
677
+ bufferedSteps.set(payload.runId, {
678
+ ...bufferedSteps.get(payload.runId),
679
+ sources: [...bufferedSteps.get(payload.runId).sources, payload.payload]
680
+ });
681
+ hasChanged = true;
682
+ break;
683
+ case "file":
684
+ bufferedSteps.set(payload.runId, {
685
+ ...bufferedSteps.get(payload.runId),
686
+ files: [...bufferedSteps.get(payload.runId).files, payload.payload]
687
+ });
688
+ hasChanged = true;
689
+ break;
690
+ case "tool-call":
691
+ bufferedSteps.set(payload.runId, {
692
+ ...bufferedSteps.get(payload.runId),
693
+ toolCalls: [...bufferedSteps.get(payload.runId).toolCalls, payload.payload]
694
+ });
695
+ hasChanged = true;
696
+ break;
697
+ case "tool-result":
698
+ bufferedSteps.set(payload.runId, {
699
+ ...bufferedSteps.get(payload.runId),
700
+ toolResults: [...bufferedSteps.get(payload.runId).toolResults, payload.payload]
701
+ });
702
+ hasChanged = true;
703
+ break;
704
+ case "object-result":
705
+ bufferedSteps.set(payload.runId, {
706
+ ...bufferedSteps.get(payload.runId),
707
+ object: payload.object
708
+ });
709
+ hasChanged = true;
710
+ break;
711
+ case "object":
712
+ bufferedSteps.set(payload.runId, {
713
+ ...bufferedSteps.get(payload.runId),
714
+ object: payload.object
715
+ });
716
+ hasChanged = true;
717
+ break;
718
+ case "step-finish":
719
+ const currentRun = bufferedSteps.get(payload.runId);
720
+ const stepResult = {
721
+ ...bufferedSteps.get(payload.runId),
722
+ stepType: currentRun.steps.length === 0 ? "initial" : "tool-result",
723
+ reasoningText: bufferedSteps.get(payload.runId).reasoning.join(""),
724
+ staticToolCalls: bufferedSteps.get(payload.runId).toolCalls.filter((part) => part.type === "tool-call" && part.payload?.dynamic === false),
725
+ dynamicToolCalls: bufferedSteps.get(payload.runId).toolCalls.filter((part) => part.type === "tool-call" && part.payload?.dynamic === true),
726
+ staticToolResults: bufferedSteps.get(payload.runId).toolResults.filter((part) => part.type === "tool-result" && part.payload?.dynamic === false),
727
+ dynamicToolResults: bufferedSteps.get(payload.runId).toolResults.filter((part) => part.type === "tool-result" && part.payload?.dynamic === true),
728
+ finishReason: payload.payload.stepResult.reason,
729
+ usage: payload.payload.output.usage,
730
+ warnings: payload.payload.stepResult.warnings || [],
731
+ response: {
732
+ id: payload.payload.id || "",
733
+ timestamp: payload.payload.metadata?.timestamp || /* @__PURE__ */ new Date(),
734
+ modelId: payload.payload.metadata?.modelId || payload.payload.metadata?.model || "",
735
+ ...bufferedSteps.get(payload.runId).response,
736
+ messages: bufferedSteps.get(payload.runId).response.messages || []
737
+ }
738
+ };
739
+ bufferedSteps.set(payload.runId, {
740
+ ...bufferedSteps.get(payload.runId),
741
+ usage: payload.payload.output.usage,
742
+ warnings: payload.payload.stepResult.warnings || [],
743
+ steps: [...bufferedSteps.get(payload.runId).steps, stepResult]
744
+ });
745
+ hasChanged = true;
746
+ break;
747
+ }
748
+ if (hasChanged) {
749
+ return {
750
+ type: "data-tool-agent",
751
+ id: payload.runId,
752
+ data: bufferedSteps.get(payload.runId)
753
+ };
754
+ }
755
+ return null;
756
+ }
757
+ function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStreamParts) {
758
+ switch (payload.type) {
759
+ case "workflow-start":
760
+ bufferedWorkflows.set(payload.runId, {
761
+ name: payload.payload.workflowId,
762
+ steps: {}
763
+ });
764
+ return {
765
+ type: isNested ? "data-tool-workflow" : "data-workflow",
766
+ id: payload.runId,
767
+ data: {
768
+ name: bufferedWorkflows.get(payload.runId).name,
769
+ status: "running",
770
+ steps: bufferedWorkflows.get(payload.runId).steps,
771
+ output: null
772
+ }
773
+ };
774
+ case "workflow-step-start": {
775
+ const current = bufferedWorkflows.get(payload.runId) || { name: "", steps: {} };
776
+ current.steps[payload.payload.id] = {
777
+ name: payload.payload.id,
778
+ status: payload.payload.status,
779
+ input: payload.payload.payload ?? null,
780
+ output: null,
781
+ suspendPayload: null,
782
+ resumePayload: null
783
+ };
784
+ bufferedWorkflows.set(payload.runId, current);
785
+ return {
786
+ type: isNested ? "data-tool-workflow" : "data-workflow",
787
+ id: payload.runId,
788
+ data: {
789
+ name: current.name,
790
+ status: "running",
791
+ steps: current.steps,
792
+ output: null
793
+ }
794
+ };
795
+ }
796
+ case "workflow-step-result": {
797
+ const current = bufferedWorkflows.get(payload.runId);
798
+ if (!current) return null;
799
+ current.steps[payload.payload.id] = {
800
+ ...current.steps[payload.payload.id],
801
+ status: payload.payload.status,
802
+ output: payload.payload.output ?? null
803
+ };
804
+ return {
805
+ type: isNested ? "data-tool-workflow" : "data-workflow",
806
+ id: payload.runId,
807
+ data: {
808
+ name: current.name,
809
+ status: "running",
810
+ steps: current.steps,
811
+ output: null
812
+ }
813
+ };
814
+ }
815
+ case "workflow-step-suspended": {
816
+ const current = bufferedWorkflows.get(payload.runId);
817
+ if (!current) return null;
818
+ current.steps[payload.payload.id] = {
819
+ ...current.steps[payload.payload.id],
820
+ status: payload.payload.status,
821
+ suspendPayload: payload.payload.suspendPayload ?? null,
822
+ resumePayload: payload.payload.resumePayload ?? null,
823
+ output: null
824
+ };
825
+ return {
826
+ type: isNested ? "data-tool-workflow" : "data-workflow",
827
+ id: payload.runId,
828
+ data: {
829
+ name: current.name,
830
+ status: "suspended",
831
+ steps: current.steps,
832
+ output: null
833
+ }
834
+ };
835
+ }
836
+ case "workflow-finish": {
837
+ const current = bufferedWorkflows.get(payload.runId);
838
+ if (!current) return null;
839
+ return {
840
+ type: isNested ? "data-tool-workflow" : "data-workflow",
841
+ id: payload.runId,
842
+ data: {
843
+ name: current.name,
844
+ steps: current.steps,
845
+ output: payload.payload.output ?? null,
846
+ status: payload.payload.workflowStatus
847
+ }
848
+ };
849
+ }
850
+ case "workflow-step-output": {
851
+ const output = payload.payload.output;
852
+ if (includeTextStreamParts && output && isMastraTextStreamChunk(output)) {
853
+ const part = convertMastraChunkToAISDKv5({ chunk: output, mode: "stream" });
854
+ const transformedChunk = convertFullStreamChunkToUIMessageStream({
855
+ part,
856
+ onError(error) {
857
+ return safeParseErrorObject(error);
858
+ }
859
+ });
860
+ return transformedChunk;
861
+ }
862
+ if (output && isDataChunkType(output)) {
863
+ if (!("data" in output)) {
864
+ throw new Error(
865
+ `UI Messages require a data property when using data- prefixed chunks
866
+ ${JSON.stringify(output)}`
867
+ );
868
+ }
869
+ return output;
870
+ }
871
+ return null;
872
+ }
873
+ default: {
874
+ if (isDataChunkType(payload)) {
875
+ if (!("data" in payload)) {
876
+ throw new Error(
877
+ `UI Messages require a data property when using data- prefixed chunks
878
+ ${JSON.stringify(payload)}`
879
+ );
880
+ }
881
+ return payload;
882
+ }
883
+ return null;
884
+ }
885
+ }
886
+ }
887
+ function transformNetwork(payload, bufferedNetworks, isNested) {
888
+ switch (payload.type) {
889
+ case "routing-agent-start": {
890
+ if (!bufferedNetworks.has(payload.runId)) {
891
+ bufferedNetworks.set(payload.runId, {
892
+ name: payload.payload.networkId,
893
+ steps: [],
894
+ usage: null,
895
+ output: null
896
+ });
897
+ }
898
+ const current = bufferedNetworks.get(payload.runId);
899
+ current.steps.push({
900
+ id: payload.payload.runId,
901
+ name: payload.payload.agentId,
902
+ status: "running",
903
+ iteration: payload.payload.inputData.iteration,
904
+ input: {
905
+ task: payload.payload.inputData.task,
906
+ threadId: payload.payload.inputData.threadId,
907
+ threadResourceId: payload.payload.inputData.threadResourceId
908
+ },
909
+ output: "",
910
+ task: null,
911
+ suspendPayload: null,
912
+ resumePayload: null,
913
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
914
+ });
915
+ return {
916
+ type: isNested ? "data-tool-network" : "data-network",
917
+ id: payload.runId,
918
+ data: {
919
+ name: bufferedNetworks.get(payload.runId).name,
920
+ status: "running",
921
+ usage: null,
922
+ steps: bufferedNetworks.get(payload.runId).steps,
923
+ output: null
924
+ }
925
+ };
926
+ }
927
+ case "routing-agent-text-start": {
928
+ const current = bufferedNetworks.get(payload.runId);
929
+ if (!current) return null;
930
+ return {
931
+ type: "text-start",
932
+ id: payload.runId
933
+ };
934
+ }
935
+ case "routing-agent-text-delta": {
936
+ const current = bufferedNetworks.get(payload.runId);
937
+ if (!current) return null;
938
+ return {
939
+ type: "text-delta",
940
+ id: payload.runId,
941
+ delta: payload.payload.text
942
+ };
943
+ }
944
+ case "agent-execution-start": {
945
+ const current = bufferedNetworks.get(payload.runId);
946
+ if (!current) return null;
947
+ current.steps.push({
948
+ id: payload.payload.runId,
949
+ name: payload.payload.agentId,
950
+ status: "running",
951
+ iteration: payload.payload.args?.iteration ?? 0,
952
+ input: { prompt: payload.payload.args?.prompt ?? "" },
953
+ output: null,
954
+ task: null,
955
+ suspendPayload: null,
956
+ resumePayload: null,
957
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
958
+ });
959
+ bufferedNetworks.set(payload.runId, current);
960
+ return {
961
+ type: isNested ? "data-tool-network" : "data-network",
962
+ id: payload.runId,
963
+ data: {
964
+ ...current,
965
+ status: "running"
966
+ }
967
+ };
968
+ }
969
+ case "workflow-execution-start": {
970
+ const current = bufferedNetworks.get(payload.runId);
971
+ if (!current) return null;
972
+ current.steps.push({
973
+ id: payload.payload.runId,
974
+ name: payload.payload.workflowId,
975
+ status: "running",
976
+ iteration: payload.payload.args?.iteration ?? 0,
977
+ input: { prompt: payload.payload.args?.prompt ?? "" },
978
+ output: null,
979
+ task: null,
980
+ suspendPayload: null,
981
+ resumePayload: null,
982
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
983
+ });
984
+ bufferedNetworks.set(payload.runId, current);
985
+ return {
986
+ type: isNested ? "data-tool-network" : "data-network",
987
+ id: payload.runId,
988
+ data: {
989
+ ...current,
990
+ status: "running"
991
+ }
992
+ };
993
+ }
994
+ case "tool-execution-start": {
995
+ const current = bufferedNetworks.get(payload.runId);
996
+ if (!current) return null;
997
+ current.steps.push({
998
+ id: payload.payload.args.toolCallId,
999
+ name: payload.payload.args?.toolName,
1000
+ status: "running",
1001
+ iteration: payload.payload.args?.iteration ? Number(payload.payload.args.iteration) : 0,
1002
+ task: {
1003
+ id: payload.payload.args?.toolName
1004
+ },
1005
+ input: payload.payload.args?.args || null,
1006
+ output: null,
1007
+ suspendPayload: null,
1008
+ resumePayload: null,
1009
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
1010
+ });
1011
+ bufferedNetworks.set(payload.runId, current);
1012
+ return {
1013
+ type: isNested ? "data-tool-network" : "data-network",
1014
+ id: payload.runId,
1015
+ data: {
1016
+ ...current,
1017
+ status: "running"
1018
+ }
1019
+ };
1020
+ }
1021
+ case "agent-execution-end": {
1022
+ const current = bufferedNetworks.get(payload.runId);
1023
+ if (!current) return null;
1024
+ const stepId = payload.payload.runId;
1025
+ const step = current.steps.find((step2) => step2.id === stepId);
1026
+ if (!step) {
1027
+ return null;
1028
+ }
1029
+ step.status = "success";
1030
+ step.output = payload.payload.result;
1031
+ return {
1032
+ type: isNested ? "data-tool-network" : "data-network",
1033
+ id: payload.runId,
1034
+ data: {
1035
+ ...current,
1036
+ usage: payload.payload?.usage ?? current.usage,
1037
+ status: "running",
1038
+ output: payload.payload.result ?? current.output
1039
+ }
1040
+ };
1041
+ }
1042
+ case "tool-execution-end": {
1043
+ const current = bufferedNetworks.get(payload.runId);
1044
+ if (!current) return null;
1045
+ const stepId = payload.payload.toolCallId;
1046
+ const step = current.steps.find((step2) => step2.id === stepId);
1047
+ if (!step) {
1048
+ return null;
1049
+ }
1050
+ step.status = "success";
1051
+ step.output = payload.payload.result;
1052
+ return {
1053
+ type: isNested ? "data-tool-network" : "data-network",
1054
+ id: payload.runId,
1055
+ data: {
1056
+ ...current,
1057
+ status: "running",
1058
+ output: payload.payload.result ?? current.output
1059
+ }
1060
+ };
1061
+ }
1062
+ case "workflow-execution-end": {
1063
+ const current = bufferedNetworks.get(payload.runId);
1064
+ if (!current) return null;
1065
+ const stepId = payload.payload.runId;
1066
+ const step = current.steps.find((step2) => step2.id === stepId);
1067
+ if (!step) {
1068
+ return null;
1069
+ }
1070
+ step.status = "success";
1071
+ step.output = payload.payload.result;
1072
+ return {
1073
+ type: isNested ? "data-tool-network" : "data-network",
1074
+ id: payload.runId,
1075
+ data: {
1076
+ ...current,
1077
+ usage: payload.payload?.usage ?? current.usage,
1078
+ status: "running",
1079
+ output: payload.payload.result ?? current.output
1080
+ }
1081
+ };
1082
+ }
1083
+ case "routing-agent-end": {
1084
+ const current = bufferedNetworks.get(payload.runId);
1085
+ if (!current) return null;
1086
+ const stepId = payload.payload.runId;
1087
+ const step = current.steps.find((step2) => step2.id === stepId);
1088
+ if (!step) {
1089
+ return null;
1090
+ }
1091
+ step.status = "success";
1092
+ step.task = {
1093
+ id: payload.payload.primitiveId,
1094
+ type: payload.payload.primitiveType,
1095
+ name: payload.payload.task,
1096
+ reason: payload.payload.selectionReason
1097
+ };
1098
+ step.output = payload.payload.result;
1099
+ return {
1100
+ type: isNested ? "data-tool-network" : "data-network",
1101
+ id: payload.runId,
1102
+ data: {
1103
+ ...current,
1104
+ usage: payload.payload?.usage ?? current.usage,
1105
+ output: payload.payload?.result ?? current.output
1106
+ }
1107
+ };
1108
+ }
1109
+ case "network-execution-event-step-finish": {
1110
+ const current = bufferedNetworks.get(payload.runId);
1111
+ if (!current) return null;
1112
+ return {
1113
+ type: isNested ? "data-tool-network" : "data-network",
1114
+ id: payload.runId,
1115
+ data: {
1116
+ ...current,
1117
+ status: "finished",
1118
+ output: payload.payload?.result ?? current.output
1119
+ }
1120
+ };
1121
+ }
1122
+ case "network-execution-event-finish": {
1123
+ const current = bufferedNetworks.get(payload.runId);
1124
+ if (!current) return null;
1125
+ return {
1126
+ type: isNested ? "data-tool-network" : "data-network",
1127
+ id: payload.runId,
1128
+ data: {
1129
+ ...current,
1130
+ usage: payload.payload?.usage ?? current.usage,
1131
+ status: "finished",
1132
+ output: payload.payload?.result ?? current.output
1133
+ }
1134
+ };
1135
+ }
1136
+ default: {
1137
+ if (payload.type.startsWith("agent-execution-event-")) {
1138
+ const stepId = payload.payload.runId;
1139
+ const current = bufferedNetworks.get(payload.runId);
1140
+ if (!current) return null;
1141
+ const step = current.steps.find((step2) => step2.id === stepId);
1142
+ if (!step) {
1143
+ return null;
1144
+ }
1145
+ step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
1146
+ const result = transformAgent(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
1147
+ if (result) {
1148
+ const { request, response, ...data } = result.data;
1149
+ step.task = data;
1150
+ }
1151
+ }
1152
+ if (payload.type.startsWith("workflow-execution-event-")) {
1153
+ const stepId = payload.payload.runId;
1154
+ const current = bufferedNetworks.get(payload.runId);
1155
+ if (!current) return null;
1156
+ const step = current.steps.find((step2) => step2.id === stepId);
1157
+ if (!step) {
1158
+ return null;
1159
+ }
1160
+ step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
1161
+ const result = transformWorkflow(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
1162
+ if (result && "data" in result) {
1163
+ const data = result.data;
1164
+ step.task = data;
1165
+ if (data.name && step.task) {
1166
+ step.task.id = data.name;
1167
+ }
1168
+ }
1169
+ }
1170
+ if (isDataChunkType(payload)) {
1171
+ if (!("data" in payload)) {
1172
+ throw new Error(
1173
+ `UI Messages require a data property when using data- prefixed chunks
1174
+ ${JSON.stringify(payload)}`
1175
+ );
1176
+ }
1177
+ const { type, data } = payload;
1178
+ return { type, data };
1179
+ }
1180
+ if (isAgentExecutionDataChunkType(payload)) {
1181
+ if (!("data" in payload.payload)) {
1182
+ throw new Error(
1183
+ `UI Messages require a data property when using data- prefixed chunks
1184
+ ${JSON.stringify(payload)}`
1185
+ );
1186
+ }
1187
+ const { type, data } = payload.payload;
1188
+ return { type, data };
1189
+ }
1190
+ if (isWorkflowExecutionDataChunkType(payload)) {
1191
+ if (!("data" in payload.payload)) {
1192
+ throw new Error(
1193
+ `UI Messages require a data property when using data- prefixed chunks
1194
+ ${JSON.stringify(payload)}`
1195
+ );
1196
+ }
1197
+ const { type, data } = payload.payload;
1198
+ return { type, data };
1199
+ }
1200
+ return null;
1201
+ }
1202
+ }
1203
+ }
1204
+
1205
+ // src/convert-streams.ts
1206
+ function toAISdkV5Stream(stream, options = {
1207
+ from: "agent",
1208
+ sendStart: true,
1209
+ sendFinish: true
1210
+ }) {
1211
+ const from = options?.from;
1212
+ if (from === "workflow") {
1213
+ const includeTextStreamParts = options?.includeTextStreamParts ?? true;
1214
+ return stream.pipeThrough(
1215
+ WorkflowStreamToAISDKTransformer({ includeTextStreamParts })
1216
+ );
1217
+ }
1218
+ if (from === "network") {
1219
+ return stream.pipeThrough(AgentNetworkToAISDKTransformer());
1220
+ }
1221
+ const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
1222
+ return agentReadable.pipeThrough(
1223
+ AgentStreamToAISDKTransformer({
1224
+ lastMessageId: options?.lastMessageId,
1225
+ sendStart: options?.sendStart,
1226
+ sendFinish: options?.sendFinish,
1227
+ sendReasoning: options?.sendReasoning,
1228
+ sendSources: options?.sendSources,
1229
+ messageMetadata: options?.messageMetadata,
1230
+ onError: options?.onError
1231
+ })
1232
+ );
1233
+ }
1234
+
1235
+ // src/chat-route.ts
1236
+ async function handleChatStream({
1237
+ mastra,
1238
+ agentId,
1239
+ params,
1240
+ defaultOptions,
1241
+ sendStart = true,
1242
+ sendFinish = true,
1243
+ sendReasoning = false,
1244
+ sendSources = false
1245
+ }) {
1246
+ const { messages, resumeData, runId, requestContext, ...rest } = params;
1247
+ if (resumeData && !runId) {
1248
+ throw new Error("runId is required when resumeData is provided");
1249
+ }
1250
+ const agentObj = mastra.getAgentById(agentId);
1251
+ if (!agentObj) {
1252
+ throw new Error(`Agent ${agentId} not found`);
1253
+ }
1254
+ if (!Array.isArray(messages)) {
1255
+ throw new Error("Messages must be an array of UIMessage objects");
1256
+ }
1257
+ const mergedOptions = {
1258
+ ...defaultOptions,
1259
+ ...rest,
1260
+ ...runId && { runId },
1261
+ requestContext: requestContext || defaultOptions?.requestContext
1262
+ };
1263
+ const result = resumeData ? await agentObj.resumeStream(resumeData, mergedOptions) : await agentObj.stream(messages, mergedOptions);
1264
+ let lastMessageId;
1265
+ if (messages.length) {
1266
+ const lastMessage = messages[messages.length - 1];
1267
+ if (lastMessage?.role === "assistant") {
1268
+ lastMessageId = lastMessage.id;
1269
+ }
1270
+ }
1271
+ return ai.createUIMessageStream({
1272
+ originalMessages: messages,
1273
+ execute: async ({ writer }) => {
1274
+ for await (const part of toAISdkV5Stream(result, {
1275
+ from: "agent",
1276
+ lastMessageId,
1277
+ sendStart,
1278
+ sendFinish,
1279
+ sendReasoning,
1280
+ sendSources
1281
+ })) {
1282
+ writer.write(part);
1283
+ }
1284
+ }
1285
+ });
1286
+ }
6
1287
  function chatRoute({
7
1288
  path = "/chat/:agentId",
8
1289
  agent,
9
- defaultOptions
1290
+ defaultOptions,
1291
+ sendStart = true,
1292
+ sendFinish = true,
1293
+ sendReasoning = false,
1294
+ sendSources = false
10
1295
  }) {
11
1296
  if (!agent && !path.includes("/:agentId")) {
12
1297
  throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
@@ -35,6 +1320,14 @@ function chatRoute({
35
1320
  schema: {
36
1321
  type: "object",
37
1322
  properties: {
1323
+ resumeData: {
1324
+ type: "object",
1325
+ description: "Resume data for the agent"
1326
+ },
1327
+ runId: {
1328
+ type: "string",
1329
+ description: "The run ID required when resuming an agent execution"
1330
+ },
38
1331
  messages: {
39
1332
  type: "array",
40
1333
  description: "Array of messages in the conversation",
@@ -105,8 +1398,9 @@ function chatRoute({
105
1398
  }
106
1399
  },
107
1400
  handler: async (c) => {
108
- const { messages, ...rest } = await c.req.json();
1401
+ const params = await c.req.json();
109
1402
  const mastra = c.get("mastra");
1403
+ const contextRequestContext = c.get("requestContext");
110
1404
  let agentToUse = agent;
111
1405
  if (!agent) {
112
1406
  const agentId = c.req.param("agentId");
@@ -117,23 +1411,263 @@ function chatRoute({
117
1411
  `Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
118
1412
  );
119
1413
  }
1414
+ if (contextRequestContext && defaultOptions?.requestContext) {
1415
+ mastra.getLogger()?.warn(`"requestContext" set in the route options will be overridden by the request's "requestContext".`);
1416
+ }
120
1417
  if (!agentToUse) {
121
1418
  throw new Error("Agent ID is required");
122
1419
  }
123
- const agentObj = mastra.getAgent(agentToUse);
124
- if (!agentObj) {
125
- throw new Error(`Agent ${agentToUse} not found`);
1420
+ const uiMessageStream = await handleChatStream({
1421
+ mastra,
1422
+ agentId: agentToUse,
1423
+ params: {
1424
+ ...params,
1425
+ requestContext: contextRequestContext || params.requestContext
1426
+ },
1427
+ defaultOptions,
1428
+ sendStart,
1429
+ sendFinish,
1430
+ sendReasoning,
1431
+ sendSources
1432
+ });
1433
+ return ai.createUIMessageStreamResponse({
1434
+ stream: uiMessageStream
1435
+ });
1436
+ }
1437
+ });
1438
+ }
1439
+ async function handleWorkflowStream({
1440
+ mastra,
1441
+ workflowId,
1442
+ params,
1443
+ includeTextStreamParts = true
1444
+ }) {
1445
+ const { runId, resourceId, inputData, resumeData, requestContext, ...rest } = params;
1446
+ const workflowObj = mastra.getWorkflowById(workflowId);
1447
+ if (!workflowObj) {
1448
+ throw new Error(`Workflow ${workflowId} not found`);
1449
+ }
1450
+ const run = await workflowObj.createRun({ runId, resourceId, ...rest });
1451
+ const stream = resumeData ? run.resumeStream({ resumeData, ...rest, requestContext }) : run.stream({ inputData, ...rest, requestContext });
1452
+ return ai.createUIMessageStream({
1453
+ execute: async ({ writer }) => {
1454
+ for await (const part of toAISdkV5Stream(stream, { from: "workflow", includeTextStreamParts })) {
1455
+ writer.write(part);
1456
+ }
1457
+ }
1458
+ });
1459
+ }
1460
+ function workflowRoute({
1461
+ path = "/api/workflows/:workflowId/stream",
1462
+ workflow,
1463
+ includeTextStreamParts = true
1464
+ }) {
1465
+ if (!workflow && !path.includes("/:workflowId")) {
1466
+ throw new Error("Path must include :workflowId to route to the correct workflow or pass the workflow explicitly");
1467
+ }
1468
+ return server.registerApiRoute(path, {
1469
+ method: "POST",
1470
+ openapi: {
1471
+ summary: "Stream a workflow in AI SDK format",
1472
+ description: "Starts a workflow run and streams events as AI SDK UIMessage chunks",
1473
+ tags: ["ai-sdk"],
1474
+ parameters: [
1475
+ {
1476
+ name: "workflowId",
1477
+ in: "path",
1478
+ required: true,
1479
+ description: "The ID of the workflow to stream",
1480
+ schema: { type: "string" }
1481
+ }
1482
+ ],
1483
+ requestBody: {
1484
+ required: true,
1485
+ content: {
1486
+ "application/json": {
1487
+ schema: {
1488
+ type: "object",
1489
+ properties: {
1490
+ runId: { type: "string" },
1491
+ resourceId: { type: "string" },
1492
+ inputData: { type: "object", additionalProperties: true },
1493
+ resumeData: { type: "object", additionalProperties: true },
1494
+ requestContext: { type: "object", additionalProperties: true },
1495
+ tracingOptions: { type: "object", additionalProperties: true },
1496
+ step: { type: "string" }
1497
+ }
1498
+ }
1499
+ }
1500
+ }
1501
+ },
1502
+ responses: {
1503
+ "200": {
1504
+ description: "Workflow UIMessage event stream",
1505
+ content: {
1506
+ "text/plain": {
1507
+ schema: { type: "string", description: "SSE stream" }
1508
+ }
1509
+ }
1510
+ }
1511
+ }
1512
+ },
1513
+ handler: async (c) => {
1514
+ const params = await c.req.json();
1515
+ const mastra = c.get("mastra");
1516
+ const contextRequestContext = c.get("requestContext");
1517
+ let workflowToUse = workflow;
1518
+ if (!workflow) {
1519
+ const workflowId = c.req.param("workflowId");
1520
+ workflowToUse = workflowId;
126
1521
  }
127
- const result = await agentObj.streamVNext(messages, {
128
- ...defaultOptions,
129
- ...rest,
130
- format: "aisdk"
1522
+ if (c.req.param("workflowId") && workflow) {
1523
+ mastra.getLogger()?.warn(
1524
+ `Fixed workflow ID was set together with a workflowId path parameter. This can lead to unexpected behavior.`
1525
+ );
1526
+ }
1527
+ if (!workflowToUse) {
1528
+ throw new Error("Workflow ID is required");
1529
+ }
1530
+ if (contextRequestContext && params.requestContext) {
1531
+ mastra.getLogger()?.warn(
1532
+ `"requestContext" from the request body will be ignored because "requestContext" is already set in the route options.`
1533
+ );
1534
+ }
1535
+ const uiMessageStream = await handleWorkflowStream({
1536
+ mastra,
1537
+ workflowId: workflowToUse,
1538
+ params: {
1539
+ ...params,
1540
+ requestContext: contextRequestContext || params.requestContext
1541
+ },
1542
+ includeTextStreamParts
131
1543
  });
132
- return result.toUIMessageStreamResponse();
1544
+ return ai.createUIMessageStreamResponse({ stream: uiMessageStream });
1545
+ }
1546
+ });
1547
+ }
1548
+ async function handleNetworkStream({
1549
+ mastra,
1550
+ agentId,
1551
+ params,
1552
+ defaultOptions
1553
+ }) {
1554
+ const { messages, ...rest } = params;
1555
+ const agentObj = mastra.getAgentById(agentId);
1556
+ if (!agentObj) {
1557
+ throw new Error(`Agent ${agentId} not found`);
1558
+ }
1559
+ const result = await agentObj.network(messages, {
1560
+ ...defaultOptions,
1561
+ ...rest
1562
+ });
1563
+ return ai.createUIMessageStream({
1564
+ execute: async ({ writer }) => {
1565
+ for await (const part of toAISdkV5Stream(result, { from: "network" })) {
1566
+ writer.write(part);
1567
+ }
133
1568
  }
134
1569
  });
135
1570
  }
1571
+ function networkRoute({
1572
+ path = "/network/:agentId",
1573
+ agent,
1574
+ defaultOptions
1575
+ }) {
1576
+ if (!agent && !path.includes("/:agentId")) {
1577
+ throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
1578
+ }
1579
+ return server.registerApiRoute(path, {
1580
+ method: "POST",
1581
+ openapi: {
1582
+ summary: "Execute an agent network and stream AI SDK events",
1583
+ description: "Routes a request to an agent network and streams UIMessage chunks in AI SDK format",
1584
+ tags: ["ai-sdk"],
1585
+ parameters: [
1586
+ {
1587
+ name: "agentId",
1588
+ in: "path",
1589
+ required: true,
1590
+ description: "The ID of the routing agent to execute as a network",
1591
+ schema: { type: "string" }
1592
+ }
1593
+ ],
1594
+ requestBody: {
1595
+ required: true,
1596
+ content: {
1597
+ "application/json": {
1598
+ schema: {
1599
+ type: "object",
1600
+ properties: {
1601
+ messages: { type: "array", items: { type: "object" } },
1602
+ requestContext: { type: "object", additionalProperties: true },
1603
+ runId: { type: "string" },
1604
+ maxSteps: { type: "number" },
1605
+ threadId: { type: "string" },
1606
+ resourceId: { type: "string" },
1607
+ modelSettings: { type: "object", additionalProperties: true },
1608
+ tools: { type: "array", items: { type: "object" } }
1609
+ },
1610
+ required: ["messages"]
1611
+ }
1612
+ }
1613
+ }
1614
+ },
1615
+ responses: {
1616
+ "200": {
1617
+ description: "Streaming AI SDK UIMessage event stream for the agent network",
1618
+ content: { "text/plain": { schema: { type: "string", description: "SSE stream" } } }
1619
+ },
1620
+ "404": {
1621
+ description: "Agent not found",
1622
+ content: {
1623
+ "application/json": {
1624
+ schema: { type: "object", properties: { error: { type: "string" } } }
1625
+ }
1626
+ }
1627
+ }
1628
+ }
1629
+ },
1630
+ handler: async (c) => {
1631
+ const params = await c.req.json();
1632
+ const mastra = c.get("mastra");
1633
+ let agentToUse = agent;
1634
+ if (!agent) {
1635
+ const agentId = c.req.param("agentId");
1636
+ agentToUse = agentId;
1637
+ }
1638
+ if (c.req.param("agentId") && agent) {
1639
+ mastra.getLogger()?.warn(
1640
+ `Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
1641
+ );
1642
+ }
1643
+ if (!agentToUse) {
1644
+ throw new Error("Agent ID is required");
1645
+ }
1646
+ const uiMessageStream = await handleNetworkStream({
1647
+ mastra,
1648
+ agentId: agentToUse,
1649
+ params,
1650
+ defaultOptions
1651
+ });
1652
+ return ai.createUIMessageStreamResponse({ stream: uiMessageStream });
1653
+ }
1654
+ });
1655
+ }
1656
+
1657
+ // src/to-ai-sdk-format.ts
1658
+ function toAISdkFormat() {
1659
+ throw new Error(
1660
+ '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.'
1661
+ );
1662
+ }
136
1663
 
137
1664
  exports.chatRoute = chatRoute;
1665
+ exports.handleChatStream = handleChatStream;
1666
+ exports.handleNetworkStream = handleNetworkStream;
1667
+ exports.handleWorkflowStream = handleWorkflowStream;
1668
+ exports.networkRoute = networkRoute;
1669
+ exports.toAISdkFormat = toAISdkFormat;
1670
+ exports.toAISdkStream = toAISdkV5Stream;
1671
+ exports.workflowRoute = workflowRoute;
138
1672
  //# sourceMappingURL=index.cjs.map
139
1673
  //# sourceMappingURL=index.cjs.map