@mastra/react 0.0.20 → 0.0.21-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/index.cjs +74 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +74 -22
- package/dist/index.js.map +1 -1
- package/dist/src/agent/hooks.d.ts +2 -1
- package/dist/src/lib/ai-sdk/types.d.ts +10 -0
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { createContext, useContext, useRef, useState, Fragment, useLayoutEffect, useEffect } from 'react';
|
|
3
3
|
import { MastraClient } from '@mastra/client-js';
|
|
4
|
+
import { v4 } from '@lukeed/uuid';
|
|
4
5
|
import { ChevronDownIcon, CheckIcon, CopyIcon } from 'lucide-react';
|
|
5
6
|
import { twMerge } from 'tailwind-merge';
|
|
6
7
|
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
|
|
@@ -255,17 +256,19 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
255
256
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
256
257
|
const parts = [...lastMessage.parts];
|
|
257
258
|
const toolPartIndex = parts.findIndex(
|
|
258
|
-
(part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
259
|
+
(part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
259
260
|
);
|
|
260
261
|
if (toolPartIndex !== -1) {
|
|
261
262
|
const toolPart = parts[toolPartIndex];
|
|
262
|
-
if (toolPart.type === "dynamic-tool") {
|
|
263
|
+
if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
|
|
264
|
+
const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
|
|
265
|
+
const toolCallId = toolPart.toolCallId;
|
|
263
266
|
if (chunk.type === "tool-result" && chunk.payload.isError || chunk.type === "tool-error") {
|
|
264
267
|
const error = chunk.type === "tool-error" ? chunk.payload.error : chunk.payload.result;
|
|
265
268
|
parts[toolPartIndex] = {
|
|
266
269
|
type: "dynamic-tool",
|
|
267
|
-
toolName
|
|
268
|
-
toolCallId
|
|
270
|
+
toolName,
|
|
271
|
+
toolCallId,
|
|
269
272
|
state: "output-error",
|
|
270
273
|
input: toolPart.input,
|
|
271
274
|
errorText: String(error),
|
|
@@ -284,8 +287,8 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
284
287
|
}
|
|
285
288
|
parts[toolPartIndex] = {
|
|
286
289
|
type: "dynamic-tool",
|
|
287
|
-
toolName
|
|
288
|
-
toolCallId
|
|
290
|
+
toolName,
|
|
291
|
+
toolCallId,
|
|
289
292
|
state: "output-available",
|
|
290
293
|
input: toolPart.input,
|
|
291
294
|
output,
|
|
@@ -307,11 +310,14 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
307
310
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
308
311
|
const parts = [...lastMessage.parts];
|
|
309
312
|
const toolPartIndex = parts.findIndex(
|
|
310
|
-
(part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
313
|
+
(part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
311
314
|
);
|
|
312
315
|
if (toolPartIndex !== -1) {
|
|
313
316
|
const toolPart = parts[toolPartIndex];
|
|
314
|
-
if (toolPart.type === "dynamic-tool") {
|
|
317
|
+
if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
|
|
318
|
+
const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : typeof toolPart.type === "string" && toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
|
|
319
|
+
const toolCallId = toolPart.toolCallId;
|
|
320
|
+
const input = toolPart.input;
|
|
315
321
|
if (chunk.payload.output?.type?.startsWith("workflow-")) {
|
|
316
322
|
const existingWorkflowState = toolPart.output || {};
|
|
317
323
|
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
|
|
@@ -319,7 +325,11 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
319
325
|
chunk.payload.output
|
|
320
326
|
);
|
|
321
327
|
parts[toolPartIndex] = {
|
|
322
|
-
|
|
328
|
+
type: "dynamic-tool",
|
|
329
|
+
toolName,
|
|
330
|
+
toolCallId,
|
|
331
|
+
state: "input-streaming",
|
|
332
|
+
input,
|
|
323
333
|
output: updatedWorkflowState
|
|
324
334
|
};
|
|
325
335
|
} else if (chunk.payload.output?.from === "AGENT" || chunk.payload.output?.from === "USER" && chunk.payload.output?.payload?.output?.type?.startsWith("workflow-")) {
|
|
@@ -328,7 +338,11 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
328
338
|
const currentOutput = toolPart.output || [];
|
|
329
339
|
const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
|
|
330
340
|
parts[toolPartIndex] = {
|
|
331
|
-
|
|
341
|
+
type: "dynamic-tool",
|
|
342
|
+
toolName,
|
|
343
|
+
toolCallId,
|
|
344
|
+
state: "input-streaming",
|
|
345
|
+
input,
|
|
332
346
|
output: [...existingOutput, chunk.payload.output]
|
|
333
347
|
};
|
|
334
348
|
}
|
|
@@ -642,6 +656,20 @@ const toAssistantUIMessage = (message) => {
|
|
|
642
656
|
}
|
|
643
657
|
return baseToolCall;
|
|
644
658
|
}
|
|
659
|
+
const requireApprovalMetadata = extendedMessage.metadata?.requireApprovalMetadata;
|
|
660
|
+
const partToolCallId = "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : void 0;
|
|
661
|
+
const suspensionData = partToolCallId ? requireApprovalMetadata?.[partToolCallId] : void 0;
|
|
662
|
+
if (suspensionData) {
|
|
663
|
+
const toolName = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.startsWith("tool-") ? part.type.substring(5) : "";
|
|
664
|
+
return {
|
|
665
|
+
type: "tool-call",
|
|
666
|
+
toolCallId: partToolCallId,
|
|
667
|
+
toolName,
|
|
668
|
+
argsText: "input" in part ? JSON.stringify(part.input) : "{}",
|
|
669
|
+
args: "input" in part ? part.input : {},
|
|
670
|
+
metadata: extendedMessage.metadata
|
|
671
|
+
};
|
|
672
|
+
}
|
|
645
673
|
return {
|
|
646
674
|
type: "text",
|
|
647
675
|
text: "",
|
|
@@ -726,7 +754,6 @@ const resolveInitialMessages = (messages) => {
|
|
|
726
754
|
childMessages,
|
|
727
755
|
result: finalResult?.text || ""
|
|
728
756
|
};
|
|
729
|
-
console.log("json", json);
|
|
730
757
|
const nextMessage = {
|
|
731
758
|
role: "assistant",
|
|
732
759
|
parts: [
|
|
@@ -754,6 +781,18 @@ const resolveInitialMessages = (messages) => {
|
|
|
754
781
|
return message;
|
|
755
782
|
}
|
|
756
783
|
}
|
|
784
|
+
const extendedMessage = message;
|
|
785
|
+
const pendingToolApprovals = extendedMessage.metadata?.pendingToolApprovals;
|
|
786
|
+
if (pendingToolApprovals && typeof pendingToolApprovals === "object") {
|
|
787
|
+
return {
|
|
788
|
+
...message,
|
|
789
|
+
metadata: {
|
|
790
|
+
...message.metadata,
|
|
791
|
+
mode: "stream",
|
|
792
|
+
requireApprovalMetadata: pendingToolApprovals
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
}
|
|
757
796
|
return message;
|
|
758
797
|
});
|
|
759
798
|
};
|
|
@@ -1157,12 +1196,24 @@ class AISdkNetworkTransformer {
|
|
|
1157
1196
|
};
|
|
1158
1197
|
}
|
|
1159
1198
|
|
|
1160
|
-
const useChat = ({ agentId, initializeMessages }) => {
|
|
1161
|
-
const
|
|
1199
|
+
const useChat = ({ agentId, resourceId, initializeMessages }) => {
|
|
1200
|
+
const extractRunIdFromMessages = (messages2) => {
|
|
1201
|
+
for (const message of messages2) {
|
|
1202
|
+
const pendingToolApprovals = message.metadata?.pendingToolApprovals;
|
|
1203
|
+
if (pendingToolApprovals && typeof pendingToolApprovals === "object") {
|
|
1204
|
+
const suspensionData = Object.values(pendingToolApprovals)[0];
|
|
1205
|
+
if (suspensionData?.runId) {
|
|
1206
|
+
return suspensionData.runId;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
return void 0;
|
|
1211
|
+
};
|
|
1212
|
+
const initialMessages = initializeMessages?.() || [];
|
|
1213
|
+
const initialRunId = extractRunIdFromMessages(initialMessages);
|
|
1214
|
+
const _currentRunId = useRef(initialRunId);
|
|
1162
1215
|
const _onChunk = useRef(void 0);
|
|
1163
|
-
const [messages, setMessages] = useState(
|
|
1164
|
-
() => resolveInitialMessages(initializeMessages?.() || [])
|
|
1165
|
-
);
|
|
1216
|
+
const [messages, setMessages] = useState(() => resolveInitialMessages(initialMessages));
|
|
1166
1217
|
const [toolCallApprovals, setToolCallApprovals] = useState({});
|
|
1167
1218
|
const baseClient = useMastraClient();
|
|
1168
1219
|
const [isRunning, setIsRunning] = useState(false);
|
|
@@ -1194,7 +1245,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1194
1245
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1195
1246
|
const response = await agent.generate({
|
|
1196
1247
|
messages: coreUserMessages,
|
|
1197
|
-
runId:
|
|
1248
|
+
runId: v4(),
|
|
1198
1249
|
maxSteps,
|
|
1199
1250
|
modelSettings: {
|
|
1200
1251
|
frequencyPenalty,
|
|
@@ -1207,7 +1258,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1207
1258
|
},
|
|
1208
1259
|
instructions,
|
|
1209
1260
|
runtimeContext,
|
|
1210
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1261
|
+
...threadId ? { threadId, resourceId: resourceId || agentId } : {},
|
|
1211
1262
|
providerOptions
|
|
1212
1263
|
});
|
|
1213
1264
|
setIsRunning(false);
|
|
@@ -1242,7 +1293,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1242
1293
|
abortSignal: signal
|
|
1243
1294
|
});
|
|
1244
1295
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1245
|
-
const runId =
|
|
1296
|
+
const runId = v4();
|
|
1246
1297
|
const response = await agent.stream({
|
|
1247
1298
|
messages: coreUserMessages,
|
|
1248
1299
|
runId,
|
|
@@ -1258,7 +1309,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1258
1309
|
},
|
|
1259
1310
|
instructions,
|
|
1260
1311
|
runtimeContext,
|
|
1261
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1312
|
+
...threadId ? { threadId, resourceId: resourceId || agentId } : {},
|
|
1262
1313
|
providerOptions,
|
|
1263
1314
|
requireToolApproval
|
|
1264
1315
|
});
|
|
@@ -1287,6 +1338,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1287
1338
|
abortSignal: signal
|
|
1288
1339
|
});
|
|
1289
1340
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1341
|
+
const runId = v4();
|
|
1290
1342
|
const response = await agent.network({
|
|
1291
1343
|
messages: coreUserMessages,
|
|
1292
1344
|
maxSteps,
|
|
@@ -1299,9 +1351,9 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1299
1351
|
topK,
|
|
1300
1352
|
topP
|
|
1301
1353
|
},
|
|
1302
|
-
runId
|
|
1354
|
+
runId,
|
|
1303
1355
|
runtimeContext,
|
|
1304
|
-
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
1356
|
+
...threadId ? { thread: threadId, resourceId: resourceId || agentId } : {}
|
|
1305
1357
|
});
|
|
1306
1358
|
const transformer = new AISdkNetworkTransformer();
|
|
1307
1359
|
await response.processDataStream({
|