@mastra/react 0.1.0-beta.4 → 0.1.0-beta.6
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 +41 -0
- package/dist/index.cjs +92 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +92 -27
- package/dist/index.js.map +1 -1
- package/dist/src/agent/hooks.d.ts +4 -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);
|
|
@@ -1228,7 +1279,8 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1228
1279
|
threadId,
|
|
1229
1280
|
modelSettings,
|
|
1230
1281
|
signal,
|
|
1231
|
-
onFinish
|
|
1282
|
+
onFinish,
|
|
1283
|
+
tracingOptions
|
|
1232
1284
|
}) => {
|
|
1233
1285
|
const {
|
|
1234
1286
|
frequencyPenalty,
|
|
@@ -1250,7 +1302,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1250
1302
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1251
1303
|
const response = await agent.generate({
|
|
1252
1304
|
messages: coreUserMessages,
|
|
1253
|
-
runId:
|
|
1305
|
+
runId: v4(),
|
|
1254
1306
|
maxSteps,
|
|
1255
1307
|
modelSettings: {
|
|
1256
1308
|
frequencyPenalty,
|
|
@@ -1263,8 +1315,9 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1263
1315
|
},
|
|
1264
1316
|
instructions,
|
|
1265
1317
|
requestContext,
|
|
1266
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1267
|
-
providerOptions
|
|
1318
|
+
...threadId ? { threadId, resourceId: resourceId || agentId } : {},
|
|
1319
|
+
providerOptions,
|
|
1320
|
+
tracingOptions
|
|
1268
1321
|
});
|
|
1269
1322
|
setIsRunning(false);
|
|
1270
1323
|
if (response && "uiMessages" in response.response && response.response.uiMessages) {
|
|
@@ -1278,7 +1331,15 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1278
1331
|
setMessages((prev) => [...prev, ...mastraUIMessages]);
|
|
1279
1332
|
}
|
|
1280
1333
|
};
|
|
1281
|
-
const stream = async ({
|
|
1334
|
+
const stream = async ({
|
|
1335
|
+
coreUserMessages,
|
|
1336
|
+
requestContext,
|
|
1337
|
+
threadId,
|
|
1338
|
+
onChunk,
|
|
1339
|
+
modelSettings,
|
|
1340
|
+
signal,
|
|
1341
|
+
tracingOptions
|
|
1342
|
+
}) => {
|
|
1282
1343
|
const {
|
|
1283
1344
|
frequencyPenalty,
|
|
1284
1345
|
presencePenalty,
|
|
@@ -1298,7 +1359,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1298
1359
|
abortSignal: signal
|
|
1299
1360
|
});
|
|
1300
1361
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1301
|
-
const runId =
|
|
1362
|
+
const runId = v4();
|
|
1302
1363
|
const response = await agent.stream({
|
|
1303
1364
|
messages: coreUserMessages,
|
|
1304
1365
|
runId,
|
|
@@ -1314,9 +1375,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1314
1375
|
},
|
|
1315
1376
|
instructions,
|
|
1316
1377
|
requestContext,
|
|
1317
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1378
|
+
...threadId ? { threadId, resourceId: resourceId || agentId } : {},
|
|
1318
1379
|
providerOptions,
|
|
1319
|
-
requireToolApproval
|
|
1380
|
+
requireToolApproval,
|
|
1381
|
+
tracingOptions
|
|
1320
1382
|
});
|
|
1321
1383
|
_onChunk.current = onChunk;
|
|
1322
1384
|
_currentRunId.current = runId;
|
|
@@ -1334,7 +1396,8 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1334
1396
|
threadId,
|
|
1335
1397
|
onNetworkChunk,
|
|
1336
1398
|
modelSettings,
|
|
1337
|
-
signal
|
|
1399
|
+
signal,
|
|
1400
|
+
tracingOptions
|
|
1338
1401
|
}) => {
|
|
1339
1402
|
const { frequencyPenalty, presencePenalty, maxRetries, maxTokens, temperature, topK, topP, maxSteps } = modelSettings || {};
|
|
1340
1403
|
setIsRunning(true);
|
|
@@ -1343,6 +1406,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1343
1406
|
abortSignal: signal
|
|
1344
1407
|
});
|
|
1345
1408
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1409
|
+
const runId = v4();
|
|
1346
1410
|
const response = await agent.network({
|
|
1347
1411
|
messages: coreUserMessages,
|
|
1348
1412
|
maxSteps,
|
|
@@ -1355,9 +1419,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1355
1419
|
topK,
|
|
1356
1420
|
topP
|
|
1357
1421
|
},
|
|
1358
|
-
runId
|
|
1422
|
+
runId,
|
|
1359
1423
|
requestContext,
|
|
1360
|
-
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
1424
|
+
...threadId ? { thread: threadId, resourceId: resourceId || agentId } : {},
|
|
1425
|
+
tracingOptions
|
|
1361
1426
|
});
|
|
1362
1427
|
const transformer = new AISdkNetworkTransformer();
|
|
1363
1428
|
await response.processDataStream({
|