@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/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: toolPart.toolName,
268
- toolCallId: toolPart.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: toolPart.toolName,
288
- toolCallId: toolPart.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
- ...toolPart,
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
- ...toolPart,
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 _currentRunId = useRef(void 0);
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: agentId,
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 = agentId;
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: agentId,
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({