@mastra/ai-sdk 0.0.0-extract-tool-ui-inp-playground-ui-20251024041825 → 0.0.0-feat-add-query-option-to-playground-20251209160219

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,6 +1,9 @@
1
1
  import { registerApiRoute } from '@mastra/core/server';
2
- import { createUIMessageStream, createUIMessageStreamResponse } from 'ai';
3
- import { DefaultGeneratedFile, DefaultGeneratedFileWithType } from '@mastra/core/stream';
2
+ import { createUIMessageStream, createUIMessageStreamResponse, wrapLanguageModel } from 'ai';
3
+ import { convertFullStreamChunkToMastra, DefaultGeneratedFile, DefaultGeneratedFileWithType } from '@mastra/core/stream';
4
+ import { TripWire, MessageList } from '@mastra/core/agent';
5
+ import { RequestContext } from '@mastra/core/di';
6
+ import { WorkingMemory, MessageHistory, SemanticRecall } from '@mastra/core/processors';
4
7
 
5
8
  // src/chat-route.ts
6
9
 
@@ -8,6 +11,55 @@ import { DefaultGeneratedFile, DefaultGeneratedFileWithType } from '@mastra/core
8
11
  var isDataChunkType = (chunk) => {
9
12
  return chunk && typeof chunk === "object" && "type" in chunk && chunk.type?.startsWith("data-");
10
13
  };
14
+ var isMastraTextStreamChunk = (chunk) => {
15
+ return chunk && typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string" && [
16
+ "text-start",
17
+ "text-delta",
18
+ "text-end",
19
+ "reasoning-start",
20
+ "reasoning-delta",
21
+ "reasoning-end",
22
+ "file",
23
+ "source",
24
+ "tool-input-start",
25
+ "tool-input-delta",
26
+ "tool-call-approval",
27
+ "tool-call-suspended",
28
+ "tool-call",
29
+ "tool-result",
30
+ "tool-error",
31
+ "error",
32
+ "start-step",
33
+ "finish-step",
34
+ "start",
35
+ "finish",
36
+ "abort",
37
+ "tool-input-end",
38
+ "object",
39
+ "tripwire",
40
+ "raw"
41
+ ].includes(chunk.type);
42
+ };
43
+ function safeParseErrorObject(obj) {
44
+ if (typeof obj !== "object" || obj === null) {
45
+ return String(obj);
46
+ }
47
+ try {
48
+ const stringified = JSON.stringify(obj);
49
+ if (stringified === "{}") {
50
+ return String(obj);
51
+ }
52
+ return stringified;
53
+ } catch {
54
+ return String(obj);
55
+ }
56
+ }
57
+ var isAgentExecutionDataChunkType = (chunk) => {
58
+ 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-");
59
+ };
60
+ var isWorkflowExecutionDataChunkType = (chunk) => {
61
+ 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-");
62
+ };
11
63
 
12
64
  // src/helpers.ts
13
65
  function convertMastraChunkToAISDKv5({
@@ -118,6 +170,28 @@ function convertMastraChunkToAISDKv5({
118
170
  toolName: chunk.payload.toolName,
119
171
  input: chunk.payload.args
120
172
  };
173
+ case "tool-call-approval":
174
+ return {
175
+ type: "data-tool-call-approval",
176
+ id: chunk.payload.toolCallId,
177
+ data: {
178
+ runId: chunk.runId,
179
+ toolCallId: chunk.payload.toolCallId,
180
+ toolName: chunk.payload.toolName,
181
+ args: chunk.payload.args
182
+ }
183
+ };
184
+ case "tool-call-suspended":
185
+ return {
186
+ type: "data-tool-call-suspended",
187
+ id: chunk.payload.toolCallId,
188
+ data: {
189
+ runId: chunk.runId,
190
+ toolCallId: chunk.payload.toolCallId,
191
+ toolName: chunk.payload.toolName,
192
+ suspendPayload: chunk.payload.suspendPayload
193
+ }
194
+ };
121
195
  case "tool-call-input-streaming-start":
122
196
  return {
123
197
  type: "tool-input-start",
@@ -208,6 +282,13 @@ function convertMastraChunkToAISDKv5({
208
282
  type: "object",
209
283
  object: chunk.object
210
284
  };
285
+ case "tripwire":
286
+ return {
287
+ type: "data-tripwire",
288
+ data: {
289
+ tripwireReason: chunk.payload.tripwireReason
290
+ }
291
+ };
211
292
  default:
212
293
  if (chunk.type && "payload" in chunk && chunk.payload) {
213
294
  return {
@@ -263,6 +344,14 @@ function convertFullStreamChunkToUIMessageStream({
263
344
  };
264
345
  }
265
346
  case "reasoning-delta": {
347
+ if (sendReasoning) {
348
+ return {
349
+ type: "reasoning-delta",
350
+ id: part.id,
351
+ delta: part.text,
352
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
353
+ };
354
+ }
266
355
  return;
267
356
  }
268
357
  case "reasoning-end": {
@@ -280,6 +369,25 @@ function convertFullStreamChunkToUIMessageStream({
280
369
  };
281
370
  }
282
371
  case "source": {
372
+ if (sendSources && part.sourceType === "url") {
373
+ return {
374
+ type: "source-url",
375
+ sourceId: part.id,
376
+ url: part.url,
377
+ title: part.title,
378
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
379
+ };
380
+ }
381
+ if (sendSources && part.sourceType === "document") {
382
+ return {
383
+ type: "source-document",
384
+ sourceId: part.id,
385
+ mediaType: part.mediaType,
386
+ title: part.title,
387
+ filename: part.filename,
388
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
389
+ };
390
+ }
283
391
  return;
284
392
  }
285
393
  case "tool-input-start": {
@@ -337,6 +445,14 @@ function convertFullStreamChunkToUIMessageStream({
337
445
  toolCallId: part.toolCallId,
338
446
  payload: part.output
339
447
  };
448
+ } else if (isDataChunkType(part.output)) {
449
+ if (!("data" in part.output)) {
450
+ throw new Error(
451
+ `UI Messages require a data property when using data- prefixed chunks
452
+ ${JSON.stringify(part)}`
453
+ );
454
+ }
455
+ return part.output;
340
456
  }
341
457
  return;
342
458
  }
@@ -362,21 +478,23 @@ function convertFullStreamChunkToUIMessageStream({
362
478
  return { type: "finish-step" };
363
479
  }
364
480
  case "start": {
365
- {
481
+ if (sendStart) {
366
482
  return {
367
483
  type: "start",
368
484
  ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {},
369
485
  ...responseMessageId != null ? { messageId: responseMessageId } : {}
370
486
  };
371
487
  }
488
+ return;
372
489
  }
373
490
  case "finish": {
374
- {
491
+ if (sendFinish) {
375
492
  return {
376
493
  type: "finish",
377
494
  ...messageMetadataValue != null ? { messageMetadata: messageMetadataValue } : {}
378
495
  };
379
496
  }
497
+ return;
380
498
  }
381
499
  case "abort": {
382
500
  return part;
@@ -403,7 +521,10 @@ function convertFullStreamChunkToUIMessageStream({
403
521
  }
404
522
 
405
523
  // src/transformers.ts
406
- function WorkflowStreamToAISDKTransformer() {
524
+ var PRIMITIVE_CACHE_SYMBOL = Symbol("primitive-cache");
525
+ function WorkflowStreamToAISDKTransformer({
526
+ includeTextStreamParts
527
+ } = {}) {
407
528
  const bufferedWorkflows = /* @__PURE__ */ new Map();
408
529
  return new TransformStream({
409
530
  start(controller) {
@@ -417,7 +538,7 @@ function WorkflowStreamToAISDKTransformer() {
417
538
  });
418
539
  },
419
540
  transform(chunk, controller) {
420
- const transformed = transformWorkflow(chunk, bufferedWorkflows);
541
+ const transformed = transformWorkflow(chunk, bufferedWorkflows, false, includeTextStreamParts);
421
542
  if (transformed) controller.enqueue(transformed);
422
543
  }
423
544
  });
@@ -441,20 +562,37 @@ function AgentNetworkToAISDKTransformer() {
441
562
  }
442
563
  });
443
564
  }
444
- function AgentStreamToAISDKTransformer() {
565
+ function AgentStreamToAISDKTransformer({
566
+ lastMessageId,
567
+ sendStart,
568
+ sendFinish,
569
+ sendReasoning,
570
+ sendSources,
571
+ messageMetadata,
572
+ onError
573
+ }) {
445
574
  let bufferedSteps = /* @__PURE__ */ new Map();
575
+ let tripwireOccurred = false;
576
+ let finishEventSent = false;
446
577
  return new TransformStream({
447
578
  transform(chunk, controller) {
579
+ if (chunk.type === "tripwire") {
580
+ tripwireOccurred = true;
581
+ }
582
+ if (chunk.type === "finish") {
583
+ finishEventSent = true;
584
+ }
448
585
  const part = convertMastraChunkToAISDKv5({ chunk, mode: "stream" });
449
586
  const transformedChunk = convertFullStreamChunkToUIMessageStream({
450
587
  part,
451
- sendReasoning: false,
452
- sendSources: false,
453
- sendStart: true,
454
- sendFinish: true,
455
- responseMessageId: chunk.runId,
456
- onError() {
457
- return "Error";
588
+ sendReasoning,
589
+ sendSources,
590
+ messageMetadataValue: messageMetadata?.({ part }),
591
+ sendStart,
592
+ sendFinish,
593
+ responseMessageId: lastMessageId,
594
+ onError(error) {
595
+ return onError ? onError(error) : safeParseErrorObject(error);
458
596
  }
459
597
  });
460
598
  if (transformedChunk) {
@@ -474,6 +612,14 @@ function AgentStreamToAISDKTransformer() {
474
612
  controller.enqueue(transformedChunk);
475
613
  }
476
614
  }
615
+ },
616
+ flush(controller) {
617
+ if (tripwireOccurred && !finishEventSent && sendFinish) {
618
+ controller.enqueue({
619
+ type: "finish",
620
+ finishReason: "other"
621
+ });
622
+ }
477
623
  }
478
624
  });
479
625
  }
@@ -613,7 +759,7 @@ function transformAgent(payload, bufferedSteps) {
613
759
  }
614
760
  return null;
615
761
  }
616
- function transformWorkflow(payload, bufferedWorkflows, isNested) {
762
+ function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStreamParts) {
617
763
  switch (payload.type) {
618
764
  case "workflow-start":
619
765
  bufferedWorkflows.set(payload.runId, {
@@ -636,7 +782,9 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
636
782
  name: payload.payload.id,
637
783
  status: payload.payload.status,
638
784
  input: payload.payload.payload ?? null,
639
- output: null
785
+ output: null,
786
+ suspendPayload: null,
787
+ resumePayload: null
640
788
  };
641
789
  bufferedWorkflows.set(payload.runId, current);
642
790
  return {
@@ -669,6 +817,27 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
669
817
  }
670
818
  };
671
819
  }
820
+ case "workflow-step-suspended": {
821
+ const current = bufferedWorkflows.get(payload.runId);
822
+ if (!current) return null;
823
+ current.steps[payload.payload.id] = {
824
+ ...current.steps[payload.payload.id],
825
+ status: payload.payload.status,
826
+ suspendPayload: payload.payload.suspendPayload ?? null,
827
+ resumePayload: payload.payload.resumePayload ?? null,
828
+ output: null
829
+ };
830
+ return {
831
+ type: isNested ? "data-tool-workflow" : "data-workflow",
832
+ id: payload.runId,
833
+ data: {
834
+ name: current.name,
835
+ status: "suspended",
836
+ steps: current.steps,
837
+ output: null
838
+ }
839
+ };
840
+ }
672
841
  case "workflow-finish": {
673
842
  const current = bufferedWorkflows.get(payload.runId);
674
843
  if (!current) return null;
@@ -683,6 +852,29 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
683
852
  }
684
853
  };
685
854
  }
855
+ case "workflow-step-output": {
856
+ const output = payload.payload.output;
857
+ if (includeTextStreamParts && output && isMastraTextStreamChunk(output)) {
858
+ const part = convertMastraChunkToAISDKv5({ chunk: output, mode: "stream" });
859
+ const transformedChunk = convertFullStreamChunkToUIMessageStream({
860
+ part,
861
+ onError(error) {
862
+ return safeParseErrorObject(error);
863
+ }
864
+ });
865
+ return transformedChunk;
866
+ }
867
+ if (output && isDataChunkType(output)) {
868
+ if (!("data" in output)) {
869
+ throw new Error(
870
+ `UI Messages require a data property when using data- prefixed chunks
871
+ ${JSON.stringify(output)}`
872
+ );
873
+ }
874
+ return output;
875
+ }
876
+ return null;
877
+ }
686
878
  default: {
687
879
  if (isDataChunkType(payload)) {
688
880
  if (!("data" in payload)) {
@@ -700,19 +892,39 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
700
892
  function transformNetwork(payload, bufferedNetworks, isNested) {
701
893
  switch (payload.type) {
702
894
  case "routing-agent-start": {
703
- if (!bufferedNetworks.has(payload.payload.runId)) {
704
- bufferedNetworks.set(payload.payload.runId, {
705
- name: payload.payload.agentId,
706
- steps: []
895
+ if (!bufferedNetworks.has(payload.runId)) {
896
+ bufferedNetworks.set(payload.runId, {
897
+ name: payload.payload.networkId,
898
+ steps: [],
899
+ usage: null,
900
+ output: null
707
901
  });
708
902
  }
903
+ const current = bufferedNetworks.get(payload.runId);
904
+ current.steps.push({
905
+ id: payload.payload.runId,
906
+ name: payload.payload.agentId,
907
+ status: "running",
908
+ iteration: payload.payload.inputData.iteration,
909
+ input: {
910
+ task: payload.payload.inputData.task,
911
+ threadId: payload.payload.inputData.threadId,
912
+ threadResourceId: payload.payload.inputData.threadResourceId
913
+ },
914
+ output: "",
915
+ task: null,
916
+ suspendPayload: null,
917
+ resumePayload: null,
918
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
919
+ });
709
920
  return {
710
921
  type: isNested ? "data-tool-network" : "data-network",
711
- id: payload.payload.runId,
922
+ id: payload.runId,
712
923
  data: {
713
- name: bufferedNetworks.get(payload.payload.runId).name,
924
+ name: bufferedNetworks.get(payload.runId).name,
714
925
  status: "running",
715
- steps: bufferedNetworks.get(payload.payload.runId).steps,
926
+ usage: null,
927
+ steps: bufferedNetworks.get(payload.runId).steps,
716
928
  output: null
717
929
  }
718
930
  };
@@ -735,150 +947,180 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
735
947
  };
736
948
  }
737
949
  case "agent-execution-start": {
738
- const current = bufferedNetworks.get(payload.payload.runId) || { name: "", steps: [] };
950
+ const current = bufferedNetworks.get(payload.runId);
951
+ if (!current) return null;
739
952
  current.steps.push({
953
+ id: payload.payload.runId,
740
954
  name: payload.payload.agentId,
741
955
  status: "running",
742
- input: payload.payload.args || null,
743
- output: null
956
+ iteration: payload.payload.args?.iteration ?? 0,
957
+ input: { prompt: payload.payload.args?.prompt ?? "" },
958
+ output: null,
959
+ task: null,
960
+ suspendPayload: null,
961
+ resumePayload: null,
962
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
744
963
  });
745
- bufferedNetworks.set(payload.payload.runId, current);
964
+ bufferedNetworks.set(payload.runId, current);
746
965
  return {
747
966
  type: isNested ? "data-tool-network" : "data-network",
748
- id: payload.payload.runId,
967
+ id: payload.runId,
749
968
  data: {
750
- name: current.name,
751
- status: "running",
752
- steps: current.steps,
753
- output: null
969
+ ...current,
970
+ status: "running"
754
971
  }
755
972
  };
756
973
  }
757
974
  case "workflow-execution-start": {
758
- const current = bufferedNetworks.get(payload.payload.runId) || { name: "", steps: [] };
975
+ const current = bufferedNetworks.get(payload.runId);
976
+ if (!current) return null;
759
977
  current.steps.push({
760
- name: payload.payload.name,
978
+ id: payload.payload.runId,
979
+ name: payload.payload.workflowId,
761
980
  status: "running",
762
- input: payload.payload.args || null,
763
- output: null
981
+ iteration: payload.payload.args?.iteration ?? 0,
982
+ input: { prompt: payload.payload.args?.prompt ?? "" },
983
+ output: null,
984
+ task: null,
985
+ suspendPayload: null,
986
+ resumePayload: null,
987
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
764
988
  });
765
- bufferedNetworks.set(payload.payload.runId, current);
989
+ bufferedNetworks.set(payload.runId, current);
766
990
  return {
767
991
  type: isNested ? "data-tool-network" : "data-network",
768
- id: payload.payload.runId,
992
+ id: payload.runId,
769
993
  data: {
770
- name: current.name,
771
- status: "running",
772
- steps: current.steps,
773
- output: null
994
+ ...current,
995
+ status: "running"
774
996
  }
775
997
  };
776
998
  }
777
999
  case "tool-execution-start": {
778
- const current = bufferedNetworks.get(payload.payload.runId) || { name: "", steps: [] };
1000
+ const current = bufferedNetworks.get(payload.runId);
1001
+ if (!current) return null;
779
1002
  current.steps.push({
1003
+ id: payload.payload.args.toolCallId,
780
1004
  name: payload.payload.args?.toolName,
781
1005
  status: "running",
1006
+ iteration: payload.payload.args?.iteration ? Number(payload.payload.args.iteration) : 0,
1007
+ task: {
1008
+ id: payload.payload.args?.toolName
1009
+ },
782
1010
  input: payload.payload.args?.args || null,
783
- output: null
1011
+ output: null,
1012
+ suspendPayload: null,
1013
+ resumePayload: null,
1014
+ [PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
784
1015
  });
785
- bufferedNetworks.set(payload.payload.runId, current);
1016
+ bufferedNetworks.set(payload.runId, current);
786
1017
  return {
787
1018
  type: isNested ? "data-tool-network" : "data-network",
788
- id: payload.payload.runId,
1019
+ id: payload.runId,
789
1020
  data: {
790
- name: current.name,
791
- status: "running",
792
- steps: current.steps,
793
- output: null
1021
+ ...current,
1022
+ status: "running"
794
1023
  }
795
1024
  };
796
1025
  }
797
1026
  case "agent-execution-end": {
798
1027
  const current = bufferedNetworks.get(payload.runId);
799
1028
  if (!current) return null;
800
- current.steps.push({
801
- name: payload.payload.agentId,
802
- status: "success",
803
- input: null,
804
- output: payload.payload.result
805
- });
1029
+ const stepId = payload.payload.runId;
1030
+ const step = current.steps.find((step2) => step2.id === stepId);
1031
+ if (!step) {
1032
+ return null;
1033
+ }
1034
+ step.status = "success";
1035
+ step.output = payload.payload.result;
806
1036
  return {
807
1037
  type: isNested ? "data-tool-network" : "data-network",
808
1038
  id: payload.runId,
809
1039
  data: {
810
- name: current.name,
1040
+ ...current,
1041
+ usage: payload.payload?.usage ?? current.usage,
811
1042
  status: "running",
812
- steps: current.steps,
813
- output: payload.payload.result ?? null
1043
+ output: payload.payload.result ?? current.output
814
1044
  }
815
1045
  };
816
1046
  }
817
1047
  case "tool-execution-end": {
818
1048
  const current = bufferedNetworks.get(payload.runId);
819
1049
  if (!current) return null;
820
- current.steps.push({
821
- name: payload.payload.toolName,
822
- status: "success",
823
- input: null,
824
- output: payload.payload.result
825
- });
1050
+ const stepId = payload.payload.toolCallId;
1051
+ const step = current.steps.find((step2) => step2.id === stepId);
1052
+ if (!step) {
1053
+ return null;
1054
+ }
1055
+ step.status = "success";
1056
+ step.output = payload.payload.result;
826
1057
  return {
827
1058
  type: isNested ? "data-tool-network" : "data-network",
828
1059
  id: payload.runId,
829
1060
  data: {
830
- name: current.name,
1061
+ ...current,
831
1062
  status: "running",
832
- steps: current.steps,
833
- output: payload.payload.result ?? null
1063
+ output: payload.payload.result ?? current.output
834
1064
  }
835
1065
  };
836
1066
  }
837
1067
  case "workflow-execution-end": {
838
1068
  const current = bufferedNetworks.get(payload.runId);
839
1069
  if (!current) return null;
840
- current.steps.push({
841
- name: payload.payload.name,
842
- status: "success",
843
- input: null,
844
- output: payload.payload.result
845
- });
1070
+ const stepId = payload.payload.runId;
1071
+ const step = current.steps.find((step2) => step2.id === stepId);
1072
+ if (!step) {
1073
+ return null;
1074
+ }
1075
+ step.status = "success";
1076
+ step.output = payload.payload.result;
846
1077
  return {
847
1078
  type: isNested ? "data-tool-network" : "data-network",
848
1079
  id: payload.runId,
849
1080
  data: {
850
- name: current.name,
1081
+ ...current,
1082
+ usage: payload.payload?.usage ?? current.usage,
851
1083
  status: "running",
852
- steps: current.steps,
853
- output: payload.payload.result ?? null
1084
+ output: payload.payload.result ?? current.output
854
1085
  }
855
1086
  };
856
1087
  }
857
1088
  case "routing-agent-end": {
858
- const current = bufferedNetworks.get(payload.payload.runId);
1089
+ const current = bufferedNetworks.get(payload.runId);
859
1090
  if (!current) return null;
1091
+ const stepId = payload.payload.runId;
1092
+ const step = current.steps.find((step2) => step2.id === stepId);
1093
+ if (!step) {
1094
+ return null;
1095
+ }
1096
+ step.status = "success";
1097
+ step.task = {
1098
+ id: payload.payload.primitiveId,
1099
+ type: payload.payload.primitiveType,
1100
+ name: payload.payload.task,
1101
+ reason: payload.payload.selectionReason
1102
+ };
1103
+ step.output = payload.payload.result;
860
1104
  return {
861
1105
  type: isNested ? "data-tool-network" : "data-network",
862
- id: payload.payload.runId,
1106
+ id: payload.runId,
863
1107
  data: {
864
- name: current.name,
865
- status: "finished",
866
- steps: current.steps,
867
- output: payload.payload?.result ?? null
1108
+ ...current,
1109
+ usage: payload.payload?.usage ?? current.usage,
1110
+ output: payload.payload?.result ?? current.output
868
1111
  }
869
1112
  };
870
1113
  }
871
1114
  case "network-execution-event-step-finish": {
872
- const current = bufferedNetworks.get(payload.payload.runId);
1115
+ const current = bufferedNetworks.get(payload.runId);
873
1116
  if (!current) return null;
874
1117
  return {
875
1118
  type: isNested ? "data-tool-network" : "data-network",
876
- id: payload.payload.runId,
1119
+ id: payload.runId,
877
1120
  data: {
878
- name: current.name,
1121
+ ...current,
879
1122
  status: "finished",
880
- steps: current.steps,
881
- output: payload.payload?.result ?? null
1123
+ output: payload.payload?.result ?? current.output
882
1124
  }
883
1125
  };
884
1126
  }
@@ -889,14 +1131,85 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
889
1131
  type: isNested ? "data-tool-network" : "data-network",
890
1132
  id: payload.runId,
891
1133
  data: {
892
- name: current.name,
1134
+ ...current,
1135
+ usage: payload.payload?.usage ?? current.usage,
893
1136
  status: "finished",
894
- steps: current.steps,
895
- output: payload.payload?.result ?? null
1137
+ output: payload.payload?.result ?? current.output
896
1138
  }
897
1139
  };
898
1140
  }
899
1141
  default: {
1142
+ if (isAgentExecutionDataChunkType(payload)) {
1143
+ if (!("data" in payload.payload)) {
1144
+ throw new Error(
1145
+ `UI Messages require a data property when using data- prefixed chunks
1146
+ ${JSON.stringify(payload)}`
1147
+ );
1148
+ }
1149
+ const { type, data } = payload.payload;
1150
+ return { type, data };
1151
+ }
1152
+ if (isWorkflowExecutionDataChunkType(payload)) {
1153
+ if (!("data" in payload.payload)) {
1154
+ throw new Error(
1155
+ `UI Messages require a data property when using data- prefixed chunks
1156
+ ${JSON.stringify(payload)}`
1157
+ );
1158
+ }
1159
+ const { type, data } = payload.payload;
1160
+ return { type, data };
1161
+ }
1162
+ if (payload.type.startsWith("agent-execution-event-")) {
1163
+ const stepId = payload.payload.runId;
1164
+ const current = bufferedNetworks.get(payload.runId);
1165
+ if (!current) return null;
1166
+ const step = current.steps.find((step2) => step2.id === stepId);
1167
+ if (!step) {
1168
+ return null;
1169
+ }
1170
+ step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
1171
+ const result = transformAgent(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
1172
+ if (result) {
1173
+ const { request, response, ...data } = result.data;
1174
+ step.task = data;
1175
+ }
1176
+ bufferedNetworks.set(payload.runId, current);
1177
+ return {
1178
+ type: isNested ? "data-tool-network" : "data-network",
1179
+ id: payload.runId,
1180
+ data: {
1181
+ ...current,
1182
+ status: "running"
1183
+ }
1184
+ };
1185
+ }
1186
+ if (payload.type.startsWith("workflow-execution-event-")) {
1187
+ const stepId = payload.payload.runId;
1188
+ const current = bufferedNetworks.get(payload.runId);
1189
+ if (!current) return null;
1190
+ const step = current.steps.find((step2) => step2.id === stepId);
1191
+ if (!step) {
1192
+ return null;
1193
+ }
1194
+ step[PRIMITIVE_CACHE_SYMBOL] = step[PRIMITIVE_CACHE_SYMBOL] || /* @__PURE__ */ new Map();
1195
+ const result = transformWorkflow(payload.payload, step[PRIMITIVE_CACHE_SYMBOL]);
1196
+ if (result && "data" in result) {
1197
+ const data = result.data;
1198
+ step.task = data;
1199
+ if (data.name && step.task) {
1200
+ step.task.id = data.name;
1201
+ }
1202
+ }
1203
+ bufferedNetworks.set(payload.runId, current);
1204
+ return {
1205
+ type: isNested ? "data-tool-network" : "data-network",
1206
+ id: payload.runId,
1207
+ data: {
1208
+ ...current,
1209
+ status: "running"
1210
+ }
1211
+ };
1212
+ }
900
1213
  if (isDataChunkType(payload)) {
901
1214
  if (!("data" in payload)) {
902
1215
  throw new Error(
@@ -904,31 +1217,104 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
904
1217
  ${JSON.stringify(payload)}`
905
1218
  );
906
1219
  }
907
- return payload;
1220
+ const { type, data } = payload;
1221
+ return { type, data };
908
1222
  }
909
1223
  return null;
910
1224
  }
911
1225
  }
912
1226
  }
913
1227
 
914
- // src/to-ai-sdk-format.ts
915
- function toAISdkFormat(stream, options = { from: "agent" }) {
1228
+ // src/convert-streams.ts
1229
+ function toAISdkV5Stream(stream, options = {
1230
+ from: "agent",
1231
+ sendStart: true,
1232
+ sendFinish: true
1233
+ }) {
916
1234
  const from = options?.from;
917
1235
  if (from === "workflow") {
918
- return stream.pipeThrough(WorkflowStreamToAISDKTransformer());
1236
+ const includeTextStreamParts = options?.includeTextStreamParts ?? true;
1237
+ return stream.pipeThrough(
1238
+ WorkflowStreamToAISDKTransformer({ includeTextStreamParts })
1239
+ );
919
1240
  }
920
1241
  if (from === "network") {
921
1242
  return stream.pipeThrough(AgentNetworkToAISDKTransformer());
922
1243
  }
923
1244
  const agentReadable = "fullStream" in stream ? stream.fullStream : stream;
924
- return agentReadable.pipeThrough(AgentStreamToAISDKTransformer());
1245
+ return agentReadable.pipeThrough(
1246
+ AgentStreamToAISDKTransformer({
1247
+ lastMessageId: options?.lastMessageId,
1248
+ sendStart: options?.sendStart,
1249
+ sendFinish: options?.sendFinish,
1250
+ sendReasoning: options?.sendReasoning,
1251
+ sendSources: options?.sendSources,
1252
+ messageMetadata: options?.messageMetadata,
1253
+ onError: options?.onError
1254
+ })
1255
+ );
925
1256
  }
926
1257
 
927
1258
  // src/chat-route.ts
1259
+ async function handleChatStream({
1260
+ mastra,
1261
+ agentId,
1262
+ params,
1263
+ defaultOptions,
1264
+ sendStart = true,
1265
+ sendFinish = true,
1266
+ sendReasoning = false,
1267
+ sendSources = false
1268
+ }) {
1269
+ const { messages, resumeData, runId, requestContext, ...rest } = params;
1270
+ if (resumeData && !runId) {
1271
+ throw new Error("runId is required when resumeData is provided");
1272
+ }
1273
+ const agentObj = mastra.getAgentById(agentId);
1274
+ if (!agentObj) {
1275
+ throw new Error(`Agent ${agentId} not found`);
1276
+ }
1277
+ if (!Array.isArray(messages)) {
1278
+ throw new Error("Messages must be an array of UIMessage objects");
1279
+ }
1280
+ const mergedOptions = {
1281
+ ...defaultOptions,
1282
+ ...rest,
1283
+ ...runId && { runId },
1284
+ requestContext: requestContext || defaultOptions?.requestContext
1285
+ };
1286
+ const result = resumeData ? await agentObj.resumeStream(resumeData, mergedOptions) : await agentObj.stream(messages, mergedOptions);
1287
+ let lastMessageId;
1288
+ if (messages.length) {
1289
+ const lastMessage = messages[messages.length - 1];
1290
+ if (lastMessage?.role === "assistant") {
1291
+ lastMessageId = lastMessage.id;
1292
+ }
1293
+ }
1294
+ return createUIMessageStream({
1295
+ originalMessages: messages,
1296
+ execute: async ({ writer }) => {
1297
+ for await (const part of toAISdkV5Stream(result, {
1298
+ from: "agent",
1299
+ lastMessageId,
1300
+ sendStart,
1301
+ sendFinish,
1302
+ sendReasoning,
1303
+ sendSources
1304
+ })) {
1305
+ writer.write(part);
1306
+ }
1307
+ }
1308
+ });
1309
+ }
928
1310
  function chatRoute({
929
1311
  path = "/chat/:agentId",
930
1312
  agent,
931
- defaultOptions
1313
+ defaultOptions,
1314
+ sendStart = true,
1315
+ sendFinish = true,
1316
+ sendReasoning = false,
1317
+ sendSources = false
932
1318
  }) {
933
1319
  if (!agent && !path.includes("/:agentId")) {
934
1320
  throw new Error("Path must include :agentId to route to the correct agent or pass the agent explicitly");
@@ -957,6 +1343,14 @@ function chatRoute({
957
1343
  schema: {
958
1344
  type: "object",
959
1345
  properties: {
1346
+ resumeData: {
1347
+ type: "object",
1348
+ description: "Resume data for the agent"
1349
+ },
1350
+ runId: {
1351
+ type: "string",
1352
+ description: "The run ID required when resuming an agent execution"
1353
+ },
960
1354
  messages: {
961
1355
  type: "array",
962
1356
  description: "Array of messages in the conversation",
@@ -1027,9 +1421,9 @@ function chatRoute({
1027
1421
  }
1028
1422
  },
1029
1423
  handler: async (c) => {
1030
- const { messages, ...rest } = await c.req.json();
1424
+ const params = await c.req.json();
1031
1425
  const mastra = c.get("mastra");
1032
- const runtimeContext = c.get("runtimeContext");
1426
+ const contextRequestContext = c.get("requestContext");
1033
1427
  let agentToUse = agent;
1034
1428
  if (!agent) {
1035
1429
  const agentId = c.req.param("agentId");
@@ -1040,28 +1434,24 @@ function chatRoute({
1040
1434
  `Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
1041
1435
  );
1042
1436
  }
1043
- if (runtimeContext && defaultOptions?.runtimeContext) {
1044
- mastra.getLogger()?.warn(`"runtimeContext" set in the route options will be overridden by the request's "runtimeContext".`);
1437
+ if (contextRequestContext && defaultOptions?.requestContext) {
1438
+ mastra.getLogger()?.warn(`"requestContext" set in the route options will be overridden by the request's "requestContext".`);
1045
1439
  }
1046
1440
  if (!agentToUse) {
1047
1441
  throw new Error("Agent ID is required");
1048
1442
  }
1049
- const agentObj = mastra.getAgent(agentToUse);
1050
- if (!agentObj) {
1051
- throw new Error(`Agent ${agentToUse} not found`);
1052
- }
1053
- const result = await agentObj.stream(messages, {
1054
- ...defaultOptions,
1055
- ...rest,
1056
- runtimeContext: runtimeContext || defaultOptions?.runtimeContext
1057
- });
1058
- const uiMessageStream = createUIMessageStream({
1059
- originalMessages: messages,
1060
- execute: async ({ writer }) => {
1061
- for await (const part of toAISdkFormat(result, { from: "agent" })) {
1062
- writer.write(part);
1063
- }
1064
- }
1443
+ const uiMessageStream = await handleChatStream({
1444
+ mastra,
1445
+ agentId: agentToUse,
1446
+ params: {
1447
+ ...params,
1448
+ requestContext: contextRequestContext || params.requestContext
1449
+ },
1450
+ defaultOptions,
1451
+ sendStart,
1452
+ sendFinish,
1453
+ sendReasoning,
1454
+ sendSources
1065
1455
  });
1066
1456
  return createUIMessageStreamResponse({
1067
1457
  stream: uiMessageStream
@@ -1069,9 +1459,31 @@ function chatRoute({
1069
1459
  }
1070
1460
  });
1071
1461
  }
1462
+ async function handleWorkflowStream({
1463
+ mastra,
1464
+ workflowId,
1465
+ params,
1466
+ includeTextStreamParts = true
1467
+ }) {
1468
+ const { runId, resourceId, inputData, resumeData, requestContext, ...rest } = params;
1469
+ const workflowObj = mastra.getWorkflowById(workflowId);
1470
+ if (!workflowObj) {
1471
+ throw new Error(`Workflow ${workflowId} not found`);
1472
+ }
1473
+ const run = await workflowObj.createRun({ runId, resourceId, ...rest });
1474
+ const stream = resumeData ? run.resumeStream({ resumeData, ...rest, requestContext }) : run.stream({ inputData, ...rest, requestContext });
1475
+ return createUIMessageStream({
1476
+ execute: async ({ writer }) => {
1477
+ for await (const part of toAISdkV5Stream(stream, { from: "workflow", includeTextStreamParts })) {
1478
+ writer.write(part);
1479
+ }
1480
+ }
1481
+ });
1482
+ }
1072
1483
  function workflowRoute({
1073
1484
  path = "/api/workflows/:workflowId/stream",
1074
- workflow
1485
+ workflow,
1486
+ includeTextStreamParts = true
1075
1487
  }) {
1076
1488
  if (!workflow && !path.includes("/:workflowId")) {
1077
1489
  throw new Error("Path must include :workflowId to route to the correct workflow or pass the workflow explicitly");
@@ -1098,9 +1510,13 @@ function workflowRoute({
1098
1510
  schema: {
1099
1511
  type: "object",
1100
1512
  properties: {
1513
+ runId: { type: "string" },
1514
+ resourceId: { type: "string" },
1101
1515
  inputData: { type: "object", additionalProperties: true },
1102
- runtimeContext: { type: "object", additionalProperties: true },
1103
- tracingOptions: { type: "object", additionalProperties: true }
1516
+ resumeData: { type: "object", additionalProperties: true },
1517
+ requestContext: { type: "object", additionalProperties: true },
1518
+ tracingOptions: { type: "object", additionalProperties: true },
1519
+ step: { type: "string" }
1104
1520
  }
1105
1521
  }
1106
1522
  }
@@ -1118,8 +1534,9 @@ function workflowRoute({
1118
1534
  }
1119
1535
  },
1120
1536
  handler: async (c) => {
1121
- const { inputData, ...rest } = await c.req.json();
1537
+ const params = await c.req.json();
1122
1538
  const mastra = c.get("mastra");
1539
+ const contextRequestContext = c.get("requestContext");
1123
1540
  let workflowToUse = workflow;
1124
1541
  if (!workflow) {
1125
1542
  const workflowId = c.req.param("workflowId");
@@ -1133,23 +1550,47 @@ function workflowRoute({
1133
1550
  if (!workflowToUse) {
1134
1551
  throw new Error("Workflow ID is required");
1135
1552
  }
1136
- const workflowObj = mastra.getWorkflow(workflowToUse);
1137
- if (!workflowObj) {
1138
- throw new Error(`Workflow ${workflowToUse} not found`);
1553
+ if (contextRequestContext && params.requestContext) {
1554
+ mastra.getLogger()?.warn(
1555
+ `"requestContext" from the request body will be ignored because "requestContext" is already set in the route options.`
1556
+ );
1139
1557
  }
1140
- const run = await workflowObj.createRunAsync();
1141
- const stream = run.streamVNext({ inputData, ...rest });
1142
- const uiMessageStream = createUIMessageStream({
1143
- execute: async ({ writer }) => {
1144
- for await (const part of toAISdkFormat(stream, { from: "workflow" })) {
1145
- writer.write(part);
1146
- }
1147
- }
1558
+ const uiMessageStream = await handleWorkflowStream({
1559
+ mastra,
1560
+ workflowId: workflowToUse,
1561
+ params: {
1562
+ ...params,
1563
+ requestContext: contextRequestContext || params.requestContext
1564
+ },
1565
+ includeTextStreamParts
1148
1566
  });
1149
1567
  return createUIMessageStreamResponse({ stream: uiMessageStream });
1150
1568
  }
1151
1569
  });
1152
1570
  }
1571
+ async function handleNetworkStream({
1572
+ mastra,
1573
+ agentId,
1574
+ params,
1575
+ defaultOptions
1576
+ }) {
1577
+ const { messages, ...rest } = params;
1578
+ const agentObj = mastra.getAgentById(agentId);
1579
+ if (!agentObj) {
1580
+ throw new Error(`Agent ${agentId} not found`);
1581
+ }
1582
+ const result = await agentObj.network(messages, {
1583
+ ...defaultOptions,
1584
+ ...rest
1585
+ });
1586
+ return createUIMessageStream({
1587
+ execute: async ({ writer }) => {
1588
+ for await (const part of toAISdkV5Stream(result, { from: "network" })) {
1589
+ writer.write(part);
1590
+ }
1591
+ }
1592
+ });
1593
+ }
1153
1594
  function networkRoute({
1154
1595
  path = "/network/:agentId",
1155
1596
  agent,
@@ -1181,13 +1622,12 @@ function networkRoute({
1181
1622
  type: "object",
1182
1623
  properties: {
1183
1624
  messages: { type: "array", items: { type: "object" } },
1184
- runtimeContext: { type: "object", additionalProperties: true },
1625
+ requestContext: { type: "object", additionalProperties: true },
1185
1626
  runId: { type: "string" },
1186
1627
  maxSteps: { type: "number" },
1187
1628
  threadId: { type: "string" },
1188
1629
  resourceId: { type: "string" },
1189
1630
  modelSettings: { type: "object", additionalProperties: true },
1190
- telemetry: { type: "object", additionalProperties: true },
1191
1631
  tools: { type: "array", items: { type: "object" } }
1192
1632
  },
1193
1633
  required: ["messages"]
@@ -1211,7 +1651,7 @@ function networkRoute({
1211
1651
  }
1212
1652
  },
1213
1653
  handler: async (c) => {
1214
- const { messages, ...rest } = await c.req.json();
1654
+ const params = await c.req.json();
1215
1655
  const mastra = c.get("mastra");
1216
1656
  let agentToUse = agent;
1217
1657
  if (!agent) {
@@ -1226,26 +1666,473 @@ function networkRoute({
1226
1666
  if (!agentToUse) {
1227
1667
  throw new Error("Agent ID is required");
1228
1668
  }
1229
- const agentObj = mastra.getAgent(agentToUse);
1230
- if (!agentObj) {
1231
- throw new Error(`Agent ${agentToUse} not found`);
1669
+ const uiMessageStream = await handleNetworkStream({
1670
+ mastra,
1671
+ agentId: agentToUse,
1672
+ params,
1673
+ defaultOptions
1674
+ });
1675
+ return createUIMessageStreamResponse({ stream: uiMessageStream });
1676
+ }
1677
+ });
1678
+ }
1679
+ function withMastra(model, options = {}) {
1680
+ const { memory, inputProcessors = [], outputProcessors = [] } = options;
1681
+ const allInputProcessors = [...inputProcessors];
1682
+ const allOutputProcessors = [...outputProcessors];
1683
+ if (memory) {
1684
+ const { storage, lastMessages, semanticRecall, workingMemory } = memory;
1685
+ const isWorkingMemoryEnabled = typeof workingMemory === "object" && workingMemory.enabled !== false;
1686
+ if (isWorkingMemoryEnabled && typeof workingMemory === "object") {
1687
+ let template;
1688
+ if (workingMemory.template) {
1689
+ template = {
1690
+ format: "markdown",
1691
+ content: workingMemory.template
1692
+ };
1232
1693
  }
1233
- const result = await agentObj.network(messages, {
1234
- ...defaultOptions,
1235
- ...rest
1694
+ const workingMemoryProcessor = new WorkingMemory({
1695
+ storage,
1696
+ template,
1697
+ scope: workingMemory.scope,
1698
+ useVNext: "version" in workingMemory && workingMemory.version === "vnext"
1699
+ });
1700
+ allInputProcessors.push(workingMemoryProcessor);
1701
+ }
1702
+ if (lastMessages !== false && lastMessages !== void 0) {
1703
+ const messageHistory = new MessageHistory({
1704
+ storage,
1705
+ lastMessages: typeof lastMessages === "number" ? lastMessages : void 0
1706
+ });
1707
+ allInputProcessors.push(messageHistory);
1708
+ allOutputProcessors.push(messageHistory);
1709
+ }
1710
+ if (semanticRecall) {
1711
+ const { vector, embedder, indexName, ...semanticConfig } = semanticRecall;
1712
+ const semanticRecallProcessor = new SemanticRecall({
1713
+ storage,
1714
+ vector,
1715
+ embedder,
1716
+ indexName: indexName || "memory_messages",
1717
+ ...semanticConfig
1718
+ });
1719
+ allInputProcessors.push(semanticRecallProcessor);
1720
+ allOutputProcessors.push(semanticRecallProcessor);
1721
+ }
1722
+ }
1723
+ return wrapLanguageModel({
1724
+ model,
1725
+ middleware: createProcessorMiddleware({
1726
+ inputProcessors: allInputProcessors,
1727
+ outputProcessors: allOutputProcessors,
1728
+ memory: memory ? {
1729
+ threadId: memory.threadId,
1730
+ resourceId: memory.resourceId
1731
+ } : void 0
1732
+ })
1733
+ });
1734
+ }
1735
+ function createProcessorMiddleware(options) {
1736
+ const { inputProcessors = [], outputProcessors = [], memory } = options;
1737
+ const requestContext = new RequestContext();
1738
+ if (memory) {
1739
+ requestContext.set("MastraMemory", {
1740
+ thread: memory.threadId ? { id: memory.threadId } : void 0,
1741
+ resourceId: memory.resourceId,
1742
+ memoryConfig: memory.config
1743
+ });
1744
+ }
1745
+ return {
1746
+ middlewareVersion: "v2",
1747
+ /**
1748
+ * Transform params runs input processors (processInput)
1749
+ */
1750
+ async transformParams({ params }) {
1751
+ const messageList = new MessageList({
1752
+ threadId: memory?.threadId,
1753
+ resourceId: memory?.resourceId
1236
1754
  });
1237
- const uiMessageStream = createUIMessageStream({
1238
- execute: async ({ writer }) => {
1239
- for await (const part of toAISdkFormat(result, { from: "network" })) {
1240
- writer.write(part);
1755
+ for (const msg of params.prompt) {
1756
+ if (msg.role === "system") {
1757
+ messageList.addSystem(msg.content);
1758
+ } else {
1759
+ messageList.add(msg, "input");
1760
+ }
1761
+ }
1762
+ for (const processor of inputProcessors) {
1763
+ if (processor.processInput) {
1764
+ try {
1765
+ await processor.processInput({
1766
+ messages: messageList.get.input.db(),
1767
+ systemMessages: messageList.getAllSystemMessages(),
1768
+ messageList,
1769
+ requestContext,
1770
+ abort: (reason) => {
1771
+ throw new TripWire(reason || "Aborted by processor");
1772
+ }
1773
+ });
1774
+ } catch (error) {
1775
+ if (error instanceof TripWire) {
1776
+ return {
1777
+ ...params,
1778
+ providerOptions: {
1779
+ ...params.providerOptions,
1780
+ mastraProcessors: {
1781
+ tripwire: true,
1782
+ reason: error.message
1783
+ }
1784
+ }
1785
+ };
1786
+ }
1787
+ throw error;
1241
1788
  }
1242
1789
  }
1790
+ }
1791
+ const newPrompt = messageList.get.all.aiV5.prompt().map(MessageList.aiV5ModelMessageToV2PromptMessage);
1792
+ return {
1793
+ ...params,
1794
+ prompt: newPrompt
1795
+ };
1796
+ },
1797
+ /**
1798
+ * Wrap generate for non-streaming output processing
1799
+ */
1800
+ async wrapGenerate({ doGenerate, params }) {
1801
+ const processorState = params.providerOptions?.mastraProcessors;
1802
+ if (processorState?.tripwire) {
1803
+ const reason = processorState.reason || "Blocked by processor";
1804
+ return {
1805
+ content: [{ type: "text", text: reason }],
1806
+ finishReason: "stop",
1807
+ usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
1808
+ warnings: [{ type: "other", message: `Tripwire: ${reason}` }]
1809
+ };
1810
+ }
1811
+ const result = await doGenerate();
1812
+ if (!outputProcessors.length) return result;
1813
+ const messageList = new MessageList({
1814
+ threadId: memory?.threadId,
1815
+ resourceId: memory?.resourceId
1243
1816
  });
1244
- return createUIMessageStreamResponse({ stream: uiMessageStream });
1817
+ for (const msg of params.prompt) {
1818
+ if (msg.role === "system") {
1819
+ messageList.addSystem(msg.content);
1820
+ } else {
1821
+ messageList.add(msg, "input");
1822
+ }
1823
+ }
1824
+ const textContent = result.content.filter((c) => c.type === "text").map((c) => c.text).join("");
1825
+ const responseMessage = {
1826
+ id: crypto.randomUUID(),
1827
+ role: "assistant",
1828
+ content: {
1829
+ format: 2,
1830
+ parts: [{ type: "text", text: textContent }]
1831
+ },
1832
+ createdAt: /* @__PURE__ */ new Date(),
1833
+ ...memory?.threadId && { threadId: memory.threadId },
1834
+ ...memory?.resourceId && { resourceId: memory.resourceId }
1835
+ };
1836
+ messageList.add(responseMessage, "response");
1837
+ for (const processor of outputProcessors) {
1838
+ if (processor.processOutputResult) {
1839
+ try {
1840
+ await processor.processOutputResult({
1841
+ messages: messageList.get.all.db(),
1842
+ messageList,
1843
+ requestContext,
1844
+ abort: (reason) => {
1845
+ throw new TripWire(reason || "Aborted by processor");
1846
+ }
1847
+ });
1848
+ } catch (error) {
1849
+ if (error instanceof TripWire) {
1850
+ return {
1851
+ content: [{ type: "text", text: error.message }],
1852
+ finishReason: "stop",
1853
+ usage: result.usage,
1854
+ warnings: [{ type: "other", message: `Output blocked: ${error.message}` }]
1855
+ };
1856
+ }
1857
+ throw error;
1858
+ }
1859
+ }
1860
+ }
1861
+ const processedText = messageList.get.response.db().map((m) => extractTextFromMastraMessage(m)).join("");
1862
+ return {
1863
+ ...result,
1864
+ content: [{ type: "text", text: processedText }]
1865
+ };
1866
+ },
1867
+ /**
1868
+ * Wrap stream for streaming output processing
1869
+ */
1870
+ async wrapStream({ doStream, params }) {
1871
+ const processorState = params.providerOptions?.mastraProcessors;
1872
+ if (processorState?.tripwire) {
1873
+ const reason = processorState.reason || "Blocked by processor";
1874
+ return {
1875
+ stream: createBlockedStream(reason)
1876
+ };
1877
+ }
1878
+ const { stream, ...rest } = await doStream();
1879
+ if (!outputProcessors.length) return { stream, ...rest };
1880
+ const processorStates = /* @__PURE__ */ new Map();
1881
+ const runId = crypto.randomUUID();
1882
+ const transformedStream = stream.pipeThrough(
1883
+ new TransformStream({
1884
+ async transform(chunk, controller) {
1885
+ let mastraChunk = convertFullStreamChunkToMastra(
1886
+ chunk,
1887
+ { runId }
1888
+ );
1889
+ if (!mastraChunk) {
1890
+ controller.enqueue(chunk);
1891
+ return;
1892
+ }
1893
+ for (const processor of outputProcessors) {
1894
+ if (processor.processOutputStream && mastraChunk) {
1895
+ let state = processorStates.get(processor.id);
1896
+ if (!state) {
1897
+ state = { streamParts: [], customState: {} };
1898
+ processorStates.set(processor.id, state);
1899
+ }
1900
+ state.streamParts.push(mastraChunk);
1901
+ try {
1902
+ const result = await processor.processOutputStream({
1903
+ part: mastraChunk,
1904
+ streamParts: state.streamParts,
1905
+ state: state.customState,
1906
+ requestContext,
1907
+ abort: (reason) => {
1908
+ throw new TripWire(reason || "Aborted by processor");
1909
+ }
1910
+ });
1911
+ if (result === null || result === void 0) {
1912
+ mastraChunk = void 0;
1913
+ } else {
1914
+ mastraChunk = result;
1915
+ }
1916
+ } catch (error) {
1917
+ if (error instanceof TripWire) {
1918
+ controller.enqueue({
1919
+ type: "error",
1920
+ error: new Error(error.message)
1921
+ });
1922
+ controller.terminate();
1923
+ return;
1924
+ }
1925
+ throw error;
1926
+ }
1927
+ }
1928
+ }
1929
+ if (mastraChunk) {
1930
+ const aiChunk = convertMastraChunkToAISDKStreamPart(mastraChunk);
1931
+ if (aiChunk) {
1932
+ controller.enqueue(aiChunk);
1933
+ }
1934
+ }
1935
+ }
1936
+ })
1937
+ );
1938
+ return { stream: transformedStream, ...rest };
1939
+ }
1940
+ };
1941
+ }
1942
+ function createBlockedStream(reason) {
1943
+ return new ReadableStream({
1944
+ start(controller) {
1945
+ const id = crypto.randomUUID();
1946
+ controller.enqueue({
1947
+ type: "text-start",
1948
+ id
1949
+ });
1950
+ controller.enqueue({
1951
+ type: "text-delta",
1952
+ id,
1953
+ delta: reason
1954
+ });
1955
+ controller.enqueue({
1956
+ type: "text-end",
1957
+ id
1958
+ });
1959
+ controller.enqueue({
1960
+ type: "finish",
1961
+ finishReason: "stop",
1962
+ usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 }
1963
+ });
1964
+ controller.close();
1245
1965
  }
1246
1966
  });
1247
1967
  }
1968
+ function extractTextFromMastraMessage(msg) {
1969
+ const content = msg.content;
1970
+ if (typeof content === "string") {
1971
+ return content;
1972
+ }
1973
+ if (content?.parts) {
1974
+ return content.parts.filter((p) => p.type === "text" && "text" in p).map((p) => p.text).join("");
1975
+ }
1976
+ return "";
1977
+ }
1978
+ function convertMastraChunkToAISDKStreamPart(chunk) {
1979
+ switch (chunk.type) {
1980
+ // Text streaming
1981
+ case "text-start":
1982
+ return {
1983
+ type: "text-start",
1984
+ id: chunk.payload.id || crypto.randomUUID(),
1985
+ providerMetadata: chunk.payload.providerMetadata
1986
+ };
1987
+ case "text-delta":
1988
+ return {
1989
+ type: "text-delta",
1990
+ id: chunk.payload.id || crypto.randomUUID(),
1991
+ delta: chunk.payload.text,
1992
+ providerMetadata: chunk.payload.providerMetadata
1993
+ };
1994
+ case "text-end":
1995
+ return {
1996
+ type: "text-end",
1997
+ id: chunk.payload.id || crypto.randomUUID(),
1998
+ providerMetadata: chunk.payload.providerMetadata
1999
+ };
2000
+ // Reasoning streaming
2001
+ case "reasoning-start":
2002
+ return {
2003
+ type: "reasoning-start",
2004
+ id: chunk.payload.id || crypto.randomUUID(),
2005
+ providerMetadata: chunk.payload.providerMetadata
2006
+ };
2007
+ case "reasoning-delta":
2008
+ return {
2009
+ type: "reasoning-delta",
2010
+ id: chunk.payload.id || crypto.randomUUID(),
2011
+ delta: chunk.payload.text,
2012
+ providerMetadata: chunk.payload.providerMetadata
2013
+ };
2014
+ case "reasoning-end":
2015
+ return {
2016
+ type: "reasoning-end",
2017
+ id: chunk.payload.id || crypto.randomUUID(),
2018
+ providerMetadata: chunk.payload.providerMetadata
2019
+ };
2020
+ // Tool call (complete)
2021
+ case "tool-call":
2022
+ return {
2023
+ type: "tool-call",
2024
+ toolCallId: chunk.payload.toolCallId,
2025
+ toolName: chunk.payload.toolName,
2026
+ input: JSON.stringify(chunk.payload.args),
2027
+ providerExecuted: chunk.payload.providerExecuted,
2028
+ providerMetadata: chunk.payload.providerMetadata
2029
+ };
2030
+ // Tool call input streaming
2031
+ case "tool-call-input-streaming-start":
2032
+ return {
2033
+ type: "tool-input-start",
2034
+ id: chunk.payload.toolCallId,
2035
+ toolName: chunk.payload.toolName,
2036
+ providerExecuted: chunk.payload.providerExecuted,
2037
+ providerMetadata: chunk.payload.providerMetadata
2038
+ };
2039
+ case "tool-call-delta":
2040
+ return {
2041
+ type: "tool-input-delta",
2042
+ id: chunk.payload.toolCallId,
2043
+ delta: chunk.payload.argsTextDelta,
2044
+ providerMetadata: chunk.payload.providerMetadata
2045
+ };
2046
+ case "tool-call-input-streaming-end":
2047
+ return {
2048
+ type: "tool-input-end",
2049
+ id: chunk.payload.toolCallId,
2050
+ providerMetadata: chunk.payload.providerMetadata
2051
+ };
2052
+ // Tool result
2053
+ case "tool-result":
2054
+ return {
2055
+ type: "tool-result",
2056
+ toolCallId: chunk.payload.toolCallId,
2057
+ toolName: chunk.payload.toolName,
2058
+ result: { type: "json", value: chunk.payload.result },
2059
+ isError: chunk.payload.isError,
2060
+ providerExecuted: chunk.payload.providerExecuted,
2061
+ providerMetadata: chunk.payload.providerMetadata
2062
+ };
2063
+ // Source (citations)
2064
+ case "source":
2065
+ if (chunk.payload.sourceType === "url") {
2066
+ return {
2067
+ type: "source",
2068
+ sourceType: "url",
2069
+ id: chunk.payload.id,
2070
+ url: chunk.payload.url,
2071
+ title: chunk.payload.title,
2072
+ providerMetadata: chunk.payload.providerMetadata
2073
+ };
2074
+ } else {
2075
+ return {
2076
+ type: "source",
2077
+ sourceType: "document",
2078
+ id: chunk.payload.id,
2079
+ mediaType: chunk.payload.mimeType,
2080
+ title: chunk.payload.title,
2081
+ filename: chunk.payload.filename,
2082
+ providerMetadata: chunk.payload.providerMetadata
2083
+ };
2084
+ }
2085
+ // File output
2086
+ case "file":
2087
+ return {
2088
+ type: "file",
2089
+ data: chunk.payload.data || chunk.payload.base64,
2090
+ mediaType: chunk.payload.mimeType
2091
+ };
2092
+ // Response metadata
2093
+ case "response-metadata":
2094
+ return {
2095
+ type: "response-metadata",
2096
+ ...chunk.payload
2097
+ };
2098
+ // Raw provider data
2099
+ case "raw":
2100
+ return {
2101
+ type: "raw",
2102
+ rawValue: chunk.payload
2103
+ };
2104
+ // Finish
2105
+ case "finish": {
2106
+ const usage = chunk.payload.output?.usage;
2107
+ return {
2108
+ type: "finish",
2109
+ finishReason: chunk.payload.stepResult?.reason || "stop",
2110
+ usage: usage ? {
2111
+ inputTokens: usage.inputTokens || 0,
2112
+ outputTokens: usage.outputTokens || 0,
2113
+ totalTokens: usage.totalTokens || 0
2114
+ } : { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
2115
+ providerMetadata: chunk.payload.metadata?.providerMetadata
2116
+ };
2117
+ }
2118
+ // Error
2119
+ case "error":
2120
+ return {
2121
+ type: "error",
2122
+ error: chunk.payload.error || chunk.payload
2123
+ };
2124
+ default:
2125
+ return null;
2126
+ }
2127
+ }
2128
+
2129
+ // src/to-ai-sdk-format.ts
2130
+ function toAISdkFormat() {
2131
+ throw new Error(
2132
+ '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.'
2133
+ );
2134
+ }
1248
2135
 
1249
- export { chatRoute, networkRoute, toAISdkFormat, workflowRoute };
2136
+ export { chatRoute, handleChatStream, handleNetworkStream, handleWorkflowStream, networkRoute, toAISdkFormat, toAISdkV5Stream as toAISdkStream, withMastra, workflowRoute };
1250
2137
  //# sourceMappingURL=index.js.map
1251
2138
  //# sourceMappingURL=index.js.map