@mastra/react 0.0.0-error-handler-fix-20251020202607 → 0.0.0-export-agent-memory-from-local-studio-20251112153946
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 +101 -2
- package/dist/index.cjs +375 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +376 -108
- package/dist/index.js.map +1 -1
- package/dist/react.css +1 -1
- package/dist/src/agent/hooks.d.ts +9 -2
- package/dist/src/agent/types.d.ts +1 -0
- package/dist/src/lib/ai-sdk/index.d.ts +1 -0
- package/dist/src/lib/ai-sdk/memory/resolveInitialMessages.d.ts +10 -0
- package/dist/src/lib/ai-sdk/memory/resolveInitialMessages.test.d.ts +1 -0
- package/dist/src/lib/ai-sdk/transformers/AISdkNetworkTransformer.test.d.ts +1 -0
- package/dist/src/lib/ai-sdk/types.d.ts +7 -0
- package/dist/src/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.d.ts +10 -0
- package/dist/src/lib/ai-sdk/utils/fromCoreUserMessageToUIMessage.test.d.ts +1 -0
- package/dist/src/lib/ai-sdk/utils/toUIMessage.test.d.ts +1 -0
- package/package.json +11 -7
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { createContext, useContext, useState, Fragment, useLayoutEffect,
|
|
2
|
+
import { createContext, useContext, useRef, useState, Fragment, useLayoutEffect, useEffect } from 'react';
|
|
3
3
|
import { MastraClient } from '@mastra/client-js';
|
|
4
4
|
import { ChevronDownIcon, CheckIcon, CopyIcon } from 'lucide-react';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -249,6 +249,7 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
249
249
|
}
|
|
250
250
|
];
|
|
251
251
|
}
|
|
252
|
+
case "tool-error":
|
|
252
253
|
case "tool-result": {
|
|
253
254
|
const lastMessage = result[result.length - 1];
|
|
254
255
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
@@ -259,25 +260,35 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
259
260
|
if (toolPartIndex !== -1) {
|
|
260
261
|
const toolPart = parts[toolPartIndex];
|
|
261
262
|
if (toolPart.type === "dynamic-tool") {
|
|
262
|
-
if (chunk.payload.isError) {
|
|
263
|
+
if (chunk.type === "tool-result" && chunk.payload.isError || chunk.type === "tool-error") {
|
|
264
|
+
const error = chunk.type === "tool-error" ? chunk.payload.error : chunk.payload.result;
|
|
263
265
|
parts[toolPartIndex] = {
|
|
264
266
|
type: "dynamic-tool",
|
|
265
267
|
toolName: toolPart.toolName,
|
|
266
268
|
toolCallId: toolPart.toolCallId,
|
|
267
269
|
state: "output-error",
|
|
268
270
|
input: toolPart.input,
|
|
269
|
-
errorText: String(
|
|
271
|
+
errorText: String(error),
|
|
270
272
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
271
273
|
};
|
|
272
274
|
} else {
|
|
273
275
|
const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
|
|
276
|
+
const isAgent = chunk?.from === "AGENT";
|
|
277
|
+
let output;
|
|
278
|
+
if (isWorkflow) {
|
|
279
|
+
output = chunk.payload.result?.result;
|
|
280
|
+
} else if (isAgent) {
|
|
281
|
+
output = parts[toolPartIndex].output ?? chunk.payload.result;
|
|
282
|
+
} else {
|
|
283
|
+
output = chunk.payload.result;
|
|
284
|
+
}
|
|
274
285
|
parts[toolPartIndex] = {
|
|
275
286
|
type: "dynamic-tool",
|
|
276
287
|
toolName: toolPart.toolName,
|
|
277
288
|
toolCallId: toolPart.toolCallId,
|
|
278
289
|
state: "output-available",
|
|
279
290
|
input: toolPart.input,
|
|
280
|
-
output
|
|
291
|
+
output,
|
|
281
292
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
282
293
|
};
|
|
283
294
|
}
|
|
@@ -311,6 +322,8 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
311
322
|
...toolPart,
|
|
312
323
|
output: updatedWorkflowState
|
|
313
324
|
};
|
|
325
|
+
} else if (chunk.payload.output?.from === "AGENT" || chunk.payload.output?.from === "USER" && chunk.payload.output?.payload?.output?.type?.startsWith("workflow-")) {
|
|
326
|
+
return toUIMessageFromAgent(chunk.payload.output, conversation);
|
|
314
327
|
} else {
|
|
315
328
|
const currentOutput = toolPart.output || [];
|
|
316
329
|
const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
|
|
@@ -384,15 +397,37 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
384
397
|
}
|
|
385
398
|
];
|
|
386
399
|
}
|
|
400
|
+
case "tool-call-approval": {
|
|
401
|
+
const lastMessage = result[result.length - 1];
|
|
402
|
+
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
403
|
+
const lastRequireApprovalMetadata = lastMessage.metadata?.mode === "stream" ? lastMessage.metadata?.requireApprovalMetadata : {};
|
|
404
|
+
return [
|
|
405
|
+
...result.slice(0, -1),
|
|
406
|
+
{
|
|
407
|
+
...lastMessage,
|
|
408
|
+
metadata: {
|
|
409
|
+
...lastMessage.metadata,
|
|
410
|
+
mode: "stream",
|
|
411
|
+
requireApprovalMetadata: {
|
|
412
|
+
...lastRequireApprovalMetadata,
|
|
413
|
+
[chunk.payload.toolCallId]: {
|
|
414
|
+
toolCallId: chunk.payload.toolCallId,
|
|
415
|
+
toolName: chunk.payload.toolName,
|
|
416
|
+
args: chunk.payload.args
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
];
|
|
422
|
+
}
|
|
387
423
|
case "finish": {
|
|
388
424
|
const lastMessage = result[result.length - 1];
|
|
389
425
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
390
426
|
const parts = lastMessage.parts.map((part) => {
|
|
391
|
-
if (part
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
return { ...part, state: "done" };
|
|
427
|
+
if (typeof part === "object" && part !== null && "type" in part && "state" in part && part.state === "streaming") {
|
|
428
|
+
if (part.type === "text" || part.type === "reasoning") {
|
|
429
|
+
return { ...part, state: "done" };
|
|
430
|
+
}
|
|
396
431
|
}
|
|
397
432
|
return part;
|
|
398
433
|
});
|
|
@@ -426,6 +461,105 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
426
461
|
return result;
|
|
427
462
|
}
|
|
428
463
|
};
|
|
464
|
+
const toUIMessageFromAgent = (chunk, conversation, metadata) => {
|
|
465
|
+
const lastMessage = conversation[conversation.length - 1];
|
|
466
|
+
if (!lastMessage || lastMessage.role !== "assistant") return conversation;
|
|
467
|
+
const parts = [...lastMessage.parts];
|
|
468
|
+
if (chunk.type === "text-delta") {
|
|
469
|
+
const agentChunk = chunk.payload;
|
|
470
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
471
|
+
if (toolPartIndex === -1) return conversation;
|
|
472
|
+
const toolPart = parts[toolPartIndex];
|
|
473
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
474
|
+
const lastChildMessage = childMessages[childMessages.length - 1];
|
|
475
|
+
const textMessage = { type: "text", content: (lastChildMessage?.content || "") + agentChunk.text };
|
|
476
|
+
const nextMessages = lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
|
|
477
|
+
parts[toolPartIndex] = {
|
|
478
|
+
...toolPart,
|
|
479
|
+
output: {
|
|
480
|
+
childMessages: nextMessages
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
} else if (chunk.type === "tool-call") {
|
|
484
|
+
const agentChunk = chunk.payload;
|
|
485
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
486
|
+
if (toolPartIndex === -1) return conversation;
|
|
487
|
+
const toolPart = parts[toolPartIndex];
|
|
488
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
489
|
+
parts[toolPartIndex] = {
|
|
490
|
+
...toolPart,
|
|
491
|
+
output: {
|
|
492
|
+
...toolPart?.output,
|
|
493
|
+
childMessages: [
|
|
494
|
+
...childMessages,
|
|
495
|
+
{
|
|
496
|
+
type: "tool",
|
|
497
|
+
toolCallId: agentChunk.toolCallId,
|
|
498
|
+
toolName: agentChunk.toolName,
|
|
499
|
+
args: agentChunk.args
|
|
500
|
+
}
|
|
501
|
+
]
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
} else if (chunk.type === "tool-output") {
|
|
505
|
+
const agentChunk = chunk.payload;
|
|
506
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
507
|
+
if (toolPartIndex === -1) return conversation;
|
|
508
|
+
const toolPart = parts[toolPartIndex];
|
|
509
|
+
if (agentChunk?.output?.type?.startsWith("workflow-")) {
|
|
510
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
511
|
+
const lastToolIndex = childMessages.length - 1;
|
|
512
|
+
const currentMessage = childMessages[lastToolIndex];
|
|
513
|
+
const actualExistingWorkflowState = currentMessage?.toolOutput || {};
|
|
514
|
+
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(actualExistingWorkflowState, agentChunk.output);
|
|
515
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
516
|
+
parts[toolPartIndex] = {
|
|
517
|
+
...toolPart,
|
|
518
|
+
output: {
|
|
519
|
+
...toolPart?.output,
|
|
520
|
+
childMessages: [
|
|
521
|
+
...childMessages.slice(0, -1),
|
|
522
|
+
{
|
|
523
|
+
...currentMessage,
|
|
524
|
+
toolOutput: { ...updatedWorkflowState, runId: agentChunk.output.runId }
|
|
525
|
+
}
|
|
526
|
+
]
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
} else if (chunk.type === "tool-result") {
|
|
532
|
+
const agentChunk = chunk.payload;
|
|
533
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
534
|
+
if (toolPartIndex === -1) return conversation;
|
|
535
|
+
const toolPart = parts[toolPartIndex];
|
|
536
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
537
|
+
const lastToolIndex = childMessages.length - 1;
|
|
538
|
+
const isWorkflow = agentChunk?.toolName?.startsWith("workflow-");
|
|
539
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
540
|
+
parts[toolPartIndex] = {
|
|
541
|
+
...toolPart,
|
|
542
|
+
output: {
|
|
543
|
+
...toolPart?.output,
|
|
544
|
+
childMessages: [
|
|
545
|
+
...childMessages.slice(0, -1),
|
|
546
|
+
{
|
|
547
|
+
...childMessages[lastToolIndex],
|
|
548
|
+
toolOutput: isWorkflow ? { ...agentChunk.result?.result, runId: agentChunk.result?.runId } : agentChunk.result
|
|
549
|
+
}
|
|
550
|
+
]
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return [
|
|
556
|
+
...conversation.slice(0, -1),
|
|
557
|
+
{
|
|
558
|
+
...lastMessage,
|
|
559
|
+
parts
|
|
560
|
+
}
|
|
561
|
+
];
|
|
562
|
+
};
|
|
429
563
|
|
|
430
564
|
const toAssistantUIMessage = (message) => {
|
|
431
565
|
const extendedMessage = message;
|
|
@@ -465,13 +599,23 @@ const toAssistantUIMessage = (message) => {
|
|
|
465
599
|
};
|
|
466
600
|
}
|
|
467
601
|
if (part.type === "file") {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
602
|
+
const type = part.mediaType.includes("image/") ? "image" : "file";
|
|
603
|
+
if (type === "file") {
|
|
604
|
+
return {
|
|
605
|
+
type,
|
|
606
|
+
mimeType: part.mediaType,
|
|
607
|
+
data: part.url,
|
|
608
|
+
// Use URL as data source
|
|
609
|
+
metadata: message.metadata
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
if (type === "image") {
|
|
613
|
+
return {
|
|
614
|
+
type,
|
|
615
|
+
image: part.url,
|
|
616
|
+
metadata: message.metadata
|
|
617
|
+
};
|
|
618
|
+
}
|
|
475
619
|
}
|
|
476
620
|
if (part.type === "dynamic-tool") {
|
|
477
621
|
const baseToolCall = {
|
|
@@ -546,6 +690,112 @@ const toAssistantUIMessage = (message) => {
|
|
|
546
690
|
return threadMessage;
|
|
547
691
|
};
|
|
548
692
|
|
|
693
|
+
const resolveInitialMessages = (messages) => {
|
|
694
|
+
return messages.map((message) => {
|
|
695
|
+
const networkPart = message.parts.find(
|
|
696
|
+
(part) => typeof part === "object" && part !== null && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string" && part.text.includes('"isNetwork":true')
|
|
697
|
+
);
|
|
698
|
+
if (networkPart && networkPart.type === "text") {
|
|
699
|
+
try {
|
|
700
|
+
const json = JSON.parse(networkPart.text);
|
|
701
|
+
if (json.isNetwork === true) {
|
|
702
|
+
const selectionReason = json.selectionReason || "";
|
|
703
|
+
const primitiveType = json.primitiveType || "";
|
|
704
|
+
const primitiveId = json.primitiveId || "";
|
|
705
|
+
const finalResult = json.finalResult;
|
|
706
|
+
const toolCalls = finalResult?.toolCalls || [];
|
|
707
|
+
const childMessages = [];
|
|
708
|
+
for (const toolCall of toolCalls) {
|
|
709
|
+
if (toolCall.type === "tool-call" && toolCall.payload) {
|
|
710
|
+
const toolCallId = toolCall.payload.toolCallId;
|
|
711
|
+
let toolResult;
|
|
712
|
+
for (const message2 of finalResult?.messages || []) {
|
|
713
|
+
for (const part of message2.content || []) {
|
|
714
|
+
if (typeof part === "object" && part.type === "tool-result" && part.toolCallId === toolCallId) {
|
|
715
|
+
toolResult = part;
|
|
716
|
+
break;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
const isWorkflow = Boolean(toolResult?.result?.result?.steps);
|
|
721
|
+
childMessages.push({
|
|
722
|
+
type: "tool",
|
|
723
|
+
toolCallId: toolCall.payload.toolCallId,
|
|
724
|
+
toolName: toolCall.payload.toolName,
|
|
725
|
+
args: toolCall.payload.args,
|
|
726
|
+
toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
if (finalResult && finalResult.text) {
|
|
731
|
+
childMessages.push({
|
|
732
|
+
type: "text",
|
|
733
|
+
content: finalResult.text
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
const result = {
|
|
737
|
+
childMessages,
|
|
738
|
+
result: finalResult?.text || ""
|
|
739
|
+
};
|
|
740
|
+
console.log("json", json);
|
|
741
|
+
const nextMessage = {
|
|
742
|
+
role: "assistant",
|
|
743
|
+
parts: [
|
|
744
|
+
{
|
|
745
|
+
type: "dynamic-tool",
|
|
746
|
+
toolCallId: primitiveId,
|
|
747
|
+
toolName: primitiveId,
|
|
748
|
+
state: "output-available",
|
|
749
|
+
input: json.input,
|
|
750
|
+
output: result
|
|
751
|
+
}
|
|
752
|
+
],
|
|
753
|
+
id: message.id,
|
|
754
|
+
metadata: {
|
|
755
|
+
...message.metadata,
|
|
756
|
+
mode: "network",
|
|
757
|
+
selectionReason,
|
|
758
|
+
agentInput: json.input,
|
|
759
|
+
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
return nextMessage;
|
|
763
|
+
}
|
|
764
|
+
} catch (error) {
|
|
765
|
+
return message;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return message;
|
|
769
|
+
});
|
|
770
|
+
};
|
|
771
|
+
const resolveToChildMessages = (messages) => {
|
|
772
|
+
const assistantMessage = messages.find((message) => message.role === "assistant");
|
|
773
|
+
if (!assistantMessage) return [];
|
|
774
|
+
const parts = assistantMessage.parts;
|
|
775
|
+
let childMessages = [];
|
|
776
|
+
for (const part of parts) {
|
|
777
|
+
const toolPart = part;
|
|
778
|
+
if (part.type.startsWith("tool-")) {
|
|
779
|
+
const toolName = part.type.substring("tool-".length);
|
|
780
|
+
const isWorkflow = toolName.startsWith("workflow-");
|
|
781
|
+
childMessages.push({
|
|
782
|
+
type: "tool",
|
|
783
|
+
toolCallId: toolPart.toolCallId,
|
|
784
|
+
toolName,
|
|
785
|
+
args: toolPart.input,
|
|
786
|
+
toolOutput: isWorkflow ? { ...toolPart.output?.result, runId: toolPart.output?.runId } : toolPart.output
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
if (part.type === "text") {
|
|
790
|
+
childMessages.push({
|
|
791
|
+
type: "text",
|
|
792
|
+
content: toolPart.text
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
return childMessages;
|
|
797
|
+
};
|
|
798
|
+
|
|
549
799
|
class AISdkNetworkTransformer {
|
|
550
800
|
transform({ chunk, conversation, metadata }) {
|
|
551
801
|
const newConversation = [...conversation];
|
|
@@ -918,92 +1168,63 @@ class AISdkNetworkTransformer {
|
|
|
918
1168
|
};
|
|
919
1169
|
}
|
|
920
1170
|
|
|
921
|
-
const
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
if (finalResult && finalResult.text) {
|
|
957
|
-
childMessages.push({
|
|
958
|
-
type: "text",
|
|
959
|
-
content: finalResult.text
|
|
960
|
-
});
|
|
961
|
-
}
|
|
962
|
-
const result = {
|
|
963
|
-
childMessages,
|
|
964
|
-
result: finalResult?.text || ""
|
|
965
|
-
};
|
|
966
|
-
console.log("json", json);
|
|
967
|
-
const nextMessage = {
|
|
968
|
-
role: "assistant",
|
|
969
|
-
parts: [
|
|
970
|
-
{
|
|
971
|
-
type: "dynamic-tool",
|
|
972
|
-
toolCallId: primitiveId,
|
|
973
|
-
toolName: primitiveId,
|
|
974
|
-
state: "output-available",
|
|
975
|
-
input: json.input,
|
|
976
|
-
output: result
|
|
977
|
-
}
|
|
978
|
-
],
|
|
979
|
-
id: message.id,
|
|
980
|
-
metadata: {
|
|
981
|
-
...message.metadata,
|
|
982
|
-
mode: "network",
|
|
983
|
-
selectionReason,
|
|
984
|
-
agentInput: json.input,
|
|
985
|
-
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
986
|
-
}
|
|
987
|
-
};
|
|
988
|
-
return nextMessage;
|
|
989
|
-
}
|
|
990
|
-
} catch (error) {
|
|
991
|
-
return message;
|
|
1171
|
+
const fromCoreUserMessageToUIMessage = (coreUserMessage) => {
|
|
1172
|
+
const id = `user-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
1173
|
+
const parts = typeof coreUserMessage.content === "string" ? [
|
|
1174
|
+
{
|
|
1175
|
+
type: "text",
|
|
1176
|
+
text: coreUserMessage.content
|
|
1177
|
+
}
|
|
1178
|
+
] : coreUserMessage.content.map((part) => {
|
|
1179
|
+
switch (part.type) {
|
|
1180
|
+
case "text": {
|
|
1181
|
+
return {
|
|
1182
|
+
type: "text",
|
|
1183
|
+
text: part.text
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
case "image": {
|
|
1187
|
+
const url = typeof part.image === "string" ? part.image : part.image instanceof URL ? part.image.toString() : "";
|
|
1188
|
+
return {
|
|
1189
|
+
type: "file",
|
|
1190
|
+
mediaType: part.mimeType ?? "image/*",
|
|
1191
|
+
url
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
case "file": {
|
|
1195
|
+
const url = typeof part.data === "string" ? part.data : part.data instanceof URL ? part.data.toString() : "";
|
|
1196
|
+
return {
|
|
1197
|
+
type: "file",
|
|
1198
|
+
mediaType: part.mimeType,
|
|
1199
|
+
url,
|
|
1200
|
+
...part.filename !== void 0 ? { filename: part.filename } : {}
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
default: {
|
|
1204
|
+
const exhaustiveCheck = part;
|
|
1205
|
+
throw new Error(`Unhandled content part type: ${exhaustiveCheck.type}`);
|
|
992
1206
|
}
|
|
993
1207
|
}
|
|
994
|
-
return message;
|
|
995
1208
|
});
|
|
1209
|
+
return {
|
|
1210
|
+
id,
|
|
1211
|
+
role: "user",
|
|
1212
|
+
parts
|
|
1213
|
+
};
|
|
996
1214
|
};
|
|
997
1215
|
|
|
998
1216
|
const useChat = ({ agentId, initializeMessages }) => {
|
|
1217
|
+
const _currentRunId = useRef(void 0);
|
|
1218
|
+
const _onChunk = useRef(void 0);
|
|
999
1219
|
const [messages, setMessages] = useState(
|
|
1000
1220
|
() => resolveInitialMessages(initializeMessages?.() || [])
|
|
1001
1221
|
);
|
|
1222
|
+
const [toolCallApprovals, setToolCallApprovals] = useState({});
|
|
1002
1223
|
const baseClient = useMastraClient();
|
|
1003
1224
|
const [isRunning, setIsRunning] = useState(false);
|
|
1004
1225
|
const generate = async ({
|
|
1005
1226
|
coreUserMessages,
|
|
1006
|
-
|
|
1227
|
+
requestContext,
|
|
1007
1228
|
threadId,
|
|
1008
1229
|
modelSettings,
|
|
1009
1230
|
signal,
|
|
@@ -1041,7 +1262,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1041
1262
|
topP
|
|
1042
1263
|
},
|
|
1043
1264
|
instructions,
|
|
1044
|
-
|
|
1265
|
+
requestContext,
|
|
1045
1266
|
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1046
1267
|
providerOptions
|
|
1047
1268
|
});
|
|
@@ -1057,7 +1278,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1057
1278
|
setMessages((prev) => [...prev, ...mastraUIMessages]);
|
|
1058
1279
|
}
|
|
1059
1280
|
};
|
|
1060
|
-
const stream = async ({ coreUserMessages,
|
|
1281
|
+
const stream = async ({ coreUserMessages, requestContext, threadId, onChunk, modelSettings, signal }) => {
|
|
1061
1282
|
const {
|
|
1062
1283
|
frequencyPenalty,
|
|
1063
1284
|
presencePenalty,
|
|
@@ -1068,7 +1289,8 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1068
1289
|
topP,
|
|
1069
1290
|
instructions,
|
|
1070
1291
|
providerOptions,
|
|
1071
|
-
maxSteps
|
|
1292
|
+
maxSteps,
|
|
1293
|
+
requireToolApproval
|
|
1072
1294
|
} = modelSettings || {};
|
|
1073
1295
|
setIsRunning(true);
|
|
1074
1296
|
const clientWithAbort = new MastraClient({
|
|
@@ -1076,9 +1298,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1076
1298
|
abortSignal: signal
|
|
1077
1299
|
});
|
|
1078
1300
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1301
|
+
const runId = agentId;
|
|
1079
1302
|
const response = await agent.stream({
|
|
1080
1303
|
messages: coreUserMessages,
|
|
1081
|
-
runId
|
|
1304
|
+
runId,
|
|
1082
1305
|
maxSteps,
|
|
1083
1306
|
modelSettings: {
|
|
1084
1307
|
frequencyPenalty,
|
|
@@ -1090,14 +1313,13 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1090
1313
|
topP
|
|
1091
1314
|
},
|
|
1092
1315
|
instructions,
|
|
1093
|
-
|
|
1316
|
+
requestContext,
|
|
1094
1317
|
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1095
|
-
providerOptions
|
|
1318
|
+
providerOptions,
|
|
1319
|
+
requireToolApproval
|
|
1096
1320
|
});
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
throw new Error("[Stream] No response body");
|
|
1100
|
-
}
|
|
1321
|
+
_onChunk.current = onChunk;
|
|
1322
|
+
_currentRunId.current = runId;
|
|
1101
1323
|
await response.processDataStream({
|
|
1102
1324
|
onChunk: async (chunk) => {
|
|
1103
1325
|
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
@@ -1108,7 +1330,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1108
1330
|
};
|
|
1109
1331
|
const network = async ({
|
|
1110
1332
|
coreUserMessages,
|
|
1111
|
-
|
|
1333
|
+
requestContext,
|
|
1112
1334
|
threadId,
|
|
1113
1335
|
onNetworkChunk,
|
|
1114
1336
|
modelSettings,
|
|
@@ -1134,7 +1356,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1134
1356
|
topP
|
|
1135
1357
|
},
|
|
1136
1358
|
runId: agentId,
|
|
1137
|
-
|
|
1359
|
+
requestContext,
|
|
1138
1360
|
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
1139
1361
|
});
|
|
1140
1362
|
const transformer = new AISdkNetworkTransformer();
|
|
@@ -1146,16 +1368,59 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1146
1368
|
});
|
|
1147
1369
|
setIsRunning(false);
|
|
1148
1370
|
};
|
|
1371
|
+
const handleCancelRun = () => {
|
|
1372
|
+
setIsRunning(false);
|
|
1373
|
+
_currentRunId.current = void 0;
|
|
1374
|
+
_onChunk.current = void 0;
|
|
1375
|
+
};
|
|
1376
|
+
const approveToolCall = async (toolCallId) => {
|
|
1377
|
+
const onChunk = _onChunk.current;
|
|
1378
|
+
const currentRunId = _currentRunId.current;
|
|
1379
|
+
if (!currentRunId)
|
|
1380
|
+
return console.info("[approveToolCall] approveToolCall can only be called after a stream has started");
|
|
1381
|
+
setIsRunning(true);
|
|
1382
|
+
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "approved" } }));
|
|
1383
|
+
const agent = baseClient.getAgent(agentId);
|
|
1384
|
+
const response = await agent.approveToolCall({ runId: currentRunId, toolCallId });
|
|
1385
|
+
await response.processDataStream({
|
|
1386
|
+
onChunk: async (chunk) => {
|
|
1387
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1388
|
+
onChunk?.(chunk);
|
|
1389
|
+
}
|
|
1390
|
+
});
|
|
1391
|
+
setIsRunning(false);
|
|
1392
|
+
};
|
|
1393
|
+
const declineToolCall = async (toolCallId) => {
|
|
1394
|
+
const onChunk = _onChunk.current;
|
|
1395
|
+
const currentRunId = _currentRunId.current;
|
|
1396
|
+
if (!currentRunId)
|
|
1397
|
+
return console.info("[declineToolCall] declineToolCall can only be called after a stream has started");
|
|
1398
|
+
setIsRunning(true);
|
|
1399
|
+
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "declined" } }));
|
|
1400
|
+
const agent = baseClient.getAgent(agentId);
|
|
1401
|
+
const response = await agent.declineToolCall({ runId: currentRunId, toolCallId });
|
|
1402
|
+
await response.processDataStream({
|
|
1403
|
+
onChunk: async (chunk) => {
|
|
1404
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1405
|
+
onChunk?.(chunk);
|
|
1406
|
+
}
|
|
1407
|
+
});
|
|
1408
|
+
setIsRunning(false);
|
|
1409
|
+
};
|
|
1149
1410
|
const sendMessage = async ({ mode = "stream", ...args }) => {
|
|
1150
1411
|
const nextMessage = { role: "user", content: [{ type: "text", text: args.message }] };
|
|
1151
|
-
const
|
|
1152
|
-
|
|
1412
|
+
const coreUserMessages = [nextMessage];
|
|
1413
|
+
if (args.coreUserMessages) {
|
|
1414
|
+
coreUserMessages.push(...args.coreUserMessages);
|
|
1415
|
+
}
|
|
1416
|
+
const uiMessages = coreUserMessages.map(fromCoreUserMessageToUIMessage);
|
|
1417
|
+
setMessages((s) => [...s, ...uiMessages]);
|
|
1153
1418
|
if (mode === "generate") {
|
|
1154
|
-
await generate({ ...args, coreUserMessages
|
|
1419
|
+
await generate({ ...args, coreUserMessages });
|
|
1155
1420
|
} else if (mode === "stream") {
|
|
1156
|
-
await stream({ ...args, coreUserMessages
|
|
1421
|
+
await stream({ ...args, coreUserMessages });
|
|
1157
1422
|
} else if (mode === "network") {
|
|
1158
|
-
await network({ ...args, coreUserMessages
|
|
1423
|
+
await network({ ...args, coreUserMessages });
|
|
1159
1424
|
}
|
|
1160
1425
|
};
|
|
1161
1426
|
return {
|
|
@@ -1163,7 +1428,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1163
1428
|
sendMessage,
|
|
1164
1429
|
isRunning,
|
|
1165
1430
|
messages,
|
|
1166
|
-
|
|
1431
|
+
approveToolCall,
|
|
1432
|
+
declineToolCall,
|
|
1433
|
+
cancelRun: handleCancelRun,
|
|
1434
|
+
toolCallApprovals
|
|
1167
1435
|
};
|
|
1168
1436
|
};
|
|
1169
1437
|
|
|
@@ -1482,5 +1750,5 @@ const MessageStreaming = ({ className, ...props }) => {
|
|
|
1482
1750
|
return /* @__PURE__ */ jsx("span", { className: className || MessageStreamingClass, ...props });
|
|
1483
1751
|
};
|
|
1484
1752
|
|
|
1485
|
-
export { AgentIcon, CodeBlock, CodeBlockClass, CodeCopyButton, Entity, EntityCaret, EntityContent, EntityContentClass, EntityTrigger, EntityTriggerClass, EntityTriggerVariantClasses, Entry, EntryClass, EntryTitle, EntryTitleClass, Icon, IconButton, IconButtonClass, IconSizes, MastraReactProvider, Message, MessageActions, MessageActionsClass, MessageClass, MessageContent, MessageContentClass, MessageList, MessageListClass, MessageStreaming, MessageStreamingClass, MessageUsage, MessageUsageClass, MessageUsageEntry, MessageUsageEntryClass, MessageUsageValue, MessageUsageValueClass, MessageUsages, MessageUsagesClass, ToolApproval, ToolApprovalActions, ToolApprovalActionsClass, ToolApprovalClass, ToolApprovalContent, ToolApprovalContentClass, ToolApprovalHeader, ToolApprovalHeaderClass, ToolApprovalTitle, ToolApprovalTitleClass, ToolsIcon, Tooltip, TooltipContent, TooltipContentClass, TooltipTrigger, WorkflowIcon, mapWorkflowStreamChunkToWatchResult, toAssistantUIMessage, toUIMessage, useChat, useEntity, useMastraClient };
|
|
1753
|
+
export { AgentIcon, CodeBlock, CodeBlockClass, CodeCopyButton, Entity, EntityCaret, EntityContent, EntityContentClass, EntityTrigger, EntityTriggerClass, EntityTriggerVariantClasses, Entry, EntryClass, EntryTitle, EntryTitleClass, Icon, IconButton, IconButtonClass, IconSizes, MastraReactProvider, Message, MessageActions, MessageActionsClass, MessageClass, MessageContent, MessageContentClass, MessageList, MessageListClass, MessageStreaming, MessageStreamingClass, MessageUsage, MessageUsageClass, MessageUsageEntry, MessageUsageEntryClass, MessageUsageValue, MessageUsageValueClass, MessageUsages, MessageUsagesClass, ToolApproval, ToolApprovalActions, ToolApprovalActionsClass, ToolApprovalClass, ToolApprovalContent, ToolApprovalContentClass, ToolApprovalHeader, ToolApprovalHeaderClass, ToolApprovalTitle, ToolApprovalTitleClass, ToolsIcon, Tooltip, TooltipContent, TooltipContentClass, TooltipTrigger, WorkflowIcon, mapWorkflowStreamChunkToWatchResult, resolveToChildMessages, toAssistantUIMessage, toUIMessage, useChat, useEntity, useMastraClient };
|
|
1486
1754
|
//# sourceMappingURL=index.js.map
|