@mastra/ai-sdk 0.2.7 → 0.3.2-alpha.0

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
@@ -10,6 +10,45 @@ var stream = require('@mastra/core/stream');
10
10
  var isDataChunkType = (chunk) => {
11
11
  return chunk && typeof chunk === "object" && "type" in chunk && chunk.type?.startsWith("data-");
12
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
+ }
13
52
  var isAgentExecutionDataChunkType = (chunk) => {
14
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-");
15
54
  };
@@ -126,6 +165,28 @@ function convertMastraChunkToAISDKv5({
126
165
  toolName: chunk.payload.toolName,
127
166
  input: chunk.payload.args
128
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
+ };
129
190
  case "tool-call-input-streaming-start":
130
191
  return {
131
192
  type: "tool-input-start",
@@ -216,6 +277,13 @@ function convertMastraChunkToAISDKv5({
216
277
  type: "object",
217
278
  object: chunk.object
218
279
  };
280
+ case "tripwire":
281
+ return {
282
+ type: "data-tripwire",
283
+ data: {
284
+ tripwireReason: chunk.payload.tripwireReason
285
+ }
286
+ };
219
287
  default:
220
288
  if (chunk.type && "payload" in chunk && chunk.payload) {
221
289
  return {
@@ -271,6 +339,14 @@ function convertFullStreamChunkToUIMessageStream({
271
339
  };
272
340
  }
273
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
+ }
274
350
  return;
275
351
  }
276
352
  case "reasoning-end": {
@@ -288,6 +364,25 @@ function convertFullStreamChunkToUIMessageStream({
288
364
  };
289
365
  }
290
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
+ }
291
386
  return;
292
387
  }
293
388
  case "tool-input-start": {
@@ -378,21 +473,23 @@ function convertFullStreamChunkToUIMessageStream({
378
473
  return { type: "finish-step" };
379
474
  }
380
475
  case "start": {
381
- {
476
+ if (sendStart) {
382
477
  return {
383
478
  type: "start",
384
479
  ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {},
385
480
  ...responseMessageId != null ? { messageId: responseMessageId } : {}
386
481
  };
387
482
  }
483
+ return;
388
484
  }
389
485
  case "finish": {
390
- {
486
+ if (sendFinish) {
391
487
  return {
392
488
  type: "finish",
393
489
  ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}
394
490
  };
395
491
  }
492
+ return;
396
493
  }
397
494
  case "abort": {
398
495
  return part;
@@ -419,7 +516,10 @@ function convertFullStreamChunkToUIMessageStream({
419
516
  }
420
517
 
421
518
  // src/transformers.ts
422
- function WorkflowStreamToAISDKTransformer() {
519
+ var PRIMITIVE_CACHE_SYMBOL = Symbol("primitive-cache");
520
+ function WorkflowStreamToAISDKTransformer({
521
+ includeTextStreamParts
522
+ } = {}) {
423
523
  const bufferedWorkflows = /* @__PURE__ */ new Map();
424
524
  return new TransformStream({
425
525
  start(controller) {
@@ -433,7 +533,7 @@ function WorkflowStreamToAISDKTransformer() {
433
533
  });
434
534
  },
435
535
  transform(chunk, controller) {
436
- const transformed = transformWorkflow(chunk, bufferedWorkflows);
536
+ const transformed = transformWorkflow(chunk, bufferedWorkflows, false, includeTextStreamParts);
437
537
  if (transformed) controller.enqueue(transformed);
438
538
  }
439
539
  });
@@ -457,20 +557,37 @@ function AgentNetworkToAISDKTransformer() {
457
557
  }
458
558
  });
459
559
  }
460
- function AgentStreamToAISDKTransformer(lastMessageId) {
560
+ function AgentStreamToAISDKTransformer({
561
+ lastMessageId,
562
+ sendStart,
563
+ sendFinish,
564
+ sendReasoning,
565
+ sendSources,
566
+ messageMetadata,
567
+ onError
568
+ }) {
461
569
  let bufferedSteps = /* @__PURE__ */ new Map();
570
+ let tripwireOccurred = false;
571
+ let finishEventSent = false;
462
572
  return new TransformStream({
463
573
  transform(chunk, controller) {
574
+ if (chunk.type === "tripwire") {
575
+ tripwireOccurred = true;
576
+ }
577
+ if (chunk.type === "finish") {
578
+ finishEventSent = true;
579
+ }
464
580
  const part = convertMastraChunkToAISDKv5({ chunk, mode: "stream" });
465
581
  const transformedChunk = convertFullStreamChunkToUIMessageStream({
466
582
  part,
467
- sendReasoning: false,
468
- sendSources: false,
469
- sendStart: true,
470
- sendFinish: true,
583
+ sendReasoning,
584
+ sendSources,
585
+ messageMetadataValue: messageMetadata?.({ part }),
586
+ sendStart,
587
+ sendFinish,
471
588
  responseMessageId: lastMessageId,
472
- onError() {
473
- return "Error";
589
+ onError(error) {
590
+ return onError ? onError(error) : safeParseErrorObject(error);
474
591
  }
475
592
  });
476
593
  if (transformedChunk) {
@@ -490,6 +607,14 @@ function AgentStreamToAISDKTransformer(lastMessageId) {
490
607
  controller.enqueue(transformedChunk);
491
608
  }
492
609
  }
610
+ },
611
+ flush(controller) {
612
+ if (tripwireOccurred && !finishEventSent && sendFinish) {
613
+ controller.enqueue({
614
+ type: "finish",
615
+ finishReason: "other"
616
+ });
617
+ }
493
618
  }
494
619
  });
495
620
  }
@@ -629,7 +754,7 @@ function transformAgent(payload, bufferedSteps) {
629
754
  }
630
755
  return null;
631
756
  }
632
- function transformWorkflow(payload, bufferedWorkflows, isNested) {
757
+ function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStreamParts) {
633
758
  switch (payload.type) {
634
759
  case "workflow-start":
635
760
  bufferedWorkflows.set(payload.runId, {
@@ -722,6 +847,29 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
722
847
  }
723
848
  };
724
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
+ }
725
873
  default: {
726
874
  if (isDataChunkType(payload)) {
727
875
  if (!("data" in payload)) {
@@ -741,12 +889,29 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
741
889
  case "routing-agent-start": {
742
890
  if (!bufferedNetworks.has(payload.runId)) {
743
891
  bufferedNetworks.set(payload.runId, {
744
- name: payload.payload.agentId,
892
+ name: payload.payload.networkId,
745
893
  steps: [],
746
894
  usage: null,
747
895
  output: null
748
896
  });
749
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
+ });
750
915
  return {
751
916
  type: isNested ? "data-tool-network" : "data-network",
752
917
  id: payload.runId,
@@ -777,14 +942,19 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
777
942
  };
778
943
  }
779
944
  case "agent-execution-start": {
780
- const current = bufferedNetworks.get(payload.runId) || { name: "", steps: [], usage: null, output: null };
945
+ const current = bufferedNetworks.get(payload.runId);
946
+ if (!current) return null;
781
947
  current.steps.push({
948
+ id: payload.payload.runId,
782
949
  name: payload.payload.agentId,
783
950
  status: "running",
784
- input: payload.payload.args || null,
951
+ iteration: payload.payload.args?.iteration ?? 0,
952
+ input: { prompt: payload.payload.args?.prompt ?? "" },
785
953
  output: null,
954
+ task: null,
786
955
  suspendPayload: null,
787
- resumePayload: null
956
+ resumePayload: null,
957
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
788
958
  });
789
959
  bufferedNetworks.set(payload.runId, current);
790
960
  return {
@@ -797,14 +967,19 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
797
967
  };
798
968
  }
799
969
  case "workflow-execution-start": {
800
- const current = bufferedNetworks.get(payload.runId) || { name: "", steps: [], usage: null, output: null };
970
+ const current = bufferedNetworks.get(payload.runId);
971
+ if (!current) return null;
801
972
  current.steps.push({
802
- name: payload.payload.name,
973
+ id: payload.payload.runId,
974
+ name: payload.payload.workflowId,
803
975
  status: "running",
804
- input: payload.payload.args || null,
976
+ iteration: payload.payload.args?.iteration ?? 0,
977
+ input: { prompt: payload.payload.args?.prompt ?? "" },
805
978
  output: null,
979
+ task: null,
806
980
  suspendPayload: null,
807
- resumePayload: null
981
+ resumePayload: null,
982
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
808
983
  });
809
984
  bufferedNetworks.set(payload.runId, current);
810
985
  return {
@@ -817,14 +992,21 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
817
992
  };
818
993
  }
819
994
  case "tool-execution-start": {
820
- const current = bufferedNetworks.get(payload.runId) || { name: "", steps: [], usage: null, output: null };
995
+ const current = bufferedNetworks.get(payload.runId);
996
+ if (!current) return null;
821
997
  current.steps.push({
998
+ id: payload.payload.args.toolCallId,
822
999
  name: payload.payload.args?.toolName,
823
1000
  status: "running",
1001
+ iteration: payload.payload.args?.iteration ? Number(payload.payload.args.iteration) : 0,
1002
+ task: {
1003
+ id: payload.payload.args?.toolName
1004
+ },
824
1005
  input: payload.payload.args?.args || null,
825
1006
  output: null,
826
1007
  suspendPayload: null,
827
- resumePayload: null
1008
+ resumePayload: null,
1009
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
828
1010
  });
829
1011
  bufferedNetworks.set(payload.runId, current);
830
1012
  return {
@@ -839,14 +1021,13 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
839
1021
  case "agent-execution-end": {
840
1022
  const current = bufferedNetworks.get(payload.runId);
841
1023
  if (!current) return null;
842
- current.steps.push({
843
- name: payload.payload.agentId,
844
- status: "success",
845
- input: null,
846
- output: payload.payload.result,
847
- suspendPayload: null,
848
- resumePayload: null
849
- });
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;
850
1031
  return {
851
1032
  type: isNested ? "data-tool-network" : "data-network",
852
1033
  id: payload.runId,
@@ -861,14 +1042,13 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
861
1042
  case "tool-execution-end": {
862
1043
  const current = bufferedNetworks.get(payload.runId);
863
1044
  if (!current) return null;
864
- current.steps.push({
865
- name: payload.payload.toolName,
866
- status: "success",
867
- input: null,
868
- output: payload.payload.result,
869
- suspendPayload: null,
870
- resumePayload: null
871
- });
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;
872
1052
  return {
873
1053
  type: isNested ? "data-tool-network" : "data-network",
874
1054
  id: payload.runId,
@@ -882,14 +1062,13 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
882
1062
  case "workflow-execution-end": {
883
1063
  const current = bufferedNetworks.get(payload.runId);
884
1064
  if (!current) return null;
885
- current.steps.push({
886
- name: payload.payload.name,
887
- status: "success",
888
- input: null,
889
- output: payload.payload.result,
890
- suspendPayload: null,
891
- resumePayload: null
892
- });
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;
893
1072
  return {
894
1073
  type: isNested ? "data-tool-network" : "data-network",
895
1074
  id: payload.runId,
@@ -904,12 +1083,24 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
904
1083
  case "routing-agent-end": {
905
1084
  const current = bufferedNetworks.get(payload.runId);
906
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;
907
1099
  return {
908
1100
  type: isNested ? "data-tool-network" : "data-network",
909
1101
  id: payload.runId,
910
1102
  data: {
911
1103
  ...current,
912
- status: "finished",
913
1104
  usage: payload.payload?.usage ?? current.usage,
914
1105
  output: payload.payload?.result ?? current.output
915
1106
  }
@@ -943,6 +1134,39 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
943
1134
  };
944
1135
  }
945
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
+ }
946
1170
  if (isDataChunkType(payload)) {
947
1171
  if (!("data" in payload)) {
948
1172
  throw new Error(
@@ -950,7 +1174,8 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
950
1174
  ${JSON.stringify(payload)}`
951
1175
  );
952
1176
  }
953
- return payload;
1177
+ const { type, data } = payload;
1178
+ return { type, data };
954
1179
  }
955
1180
  if (isAgentExecutionDataChunkType(payload)) {
956
1181
  if (!("data" in payload.payload)) {
@@ -959,7 +1184,8 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
959
1184
  ${JSON.stringify(payload)}`
960
1185
  );
961
1186
  }
962
- return payload.payload;
1187
+ const { type, data } = payload.payload;
1188
+ return { type, data };
963
1189
  }
964
1190
  if (isWorkflowExecutionDataChunkType(payload)) {
965
1191
  if (!("data" in payload.payload)) {
@@ -968,7 +1194,8 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
968
1194
  ${JSON.stringify(payload)}`
969
1195
  );
970
1196
  }
971
- return payload.payload;
1197
+ const { type, data } = payload.payload;
1198
+ return { type, data };
972
1199
  }
973
1200
  return null;
974
1201
  }
@@ -976,23 +1203,44 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
976
1203
  }
977
1204
 
978
1205
  // src/to-ai-sdk-format.ts
979
- function toAISdkFormat(stream, options = { from: "agent" }) {
1206
+ function toAISdkFormat(stream, options = {
1207
+ from: "agent",
1208
+ sendStart: true,
1209
+ sendFinish: true
1210
+ }) {
980
1211
  const from = options?.from;
981
1212
  if (from === "workflow") {
982
- return stream.pipeThrough(WorkflowStreamToAISDKTransformer());
1213
+ const includeTextStreamParts = options?.includeTextStreamParts ?? false;
1214
+ return stream.pipeThrough(
1215
+ WorkflowStreamToAISDKTransformer({ includeTextStreamParts })
1216
+ );
983
1217
  }
984
1218
  if (from === "network") {
985
1219
  return stream.pipeThrough(AgentNetworkToAISDKTransformer());
986
1220
  }
987
1221
  const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
988
- return agentReadable.pipeThrough(AgentStreamToAISDKTransformer(options?.lastMessageId));
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
+ );
989
1233
  }
990
1234
 
991
1235
  // src/chat-route.ts
992
1236
  function chatRoute({
993
1237
  path = "/chat/:agentId",
994
1238
  agent,
995
- defaultOptions
1239
+ defaultOptions,
1240
+ sendStart = true,
1241
+ sendFinish = true,
1242
+ sendReasoning = false,
1243
+ sendSources = false
996
1244
  }) {
997
1245
  if (!agent && !path.includes("/:agentId")) {
998
1246
  throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
@@ -1110,7 +1358,7 @@ function chatRoute({
1110
1358
  if (!agentToUse) {
1111
1359
  throw new Error("Agent ID is required");
1112
1360
  }
1113
- const agentObj = mastra.getAgent(agentToUse);
1361
+ const agentObj = mastra.getAgentById(agentToUse);
1114
1362
  if (!agentObj) {
1115
1363
  throw new Error(`Agent ${agentToUse} not found`);
1116
1364
  }
@@ -1126,7 +1374,14 @@ function chatRoute({
1126
1374
  const uiMessageStream = ai.createUIMessageStream({
1127
1375
  originalMessages: messages,
1128
1376
  execute: async ({ writer }) => {
1129
- for await (const part of toAISdkFormat(result, { from: "agent", lastMessageId })) {
1377
+ for await (const part of toAISdkFormat(result, {
1378
+ from: "agent",
1379
+ lastMessageId,
1380
+ sendStart,
1381
+ sendFinish,
1382
+ sendReasoning,
1383
+ sendSources
1384
+ })) {
1130
1385
  writer.write(part);
1131
1386
  }
1132
1387
  }
@@ -1139,7 +1394,8 @@ function chatRoute({
1139
1394
  }
1140
1395
  function workflowRoute({
1141
1396
  path = "/api/workflows/:workflowId/stream",
1142
- workflow
1397
+ workflow,
1398
+ includeTextStreamParts = false
1143
1399
  }) {
1144
1400
  if (!workflow && !path.includes("/:workflowId")) {
1145
1401
  throw new Error("Path must include :workflowId to route to the correct workflow or pass the workflow explicitly");
@@ -1170,7 +1426,7 @@ function workflowRoute({
1170
1426
  resourceId: { type: "string" },
1171
1427
  inputData: { type: "object", additionalProperties: true },
1172
1428
  resumeData: { type: "object", additionalProperties: true },
1173
- requestContext: { type: "object", additionalProperties: true },
1429
+ runtimeContext: { type: "object", additionalProperties: true },
1174
1430
  tracingOptions: { type: "object", additionalProperties: true },
1175
1431
  step: { type: "string" }
1176
1432
  }
@@ -1192,6 +1448,7 @@ function workflowRoute({
1192
1448
  handler: async (c) => {
1193
1449
  const { runId, resourceId, inputData, resumeData, ...rest } = await c.req.json();
1194
1450
  const mastra = c.get("mastra");
1451
+ const runtimeContext = c.get("runtimeContext");
1195
1452
  let workflowToUse = workflow;
1196
1453
  if (!workflow) {
1197
1454
  const workflowId = c.req.param("workflowId");
@@ -1205,15 +1462,20 @@ function workflowRoute({
1205
1462
  if (!workflowToUse) {
1206
1463
  throw new Error("Workflow ID is required");
1207
1464
  }
1208
- const workflowObj = mastra.getWorkflow(workflowToUse);
1465
+ const workflowObj = mastra.getWorkflowById(workflowToUse);
1209
1466
  if (!workflowObj) {
1210
1467
  throw new Error(`Workflow ${workflowToUse} not found`);
1211
1468
  }
1469
+ if (runtimeContext && rest.runtimeContext) {
1470
+ mastra.getLogger()?.warn(
1471
+ `"runtimeContext" from the request body will be ignored because "runtimeContext" is already set in the route options.`
1472
+ );
1473
+ }
1212
1474
  const run = await workflowObj.createRunAsync({ runId, resourceId, ...rest });
1213
- const stream = resumeData ? run.resumeStream({ resumeData, ...rest }) : run.stream({ inputData, ...rest });
1475
+ const stream = resumeData ? run.resumeStream({ resumeData, ...rest, runtimeContext: runtimeContext || rest.runtimeContext }) : run.stream({ inputData, ...rest, runtimeContext: runtimeContext || rest.runtimeContext });
1214
1476
  const uiMessageStream = ai.createUIMessageStream({
1215
1477
  execute: async ({ writer }) => {
1216
- for await (const part of toAISdkFormat(stream, { from: "workflow" })) {
1478
+ for await (const part of toAISdkFormat(stream, { from: "workflow", includeTextStreamParts })) {
1217
1479
  writer.write(part);
1218
1480
  }
1219
1481
  }
@@ -1298,7 +1560,7 @@ function networkRoute({
1298
1560
  if (!agentToUse) {
1299
1561
  throw new Error("Agent ID is required");
1300
1562
  }
1301
- const agentObj = mastra.getAgent(agentToUse);
1563
+ const agentObj = mastra.getAgentById(agentToUse);
1302
1564
  if (!agentObj) {
1303
1565
  throw new Error(`Agent ${agentToUse} not found`);
1304
1566
  }