@mastra/react 0.0.0-model-router-unknown-provider-20251017212006 → 0.0.0-playground-studio-cloud-20251031080052
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 +67 -2
- package/dist/index.cjs +365 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +366 -104
- package/dist/index.js.map +1 -1
- package/dist/react.css +1 -1
- package/dist/src/agent/hooks.d.ts +7 -0
- 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 +6 -5
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
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
|
-
import { flushSync } from 'react-dom';
|
|
5
4
|
import { ChevronDownIcon, CheckIcon, CopyIcon } from 'lucide-react';
|
|
6
5
|
import { twMerge } from 'tailwind-merge';
|
|
7
6
|
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
|
|
@@ -250,6 +249,7 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
250
249
|
}
|
|
251
250
|
];
|
|
252
251
|
}
|
|
252
|
+
case "tool-error":
|
|
253
253
|
case "tool-result": {
|
|
254
254
|
const lastMessage = result[result.length - 1];
|
|
255
255
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
@@ -260,25 +260,35 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
260
260
|
if (toolPartIndex !== -1) {
|
|
261
261
|
const toolPart = parts[toolPartIndex];
|
|
262
262
|
if (toolPart.type === "dynamic-tool") {
|
|
263
|
-
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;
|
|
264
265
|
parts[toolPartIndex] = {
|
|
265
266
|
type: "dynamic-tool",
|
|
266
267
|
toolName: toolPart.toolName,
|
|
267
268
|
toolCallId: toolPart.toolCallId,
|
|
268
269
|
state: "output-error",
|
|
269
270
|
input: toolPart.input,
|
|
270
|
-
errorText: String(
|
|
271
|
+
errorText: String(error),
|
|
271
272
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
272
273
|
};
|
|
273
274
|
} else {
|
|
274
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
|
+
}
|
|
275
285
|
parts[toolPartIndex] = {
|
|
276
286
|
type: "dynamic-tool",
|
|
277
287
|
toolName: toolPart.toolName,
|
|
278
288
|
toolCallId: toolPart.toolCallId,
|
|
279
289
|
state: "output-available",
|
|
280
290
|
input: toolPart.input,
|
|
281
|
-
output
|
|
291
|
+
output,
|
|
282
292
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
283
293
|
};
|
|
284
294
|
}
|
|
@@ -312,6 +322,8 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
312
322
|
...toolPart,
|
|
313
323
|
output: updatedWorkflowState
|
|
314
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);
|
|
315
327
|
} else {
|
|
316
328
|
const currentOutput = toolPart.output || [];
|
|
317
329
|
const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
|
|
@@ -385,6 +397,29 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
385
397
|
}
|
|
386
398
|
];
|
|
387
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
|
+
}
|
|
388
423
|
case "finish": {
|
|
389
424
|
const lastMessage = result[result.length - 1];
|
|
390
425
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
@@ -427,6 +462,105 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
427
462
|
return result;
|
|
428
463
|
}
|
|
429
464
|
};
|
|
465
|
+
const toUIMessageFromAgent = (chunk, conversation, metadata) => {
|
|
466
|
+
const lastMessage = conversation[conversation.length - 1];
|
|
467
|
+
if (!lastMessage || lastMessage.role !== "assistant") return conversation;
|
|
468
|
+
const parts = [...lastMessage.parts];
|
|
469
|
+
if (chunk.type === "text-delta") {
|
|
470
|
+
const agentChunk = chunk.payload;
|
|
471
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
472
|
+
if (toolPartIndex === -1) return conversation;
|
|
473
|
+
const toolPart = parts[toolPartIndex];
|
|
474
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
475
|
+
const lastChildMessage = childMessages[childMessages.length - 1];
|
|
476
|
+
const textMessage = { type: "text", content: (lastChildMessage?.content || "") + agentChunk.text };
|
|
477
|
+
const nextMessages = lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
|
|
478
|
+
parts[toolPartIndex] = {
|
|
479
|
+
...toolPart,
|
|
480
|
+
output: {
|
|
481
|
+
childMessages: nextMessages
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
} else if (chunk.type === "tool-call") {
|
|
485
|
+
const agentChunk = chunk.payload;
|
|
486
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
487
|
+
if (toolPartIndex === -1) return conversation;
|
|
488
|
+
const toolPart = parts[toolPartIndex];
|
|
489
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
490
|
+
parts[toolPartIndex] = {
|
|
491
|
+
...toolPart,
|
|
492
|
+
output: {
|
|
493
|
+
...toolPart?.output,
|
|
494
|
+
childMessages: [
|
|
495
|
+
...childMessages,
|
|
496
|
+
{
|
|
497
|
+
type: "tool",
|
|
498
|
+
toolCallId: agentChunk.toolCallId,
|
|
499
|
+
toolName: agentChunk.toolName,
|
|
500
|
+
args: agentChunk.args
|
|
501
|
+
}
|
|
502
|
+
]
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
} else if (chunk.type === "tool-output") {
|
|
506
|
+
const agentChunk = chunk.payload;
|
|
507
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
508
|
+
if (toolPartIndex === -1) return conversation;
|
|
509
|
+
const toolPart = parts[toolPartIndex];
|
|
510
|
+
if (agentChunk?.output?.type?.startsWith("workflow-")) {
|
|
511
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
512
|
+
const lastToolIndex = childMessages.length - 1;
|
|
513
|
+
const currentMessage = childMessages[lastToolIndex];
|
|
514
|
+
const actualExistingWorkflowState = currentMessage?.toolOutput || {};
|
|
515
|
+
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(actualExistingWorkflowState, agentChunk.output);
|
|
516
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
517
|
+
parts[toolPartIndex] = {
|
|
518
|
+
...toolPart,
|
|
519
|
+
output: {
|
|
520
|
+
...toolPart?.output,
|
|
521
|
+
childMessages: [
|
|
522
|
+
...childMessages.slice(0, -1),
|
|
523
|
+
{
|
|
524
|
+
...currentMessage,
|
|
525
|
+
toolOutput: { ...updatedWorkflowState, runId: agentChunk.output.runId }
|
|
526
|
+
}
|
|
527
|
+
]
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
} else if (chunk.type === "tool-result") {
|
|
533
|
+
const agentChunk = chunk.payload;
|
|
534
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
535
|
+
if (toolPartIndex === -1) return conversation;
|
|
536
|
+
const toolPart = parts[toolPartIndex];
|
|
537
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
538
|
+
const lastToolIndex = childMessages.length - 1;
|
|
539
|
+
const isWorkflow = agentChunk?.toolName?.startsWith("workflow-");
|
|
540
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
541
|
+
parts[toolPartIndex] = {
|
|
542
|
+
...toolPart,
|
|
543
|
+
output: {
|
|
544
|
+
...toolPart?.output,
|
|
545
|
+
childMessages: [
|
|
546
|
+
...childMessages.slice(0, -1),
|
|
547
|
+
{
|
|
548
|
+
...childMessages[lastToolIndex],
|
|
549
|
+
toolOutput: isWorkflow ? { ...agentChunk.result?.result, runId: agentChunk.result?.runId } : agentChunk.result
|
|
550
|
+
}
|
|
551
|
+
]
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return [
|
|
557
|
+
...conversation.slice(0, -1),
|
|
558
|
+
{
|
|
559
|
+
...lastMessage,
|
|
560
|
+
parts
|
|
561
|
+
}
|
|
562
|
+
];
|
|
563
|
+
};
|
|
430
564
|
|
|
431
565
|
const toAssistantUIMessage = (message) => {
|
|
432
566
|
const extendedMessage = message;
|
|
@@ -466,13 +600,23 @@ const toAssistantUIMessage = (message) => {
|
|
|
466
600
|
};
|
|
467
601
|
}
|
|
468
602
|
if (part.type === "file") {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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
|
+
}
|
|
476
620
|
}
|
|
477
621
|
if (part.type === "dynamic-tool") {
|
|
478
622
|
const baseToolCall = {
|
|
@@ -547,6 +691,110 @@ const toAssistantUIMessage = (message) => {
|
|
|
547
691
|
return threadMessage;
|
|
548
692
|
};
|
|
549
693
|
|
|
694
|
+
const resolveInitialMessages = (messages) => {
|
|
695
|
+
return messages.map((message) => {
|
|
696
|
+
const networkPart = message.parts.find((part) => part.type === "text" && part.text.includes('"isNetwork":true'));
|
|
697
|
+
if (networkPart && networkPart.type === "text") {
|
|
698
|
+
try {
|
|
699
|
+
const json = JSON.parse(networkPart.text);
|
|
700
|
+
if (json.isNetwork === true) {
|
|
701
|
+
const selectionReason = json.selectionReason || "";
|
|
702
|
+
const primitiveType = json.primitiveType || "";
|
|
703
|
+
const primitiveId = json.primitiveId || "";
|
|
704
|
+
const finalResult = json.finalResult;
|
|
705
|
+
const toolCalls = finalResult?.toolCalls || [];
|
|
706
|
+
const childMessages = [];
|
|
707
|
+
for (const toolCall of toolCalls) {
|
|
708
|
+
if (toolCall.type === "tool-call" && toolCall.payload) {
|
|
709
|
+
const toolCallId = toolCall.payload.toolCallId;
|
|
710
|
+
let toolResult;
|
|
711
|
+
for (const message2 of finalResult?.messages || []) {
|
|
712
|
+
for (const part of message2.content || []) {
|
|
713
|
+
if (typeof part === "object" && part.type === "tool-result" && part.toolCallId === toolCallId) {
|
|
714
|
+
toolResult = part;
|
|
715
|
+
break;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
const isWorkflow = Boolean(toolResult?.result?.result?.steps);
|
|
720
|
+
childMessages.push({
|
|
721
|
+
type: "tool",
|
|
722
|
+
toolCallId: toolCall.payload.toolCallId,
|
|
723
|
+
toolName: toolCall.payload.toolName,
|
|
724
|
+
args: toolCall.payload.args,
|
|
725
|
+
toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
if (finalResult && finalResult.text) {
|
|
730
|
+
childMessages.push({
|
|
731
|
+
type: "text",
|
|
732
|
+
content: finalResult.text
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
const result = {
|
|
736
|
+
childMessages,
|
|
737
|
+
result: finalResult?.text || ""
|
|
738
|
+
};
|
|
739
|
+
console.log("json", json);
|
|
740
|
+
const nextMessage = {
|
|
741
|
+
role: "assistant",
|
|
742
|
+
parts: [
|
|
743
|
+
{
|
|
744
|
+
type: "dynamic-tool",
|
|
745
|
+
toolCallId: primitiveId,
|
|
746
|
+
toolName: primitiveId,
|
|
747
|
+
state: "output-available",
|
|
748
|
+
input: json.input,
|
|
749
|
+
output: result
|
|
750
|
+
}
|
|
751
|
+
],
|
|
752
|
+
id: message.id,
|
|
753
|
+
metadata: {
|
|
754
|
+
...message.metadata,
|
|
755
|
+
mode: "network",
|
|
756
|
+
selectionReason,
|
|
757
|
+
agentInput: json.input,
|
|
758
|
+
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
return nextMessage;
|
|
762
|
+
}
|
|
763
|
+
} catch (error) {
|
|
764
|
+
return message;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
return message;
|
|
768
|
+
});
|
|
769
|
+
};
|
|
770
|
+
const resolveToChildMessages = (messages) => {
|
|
771
|
+
const assistantMessage = messages.find((message) => message.role === "assistant");
|
|
772
|
+
if (!assistantMessage) return [];
|
|
773
|
+
const parts = assistantMessage.parts;
|
|
774
|
+
let childMessages = [];
|
|
775
|
+
for (const part of parts) {
|
|
776
|
+
const toolPart = part;
|
|
777
|
+
if (part.type.startsWith("tool-")) {
|
|
778
|
+
const toolName = part.type.substring("tool-".length);
|
|
779
|
+
const isWorkflow = toolName.startsWith("workflow-");
|
|
780
|
+
childMessages.push({
|
|
781
|
+
type: "tool",
|
|
782
|
+
toolCallId: toolPart.toolCallId,
|
|
783
|
+
toolName,
|
|
784
|
+
args: toolPart.input,
|
|
785
|
+
toolOutput: isWorkflow ? { ...toolPart.output?.result, runId: toolPart.output?.runId } : toolPart.output
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
if (part.type === "text") {
|
|
789
|
+
childMessages.push({
|
|
790
|
+
type: "text",
|
|
791
|
+
content: toolPart.text
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
return childMessages;
|
|
796
|
+
};
|
|
797
|
+
|
|
550
798
|
class AISdkNetworkTransformer {
|
|
551
799
|
transform({ chunk, conversation, metadata }) {
|
|
552
800
|
const newConversation = [...conversation];
|
|
@@ -919,87 +1167,58 @@ class AISdkNetworkTransformer {
|
|
|
919
1167
|
};
|
|
920
1168
|
}
|
|
921
1169
|
|
|
922
|
-
const
|
|
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
|
-
|
|
957
|
-
if (finalResult && finalResult.text) {
|
|
958
|
-
childMessages.push({
|
|
959
|
-
type: "text",
|
|
960
|
-
content: finalResult.text
|
|
961
|
-
});
|
|
962
|
-
}
|
|
963
|
-
const result = {
|
|
964
|
-
childMessages,
|
|
965
|
-
result: finalResult?.text || ""
|
|
966
|
-
};
|
|
967
|
-
console.log("json", json);
|
|
968
|
-
const nextMessage = {
|
|
969
|
-
role: "assistant",
|
|
970
|
-
parts: [
|
|
971
|
-
{
|
|
972
|
-
type: "dynamic-tool",
|
|
973
|
-
toolCallId: primitiveId,
|
|
974
|
-
toolName: primitiveId,
|
|
975
|
-
state: "output-available",
|
|
976
|
-
input: json.input,
|
|
977
|
-
output: result
|
|
978
|
-
}
|
|
979
|
-
],
|
|
980
|
-
id: message.id,
|
|
981
|
-
metadata: {
|
|
982
|
-
...message.metadata,
|
|
983
|
-
mode: "network",
|
|
984
|
-
selectionReason,
|
|
985
|
-
agentInput: json.input,
|
|
986
|
-
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
987
|
-
}
|
|
988
|
-
};
|
|
989
|
-
return nextMessage;
|
|
990
|
-
}
|
|
991
|
-
} catch (error) {
|
|
992
|
-
return message;
|
|
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}`);
|
|
993
1205
|
}
|
|
994
1206
|
}
|
|
995
|
-
return message;
|
|
996
1207
|
});
|
|
1208
|
+
return {
|
|
1209
|
+
id,
|
|
1210
|
+
role: "user",
|
|
1211
|
+
parts
|
|
1212
|
+
};
|
|
997
1213
|
};
|
|
998
1214
|
|
|
999
1215
|
const useChat = ({ agentId, initializeMessages }) => {
|
|
1216
|
+
const _currentRunId = useRef(void 0);
|
|
1217
|
+
const _onChunk = useRef(void 0);
|
|
1000
1218
|
const [messages, setMessages] = useState(
|
|
1001
1219
|
() => resolveInitialMessages(initializeMessages?.() || [])
|
|
1002
1220
|
);
|
|
1221
|
+
const [toolCallApprovals, setToolCallApprovals] = useState({});
|
|
1003
1222
|
const baseClient = useMastraClient();
|
|
1004
1223
|
const [isRunning, setIsRunning] = useState(false);
|
|
1005
1224
|
const generate = async ({
|
|
@@ -1069,7 +1288,8 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1069
1288
|
topP,
|
|
1070
1289
|
instructions,
|
|
1071
1290
|
providerOptions,
|
|
1072
|
-
maxSteps
|
|
1291
|
+
maxSteps,
|
|
1292
|
+
requireToolApproval
|
|
1073
1293
|
} = modelSettings || {};
|
|
1074
1294
|
setIsRunning(true);
|
|
1075
1295
|
const clientWithAbort = new MastraClient({
|
|
@@ -1077,9 +1297,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1077
1297
|
abortSignal: signal
|
|
1078
1298
|
});
|
|
1079
1299
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1300
|
+
const runId = agentId;
|
|
1080
1301
|
const response = await agent.stream({
|
|
1081
1302
|
messages: coreUserMessages,
|
|
1082
|
-
runId
|
|
1303
|
+
runId,
|
|
1083
1304
|
maxSteps,
|
|
1084
1305
|
modelSettings: {
|
|
1085
1306
|
frequencyPenalty,
|
|
@@ -1093,17 +1314,14 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1093
1314
|
instructions,
|
|
1094
1315
|
runtimeContext,
|
|
1095
1316
|
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1096
|
-
providerOptions
|
|
1317
|
+
providerOptions,
|
|
1318
|
+
requireToolApproval
|
|
1097
1319
|
});
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
throw new Error("[Stream] No response body");
|
|
1101
|
-
}
|
|
1320
|
+
_onChunk.current = onChunk;
|
|
1321
|
+
_currentRunId.current = runId;
|
|
1102
1322
|
await response.processDataStream({
|
|
1103
1323
|
onChunk: async (chunk) => {
|
|
1104
|
-
|
|
1105
|
-
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1106
|
-
});
|
|
1324
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1107
1325
|
onChunk?.(chunk);
|
|
1108
1326
|
}
|
|
1109
1327
|
});
|
|
@@ -1143,24 +1361,65 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1143
1361
|
const transformer = new AISdkNetworkTransformer();
|
|
1144
1362
|
await response.processDataStream({
|
|
1145
1363
|
onChunk: async (chunk) => {
|
|
1146
|
-
|
|
1147
|
-
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1148
|
-
});
|
|
1364
|
+
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1149
1365
|
onNetworkChunk?.(chunk);
|
|
1150
1366
|
}
|
|
1151
1367
|
});
|
|
1152
1368
|
setIsRunning(false);
|
|
1153
1369
|
};
|
|
1370
|
+
const handleCancelRun = () => {
|
|
1371
|
+
setIsRunning(false);
|
|
1372
|
+
_currentRunId.current = void 0;
|
|
1373
|
+
_onChunk.current = void 0;
|
|
1374
|
+
};
|
|
1375
|
+
const approveToolCall = async (toolCallId) => {
|
|
1376
|
+
const onChunk = _onChunk.current;
|
|
1377
|
+
const currentRunId = _currentRunId.current;
|
|
1378
|
+
if (!currentRunId)
|
|
1379
|
+
return console.info("[approveToolCall] approveToolCall can only be called after a stream has started");
|
|
1380
|
+
setIsRunning(true);
|
|
1381
|
+
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "approved" } }));
|
|
1382
|
+
const agent = baseClient.getAgent(agentId);
|
|
1383
|
+
const response = await agent.approveToolCall({ runId: currentRunId, toolCallId });
|
|
1384
|
+
await response.processDataStream({
|
|
1385
|
+
onChunk: async (chunk) => {
|
|
1386
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1387
|
+
onChunk?.(chunk);
|
|
1388
|
+
}
|
|
1389
|
+
});
|
|
1390
|
+
setIsRunning(false);
|
|
1391
|
+
};
|
|
1392
|
+
const declineToolCall = async (toolCallId) => {
|
|
1393
|
+
const onChunk = _onChunk.current;
|
|
1394
|
+
const currentRunId = _currentRunId.current;
|
|
1395
|
+
if (!currentRunId)
|
|
1396
|
+
return console.info("[declineToolCall] declineToolCall can only be called after a stream has started");
|
|
1397
|
+
setIsRunning(true);
|
|
1398
|
+
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "declined" } }));
|
|
1399
|
+
const agent = baseClient.getAgent(agentId);
|
|
1400
|
+
const response = await agent.declineToolCall({ runId: currentRunId, toolCallId });
|
|
1401
|
+
await response.processDataStream({
|
|
1402
|
+
onChunk: async (chunk) => {
|
|
1403
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1404
|
+
onChunk?.(chunk);
|
|
1405
|
+
}
|
|
1406
|
+
});
|
|
1407
|
+
setIsRunning(false);
|
|
1408
|
+
};
|
|
1154
1409
|
const sendMessage = async ({ mode = "stream", ...args }) => {
|
|
1155
1410
|
const nextMessage = { role: "user", content: [{ type: "text", text: args.message }] };
|
|
1156
|
-
const
|
|
1157
|
-
|
|
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]);
|
|
1158
1417
|
if (mode === "generate") {
|
|
1159
|
-
await generate({ ...args, coreUserMessages
|
|
1418
|
+
await generate({ ...args, coreUserMessages });
|
|
1160
1419
|
} else if (mode === "stream") {
|
|
1161
|
-
await stream({ ...args, coreUserMessages
|
|
1420
|
+
await stream({ ...args, coreUserMessages });
|
|
1162
1421
|
} else if (mode === "network") {
|
|
1163
|
-
await network({ ...args, coreUserMessages
|
|
1422
|
+
await network({ ...args, coreUserMessages });
|
|
1164
1423
|
}
|
|
1165
1424
|
};
|
|
1166
1425
|
return {
|
|
@@ -1168,7 +1427,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1168
1427
|
sendMessage,
|
|
1169
1428
|
isRunning,
|
|
1170
1429
|
messages,
|
|
1171
|
-
|
|
1430
|
+
approveToolCall,
|
|
1431
|
+
declineToolCall,
|
|
1432
|
+
cancelRun: handleCancelRun,
|
|
1433
|
+
toolCallApprovals
|
|
1172
1434
|
};
|
|
1173
1435
|
};
|
|
1174
1436
|
|
|
@@ -1487,5 +1749,5 @@ const MessageStreaming = ({ className, ...props }) => {
|
|
|
1487
1749
|
return /* @__PURE__ */ jsx("span", { className: className || MessageStreamingClass, ...props });
|
|
1488
1750
|
};
|
|
1489
1751
|
|
|
1490
|
-
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 };
|
|
1752
|
+
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 };
|
|
1491
1753
|
//# sourceMappingURL=index.js.map
|