@mastra/ai-sdk 0.0.0-dynamic-model-router-20251010230835 → 0.0.0-error-handler-fix-20251020202607

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
@@ -210,6 +210,9 @@ function convertMastraChunkToAISDKv5({
210
210
  ...chunk.payload || {}
211
211
  };
212
212
  }
213
+ if ("type" in chunk && chunk.type?.startsWith("data-")) {
214
+ return chunk;
215
+ }
213
216
  return;
214
217
  }
215
218
  }
@@ -223,7 +226,7 @@ function convertFullStreamChunkToUIMessageStream({
223
226
  sendFinish,
224
227
  responseMessageId
225
228
  }) {
226
- const partType = part.type;
229
+ const partType = part?.type;
227
230
  switch (partType) {
228
231
  case "text-start": {
229
232
  return {
@@ -380,8 +383,16 @@ function convertFullStreamChunkToUIMessageStream({
380
383
  return;
381
384
  }
382
385
  default: {
383
- const exhaustiveCheck = partType;
384
- throw new Error(`Unknown chunk type: ${exhaustiveCheck}`);
386
+ if ("type" in part && part.type?.startsWith("data-")) {
387
+ if (!("data" in part)) {
388
+ throw new Error(
389
+ `UI Messages require a data property when using data- prefixed chunks
390
+ ${JSON.stringify(part)}`
391
+ );
392
+ }
393
+ return part;
394
+ }
395
+ return;
385
396
  }
386
397
  }
387
398
  }
@@ -392,24 +403,35 @@ function WorkflowStreamToAISDKTransformer() {
392
403
  return new TransformStream({
393
404
  start(controller) {
394
405
  controller.enqueue({
395
- data: JSON.stringify({
396
- type: "start",
397
- messageId: "1"
398
- })
406
+ type: "start"
399
407
  });
400
408
  },
401
409
  flush(controller) {
402
410
  controller.enqueue({
403
- data: JSON.stringify({
404
- type: "finish"
405
- })
411
+ type: "finish"
412
+ });
413
+ },
414
+ transform(chunk, controller) {
415
+ const transformed = transformWorkflow(chunk, bufferedWorkflows);
416
+ if (transformed) controller.enqueue(transformed);
417
+ }
418
+ });
419
+ }
420
+ function AgentNetworkToAISDKTransformer() {
421
+ const bufferedNetworks = /* @__PURE__ */ new Map();
422
+ return new TransformStream({
423
+ start(controller) {
424
+ controller.enqueue({
425
+ type: "start"
406
426
  });
427
+ },
428
+ flush(controller) {
407
429
  controller.enqueue({
408
- data: "[DONE]"
430
+ type: "finish"
409
431
  });
410
432
  },
411
433
  transform(chunk, controller) {
412
- const transformed = transformWorkflow(chunk, bufferedWorkflows);
434
+ const transformed = transformNetwork(chunk, bufferedNetworks);
413
435
  if (transformed) controller.enqueue(transformed);
414
436
  }
415
437
  });
@@ -437,11 +459,11 @@ function AgentStreamToAISDKTransformer() {
437
459
  if (agentTransformed) controller.enqueue(agentTransformed);
438
460
  } else if (transformedChunk.type === "tool-workflow") {
439
461
  const payload = transformedChunk.payload;
440
- const workflowChunk = transformWorkflow(payload, bufferedSteps);
462
+ const workflowChunk = transformWorkflow(payload, bufferedSteps, true);
441
463
  if (workflowChunk) controller.enqueue(workflowChunk);
442
464
  } else if (transformedChunk.type === "tool-network") {
443
465
  const payload = transformedChunk.payload;
444
- const networkChunk = transformNetwork(payload, bufferedSteps);
466
+ const networkChunk = transformNetwork(payload, bufferedSteps, true);
445
467
  if (networkChunk) controller.enqueue(networkChunk);
446
468
  } else {
447
469
  controller.enqueue(transformedChunk);
@@ -586,7 +608,7 @@ function transformAgent(payload, bufferedSteps) {
586
608
  }
587
609
  return null;
588
610
  }
589
- function transformWorkflow(payload, bufferedWorkflows) {
611
+ function transformWorkflow(payload, bufferedWorkflows, isNested) {
590
612
  switch (payload.type) {
591
613
  case "workflow-start":
592
614
  bufferedWorkflows.set(payload.runId, {
@@ -594,7 +616,7 @@ function transformWorkflow(payload, bufferedWorkflows) {
594
616
  steps: {}
595
617
  });
596
618
  return {
597
- type: "data-workflow",
619
+ type: isNested ? "data-tool-workflow" : "data-workflow",
598
620
  id: payload.runId,
599
621
  data: {
600
622
  name: bufferedWorkflows.get(payload.runId).name,
@@ -613,7 +635,7 @@ function transformWorkflow(payload, bufferedWorkflows) {
613
635
  };
614
636
  bufferedWorkflows.set(payload.runId, current);
615
637
  return {
616
- type: "data-workflow",
638
+ type: isNested ? "data-tool-workflow" : "data-workflow",
617
639
  id: payload.runId,
618
640
  data: {
619
641
  name: current.name,
@@ -632,7 +654,7 @@ function transformWorkflow(payload, bufferedWorkflows) {
632
654
  output: payload.payload.output ?? null
633
655
  };
634
656
  return {
635
- type: "data-workflow",
657
+ type: isNested ? "data-tool-workflow" : "data-workflow",
636
658
  id: payload.runId,
637
659
  data: {
638
660
  name: current.name,
@@ -646,7 +668,7 @@ function transformWorkflow(payload, bufferedWorkflows) {
646
668
  const current = bufferedWorkflows.get(payload.runId);
647
669
  if (!current) return null;
648
670
  return {
649
- type: "data-workflow",
671
+ type: isNested ? "data-tool-workflow" : "data-workflow",
650
672
  id: payload.runId,
651
673
  data: {
652
674
  name: current.name,
@@ -660,15 +682,17 @@ function transformWorkflow(payload, bufferedWorkflows) {
660
682
  return null;
661
683
  }
662
684
  }
663
- function transformNetwork(payload, bufferedNetworks) {
685
+ function transformNetwork(payload, bufferedNetworks, isNested) {
664
686
  switch (payload.type) {
665
687
  case "routing-agent-start": {
666
- bufferedNetworks.set(payload.payload.runId, {
667
- name: payload.payload.agentId,
668
- steps: []
669
- });
688
+ if (!bufferedNetworks.has(payload.payload.runId)) {
689
+ bufferedNetworks.set(payload.payload.runId, {
690
+ name: payload.payload.agentId,
691
+ steps: []
692
+ });
693
+ }
670
694
  return {
671
- type: "data-network",
695
+ type: isNested ? "data-tool-network" : "data-network",
672
696
  id: payload.payload.runId,
673
697
  data: {
674
698
  name: bufferedNetworks.get(payload.payload.runId).name,
@@ -678,6 +702,23 @@ function transformNetwork(payload, bufferedNetworks) {
678
702
  }
679
703
  };
680
704
  }
705
+ case "routing-agent-text-start": {
706
+ const current = bufferedNetworks.get(payload.runId);
707
+ if (!current) return null;
708
+ return {
709
+ type: "text-start",
710
+ id: payload.runId
711
+ };
712
+ }
713
+ case "routing-agent-text-delta": {
714
+ const current = bufferedNetworks.get(payload.runId);
715
+ if (!current) return null;
716
+ return {
717
+ type: "text-delta",
718
+ id: payload.runId,
719
+ delta: payload.payload.text
720
+ };
721
+ }
681
722
  case "agent-execution-start": {
682
723
  const current = bufferedNetworks.get(payload.payload.runId) || { name: "", steps: [] };
683
724
  current.steps.push({
@@ -688,7 +729,7 @@ function transformNetwork(payload, bufferedNetworks) {
688
729
  });
689
730
  bufferedNetworks.set(payload.payload.runId, current);
690
731
  return {
691
- type: "data-network",
732
+ type: isNested ? "data-tool-network" : "data-network",
692
733
  id: payload.payload.runId,
693
734
  data: {
694
735
  name: current.name,
@@ -708,7 +749,7 @@ function transformNetwork(payload, bufferedNetworks) {
708
749
  });
709
750
  bufferedNetworks.set(payload.payload.runId, current);
710
751
  return {
711
- type: "data-network",
752
+ type: isNested ? "data-tool-network" : "data-network",
712
753
  id: payload.payload.runId,
713
754
  data: {
714
755
  name: current.name,
@@ -728,7 +769,7 @@ function transformNetwork(payload, bufferedNetworks) {
728
769
  });
729
770
  bufferedNetworks.set(payload.payload.runId, current);
730
771
  return {
731
- type: "data-network",
772
+ type: isNested ? "data-tool-network" : "data-network",
732
773
  id: payload.payload.runId,
733
774
  data: {
734
775
  name: current.name,
@@ -738,32 +779,63 @@ function transformNetwork(payload, bufferedNetworks) {
738
779
  }
739
780
  };
740
781
  }
741
- case "agent-execution-end":
782
+ case "agent-execution-end": {
783
+ const current = bufferedNetworks.get(payload.runId);
784
+ if (!current) return null;
785
+ current.steps.push({
786
+ name: payload.payload.agentId,
787
+ status: "success",
788
+ input: null,
789
+ output: payload.payload.result
790
+ });
791
+ return {
792
+ type: isNested ? "data-tool-network" : "data-network",
793
+ id: payload.runId,
794
+ data: {
795
+ name: current.name,
796
+ status: "running",
797
+ steps: current.steps,
798
+ output: payload.payload.result ?? null
799
+ }
800
+ };
801
+ }
742
802
  case "tool-execution-end": {
743
803
  const current = bufferedNetworks.get(payload.runId);
744
804
  if (!current) return null;
805
+ current.steps.push({
806
+ name: payload.payload.toolName,
807
+ status: "success",
808
+ input: null,
809
+ output: payload.payload.result
810
+ });
745
811
  return {
746
- type: "data-network",
812
+ type: isNested ? "data-tool-network" : "data-network",
747
813
  id: payload.runId,
748
814
  data: {
749
815
  name: current.name,
750
816
  status: "running",
751
817
  steps: current.steps,
752
- output: null
818
+ output: payload.payload.result ?? null
753
819
  }
754
820
  };
755
821
  }
756
822
  case "workflow-execution-end": {
757
823
  const current = bufferedNetworks.get(payload.runId);
758
824
  if (!current) return null;
825
+ current.steps.push({
826
+ name: payload.payload.name,
827
+ status: "success",
828
+ input: null,
829
+ output: payload.payload.result
830
+ });
759
831
  return {
760
- type: "data-network",
832
+ type: isNested ? "data-tool-network" : "data-network",
761
833
  id: payload.runId,
762
834
  data: {
763
835
  name: current.name,
764
836
  status: "running",
765
837
  steps: current.steps,
766
- output: null
838
+ output: payload.payload.result ?? null
767
839
  }
768
840
  };
769
841
  }
@@ -771,7 +843,7 @@ function transformNetwork(payload, bufferedNetworks) {
771
843
  const current = bufferedNetworks.get(payload.payload.runId);
772
844
  if (!current) return null;
773
845
  return {
774
- type: "data-network",
846
+ type: isNested ? "data-tool-network" : "data-network",
775
847
  id: payload.payload.runId,
776
848
  data: {
777
849
  name: current.name,
@@ -785,7 +857,7 @@ function transformNetwork(payload, bufferedNetworks) {
785
857
  const current = bufferedNetworks.get(payload.payload.runId);
786
858
  if (!current) return null;
787
859
  return {
788
- type: "data-network",
860
+ type: isNested ? "data-tool-network" : "data-network",
789
861
  id: payload.payload.runId,
790
862
  data: {
791
863
  name: current.name,
@@ -799,7 +871,7 @@ function transformNetwork(payload, bufferedNetworks) {
799
871
  const current = bufferedNetworks.get(payload.runId);
800
872
  if (!current) return null;
801
873
  return {
802
- type: "data-network",
874
+ type: isNested ? "data-tool-network" : "data-network",
803
875
  id: payload.runId,
804
876
  data: {
805
877
  name: current.name,
@@ -815,8 +887,16 @@ function transformNetwork(payload, bufferedNetworks) {
815
887
  }
816
888
 
817
889
  // src/to-ai-sdk-format.ts
818
- function toAISdkFormat(stream) {
819
- return stream.fullStream.pipeThrough(AgentStreamToAISDKTransformer());
890
+ function toAISdkFormat(stream, options = { from: "agent" }) {
891
+ const from = options?.from;
892
+ if (from === "workflow") {
893
+ return stream.pipeThrough(WorkflowStreamToAISDKTransformer());
894
+ }
895
+ if (from === "network") {
896
+ return stream.pipeThrough(AgentNetworkToAISDKTransformer());
897
+ }
898
+ const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
899
+ return agentReadable.pipeThrough(AgentStreamToAISDKTransformer());
820
900
  }
821
901
 
822
902
  // src/chat-route.ts
@@ -951,8 +1031,9 @@ function chatRoute({
951
1031
  runtimeContext: runtimeContext || defaultOptions?.runtimeContext
952
1032
  });
953
1033
  const uiMessageStream = ai.createUIMessageStream({
1034
+ originalMessages: messages,
954
1035
  execute: async ({ writer }) => {
955
- for await (const part of toAISdkFormat(result)) {
1036
+ for await (const part of toAISdkFormat(result, { from: "agent" })) {
956
1037
  writer.write(part);
957
1038
  }
958
1039
  }
@@ -963,9 +1044,186 @@ function chatRoute({
963
1044
  }
964
1045
  });
965
1046
  }
1047
+ function workflowRoute({
1048
+ path = "/api/workflows/:workflowId/stream",
1049
+ workflow
1050
+ }) {
1051
+ if (!workflow && !path.includes("/:workflowId")) {
1052
+ throw new Error("Path must include :workflowId to route to the correct workflow or pass the workflow explicitly");
1053
+ }
1054
+ return server.registerApiRoute(path, {
1055
+ method: "POST",
1056
+ openapi: {
1057
+ summary: "Stream a workflow in AI SDK format",
1058
+ description: "Starts a workflow run and streams events as AI SDK UIMessage chunks",
1059
+ tags: ["ai-sdk"],
1060
+ parameters: [
1061
+ {
1062
+ name: "workflowId",
1063
+ in: "path",
1064
+ required: true,
1065
+ description: "The ID of the workflow to stream",
1066
+ schema: { type: "string" }
1067
+ }
1068
+ ],
1069
+ requestBody: {
1070
+ required: true,
1071
+ content: {
1072
+ "application/json": {
1073
+ schema: {
1074
+ type: "object",
1075
+ properties: {
1076
+ inputData: { type: "object", additionalProperties: true },
1077
+ runtimeContext: { type: "object", additionalProperties: true },
1078
+ tracingOptions: { type: "object", additionalProperties: true }
1079
+ }
1080
+ }
1081
+ }
1082
+ }
1083
+ },
1084
+ responses: {
1085
+ "200": {
1086
+ description: "Workflow UIMessage event stream",
1087
+ content: {
1088
+ "text/plain": {
1089
+ schema: { type: "string", description: "SSE stream" }
1090
+ }
1091
+ }
1092
+ }
1093
+ }
1094
+ },
1095
+ handler: async (c) => {
1096
+ const { inputData, ...rest } = await c.req.json();
1097
+ const mastra = c.get("mastra");
1098
+ let workflowToUse = workflow;
1099
+ if (!workflow) {
1100
+ const workflowId = c.req.param("workflowId");
1101
+ workflowToUse = workflowId;
1102
+ }
1103
+ if (c.req.param("workflowId") && workflow) {
1104
+ mastra.getLogger()?.warn(
1105
+ `Fixed workflow ID was set together with a workflowId path parameter. This can lead to unexpected behavior.`
1106
+ );
1107
+ }
1108
+ if (!workflowToUse) {
1109
+ throw new Error("Workflow ID is required");
1110
+ }
1111
+ const workflowObj = mastra.getWorkflow(workflowToUse);
1112
+ if (!workflowObj) {
1113
+ throw new Error(`Workflow ${workflowToUse} not found`);
1114
+ }
1115
+ const run = await workflowObj.createRunAsync();
1116
+ const stream = run.streamVNext({ inputData, ...rest });
1117
+ const uiMessageStream = ai.createUIMessageStream({
1118
+ execute: async ({ writer }) => {
1119
+ for await (const part of toAISdkFormat(stream, { from: "workflow" })) {
1120
+ writer.write(part);
1121
+ }
1122
+ }
1123
+ });
1124
+ return ai.createUIMessageStreamResponse({ stream: uiMessageStream });
1125
+ }
1126
+ });
1127
+ }
1128
+ function networkRoute({
1129
+ path = "/network/:agentId",
1130
+ agent,
1131
+ defaultOptions
1132
+ }) {
1133
+ if (!agent && !path.includes("/:agentId")) {
1134
+ throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
1135
+ }
1136
+ return server.registerApiRoute(path, {
1137
+ method: "POST",
1138
+ openapi: {
1139
+ summary: "Execute an agent network and stream AI SDK events",
1140
+ description: "Routes a request to an agent network and streams UIMessage chunks in AI SDK format",
1141
+ tags: ["ai-sdk"],
1142
+ parameters: [
1143
+ {
1144
+ name: "agentId",
1145
+ in: "path",
1146
+ required: true,
1147
+ description: "The ID of the routing agent to execute as a network",
1148
+ schema: { type: "string" }
1149
+ }
1150
+ ],
1151
+ requestBody: {
1152
+ required: true,
1153
+ content: {
1154
+ "application/json": {
1155
+ schema: {
1156
+ type: "object",
1157
+ properties: {
1158
+ messages: { type: "array", items: { type: "object" } },
1159
+ runtimeContext: { type: "object", additionalProperties: true },
1160
+ runId: { type: "string" },
1161
+ maxSteps: { type: "number" },
1162
+ threadId: { type: "string" },
1163
+ resourceId: { type: "string" },
1164
+ modelSettings: { type: "object", additionalProperties: true },
1165
+ telemetry: { type: "object", additionalProperties: true },
1166
+ tools: { type: "array", items: { type: "object" } }
1167
+ },
1168
+ required: ["messages"]
1169
+ }
1170
+ }
1171
+ }
1172
+ },
1173
+ responses: {
1174
+ "200": {
1175
+ description: "Streaming AI SDK UIMessage event stream for the agent network",
1176
+ content: { "text/plain": { schema: { type: "string", description: "SSE stream" } } }
1177
+ },
1178
+ "404": {
1179
+ description: "Agent not found",
1180
+ content: {
1181
+ "application/json": {
1182
+ schema: { type: "object", properties: { error: { type: "string" } } }
1183
+ }
1184
+ }
1185
+ }
1186
+ }
1187
+ },
1188
+ handler: async (c) => {
1189
+ const { messages, ...rest } = await c.req.json();
1190
+ const mastra = c.get("mastra");
1191
+ let agentToUse = agent;
1192
+ if (!agent) {
1193
+ const agentId = c.req.param("agentId");
1194
+ agentToUse = agentId;
1195
+ }
1196
+ if (c.req.param("agentId") && agent) {
1197
+ mastra.getLogger()?.warn(
1198
+ `Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
1199
+ );
1200
+ }
1201
+ if (!agentToUse) {
1202
+ throw new Error("Agent ID is required");
1203
+ }
1204
+ const agentObj = mastra.getAgent(agentToUse);
1205
+ if (!agentObj) {
1206
+ throw new Error(`Agent ${agentToUse} not found`);
1207
+ }
1208
+ const result = await agentObj.network(messages, {
1209
+ ...defaultOptions,
1210
+ ...rest
1211
+ });
1212
+ const uiMessageStream = ai.createUIMessageStream({
1213
+ execute: async ({ writer }) => {
1214
+ for await (const part of toAISdkFormat(result, { from: "network" })) {
1215
+ writer.write(part);
1216
+ }
1217
+ }
1218
+ });
1219
+ return ai.createUIMessageStreamResponse({ stream: uiMessageStream });
1220
+ }
1221
+ });
1222
+ }
966
1223
 
967
- exports.WorkflowStreamToAISDKTransformer = WorkflowStreamToAISDKTransformer;
968
1224
  exports.chatRoute = chatRoute;
1225
+ exports.networkRoute = networkRoute;
969
1226
  exports.toAISdkFormat = toAISdkFormat;
1227
+ exports.workflowRoute = workflowRoute;
970
1228
  //# sourceMappingURL=index.cjs.map
971
1229
  //# sourceMappingURL=index.cjs.map