@mastra/ai-sdk 0.0.0-roamin-openaivoice-speak-options-passing-20250926163614 → 0.0.0-safe-stringify-telemetry-20251205024938

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