@mastra/ai-sdk 1.0.0-beta.3 → 1.0.0-beta.5
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/CHANGELOG.md +139 -0
- package/README.md +60 -0
- package/dist/__tests__/__fixtures__/network.stream.d.ts +2329 -0
- package/dist/__tests__/__fixtures__/network.stream.d.ts.map +1 -0
- package/dist/chat-route.d.ts +33 -1
- package/dist/chat-route.d.ts.map +1 -1
- package/dist/convert-streams.d.ts +17 -1
- package/dist/convert-streams.d.ts.map +1 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/index.cjs +348 -103
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +346 -104
- package/dist/index.js.map +1 -1
- package/dist/network-route.d.ts +30 -2
- package/dist/network-route.d.ts.map +1 -1
- package/dist/transformers.d.ts +130 -10
- package/dist/transformers.d.ts.map +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/workflow-route.d.ts +38 -1
- package/dist/workflow-route.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -10,6 +10,31 @@ 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
|
+
};
|
|
13
38
|
function safeParseErrorObject(obj) {
|
|
14
39
|
if (typeof obj !== "object" || obj === null) {
|
|
15
40
|
return String(obj);
|
|
@@ -140,6 +165,28 @@ function convertMastraChunkToAISDKv5({
|
|
|
140
165
|
toolName: chunk.payload.toolName,
|
|
141
166
|
input: chunk.payload.args
|
|
142
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
|
+
};
|
|
143
190
|
case "tool-call-input-streaming-start":
|
|
144
191
|
return {
|
|
145
192
|
type: "tool-input-start",
|
|
@@ -469,7 +516,10 @@ function convertFullStreamChunkToUIMessageStream({
|
|
|
469
516
|
}
|
|
470
517
|
|
|
471
518
|
// src/transformers.ts
|
|
472
|
-
|
|
519
|
+
var PRIMITIVE_CACHE_SYMBOL = Symbol("primitive-cache");
|
|
520
|
+
function WorkflowStreamToAISDKTransformer({
|
|
521
|
+
includeTextStreamParts
|
|
522
|
+
} = {}) {
|
|
473
523
|
const bufferedWorkflows = /* @__PURE__ */ new Map();
|
|
474
524
|
return new TransformStream({
|
|
475
525
|
start(controller) {
|
|
@@ -483,7 +533,7 @@ function WorkflowStreamToAISDKTransformer() {
|
|
|
483
533
|
});
|
|
484
534
|
},
|
|
485
535
|
transform(chunk, controller) {
|
|
486
|
-
const transformed = transformWorkflow(chunk, bufferedWorkflows);
|
|
536
|
+
const transformed = transformWorkflow(chunk, bufferedWorkflows, false, includeTextStreamParts);
|
|
487
537
|
if (transformed) controller.enqueue(transformed);
|
|
488
538
|
}
|
|
489
539
|
});
|
|
@@ -512,7 +562,9 @@ function AgentStreamToAISDKTransformer({
|
|
|
512
562
|
sendStart,
|
|
513
563
|
sendFinish,
|
|
514
564
|
sendReasoning,
|
|
515
|
-
sendSources
|
|
565
|
+
sendSources,
|
|
566
|
+
messageMetadata,
|
|
567
|
+
onError
|
|
516
568
|
}) {
|
|
517
569
|
let bufferedSteps = /* @__PURE__ */ new Map();
|
|
518
570
|
let tripwireOccurred = false;
|
|
@@ -530,11 +582,12 @@ function AgentStreamToAISDKTransformer({
|
|
|
530
582
|
part,
|
|
531
583
|
sendReasoning,
|
|
532
584
|
sendSources,
|
|
585
|
+
messageMetadataValue: messageMetadata?.({ part }),
|
|
533
586
|
sendStart,
|
|
534
587
|
sendFinish,
|
|
535
588
|
responseMessageId: lastMessageId,
|
|
536
589
|
onError(error) {
|
|
537
|
-
return safeParseErrorObject(error);
|
|
590
|
+
return onError ? onError(error) : safeParseErrorObject(error);
|
|
538
591
|
}
|
|
539
592
|
});
|
|
540
593
|
if (transformedChunk) {
|
|
@@ -701,7 +754,7 @@ function transformAgent(payload, bufferedSteps) {
|
|
|
701
754
|
}
|
|
702
755
|
return null;
|
|
703
756
|
}
|
|
704
|
-
function transformWorkflow(payload, bufferedWorkflows, isNested) {
|
|
757
|
+
function transformWorkflow(payload, bufferedWorkflows, isNested, includeTextStreamParts) {
|
|
705
758
|
switch (payload.type) {
|
|
706
759
|
case "workflow-start":
|
|
707
760
|
bufferedWorkflows.set(payload.runId, {
|
|
@@ -794,6 +847,29 @@ function transformWorkflow(payload, bufferedWorkflows, isNested) {
|
|
|
794
847
|
}
|
|
795
848
|
};
|
|
796
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
|
+
}
|
|
797
873
|
default: {
|
|
798
874
|
if (isDataChunkType(payload)) {
|
|
799
875
|
if (!("data" in payload)) {
|
|
@@ -813,12 +889,29 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
813
889
|
case "routing-agent-start": {
|
|
814
890
|
if (!bufferedNetworks.has(payload.runId)) {
|
|
815
891
|
bufferedNetworks.set(payload.runId, {
|
|
816
|
-
name: payload.payload.
|
|
892
|
+
name: payload.payload.networkId,
|
|
817
893
|
steps: [],
|
|
818
894
|
usage: null,
|
|
819
895
|
output: null
|
|
820
896
|
});
|
|
821
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
|
+
});
|
|
822
915
|
return {
|
|
823
916
|
type: isNested ? "data-tool-network" : "data-network",
|
|
824
917
|
id: payload.runId,
|
|
@@ -849,14 +942,19 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
849
942
|
};
|
|
850
943
|
}
|
|
851
944
|
case "agent-execution-start": {
|
|
852
|
-
const current = bufferedNetworks.get(payload.runId)
|
|
945
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
946
|
+
if (!current) return null;
|
|
853
947
|
current.steps.push({
|
|
948
|
+
id: payload.payload.runId,
|
|
854
949
|
name: payload.payload.agentId,
|
|
855
950
|
status: "running",
|
|
856
|
-
|
|
951
|
+
iteration: payload.payload.args?.iteration ?? 0,
|
|
952
|
+
input: { prompt: payload.payload.args?.prompt ?? "" },
|
|
857
953
|
output: null,
|
|
954
|
+
task: null,
|
|
858
955
|
suspendPayload: null,
|
|
859
|
-
resumePayload: null
|
|
956
|
+
resumePayload: null,
|
|
957
|
+
[PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
|
|
860
958
|
});
|
|
861
959
|
bufferedNetworks.set(payload.runId, current);
|
|
862
960
|
return {
|
|
@@ -869,14 +967,19 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
869
967
|
};
|
|
870
968
|
}
|
|
871
969
|
case "workflow-execution-start": {
|
|
872
|
-
const current = bufferedNetworks.get(payload.runId)
|
|
970
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
971
|
+
if (!current) return null;
|
|
873
972
|
current.steps.push({
|
|
874
|
-
|
|
973
|
+
id: payload.payload.runId,
|
|
974
|
+
name: payload.payload.workflowId,
|
|
875
975
|
status: "running",
|
|
876
|
-
|
|
976
|
+
iteration: payload.payload.args?.iteration ?? 0,
|
|
977
|
+
input: { prompt: payload.payload.args?.prompt ?? "" },
|
|
877
978
|
output: null,
|
|
979
|
+
task: null,
|
|
878
980
|
suspendPayload: null,
|
|
879
|
-
resumePayload: null
|
|
981
|
+
resumePayload: null,
|
|
982
|
+
[PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
|
|
880
983
|
});
|
|
881
984
|
bufferedNetworks.set(payload.runId, current);
|
|
882
985
|
return {
|
|
@@ -889,14 +992,21 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
889
992
|
};
|
|
890
993
|
}
|
|
891
994
|
case "tool-execution-start": {
|
|
892
|
-
const current = bufferedNetworks.get(payload.runId)
|
|
995
|
+
const current = bufferedNetworks.get(payload.runId);
|
|
996
|
+
if (!current) return null;
|
|
893
997
|
current.steps.push({
|
|
998
|
+
id: payload.payload.args.toolCallId,
|
|
894
999
|
name: payload.payload.args?.toolName,
|
|
895
1000
|
status: "running",
|
|
1001
|
+
iteration: payload.payload.args?.iteration ? Number(payload.payload.args.iteration) : 0,
|
|
1002
|
+
task: {
|
|
1003
|
+
id: payload.payload.args?.toolName
|
|
1004
|
+
},
|
|
896
1005
|
input: payload.payload.args?.args || null,
|
|
897
1006
|
output: null,
|
|
898
1007
|
suspendPayload: null,
|
|
899
|
-
resumePayload: null
|
|
1008
|
+
resumePayload: null,
|
|
1009
|
+
[PRIMITIVE_CACHE_SYMBOL]: /* @__PURE__ */ new Map()
|
|
900
1010
|
});
|
|
901
1011
|
bufferedNetworks.set(payload.runId, current);
|
|
902
1012
|
return {
|
|
@@ -911,14 +1021,13 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
911
1021
|
case "agent-execution-end": {
|
|
912
1022
|
const current = bufferedNetworks.get(payload.runId);
|
|
913
1023
|
if (!current) return null;
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
});
|
|
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;
|
|
922
1031
|
return {
|
|
923
1032
|
type: isNested ? "data-tool-network" : "data-network",
|
|
924
1033
|
id: payload.runId,
|
|
@@ -933,14 +1042,13 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
933
1042
|
case "tool-execution-end": {
|
|
934
1043
|
const current = bufferedNetworks.get(payload.runId);
|
|
935
1044
|
if (!current) return null;
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
});
|
|
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;
|
|
944
1052
|
return {
|
|
945
1053
|
type: isNested ? "data-tool-network" : "data-network",
|
|
946
1054
|
id: payload.runId,
|
|
@@ -954,14 +1062,13 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
954
1062
|
case "workflow-execution-end": {
|
|
955
1063
|
const current = bufferedNetworks.get(payload.runId);
|
|
956
1064
|
if (!current) return null;
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
});
|
|
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;
|
|
965
1072
|
return {
|
|
966
1073
|
type: isNested ? "data-tool-network" : "data-network",
|
|
967
1074
|
id: payload.runId,
|
|
@@ -976,12 +1083,24 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
976
1083
|
case "routing-agent-end": {
|
|
977
1084
|
const current = bufferedNetworks.get(payload.runId);
|
|
978
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;
|
|
979
1099
|
return {
|
|
980
1100
|
type: isNested ? "data-tool-network" : "data-network",
|
|
981
1101
|
id: payload.runId,
|
|
982
1102
|
data: {
|
|
983
1103
|
...current,
|
|
984
|
-
status: "finished",
|
|
985
1104
|
usage: payload.payload?.usage ?? current.usage,
|
|
986
1105
|
output: payload.payload?.result ?? current.output
|
|
987
1106
|
}
|
|
@@ -1015,6 +1134,39 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
1015
1134
|
};
|
|
1016
1135
|
}
|
|
1017
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
|
+
}
|
|
1018
1170
|
if (isDataChunkType(payload)) {
|
|
1019
1171
|
if (!("data" in payload)) {
|
|
1020
1172
|
throw new Error(
|
|
@@ -1022,7 +1174,8 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
1022
1174
|
${JSON.stringify(payload)}`
|
|
1023
1175
|
);
|
|
1024
1176
|
}
|
|
1025
|
-
|
|
1177
|
+
const { type, data } = payload;
|
|
1178
|
+
return { type, data };
|
|
1026
1179
|
}
|
|
1027
1180
|
if (isAgentExecutionDataChunkType(payload)) {
|
|
1028
1181
|
if (!("data" in payload.payload)) {
|
|
@@ -1031,7 +1184,8 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
1031
1184
|
${JSON.stringify(payload)}`
|
|
1032
1185
|
);
|
|
1033
1186
|
}
|
|
1034
|
-
|
|
1187
|
+
const { type, data } = payload.payload;
|
|
1188
|
+
return { type, data };
|
|
1035
1189
|
}
|
|
1036
1190
|
if (isWorkflowExecutionDataChunkType(payload)) {
|
|
1037
1191
|
if (!("data" in payload.payload)) {
|
|
@@ -1040,7 +1194,8 @@ function transformNetwork(payload, bufferedNetworks, isNested) {
|
|
|
1040
1194
|
${JSON.stringify(payload)}`
|
|
1041
1195
|
);
|
|
1042
1196
|
}
|
|
1043
|
-
|
|
1197
|
+
const { type, data } = payload.payload;
|
|
1198
|
+
return { type, data };
|
|
1044
1199
|
}
|
|
1045
1200
|
return null;
|
|
1046
1201
|
}
|
|
@@ -1055,7 +1210,10 @@ function toAISdkV5Stream(stream, options = {
|
|
|
1055
1210
|
}) {
|
|
1056
1211
|
const from = options?.from;
|
|
1057
1212
|
if (from === "workflow") {
|
|
1058
|
-
|
|
1213
|
+
const includeTextStreamParts = options?.includeTextStreamParts ?? true;
|
|
1214
|
+
return stream.pipeThrough(
|
|
1215
|
+
WorkflowStreamToAISDKTransformer({ includeTextStreamParts })
|
|
1216
|
+
);
|
|
1059
1217
|
}
|
|
1060
1218
|
if (from === "network") {
|
|
1061
1219
|
return stream.pipeThrough(AgentNetworkToAISDKTransformer());
|
|
@@ -1067,12 +1225,65 @@ function toAISdkV5Stream(stream, options = {
|
|
|
1067
1225
|
sendStart: options?.sendStart,
|
|
1068
1226
|
sendFinish: options?.sendFinish,
|
|
1069
1227
|
sendReasoning: options?.sendReasoning,
|
|
1070
|
-
sendSources: options?.sendSources
|
|
1228
|
+
sendSources: options?.sendSources,
|
|
1229
|
+
messageMetadata: options?.messageMetadata,
|
|
1230
|
+
onError: options?.onError
|
|
1071
1231
|
})
|
|
1072
1232
|
);
|
|
1073
1233
|
}
|
|
1074
1234
|
|
|
1075
1235
|
// src/chat-route.ts
|
|
1236
|
+
async function handleChatStream({
|
|
1237
|
+
mastra,
|
|
1238
|
+
agentId,
|
|
1239
|
+
params,
|
|
1240
|
+
defaultOptions,
|
|
1241
|
+
sendStart = true,
|
|
1242
|
+
sendFinish = true,
|
|
1243
|
+
sendReasoning = false,
|
|
1244
|
+
sendSources = false
|
|
1245
|
+
}) {
|
|
1246
|
+
const { messages, resumeData, runId, requestContext, ...rest } = params;
|
|
1247
|
+
if (resumeData && !runId) {
|
|
1248
|
+
throw new Error("runId is required when resumeData is provided");
|
|
1249
|
+
}
|
|
1250
|
+
const agentObj = mastra.getAgentById(agentId);
|
|
1251
|
+
if (!agentObj) {
|
|
1252
|
+
throw new Error(`Agent ${agentId} not found`);
|
|
1253
|
+
}
|
|
1254
|
+
if (!Array.isArray(messages)) {
|
|
1255
|
+
throw new Error("Messages must be an array of UIMessage objects");
|
|
1256
|
+
}
|
|
1257
|
+
const mergedOptions = {
|
|
1258
|
+
...defaultOptions,
|
|
1259
|
+
...rest,
|
|
1260
|
+
...runId && { runId },
|
|
1261
|
+
requestContext: requestContext || defaultOptions?.requestContext
|
|
1262
|
+
};
|
|
1263
|
+
const result = resumeData ? await agentObj.resumeStream(resumeData, mergedOptions) : await agentObj.stream(messages, mergedOptions);
|
|
1264
|
+
let lastMessageId;
|
|
1265
|
+
if (messages.length) {
|
|
1266
|
+
const lastMessage = messages[messages.length - 1];
|
|
1267
|
+
if (lastMessage?.role === "assistant") {
|
|
1268
|
+
lastMessageId = lastMessage.id;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
return ai.createUIMessageStream({
|
|
1272
|
+
originalMessages: messages,
|
|
1273
|
+
execute: async ({ writer }) => {
|
|
1274
|
+
for await (const part of toAISdkV5Stream(result, {
|
|
1275
|
+
from: "agent",
|
|
1276
|
+
lastMessageId,
|
|
1277
|
+
sendStart,
|
|
1278
|
+
sendFinish,
|
|
1279
|
+
sendReasoning,
|
|
1280
|
+
sendSources
|
|
1281
|
+
})) {
|
|
1282
|
+
writer.write(part);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1076
1287
|
function chatRoute({
|
|
1077
1288
|
path = "/chat/:agentId",
|
|
1078
1289
|
agent,
|
|
@@ -1109,6 +1320,14 @@ function chatRoute({
|
|
|
1109
1320
|
schema: {
|
|
1110
1321
|
type: "object",
|
|
1111
1322
|
properties: {
|
|
1323
|
+
resumeData: {
|
|
1324
|
+
type: "object",
|
|
1325
|
+
description: "Resume data for the agent"
|
|
1326
|
+
},
|
|
1327
|
+
runId: {
|
|
1328
|
+
type: "string",
|
|
1329
|
+
description: "The run ID required when resuming an agent execution"
|
|
1330
|
+
},
|
|
1112
1331
|
messages: {
|
|
1113
1332
|
type: "array",
|
|
1114
1333
|
description: "Array of messages in the conversation",
|
|
@@ -1179,9 +1398,9 @@ function chatRoute({
|
|
|
1179
1398
|
}
|
|
1180
1399
|
},
|
|
1181
1400
|
handler: async (c) => {
|
|
1182
|
-
const
|
|
1401
|
+
const params = await c.req.json();
|
|
1183
1402
|
const mastra = c.get("mastra");
|
|
1184
|
-
const
|
|
1403
|
+
const contextRequestContext = c.get("requestContext");
|
|
1185
1404
|
let agentToUse = agent;
|
|
1186
1405
|
if (!agent) {
|
|
1187
1406
|
const agentId = c.req.param("agentId");
|
|
@@ -1192,39 +1411,24 @@ function chatRoute({
|
|
|
1192
1411
|
`Fixed agent ID was set together with an agentId path parameter. This can lead to unexpected behavior.`
|
|
1193
1412
|
);
|
|
1194
1413
|
}
|
|
1195
|
-
if (
|
|
1414
|
+
if (contextRequestContext && defaultOptions?.requestContext) {
|
|
1196
1415
|
mastra.getLogger()?.warn(`"requestContext" set in the route options will be overridden by the request's "requestContext".`);
|
|
1197
1416
|
}
|
|
1198
1417
|
if (!agentToUse) {
|
|
1199
1418
|
throw new Error("Agent ID is required");
|
|
1200
1419
|
}
|
|
1201
|
-
const
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
}
|
|
1214
|
-
const uiMessageStream = ai.createUIMessageStream({
|
|
1215
|
-
originalMessages: messages,
|
|
1216
|
-
execute: async ({ writer }) => {
|
|
1217
|
-
for await (const part of toAISdkV5Stream(result, {
|
|
1218
|
-
from: "agent",
|
|
1219
|
-
lastMessageId,
|
|
1220
|
-
sendStart,
|
|
1221
|
-
sendFinish,
|
|
1222
|
-
sendReasoning,
|
|
1223
|
-
sendSources
|
|
1224
|
-
})) {
|
|
1225
|
-
writer.write(part);
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1420
|
+
const uiMessageStream = await handleChatStream({
|
|
1421
|
+
mastra,
|
|
1422
|
+
agentId: agentToUse,
|
|
1423
|
+
params: {
|
|
1424
|
+
...params,
|
|
1425
|
+
requestContext: contextRequestContext || params.requestContext
|
|
1426
|
+
},
|
|
1427
|
+
defaultOptions,
|
|
1428
|
+
sendStart,
|
|
1429
|
+
sendFinish,
|
|
1430
|
+
sendReasoning,
|
|
1431
|
+
sendSources
|
|
1228
1432
|
});
|
|
1229
1433
|
return ai.createUIMessageStreamResponse({
|
|
1230
1434
|
stream: uiMessageStream
|
|
@@ -1232,9 +1436,31 @@ function chatRoute({
|
|
|
1232
1436
|
}
|
|
1233
1437
|
});
|
|
1234
1438
|
}
|
|
1439
|
+
async function handleWorkflowStream({
|
|
1440
|
+
mastra,
|
|
1441
|
+
workflowId,
|
|
1442
|
+
params,
|
|
1443
|
+
includeTextStreamParts = true
|
|
1444
|
+
}) {
|
|
1445
|
+
const { runId, resourceId, inputData, resumeData, requestContext, ...rest } = params;
|
|
1446
|
+
const workflowObj = mastra.getWorkflowById(workflowId);
|
|
1447
|
+
if (!workflowObj) {
|
|
1448
|
+
throw new Error(`Workflow ${workflowId} not found`);
|
|
1449
|
+
}
|
|
1450
|
+
const run = await workflowObj.createRun({ runId, resourceId, ...rest });
|
|
1451
|
+
const stream = resumeData ? run.resumeStream({ resumeData, ...rest, requestContext }) : run.stream({ inputData, ...rest, requestContext });
|
|
1452
|
+
return ai.createUIMessageStream({
|
|
1453
|
+
execute: async ({ writer }) => {
|
|
1454
|
+
for await (const part of toAISdkV5Stream(stream, { from: "workflow", includeTextStreamParts })) {
|
|
1455
|
+
writer.write(part);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1235
1460
|
function workflowRoute({
|
|
1236
1461
|
path = "/api/workflows/:workflowId/stream",
|
|
1237
|
-
workflow
|
|
1462
|
+
workflow,
|
|
1463
|
+
includeTextStreamParts = true
|
|
1238
1464
|
}) {
|
|
1239
1465
|
if (!workflow && !path.includes("/:workflowId")) {
|
|
1240
1466
|
throw new Error("Path must include :workflowId to route to the correct workflow or pass the workflow explicitly");
|
|
@@ -1285,8 +1511,9 @@ function workflowRoute({
|
|
|
1285
1511
|
}
|
|
1286
1512
|
},
|
|
1287
1513
|
handler: async (c) => {
|
|
1288
|
-
const
|
|
1514
|
+
const params = await c.req.json();
|
|
1289
1515
|
const mastra = c.get("mastra");
|
|
1516
|
+
const contextRequestContext = c.get("requestContext");
|
|
1290
1517
|
let workflowToUse = workflow;
|
|
1291
1518
|
if (!workflow) {
|
|
1292
1519
|
const workflowId = c.req.param("workflowId");
|
|
@@ -1300,23 +1527,47 @@ function workflowRoute({
|
|
|
1300
1527
|
if (!workflowToUse) {
|
|
1301
1528
|
throw new Error("Workflow ID is required");
|
|
1302
1529
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1530
|
+
if (contextRequestContext && params.requestContext) {
|
|
1531
|
+
mastra.getLogger()?.warn(
|
|
1532
|
+
`"requestContext" from the request body will be ignored because "requestContext" is already set in the route options.`
|
|
1533
|
+
);
|
|
1306
1534
|
}
|
|
1307
|
-
const
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1535
|
+
const uiMessageStream = await handleWorkflowStream({
|
|
1536
|
+
mastra,
|
|
1537
|
+
workflowId: workflowToUse,
|
|
1538
|
+
params: {
|
|
1539
|
+
...params,
|
|
1540
|
+
requestContext: contextRequestContext || params.requestContext
|
|
1541
|
+
},
|
|
1542
|
+
includeTextStreamParts
|
|
1315
1543
|
});
|
|
1316
1544
|
return ai.createUIMessageStreamResponse({ stream: uiMessageStream });
|
|
1317
1545
|
}
|
|
1318
1546
|
});
|
|
1319
1547
|
}
|
|
1548
|
+
async function handleNetworkStream({
|
|
1549
|
+
mastra,
|
|
1550
|
+
agentId,
|
|
1551
|
+
params,
|
|
1552
|
+
defaultOptions
|
|
1553
|
+
}) {
|
|
1554
|
+
const { messages, ...rest } = params;
|
|
1555
|
+
const agentObj = mastra.getAgentById(agentId);
|
|
1556
|
+
if (!agentObj) {
|
|
1557
|
+
throw new Error(`Agent ${agentId} not found`);
|
|
1558
|
+
}
|
|
1559
|
+
const result = await agentObj.network(messages, {
|
|
1560
|
+
...defaultOptions,
|
|
1561
|
+
...rest
|
|
1562
|
+
});
|
|
1563
|
+
return ai.createUIMessageStream({
|
|
1564
|
+
execute: async ({ writer }) => {
|
|
1565
|
+
for await (const part of toAISdkV5Stream(result, { from: "network" })) {
|
|
1566
|
+
writer.write(part);
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1320
1571
|
function networkRoute({
|
|
1321
1572
|
path = "/network/:agentId",
|
|
1322
1573
|
agent,
|
|
@@ -1377,7 +1628,7 @@ function networkRoute({
|
|
|
1377
1628
|
}
|
|
1378
1629
|
},
|
|
1379
1630
|
handler: async (c) => {
|
|
1380
|
-
const
|
|
1631
|
+
const params = await c.req.json();
|
|
1381
1632
|
const mastra = c.get("mastra");
|
|
1382
1633
|
let agentToUse = agent;
|
|
1383
1634
|
if (!agent) {
|
|
@@ -1392,20 +1643,11 @@ function networkRoute({
|
|
|
1392
1643
|
if (!agentToUse) {
|
|
1393
1644
|
throw new Error("Agent ID is required");
|
|
1394
1645
|
}
|
|
1395
|
-
const
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
...defaultOptions,
|
|
1401
|
-
...rest
|
|
1402
|
-
});
|
|
1403
|
-
const uiMessageStream = ai.createUIMessageStream({
|
|
1404
|
-
execute: async ({ writer }) => {
|
|
1405
|
-
for await (const part of toAISdkV5Stream(result, { from: "network" })) {
|
|
1406
|
-
writer.write(part);
|
|
1407
|
-
}
|
|
1408
|
-
}
|
|
1646
|
+
const uiMessageStream = await handleNetworkStream({
|
|
1647
|
+
mastra,
|
|
1648
|
+
agentId: agentToUse,
|
|
1649
|
+
params,
|
|
1650
|
+
defaultOptions
|
|
1409
1651
|
});
|
|
1410
1652
|
return ai.createUIMessageStreamResponse({ stream: uiMessageStream });
|
|
1411
1653
|
}
|
|
@@ -1420,6 +1662,9 @@ function toAISdkFormat() {
|
|
|
1420
1662
|
}
|
|
1421
1663
|
|
|
1422
1664
|
exports.chatRoute = chatRoute;
|
|
1665
|
+
exports.handleChatStream = handleChatStream;
|
|
1666
|
+
exports.handleNetworkStream = handleNetworkStream;
|
|
1667
|
+
exports.handleWorkflowStream = handleWorkflowStream;
|
|
1423
1668
|
exports.networkRoute = networkRoute;
|
|
1424
1669
|
exports.toAISdkFormat = toAISdkFormat;
|
|
1425
1670
|
exports.toAISdkStream = toAISdkV5Stream;
|