@mastra/ai-sdk 0.0.0-usechat-duplicate-20251016110554 → 0.0.0-vnext-20251104230439

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
@@ -5,6 +5,27 @@ var ai = require('ai');
5
5
  var stream = require('@mastra/core/stream');
6
6
 
7
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
+ function safeParseErrorObject(obj) {
14
+ if (typeof obj !== "object" || obj === null) {
15
+ return String(obj);
16
+ }
17
+ try {
18
+ const stringified = JSON.stringify(obj);
19
+ if (stringified === "{}") {
20
+ return String(obj);
21
+ }
22
+ return stringified;
23
+ } catch {
24
+ return String(obj);
25
+ }
26
+ }
27
+
28
+ // src/helpers.ts
8
29
  function convertMastraChunkToAISDKv5({
9
30
  chunk,
10
31
  mode = "stream"
@@ -210,6 +231,9 @@ function convertMastraChunkToAISDKv5({
210
231
  ...chunk.payload || {}
211
232
  };
212
233
  }
234
+ if ("type" in chunk && chunk.type?.startsWith("data-")) {
235
+ return chunk;
236
+ }
213
237
  return;
214
238
  }
215
239
  }
@@ -223,7 +247,7 @@ function convertFullStreamChunkToUIMessageStream({
223
247
  sendFinish,
224
248
  responseMessageId
225
249
  }) {
226
- const partType = part.type;
250
+ const partType = part?.type;
227
251
  switch (partType) {
228
252
  case "text-start": {
229
253
  return {
@@ -380,8 +404,16 @@ function convertFullStreamChunkToUIMessageStream({
380
404
  return;
381
405
  }
382
406
  default: {
383
- const exhaustiveCheck = partType;
384
- throw new Error(`Unknown chunk type: ${exhaustiveCheck}`);
407
+ if (isDataChunkType(part)) {
408
+ if (!("data" in part)) {
409
+ throw new Error(
410
+ `UI Messages require a data property when using data- prefixed chunks
411
+ ${JSON.stringify(part)}`
412
+ );
413
+ }
414
+ return part;
415
+ }
416
+ return;
385
417
  }
386
418
  }
387
419
  }
@@ -425,7 +457,7 @@ function AgentNetworkToAISDKTransformer() {
425
457
  }
426
458
  });
427
459
  }
428
- function AgentStreamToAISDKTransformer() {
460
+ function AgentStreamToAISDKTransformer(lastMessageId) {
429
461
  let bufferedSteps = /* @__PURE__ */ new Map();
430
462
  return new TransformStream({
431
463
  transform(chunk, controller) {
@@ -436,9 +468,9 @@ function AgentStreamToAISDKTransformer() {
436
468
  sendSources: false,
437
469
  sendStart: true,
438
470
  sendFinish: true,
439
- responseMessageId: chunk.runId,
440
- onError() {
441
- return "Error";
471
+ responseMessageId: lastMessageId,
472
+ onError(error) {
473
+ return safeParseErrorObject(error);
442
474
  }
443
475
  });
444
476
  if (transformedChunk) {
@@ -620,7 +652,9 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
620
652
  name: payload.payload.id,
621
653
  status: payload.payload.status,
622
654
  input: payload.payload.payload ?? null,
623
- output: null
655
+ output: null,
656
+ suspendPayload: null,
657
+ resumePayload: null
624
658
  };
625
659
  bufferedWorkflows.set(payload.runId, current);
626
660
  return {
@@ -653,6 +687,27 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
653
687
  }
654
688
  };
655
689
  }
690
+ case "workflow-step-suspended": {
691
+ const current = bufferedWorkflows.get(payload.runId);
692
+ if (!current) return null;
693
+ current.steps[payload.payload.id] = {
694
+ ...current.steps[payload.payload.id],
695
+ status: payload.payload.status,
696
+ suspendPayload: payload.payload.suspendPayload ?? null,
697
+ resumePayload: payload.payload.resumePayload ?? null,
698
+ output: null
699
+ };
700
+ return {
701
+ type: isNested ? "data-tool-workflow" : "data-workflow",
702
+ id: payload.runId,
703
+ data: {
704
+ name: current.name,
705
+ status: "suspended",
706
+ steps: current.steps,
707
+ output: null
708
+ }
709
+ };
710
+ }
656
711
  case "workflow-finish": {
657
712
  const current = bufferedWorkflows.get(payload.runId);
658
713
  if (!current) return null;
@@ -667,87 +722,117 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
667
722
  }
668
723
  };
669
724
  }
670
- default:
725
+ default: {
726
+ if (isDataChunkType(payload)) {
727
+ if (!("data" in payload)) {
728
+ throw new Error(
729
+ `UI Messages require a data property when using data- prefixed chunks
730
+ ${JSON.stringify(payload)}`
731
+ );
732
+ }
733
+ return payload;
734
+ }
671
735
  return null;
736
+ }
672
737
  }
673
738
  }
674
739
  function transformNetwork(payload, bufferedNetworks, isNested) {
675
740
  switch (payload.type) {
676
741
  case "routing-agent-start": {
677
- if (!bufferedNetworks.has(payload.payload.runId)) {
678
- bufferedNetworks.set(payload.payload.runId, {
742
+ if (!bufferedNetworks.has(payload.runId)) {
743
+ bufferedNetworks.set(payload.runId, {
679
744
  name: payload.payload.agentId,
680
- steps: []
745
+ steps: [],
746
+ usage: null,
747
+ output: null
681
748
  });
682
749
  }
683
750
  return {
684
751
  type: isNested ? "data-tool-network" : "data-network",
685
- id: payload.payload.runId,
752
+ id: payload.runId,
686
753
  data: {
687
- name: bufferedNetworks.get(payload.payload.runId).name,
754
+ name: bufferedNetworks.get(payload.runId).name,
688
755
  status: "running",
689
- steps: bufferedNetworks.get(payload.payload.runId).steps,
756
+ usage: null,
757
+ steps: bufferedNetworks.get(payload.runId).steps,
690
758
  output: null
691
759
  }
692
760
  };
693
761
  }
762
+ case "routing-agent-text-start": {
763
+ const current = bufferedNetworks.get(payload.runId);
764
+ if (!current) return null;
765
+ return {
766
+ type: "text-start",
767
+ id: payload.runId
768
+ };
769
+ }
770
+ case "routing-agent-text-delta": {
771
+ const current = bufferedNetworks.get(payload.runId);
772
+ if (!current) return null;
773
+ return {
774
+ type: "text-delta",
775
+ id: payload.runId,
776
+ delta: payload.payload.text
777
+ };
778
+ }
694
779
  case "agent-execution-start": {
695
- const current = bufferedNetworks.get(payload.payload.runId) || { name: "", steps: [] };
780
+ const current = bufferedNetworks.get(payload.runId) || { name: "", steps: [], usage: null, output: null };
696
781
  current.steps.push({
697
782
  name: payload.payload.agentId,
698
783
  status: "running",
699
784
  input: payload.payload.args || null,
700
- output: null
785
+ output: null,
786
+ suspendPayload: null,
787
+ resumePayload: null
701
788
  });
702
- bufferedNetworks.set(payload.payload.runId, current);
789
+ bufferedNetworks.set(payload.runId, current);
703
790
  return {
704
791
  type: isNested ? "data-tool-network" : "data-network",
705
- id: payload.payload.runId,
792
+ id: payload.runId,
706
793
  data: {
707
- name: current.name,
708
- status: "running",
709
- steps: current.steps,
710
- output: null
794
+ ...current,
795
+ status: "running"
711
796
  }
712
797
  };
713
798
  }
714
799
  case "workflow-execution-start": {
715
- const current = bufferedNetworks.get(payload.payload.runId) || { name: "", steps: [] };
800
+ const current = bufferedNetworks.get(payload.runId) || { name: "", steps: [], usage: null, output: null };
716
801
  current.steps.push({
717
802
  name: payload.payload.name,
718
803
  status: "running",
719
804
  input: payload.payload.args || null,
720
- output: null
805
+ output: null,
806
+ suspendPayload: null,
807
+ resumePayload: null
721
808
  });
722
- bufferedNetworks.set(payload.payload.runId, current);
809
+ bufferedNetworks.set(payload.runId, current);
723
810
  return {
724
811
  type: isNested ? "data-tool-network" : "data-network",
725
- id: payload.payload.runId,
812
+ id: payload.runId,
726
813
  data: {
727
- name: current.name,
728
- status: "running",
729
- steps: current.steps,
730
- output: null
814
+ ...current,
815
+ status: "running"
731
816
  }
732
817
  };
733
818
  }
734
819
  case "tool-execution-start": {
735
- const current = bufferedNetworks.get(payload.payload.runId) || { name: "", steps: [] };
820
+ const current = bufferedNetworks.get(payload.runId) || { name: "", steps: [], usage: null, output: null };
736
821
  current.steps.push({
737
822
  name: payload.payload.args?.toolName,
738
823
  status: "running",
739
824
  input: payload.payload.args?.args || null,
740
- output: null
825
+ output: null,
826
+ suspendPayload: null,
827
+ resumePayload: null
741
828
  });
742
- bufferedNetworks.set(payload.payload.runId, current);
829
+ bufferedNetworks.set(payload.runId, current);
743
830
  return {
744
831
  type: isNested ? "data-tool-network" : "data-network",
745
- id: payload.payload.runId,
832
+ id: payload.runId,
746
833
  data: {
747
- name: current.name,
748
- status: "running",
749
- steps: current.steps,
750
- output: null
834
+ ...current,
835
+ status: "running"
751
836
  }
752
837
  };
753
838
  }
@@ -758,16 +843,18 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
758
843
  name: payload.payload.agentId,
759
844
  status: "success",
760
845
  input: null,
761
- output: payload.payload.result
846
+ output: payload.payload.result,
847
+ suspendPayload: null,
848
+ resumePayload: null
762
849
  });
763
850
  return {
764
851
  type: isNested ? "data-tool-network" : "data-network",
765
852
  id: payload.runId,
766
853
  data: {
767
- name: current.name,
854
+ ...current,
855
+ usage: payload.payload?.usage ?? current.usage,
768
856
  status: "running",
769
- steps: current.steps,
770
- output: payload.payload.result ?? null
857
+ output: payload.payload.result ?? current.output
771
858
  }
772
859
  };
773
860
  }
@@ -778,16 +865,17 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
778
865
  name: payload.payload.toolName,
779
866
  status: "success",
780
867
  input: null,
781
- output: payload.payload.result
868
+ output: payload.payload.result,
869
+ suspendPayload: null,
870
+ resumePayload: null
782
871
  });
783
872
  return {
784
873
  type: isNested ? "data-tool-network" : "data-network",
785
874
  id: payload.runId,
786
875
  data: {
787
- name: current.name,
876
+ ...current,
788
877
  status: "running",
789
- steps: current.steps,
790
- output: payload.payload.result ?? null
878
+ output: payload.payload.result ?? current.output
791
879
  }
792
880
  };
793
881
  }
@@ -798,44 +886,45 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
798
886
  name: payload.payload.name,
799
887
  status: "success",
800
888
  input: null,
801
- output: payload.payload.result
889
+ output: payload.payload.result,
890
+ suspendPayload: null,
891
+ resumePayload: null
802
892
  });
803
893
  return {
804
894
  type: isNested ? "data-tool-network" : "data-network",
805
895
  id: payload.runId,
806
896
  data: {
807
- name: current.name,
897
+ ...current,
898
+ usage: payload.payload?.usage ?? current.usage,
808
899
  status: "running",
809
- steps: current.steps,
810
- output: payload.payload.result ?? null
900
+ output: payload.payload.result ?? current.output
811
901
  }
812
902
  };
813
903
  }
814
904
  case "routing-agent-end": {
815
- const current = bufferedNetworks.get(payload.payload.runId);
905
+ const current = bufferedNetworks.get(payload.runId);
816
906
  if (!current) return null;
817
907
  return {
818
908
  type: isNested ? "data-tool-network" : "data-network",
819
- id: payload.payload.runId,
909
+ id: payload.runId,
820
910
  data: {
821
- name: current.name,
911
+ ...current,
822
912
  status: "finished",
823
- steps: current.steps,
824
- output: payload.payload?.result ?? null
913
+ usage: payload.payload?.usage ?? current.usage,
914
+ output: payload.payload?.result ?? current.output
825
915
  }
826
916
  };
827
917
  }
828
918
  case "network-execution-event-step-finish": {
829
- const current = bufferedNetworks.get(payload.payload.runId);
919
+ const current = bufferedNetworks.get(payload.runId);
830
920
  if (!current) return null;
831
921
  return {
832
922
  type: isNested ? "data-tool-network" : "data-network",
833
- id: payload.payload.runId,
923
+ id: payload.runId,
834
924
  data: {
835
- name: current.name,
925
+ ...current,
836
926
  status: "finished",
837
- steps: current.steps,
838
- output: payload.payload?.result ?? null
927
+ output: payload.payload?.result ?? current.output
839
928
  }
840
929
  };
841
930
  }
@@ -846,20 +935,30 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
846
935
  type: isNested ? "data-tool-network" : "data-network",
847
936
  id: payload.runId,
848
937
  data: {
849
- name: current.name,
938
+ ...current,
939
+ usage: payload.payload?.usage ?? current.usage,
850
940
  status: "finished",
851
- steps: current.steps,
852
- output: payload.payload?.result ?? null
941
+ output: payload.payload?.result ?? current.output
853
942
  }
854
943
  };
855
944
  }
856
- default:
945
+ default: {
946
+ if (isDataChunkType(payload)) {
947
+ if (!("data" in payload)) {
948
+ throw new Error(
949
+ `UI Messages require a data property when using data- prefixed chunks
950
+ ${JSON.stringify(payload)}`
951
+ );
952
+ }
953
+ return payload;
954
+ }
857
955
  return null;
956
+ }
858
957
  }
859
958
  }
860
959
 
861
- // src/to-ai-sdk-format.ts
862
- function toAISdkFormat(stream, options = { from: "agent" }) {
960
+ // src/convert-streams.ts
961
+ function toAISdkV5Stream(stream, options = { from: "agent" }) {
863
962
  const from = options?.from;
864
963
  if (from === "workflow") {
865
964
  return stream.pipeThrough(WorkflowStreamToAISDKTransformer());
@@ -868,7 +967,7 @@ function toAISdkFormat(stream, options = { from: "agent" }) {
868
967
  return stream.pipeThrough(AgentNetworkToAISDKTransformer());
869
968
  }
870
969
  const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
871
- return agentReadable.pipeThrough(AgentStreamToAISDKTransformer());
970
+ return agentReadable.pipeThrough(AgentStreamToAISDKTransformer(options?.lastMessageId));
872
971
  }
873
972
 
874
973
  // src/chat-route.ts
@@ -976,7 +1075,7 @@ function chatRoute({
976
1075
  handler: async (c) => {
977
1076
  const { messages, ...rest } = await c.req.json();
978
1077
  const mastra = c.get("mastra");
979
- const runtimeContext = c.get("runtimeContext");
1078
+ const requestContext = c.get("requestContext");
980
1079
  let agentToUse = agent;
981
1080
  if (!agent) {
982
1081
  const agentId = c.req.param("agentId");
@@ -987,8 +1086,8 @@ function chatRoute({
987
1086
  `Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
988
1087
  );
989
1088
  }
990
- if (runtimeContext && defaultOptions?.runtimeContext) {
991
- mastra.getLogger()?.warn(`"runtimeContext" set in the route options will be overridden by the request's "runtimeContext".`);
1089
+ if (requestContext && defaultOptions?.requestContext) {
1090
+ mastra.getLogger()?.warn(`"requestContext" set in the route options will be overridden by the request's "requestContext".`);
992
1091
  }
993
1092
  if (!agentToUse) {
994
1093
  throw new Error("Agent ID is required");
@@ -1000,12 +1099,16 @@ function chatRoute({
1000
1099
  const result = await agentObj.stream(messages, {
1001
1100
  ...defaultOptions,
1002
1101
  ...rest,
1003
- runtimeContext: runtimeContext || defaultOptions?.runtimeContext
1102
+ requestContext: requestContext || defaultOptions?.requestContext
1004
1103
  });
1104
+ let lastMessageId;
1105
+ if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
1106
+ lastMessageId = messages[messages.length - 1].id;
1107
+ }
1005
1108
  const uiMessageStream = ai.createUIMessageStream({
1006
1109
  originalMessages: messages,
1007
1110
  execute: async ({ writer }) => {
1008
- for await (const part of toAISdkFormat(result, { from: "agent" })) {
1111
+ for await (const part of toAISdkV5Stream(result, { from: "agent", lastMessageId })) {
1009
1112
  writer.write(part);
1010
1113
  }
1011
1114
  }
@@ -1046,7 +1149,7 @@ function workflowRoute({
1046
1149
  type: "object",
1047
1150
  properties: {
1048
1151
  inputData: { type: "object", additionalProperties: true },
1049
- runtimeContext: { type: "object", additionalProperties: true },
1152
+ requestContext: { type: "object", additionalProperties: true },
1050
1153
  tracingOptions: { type: "object", additionalProperties: true }
1051
1154
  }
1052
1155
  }
@@ -1065,7 +1168,7 @@ function workflowRoute({
1065
1168
  }
1066
1169
  },
1067
1170
  handler: async (c) => {
1068
- const { inputData, ...rest } = await c.req.json();
1171
+ const { inputData, resumeData, ...rest } = await c.req.json();
1069
1172
  const mastra = c.get("mastra");
1070
1173
  let workflowToUse = workflow;
1071
1174
  if (!workflow) {
@@ -1084,11 +1187,11 @@ function workflowRoute({
1084
1187
  if (!workflowObj) {
1085
1188
  throw new Error(`Workflow ${workflowToUse} not found`);
1086
1189
  }
1087
- const run = await workflowObj.createRunAsync();
1088
- const stream = run.streamVNext({ inputData, ...rest });
1190
+ const run = await workflowObj.createRun();
1191
+ const stream = resumeData ? run.resumeStream({ resumeData, ...rest }) : run.stream({ inputData, ...rest });
1089
1192
  const uiMessageStream = ai.createUIMessageStream({
1090
1193
  execute: async ({ writer }) => {
1091
- for await (const part of toAISdkFormat(stream, { from: "workflow" })) {
1194
+ for await (const part of toAISdkV5Stream(stream, { from: "workflow" })) {
1092
1195
  writer.write(part);
1093
1196
  }
1094
1197
  }
@@ -1128,13 +1231,12 @@ function networkRoute({
1128
1231
  type: "object",
1129
1232
  properties: {
1130
1233
  messages: { type: "array", items: { type: "object" } },
1131
- runtimeContext: { type: "object", additionalProperties: true },
1234
+ requestContext: { type: "object", additionalProperties: true },
1132
1235
  runId: { type: "string" },
1133
1236
  maxSteps: { type: "number" },
1134
1237
  threadId: { type: "string" },
1135
1238
  resourceId: { type: "string" },
1136
1239
  modelSettings: { type: "object", additionalProperties: true },
1137
- telemetry: { type: "object", additionalProperties: true },
1138
1240
  tools: { type: "array", items: { type: "object" } }
1139
1241
  },
1140
1242
  required: ["messages"]
@@ -1183,7 +1285,7 @@ function networkRoute({
1183
1285
  });
1184
1286
  const uiMessageStream = ai.createUIMessageStream({
1185
1287
  execute: async ({ writer }) => {
1186
- for await (const part of toAISdkFormat(result, { from: "network" })) {
1288
+ for await (const part of toAISdkV5Stream(result, { from: "network" })) {
1187
1289
  writer.write(part);
1188
1290
  }
1189
1291
  }
@@ -1193,9 +1295,17 @@ function networkRoute({
1193
1295
  });
1194
1296
  }
1195
1297
 
1298
+ // src/to-ai-sdk-format.ts
1299
+ function toAISdkFormat() {
1300
+ throw new Error(
1301
+ '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.'
1302
+ );
1303
+ }
1304
+
1196
1305
  exports.chatRoute = chatRoute;
1197
1306
  exports.networkRoute = networkRoute;
1198
1307
  exports.toAISdkFormat = toAISdkFormat;
1308
+ exports.toAISdkStream = toAISdkV5Stream;
1199
1309
  exports.workflowRoute = workflowRoute;
1200
1310
  //# sourceMappingURL=index.cjs.map
1201
1311
  //# sourceMappingURL=index.cjs.map