@mastra/react 0.0.0-remove-unused-model-providers-api-20251030210744 → 0.0.0-safe-stringify-telemetry-20251205024938

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
  }
@@ -600,23 +614,13 @@ const toAssistantUIMessage = (message) => {
600
614
  };
601
615
  }
602
616
  if (part.type === "file") {
603
- const type = part.mediaType.includes("image/") ? "image" : "file";
604
- if (type === "file") {
605
- return {
606
- type,
607
- mimeType: part.mediaType,
608
- data: part.url,
609
- // Use URL as data source
610
- metadata: message.metadata
611
- };
612
- }
613
- if (type === "image") {
614
- return {
615
- type,
616
- image: part.url,
617
- metadata: message.metadata
618
- };
619
- }
617
+ return {
618
+ type: "file",
619
+ mimeType: part.mediaType,
620
+ data: part.url,
621
+ // Use URL as data source
622
+ metadata: message.metadata
623
+ };
620
624
  }
621
625
  if (part.type === "dynamic-tool") {
622
626
  const baseToolCall = {
@@ -652,6 +656,20 @@ const toAssistantUIMessage = (message) => {
652
656
  }
653
657
  return baseToolCall;
654
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
+ }
655
673
  return {
656
674
  type: "text",
657
675
  text: "",
@@ -736,7 +754,6 @@ const resolveInitialMessages = (messages) => {
736
754
  childMessages,
737
755
  result: finalResult?.text || ""
738
756
  };
739
- console.log("json", json);
740
757
  const nextMessage = {
741
758
  role: "assistant",
742
759
  parts: [
@@ -764,6 +781,18 @@ const resolveInitialMessages = (messages) => {
764
781
  return message;
765
782
  }
766
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
+ }
767
796
  return message;
768
797
  });
769
798
  };
@@ -1167,63 +1196,30 @@ class AISdkNetworkTransformer {
1167
1196
  };
1168
1197
  }
1169
1198
 
1170
- const fromCoreUserMessageToUIMessage = (coreUserMessage) => {
1171
- const id = `user-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
1172
- const parts = typeof coreUserMessage.content === "string" ? [
1173
- {
1174
- type: "text",
1175
- text: coreUserMessage.content
1176
- }
1177
- ] : coreUserMessage.content.map((part) => {
1178
- switch (part.type) {
1179
- case "text": {
1180
- return {
1181
- type: "text",
1182
- text: part.text
1183
- };
1184
- }
1185
- case "image": {
1186
- const url = typeof part.image === "string" ? part.image : part.image instanceof URL ? part.image.toString() : "";
1187
- return {
1188
- type: "file",
1189
- mediaType: part.mimeType ?? "image/*",
1190
- url
1191
- };
1192
- }
1193
- case "file": {
1194
- const url = typeof part.data === "string" ? part.data : part.data instanceof URL ? part.data.toString() : "";
1195
- return {
1196
- type: "file",
1197
- mediaType: part.mimeType,
1198
- url,
1199
- ...part.filename !== void 0 ? { filename: part.filename } : {}
1200
- };
1201
- }
1202
- default: {
1203
- const exhaustiveCheck = part;
1204
- throw new Error(`Unhandled content part type: ${exhaustiveCheck.type}`);
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
+ }
1205
1208
  }
1206
1209
  }
1207
- });
1208
- return {
1209
- id,
1210
- role: "user",
1211
- parts
1210
+ return void 0;
1212
1211
  };
1213
- };
1214
-
1215
- const useChat = ({ agentId, initializeMessages }) => {
1216
- const _currentRunId = useRef(void 0);
1212
+ const initialMessages = initializeMessages?.() || [];
1213
+ const initialRunId = extractRunIdFromMessages(initialMessages);
1214
+ const _currentRunId = useRef(initialRunId);
1217
1215
  const _onChunk = useRef(void 0);
1218
- const [messages, setMessages] = useState(
1219
- () => resolveInitialMessages(initializeMessages?.() || [])
1220
- );
1216
+ const [messages, setMessages] = useState(() => resolveInitialMessages(initialMessages));
1221
1217
  const [toolCallApprovals, setToolCallApprovals] = useState({});
1222
1218
  const baseClient = useMastraClient();
1223
1219
  const [isRunning, setIsRunning] = useState(false);
1224
1220
  const generate = async ({
1225
1221
  coreUserMessages,
1226
- requestContext,
1222
+ runtimeContext,
1227
1223
  threadId,
1228
1224
  modelSettings,
1229
1225
  signal,
@@ -1249,7 +1245,7 @@ const useChat = ({ agentId, initializeMessages }) => {
1249
1245
  const agent = clientWithAbort.getAgent(agentId);
1250
1246
  const response = await agent.generate({
1251
1247
  messages: coreUserMessages,
1252
- runId: agentId,
1248
+ runId: v4(),
1253
1249
  maxSteps,
1254
1250
  modelSettings: {
1255
1251
  frequencyPenalty,
@@ -1261,8 +1257,8 @@ const useChat = ({ agentId, initializeMessages }) => {
1261
1257
  topP
1262
1258
  },
1263
1259
  instructions,
1264
- requestContext,
1265
- ...threadId ? { threadId, resourceId: agentId } : {},
1260
+ runtimeContext,
1261
+ ...threadId ? { threadId, resourceId: resourceId || agentId } : {},
1266
1262
  providerOptions
1267
1263
  });
1268
1264
  setIsRunning(false);
@@ -1277,7 +1273,7 @@ const useChat = ({ agentId, initializeMessages }) => {
1277
1273
  setMessages((prev) => [...prev, ...mastraUIMessages]);
1278
1274
  }
1279
1275
  };
1280
- const stream = async ({ coreUserMessages, requestContext, threadId, onChunk, modelSettings, signal }) => {
1276
+ const stream = async ({ coreUserMessages, runtimeContext, threadId, onChunk, modelSettings, signal }) => {
1281
1277
  const {
1282
1278
  frequencyPenalty,
1283
1279
  presencePenalty,
@@ -1297,7 +1293,7 @@ const useChat = ({ agentId, initializeMessages }) => {
1297
1293
  abortSignal: signal
1298
1294
  });
1299
1295
  const agent = clientWithAbort.getAgent(agentId);
1300
- const runId = agentId;
1296
+ const runId = v4();
1301
1297
  const response = await agent.stream({
1302
1298
  messages: coreUserMessages,
1303
1299
  runId,
@@ -1312,8 +1308,8 @@ const useChat = ({ agentId, initializeMessages }) => {
1312
1308
  topP
1313
1309
  },
1314
1310
  instructions,
1315
- requestContext,
1316
- ...threadId ? { threadId, resourceId: agentId } : {},
1311
+ runtimeContext,
1312
+ ...threadId ? { threadId, resourceId: resourceId || agentId } : {},
1317
1313
  providerOptions,
1318
1314
  requireToolApproval
1319
1315
  });
@@ -1329,7 +1325,7 @@ const useChat = ({ agentId, initializeMessages }) => {
1329
1325
  };
1330
1326
  const network = async ({
1331
1327
  coreUserMessages,
1332
- requestContext,
1328
+ runtimeContext,
1333
1329
  threadId,
1334
1330
  onNetworkChunk,
1335
1331
  modelSettings,
@@ -1342,6 +1338,7 @@ const useChat = ({ agentId, initializeMessages }) => {
1342
1338
  abortSignal: signal
1343
1339
  });
1344
1340
  const agent = clientWithAbort.getAgent(agentId);
1341
+ const runId = v4();
1345
1342
  const response = await agent.network({
1346
1343
  messages: coreUserMessages,
1347
1344
  maxSteps,
@@ -1354,9 +1351,9 @@ const useChat = ({ agentId, initializeMessages }) => {
1354
1351
  topK,
1355
1352
  topP
1356
1353
  },
1357
- runId: agentId,
1358
- requestContext,
1359
- ...threadId ? { thread: threadId, resourceId: agentId } : {}
1354
+ runId,
1355
+ runtimeContext,
1356
+ ...threadId ? { thread: threadId, resourceId: resourceId || agentId } : {}
1360
1357
  });
1361
1358
  const transformer = new AISdkNetworkTransformer();
1362
1359
  await response.processDataStream({
@@ -1408,18 +1405,14 @@ const useChat = ({ agentId, initializeMessages }) => {
1408
1405
  };
1409
1406
  const sendMessage = async ({ mode = "stream", ...args }) => {
1410
1407
  const nextMessage = { role: "user", content: [{ type: "text", text: args.message }] };
1411
- const coreUserMessages = [nextMessage];
1412
- if (args.coreUserMessages) {
1413
- coreUserMessages.push(...args.coreUserMessages);
1414
- }
1415
- const uiMessages = coreUserMessages.map(fromCoreUserMessageToUIMessage);
1416
- setMessages((s) => [...s, ...uiMessages]);
1408
+ const messages2 = args.coreUserMessages ? [nextMessage, ...args.coreUserMessages] : [nextMessage];
1409
+ setMessages((s) => [...s, { role: "user", parts: [{ type: "text", text: args.message }] }]);
1417
1410
  if (mode === "generate") {
1418
- await generate({ ...args, coreUserMessages });
1411
+ await generate({ ...args, coreUserMessages: messages2 });
1419
1412
  } else if (mode === "stream") {
1420
- await stream({ ...args, coreUserMessages });
1413
+ await stream({ ...args, coreUserMessages: messages2 });
1421
1414
  } else if (mode === "network") {
1422
- await network({ ...args, coreUserMessages });
1415
+ await network({ ...args, coreUserMessages: messages2 });
1423
1416
  }
1424
1417
  };
1425
1418
  return {