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