@mastra/react 1.6.0-alpha.9 → 1.6.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 +170 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +170 -107
- package/dist/index.js.map +1 -1
- package/dist/lib/mastra-db/accumulator.d.ts.map +1 -1
- package/dist/workflows/hooks.d.ts.map +1 -1
- package/dist/workflows/types.d.ts +4 -0
- package/dist/workflows/types.d.ts.map +1 -1
- package/dist/workflows/use-stream-workflow.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -140,6 +140,37 @@ function toolErrorText(error) {
|
|
|
140
140
|
}
|
|
141
141
|
return String(error);
|
|
142
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Agent-as-tool boundaries wrap progressive chunks in nested `tool-output`
|
|
145
|
+
* envelopes. Peel only agent boundaries; workflow/tool envelopes remain the
|
|
146
|
+
* leaf so existing child-message accumulation can process them normally.
|
|
147
|
+
*/
|
|
148
|
+
const normalizeNestedAgentOutput = (output) => {
|
|
149
|
+
const boundaries = [];
|
|
150
|
+
const seen = /* @__PURE__ */ new Set();
|
|
151
|
+
let current = output;
|
|
152
|
+
while (current !== null && typeof current === "object") {
|
|
153
|
+
if (seen.has(current)) return void 0;
|
|
154
|
+
seen.add(current);
|
|
155
|
+
const chunk = current;
|
|
156
|
+
if (chunk.type !== "tool-output") return {
|
|
157
|
+
leaf: current,
|
|
158
|
+
boundaries
|
|
159
|
+
};
|
|
160
|
+
const toolCallId = chunk.payload?.toolCallId;
|
|
161
|
+
const toolName = chunk.payload?.toolName;
|
|
162
|
+
if (typeof toolName !== "string" || !toolName.startsWith("agent-")) return {
|
|
163
|
+
leaf: current,
|
|
164
|
+
boundaries
|
|
165
|
+
};
|
|
166
|
+
if (typeof toolCallId !== "string" || !("output" in (chunk.payload ?? {}))) return void 0;
|
|
167
|
+
boundaries.push({
|
|
168
|
+
toolCallId,
|
|
169
|
+
toolName
|
|
170
|
+
});
|
|
171
|
+
current = chunk.payload?.output;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
143
174
|
const cloneMetadata = (metadata) => metadata ? { ...metadata } : {};
|
|
144
175
|
const withParts = (message, parts) => ({
|
|
145
176
|
...message,
|
|
@@ -837,7 +868,7 @@ const accumulateChunk = ({ chunk, conversation, metadata }) => {
|
|
|
837
868
|
toolName,
|
|
838
869
|
args,
|
|
839
870
|
errorText,
|
|
840
|
-
...
|
|
871
|
+
...chunk.from === "AGENT" ? { result: toolPart.toolInvocation.result } : {}
|
|
841
872
|
}
|
|
842
873
|
};
|
|
843
874
|
} else {
|
|
@@ -859,7 +890,7 @@ const accumulateChunk = ({ chunk, conversation, metadata }) => {
|
|
|
859
890
|
};
|
|
860
891
|
else output = payloadResult;
|
|
861
892
|
} else if (isAgent) {
|
|
862
|
-
const existingOutput = toolPart.toolInvocation.state === "result" ? toolPart.toolInvocation.result : void 0;
|
|
893
|
+
const existingOutput = toolPart.toolInvocation.state === "partial-call" || toolPart.toolInvocation.state === "result" ? toolPart.toolInvocation.result : void 0;
|
|
863
894
|
const existingChild = existingOutput?.childMessages;
|
|
864
895
|
output = existingOutput ? {
|
|
865
896
|
...payloadResult,
|
|
@@ -936,8 +967,13 @@ const accumulateChunk = ({ chunk, conversation, metadata }) => {
|
|
|
936
967
|
result: updated
|
|
937
968
|
}
|
|
938
969
|
};
|
|
939
|
-
} else if (
|
|
940
|
-
|
|
970
|
+
} else if (toolName.startsWith("agent-") || payloadOutput?.from === "AGENT") {
|
|
971
|
+
const normalized = normalizeNestedAgentOutput(payloadOutput);
|
|
972
|
+
if (!normalized) return result;
|
|
973
|
+
const { leaf, boundaries } = normalized;
|
|
974
|
+
if (leaf.from === "AGENT" || leaf.type === "tool-output" && leaf.payload?.output?.type?.startsWith("workflow-")) return accumulateAgentChunk(leaf, result, metadata, toolCallId, toolName, boundaries);
|
|
975
|
+
return result;
|
|
976
|
+
} else {
|
|
941
977
|
const currentResult = toolPart.toolInvocation.result;
|
|
942
978
|
const existing = Array.isArray(currentResult) ? currentResult : [];
|
|
943
979
|
parts[toolPartIndex] = {
|
|
@@ -1165,112 +1201,130 @@ const accumulateChunk = ({ chunk, conversation, metadata }) => {
|
|
|
1165
1201
|
* that isn't enumerated above.
|
|
1166
1202
|
*/
|
|
1167
1203
|
const assertExhaustive = (_chunk, fallback) => fallback;
|
|
1168
|
-
const
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1204
|
+
const findAgentChildToolIndex = (childMessages, toolCallId, toolName) => {
|
|
1205
|
+
for (let index = childMessages.length - 1; index >= 0; index--) {
|
|
1206
|
+
const message = childMessages[index];
|
|
1207
|
+
if (message?.type !== "tool") continue;
|
|
1208
|
+
if (toolCallId ? message.toolCallId === toolCallId : toolName && message.toolName === toolName) return index;
|
|
1209
|
+
}
|
|
1210
|
+
return -1;
|
|
1211
|
+
};
|
|
1212
|
+
const accumulateAgentChildMessages = (chunk, childMessages) => {
|
|
1173
1213
|
if (chunk.type === "text-delta") {
|
|
1174
|
-
const
|
|
1175
|
-
const toolPartIndex = findToolPartIndex();
|
|
1176
|
-
if (toolPartIndex === -1) return conversation;
|
|
1177
|
-
const toolPart = parts[toolPartIndex];
|
|
1178
|
-
const existingResult = toolPart.toolInvocation.result || {};
|
|
1179
|
-
const childMessages = existingResult.childMessages || [];
|
|
1214
|
+
const text = chunk.payload.text;
|
|
1180
1215
|
const lastChildMessage = childMessages[childMessages.length - 1];
|
|
1181
1216
|
const textMessage = {
|
|
1182
1217
|
type: "text",
|
|
1183
|
-
content: (lastChildMessage?.content
|
|
1218
|
+
content: (lastChildMessage?.type === "text" ? lastChildMessage.content : "") + text
|
|
1184
1219
|
};
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1220
|
+
return lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
|
|
1221
|
+
}
|
|
1222
|
+
if (chunk.type === "tool-call") {
|
|
1223
|
+
const existingIndex = findAgentChildToolIndex(childMessages, chunk.payload.toolCallId);
|
|
1224
|
+
const toolMessage = {
|
|
1225
|
+
...existingIndex === -1 ? {} : childMessages[existingIndex],
|
|
1226
|
+
type: "tool",
|
|
1227
|
+
toolCallId: chunk.payload.toolCallId,
|
|
1228
|
+
toolName: chunk.payload.toolName,
|
|
1229
|
+
args: chunk.payload.args
|
|
1195
1230
|
};
|
|
1196
|
-
|
|
1197
|
-
const
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
const
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
}]
|
|
1215
|
-
}
|
|
1231
|
+
if (existingIndex === -1) return [...childMessages, toolMessage];
|
|
1232
|
+
const nextMessages = [...childMessages];
|
|
1233
|
+
nextMessages[existingIndex] = toolMessage;
|
|
1234
|
+
return nextMessages;
|
|
1235
|
+
}
|
|
1236
|
+
if (chunk.type === "tool-output" && chunk.payload.output?.type?.startsWith("workflow-")) {
|
|
1237
|
+
const toolIndex = findAgentChildToolIndex(childMessages, chunk.payload.toolCallId, chunk.payload.toolName);
|
|
1238
|
+
if (toolIndex === -1) return childMessages;
|
|
1239
|
+
const currentMessage = childMessages[toolIndex];
|
|
1240
|
+
if (currentMessage?.type !== "tool") return childMessages;
|
|
1241
|
+
const existingWorkflowState = currentMessage.toolOutput && typeof currentMessage.toolOutput === "object" ? currentMessage.toolOutput : {};
|
|
1242
|
+
const updated = mapWorkflowStreamChunkToWatchResult(existingWorkflowState, chunk.payload.output);
|
|
1243
|
+
const nextMessages = [...childMessages];
|
|
1244
|
+
nextMessages[toolIndex] = {
|
|
1245
|
+
...currentMessage,
|
|
1246
|
+
toolOutput: {
|
|
1247
|
+
...updated,
|
|
1248
|
+
runId: chunk.payload.output.runId
|
|
1216
1249
|
}
|
|
1217
1250
|
};
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
...toolPart.toolInvocation,
|
|
1234
|
-
result: {
|
|
1235
|
-
...existingResult,
|
|
1236
|
-
childMessages: [...childMessages.slice(0, -1), {
|
|
1237
|
-
...currentMessage,
|
|
1238
|
-
toolOutput: {
|
|
1239
|
-
...updated,
|
|
1240
|
-
runId: agentChunk.output.runId
|
|
1241
|
-
}
|
|
1242
|
-
}]
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
} else if (chunk.type === "tool-result") {
|
|
1248
|
-
const agentChunk = chunk.payload;
|
|
1249
|
-
const toolPartIndex = findToolPartIndex();
|
|
1250
|
-
if (toolPartIndex === -1) return conversation;
|
|
1251
|
-
const toolPart = parts[toolPartIndex];
|
|
1252
|
-
const existingResult = toolPart.toolInvocation.result || {};
|
|
1253
|
-
const childMessages = existingResult.childMessages || [];
|
|
1254
|
-
const lastIndex = childMessages.length - 1;
|
|
1255
|
-
const isWorkflow = agentChunk?.toolName?.startsWith("workflow-");
|
|
1256
|
-
if (lastIndex >= 0 && childMessages[lastIndex]?.type === "tool") parts[toolPartIndex] = {
|
|
1257
|
-
...toolPart,
|
|
1258
|
-
toolInvocation: {
|
|
1259
|
-
...toolPart.toolInvocation,
|
|
1260
|
-
result: {
|
|
1261
|
-
...existingResult,
|
|
1262
|
-
childMessages: [...childMessages.slice(0, -1), {
|
|
1263
|
-
...childMessages[lastIndex],
|
|
1264
|
-
toolOutput: isWorkflow ? {
|
|
1265
|
-
...agentChunk.result?.result,
|
|
1266
|
-
runId: agentChunk.result?.runId
|
|
1267
|
-
} : agentChunk.result
|
|
1268
|
-
}]
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1251
|
+
return nextMessages;
|
|
1252
|
+
}
|
|
1253
|
+
if (chunk.type === "tool-result") {
|
|
1254
|
+
const toolIndex = findAgentChildToolIndex(childMessages, chunk.payload.toolCallId, chunk.payload.toolName);
|
|
1255
|
+
if (toolIndex === -1) return childMessages;
|
|
1256
|
+
const currentMessage = childMessages[toolIndex];
|
|
1257
|
+
if (currentMessage?.type !== "tool") return childMessages;
|
|
1258
|
+
const result = chunk.payload.result;
|
|
1259
|
+
const nextMessages = [...childMessages];
|
|
1260
|
+
nextMessages[toolIndex] = {
|
|
1261
|
+
...currentMessage,
|
|
1262
|
+
toolOutput: chunk.payload.toolName?.startsWith("workflow-") ? {
|
|
1263
|
+
...result?.result ?? {},
|
|
1264
|
+
runId: result?.runId
|
|
1265
|
+
} : chunk.payload.result
|
|
1271
1266
|
};
|
|
1267
|
+
return nextMessages;
|
|
1272
1268
|
}
|
|
1273
|
-
return
|
|
1269
|
+
return childMessages;
|
|
1270
|
+
};
|
|
1271
|
+
const routeAgentChunk = (chunk, childMessages, boundaries) => {
|
|
1272
|
+
const [boundary, ...remaining] = boundaries;
|
|
1273
|
+
if (!boundary) return accumulateAgentChildMessages(chunk, childMessages);
|
|
1274
|
+
let toolIndex = findAgentChildToolIndex(childMessages, boundary.toolCallId, boundary.toolName);
|
|
1275
|
+
let nextMessages = childMessages;
|
|
1276
|
+
if (toolIndex === -1) {
|
|
1277
|
+
toolIndex = childMessages.length;
|
|
1278
|
+
nextMessages = [...childMessages, {
|
|
1279
|
+
type: "tool",
|
|
1280
|
+
toolCallId: boundary.toolCallId,
|
|
1281
|
+
toolName: boundary.toolName,
|
|
1282
|
+
args: {}
|
|
1283
|
+
}];
|
|
1284
|
+
}
|
|
1285
|
+
const currentMessage = nextMessages[toolIndex];
|
|
1286
|
+
if (currentMessage?.type !== "tool" || !currentMessage.toolName.startsWith("agent-")) return childMessages;
|
|
1287
|
+
const currentOutput = currentMessage.toolOutput !== null && typeof currentMessage.toolOutput === "object" ? currentMessage.toolOutput : {};
|
|
1288
|
+
const nestedMessages = Array.isArray(currentOutput.childMessages) ? currentOutput.childMessages : [];
|
|
1289
|
+
const updatedNestedMessages = routeAgentChunk(chunk, nestedMessages, remaining);
|
|
1290
|
+
if (updatedNestedMessages === nestedMessages) return childMessages;
|
|
1291
|
+
const updatedMessages = [...nextMessages];
|
|
1292
|
+
updatedMessages[toolIndex] = {
|
|
1293
|
+
...currentMessage,
|
|
1294
|
+
toolOutput: {
|
|
1295
|
+
...currentOutput,
|
|
1296
|
+
childMessages: updatedNestedMessages
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1299
|
+
return updatedMessages;
|
|
1300
|
+
};
|
|
1301
|
+
const accumulateAgentChunk = (chunk, conversation, _metadata, parentToolCallId, parentToolName, boundaries = []) => {
|
|
1302
|
+
if (!parentToolCallId) return conversation;
|
|
1303
|
+
const location = locateToolPart(conversation, parentToolCallId, false);
|
|
1304
|
+
if (!location) return conversation;
|
|
1305
|
+
const targetMessage = conversation[location.messageIndex];
|
|
1306
|
+
if (!targetMessage || targetMessage.role !== "assistant") return conversation;
|
|
1307
|
+
const parts = [...targetMessage.content.parts];
|
|
1308
|
+
const toolPart = parts[location.toolPartIndex];
|
|
1309
|
+
if (!toolPart || !isToolPart(toolPart)) return conversation;
|
|
1310
|
+
if (parentToolName && toolPart.toolInvocation.toolName !== parentToolName) return conversation;
|
|
1311
|
+
const invocationResult = "result" in toolPart.toolInvocation && toolPart.toolInvocation.result !== null ? toolPart.toolInvocation.result : void 0;
|
|
1312
|
+
const existingResult = invocationResult && typeof invocationResult === "object" ? invocationResult : {};
|
|
1313
|
+
const childMessages = Array.isArray(existingResult.childMessages) ? existingResult.childMessages : [];
|
|
1314
|
+
const updatedChildMessages = routeAgentChunk(chunk, childMessages, boundaries);
|
|
1315
|
+
if (updatedChildMessages === childMessages) return conversation;
|
|
1316
|
+
parts[location.toolPartIndex] = {
|
|
1317
|
+
...toolPart,
|
|
1318
|
+
toolInvocation: {
|
|
1319
|
+
...toolPart.toolInvocation,
|
|
1320
|
+
state: "partial-call",
|
|
1321
|
+
result: {
|
|
1322
|
+
...existingResult,
|
|
1323
|
+
childMessages: updatedChildMessages
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
};
|
|
1327
|
+
return replaceAt(conversation, location.messageIndex, withParts(targetMessage, parts));
|
|
1274
1328
|
};
|
|
1275
1329
|
const networkMode = (metadata) => ({
|
|
1276
1330
|
...metadata,
|
|
@@ -2886,14 +2940,17 @@ function useStreamWorkflow({ debugMode, tracingOptions, onError }) {
|
|
|
2886
2940
|
}
|
|
2887
2941
|
}
|
|
2888
2942
|
}
|
|
2889
|
-
const streamWorkflow = useMutation(({ workflowId, runId, inputData, initialState, requestContext, perStep }) => {
|
|
2943
|
+
const streamWorkflow = useMutation(({ workflowId, runId, inputData, initialState, requestContext, perStep, resourceId }) => {
|
|
2890
2944
|
setStreamResult({
|
|
2891
2945
|
status: "pending",
|
|
2892
2946
|
input: inputData,
|
|
2893
2947
|
steps: {}
|
|
2894
2948
|
});
|
|
2895
2949
|
return consumeStream(async (signal) => {
|
|
2896
|
-
const run = await client.getWorkflow(workflowId).createRun({
|
|
2950
|
+
const run = await client.getWorkflow(workflowId).createRun({
|
|
2951
|
+
runId,
|
|
2952
|
+
resourceId
|
|
2953
|
+
});
|
|
2897
2954
|
if (signal.aborted) return;
|
|
2898
2955
|
return run.stream({
|
|
2899
2956
|
inputData,
|
|
@@ -2901,7 +2958,8 @@ function useStreamWorkflow({ debugMode, tracingOptions, onError }) {
|
|
|
2901
2958
|
requestContext,
|
|
2902
2959
|
closeOnSuspend: true,
|
|
2903
2960
|
tracingOptions,
|
|
2904
|
-
perStep: perStep ?? debugMode
|
|
2961
|
+
perStep: perStep ?? debugMode,
|
|
2962
|
+
resourceId
|
|
2905
2963
|
});
|
|
2906
2964
|
}, "Error streaming workflow");
|
|
2907
2965
|
});
|
|
@@ -2972,9 +3030,12 @@ function useStreamWorkflow({ debugMode, tracingOptions, onError }) {
|
|
|
2972
3030
|
*/
|
|
2973
3031
|
function useCreateWorkflowRun() {
|
|
2974
3032
|
const client = useMastraClient();
|
|
2975
|
-
return useMutation(async ({ workflowId, prevRunId }) => {
|
|
3033
|
+
return useMutation(async ({ workflowId, prevRunId, resourceId }) => {
|
|
2976
3034
|
try {
|
|
2977
|
-
const { runId: newRunId } = await client.getWorkflow(workflowId).createRun({
|
|
3035
|
+
const { runId: newRunId } = await client.getWorkflow(workflowId).createRun({
|
|
3036
|
+
runId: prevRunId,
|
|
3037
|
+
resourceId
|
|
3038
|
+
});
|
|
2978
3039
|
return { runId: newRunId };
|
|
2979
3040
|
} catch (error) {
|
|
2980
3041
|
console.error("Error creating workflow run:", error);
|
|
@@ -3156,7 +3217,8 @@ const useBrowserSpeechRecognition = ({ language = "en-US" }) => {
|
|
|
3156
3217
|
setState((prev) => ({
|
|
3157
3218
|
...prev,
|
|
3158
3219
|
isListening: true,
|
|
3159
|
-
error: null
|
|
3220
|
+
error: null,
|
|
3221
|
+
transcript: ""
|
|
3160
3222
|
}));
|
|
3161
3223
|
};
|
|
3162
3224
|
recognition.onresult = (event) => {
|
|
@@ -3165,9 +3227,10 @@ const useBrowserSpeechRecognition = ({ language = "en-US" }) => {
|
|
|
3165
3227
|
const transcript = event.results[i][0].transcript;
|
|
3166
3228
|
if (event.results[i].isFinal) finalTranscript += transcript + " ";
|
|
3167
3229
|
}
|
|
3230
|
+
if (!finalTranscript) return;
|
|
3168
3231
|
setState((prev) => ({
|
|
3169
3232
|
...prev,
|
|
3170
|
-
transcript: finalTranscript
|
|
3233
|
+
transcript: prev.transcript + finalTranscript
|
|
3171
3234
|
}));
|
|
3172
3235
|
};
|
|
3173
3236
|
recognition.onerror = (event) => {
|