@mastra/react 0.1.0-beta.3 → 0.1.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 +39 -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 +7 -6
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
|
}
|
|
@@ -651,6 +665,20 @@ const toAssistantUIMessage = (message) => {
|
|
|
651
665
|
}
|
|
652
666
|
return baseToolCall;
|
|
653
667
|
}
|
|
668
|
+
const requireApprovalMetadata = extendedMessage.metadata?.requireApprovalMetadata;
|
|
669
|
+
const partToolCallId = "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : void 0;
|
|
670
|
+
const suspensionData = partToolCallId ? requireApprovalMetadata?.[partToolCallId] : void 0;
|
|
671
|
+
if (suspensionData) {
|
|
672
|
+
const toolName = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.startsWith("tool-") ? part.type.substring(5) : "";
|
|
673
|
+
return {
|
|
674
|
+
type: "tool-call",
|
|
675
|
+
toolCallId: partToolCallId,
|
|
676
|
+
toolName,
|
|
677
|
+
argsText: "input" in part ? JSON.stringify(part.input) : "{}",
|
|
678
|
+
args: "input" in part ? part.input : {},
|
|
679
|
+
metadata: extendedMessage.metadata
|
|
680
|
+
};
|
|
681
|
+
}
|
|
654
682
|
return {
|
|
655
683
|
type: "text",
|
|
656
684
|
text: "",
|
|
@@ -737,7 +765,6 @@ const resolveInitialMessages = (messages) => {
|
|
|
737
765
|
childMessages,
|
|
738
766
|
result: finalResult?.text || ""
|
|
739
767
|
};
|
|
740
|
-
console.log("json", json);
|
|
741
768
|
const nextMessage = {
|
|
742
769
|
role: "assistant",
|
|
743
770
|
parts: [
|
|
@@ -765,6 +792,18 @@ const resolveInitialMessages = (messages) => {
|
|
|
765
792
|
return message;
|
|
766
793
|
}
|
|
767
794
|
}
|
|
795
|
+
const extendedMessage = message;
|
|
796
|
+
const pendingToolApprovals = extendedMessage.metadata?.pendingToolApprovals;
|
|
797
|
+
if (pendingToolApprovals && typeof pendingToolApprovals === "object") {
|
|
798
|
+
return {
|
|
799
|
+
...message,
|
|
800
|
+
metadata: {
|
|
801
|
+
...message.metadata,
|
|
802
|
+
mode: "stream",
|
|
803
|
+
requireApprovalMetadata: pendingToolApprovals
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
}
|
|
768
807
|
return message;
|
|
769
808
|
});
|
|
770
809
|
};
|
|
@@ -1213,12 +1252,24 @@ const fromCoreUserMessageToUIMessage = (coreUserMessage) => {
|
|
|
1213
1252
|
};
|
|
1214
1253
|
};
|
|
1215
1254
|
|
|
1216
|
-
const useChat = ({ agentId, initializeMessages }) => {
|
|
1217
|
-
const
|
|
1255
|
+
const useChat = ({ agentId, resourceId, initializeMessages }) => {
|
|
1256
|
+
const extractRunIdFromMessages = (messages2) => {
|
|
1257
|
+
for (const message of messages2) {
|
|
1258
|
+
const pendingToolApprovals = message.metadata?.pendingToolApprovals;
|
|
1259
|
+
if (pendingToolApprovals && typeof pendingToolApprovals === "object") {
|
|
1260
|
+
const suspensionData = Object.values(pendingToolApprovals)[0];
|
|
1261
|
+
if (suspensionData?.runId) {
|
|
1262
|
+
return suspensionData.runId;
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
return void 0;
|
|
1267
|
+
};
|
|
1268
|
+
const initialMessages = initializeMessages?.() || [];
|
|
1269
|
+
const initialRunId = extractRunIdFromMessages(initialMessages);
|
|
1270
|
+
const _currentRunId = useRef(initialRunId);
|
|
1218
1271
|
const _onChunk = useRef(void 0);
|
|
1219
|
-
const [messages, setMessages] = useState(
|
|
1220
|
-
() => resolveInitialMessages(initializeMessages?.() || [])
|
|
1221
|
-
);
|
|
1272
|
+
const [messages, setMessages] = useState(() => resolveInitialMessages(initialMessages));
|
|
1222
1273
|
const [toolCallApprovals, setToolCallApprovals] = useState({});
|
|
1223
1274
|
const baseClient = useMastraClient();
|
|
1224
1275
|
const [isRunning, setIsRunning] = useState(false);
|
|
@@ -1250,7 +1301,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1250
1301
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1251
1302
|
const response = await agent.generate({
|
|
1252
1303
|
messages: coreUserMessages,
|
|
1253
|
-
runId:
|
|
1304
|
+
runId: v4(),
|
|
1254
1305
|
maxSteps,
|
|
1255
1306
|
modelSettings: {
|
|
1256
1307
|
frequencyPenalty,
|
|
@@ -1263,7 +1314,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1263
1314
|
},
|
|
1264
1315
|
instructions,
|
|
1265
1316
|
requestContext,
|
|
1266
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1317
|
+
...threadId ? { threadId, resourceId: resourceId || agentId } : {},
|
|
1267
1318
|
providerOptions
|
|
1268
1319
|
});
|
|
1269
1320
|
setIsRunning(false);
|
|
@@ -1298,7 +1349,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1298
1349
|
abortSignal: signal
|
|
1299
1350
|
});
|
|
1300
1351
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1301
|
-
const runId =
|
|
1352
|
+
const runId = v4();
|
|
1302
1353
|
const response = await agent.stream({
|
|
1303
1354
|
messages: coreUserMessages,
|
|
1304
1355
|
runId,
|
|
@@ -1314,7 +1365,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1314
1365
|
},
|
|
1315
1366
|
instructions,
|
|
1316
1367
|
requestContext,
|
|
1317
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1368
|
+
...threadId ? { threadId, resourceId: resourceId || agentId } : {},
|
|
1318
1369
|
providerOptions,
|
|
1319
1370
|
requireToolApproval
|
|
1320
1371
|
});
|
|
@@ -1343,6 +1394,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1343
1394
|
abortSignal: signal
|
|
1344
1395
|
});
|
|
1345
1396
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1397
|
+
const runId = v4();
|
|
1346
1398
|
const response = await agent.network({
|
|
1347
1399
|
messages: coreUserMessages,
|
|
1348
1400
|
maxSteps,
|
|
@@ -1355,9 +1407,9 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1355
1407
|
topK,
|
|
1356
1408
|
topP
|
|
1357
1409
|
},
|
|
1358
|
-
runId
|
|
1410
|
+
runId,
|
|
1359
1411
|
requestContext,
|
|
1360
|
-
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
1412
|
+
...threadId ? { thread: threadId, resourceId: resourceId || agentId } : {}
|
|
1361
1413
|
});
|
|
1362
1414
|
const transformer = new AISdkNetworkTransformer();
|
|
1363
1415
|
await response.processDataStream({
|