@mastra/react 0.0.0-monorepo-binary-20251013210052 → 0.0.0-remove-unused-model-providers-api-20251030210744
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 +134 -2
- package/dist/index.cjs +443 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +444 -121
- 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.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 +14 -9
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,9 +691,116 @@ 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];
|
|
801
|
+
if (chunk.type === "routing-agent-text-delta") {
|
|
802
|
+
return this.handleRoutingAgentConversation(chunk, newConversation);
|
|
803
|
+
}
|
|
553
804
|
if (chunk.type.startsWith("agent-execution-")) {
|
|
554
805
|
return this.handleAgentConversation(chunk, newConversation, metadata);
|
|
555
806
|
}
|
|
@@ -560,22 +811,80 @@ class AISdkNetworkTransformer {
|
|
|
560
811
|
return this.handleToolConversation(chunk, newConversation, metadata);
|
|
561
812
|
}
|
|
562
813
|
if (chunk.type === "network-execution-event-step-finish") {
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
814
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
815
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
816
|
+
const agentChunk = chunk.payload;
|
|
817
|
+
const parts = [...lastMessage.parts];
|
|
818
|
+
const textPartIndex = parts.findIndex((part) => part.type === "text");
|
|
819
|
+
if (textPartIndex === -1) {
|
|
820
|
+
parts.push({
|
|
821
|
+
type: "text",
|
|
822
|
+
text: agentChunk.result,
|
|
823
|
+
state: "done"
|
|
824
|
+
});
|
|
825
|
+
return [
|
|
826
|
+
...newConversation.slice(0, -1),
|
|
567
827
|
{
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
state: "done"
|
|
828
|
+
...lastMessage,
|
|
829
|
+
parts
|
|
571
830
|
}
|
|
572
|
-
]
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
831
|
+
];
|
|
832
|
+
}
|
|
833
|
+
const textPart = parts[textPartIndex];
|
|
834
|
+
if (textPart.type === "text") {
|
|
835
|
+
parts[textPartIndex] = {
|
|
836
|
+
...textPart,
|
|
837
|
+
state: "done"
|
|
838
|
+
};
|
|
839
|
+
return [
|
|
840
|
+
...newConversation.slice(0, -1),
|
|
841
|
+
{
|
|
842
|
+
...lastMessage,
|
|
843
|
+
parts
|
|
844
|
+
}
|
|
845
|
+
];
|
|
846
|
+
}
|
|
847
|
+
return newConversation;
|
|
576
848
|
}
|
|
577
849
|
return newConversation;
|
|
578
850
|
}
|
|
851
|
+
handleRoutingAgentConversation = (chunk, newConversation) => {
|
|
852
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
853
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
854
|
+
const agentChunk = chunk.payload;
|
|
855
|
+
const parts = [...lastMessage.parts];
|
|
856
|
+
const textPartIndex = parts.findIndex((part) => part.type === "text");
|
|
857
|
+
if (textPartIndex === -1) {
|
|
858
|
+
parts.push({
|
|
859
|
+
type: "text",
|
|
860
|
+
text: agentChunk.text,
|
|
861
|
+
state: "streaming"
|
|
862
|
+
});
|
|
863
|
+
return [
|
|
864
|
+
...newConversation.slice(0, -1),
|
|
865
|
+
{
|
|
866
|
+
...lastMessage,
|
|
867
|
+
parts
|
|
868
|
+
}
|
|
869
|
+
];
|
|
870
|
+
}
|
|
871
|
+
const textPart = parts[textPartIndex];
|
|
872
|
+
if (textPart.type === "text") {
|
|
873
|
+
parts[textPartIndex] = {
|
|
874
|
+
...textPart,
|
|
875
|
+
text: textPart.text + agentChunk.text,
|
|
876
|
+
state: "streaming"
|
|
877
|
+
};
|
|
878
|
+
return [
|
|
879
|
+
...newConversation.slice(0, -1),
|
|
880
|
+
{
|
|
881
|
+
...lastMessage,
|
|
882
|
+
parts
|
|
883
|
+
}
|
|
884
|
+
];
|
|
885
|
+
}
|
|
886
|
+
return newConversation;
|
|
887
|
+
};
|
|
579
888
|
handleAgentConversation = (chunk, newConversation, metadata) => {
|
|
580
889
|
if (chunk.type === "agent-execution-start") {
|
|
581
890
|
const primitiveId = chunk.payload?.args?.primitiveId;
|
|
@@ -858,92 +1167,63 @@ class AISdkNetworkTransformer {
|
|
|
858
1167
|
};
|
|
859
1168
|
}
|
|
860
1169
|
|
|
861
|
-
const
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
if (finalResult && finalResult.text) {
|
|
897
|
-
childMessages.push({
|
|
898
|
-
type: "text",
|
|
899
|
-
content: finalResult.text
|
|
900
|
-
});
|
|
901
|
-
}
|
|
902
|
-
const result = {
|
|
903
|
-
childMessages,
|
|
904
|
-
result: finalResult?.text || ""
|
|
905
|
-
};
|
|
906
|
-
console.log("json", json);
|
|
907
|
-
const nextMessage = {
|
|
908
|
-
role: "assistant",
|
|
909
|
-
parts: [
|
|
910
|
-
{
|
|
911
|
-
type: "dynamic-tool",
|
|
912
|
-
toolCallId: primitiveId,
|
|
913
|
-
toolName: primitiveId,
|
|
914
|
-
state: "output-available",
|
|
915
|
-
input: json.input,
|
|
916
|
-
output: result
|
|
917
|
-
}
|
|
918
|
-
],
|
|
919
|
-
id: message.id,
|
|
920
|
-
metadata: {
|
|
921
|
-
...message.metadata,
|
|
922
|
-
mode: "network",
|
|
923
|
-
selectionReason,
|
|
924
|
-
agentInput: json.input,
|
|
925
|
-
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
926
|
-
}
|
|
927
|
-
};
|
|
928
|
-
return nextMessage;
|
|
929
|
-
}
|
|
930
|
-
} catch (error) {
|
|
931
|
-
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}`);
|
|
932
1205
|
}
|
|
933
1206
|
}
|
|
934
|
-
return message;
|
|
935
1207
|
});
|
|
1208
|
+
return {
|
|
1209
|
+
id,
|
|
1210
|
+
role: "user",
|
|
1211
|
+
parts
|
|
1212
|
+
};
|
|
936
1213
|
};
|
|
937
1214
|
|
|
938
1215
|
const useChat = ({ agentId, initializeMessages }) => {
|
|
1216
|
+
const _currentRunId = useRef(void 0);
|
|
1217
|
+
const _onChunk = useRef(void 0);
|
|
939
1218
|
const [messages, setMessages] = useState(
|
|
940
1219
|
() => resolveInitialMessages(initializeMessages?.() || [])
|
|
941
1220
|
);
|
|
1221
|
+
const [toolCallApprovals, setToolCallApprovals] = useState({});
|
|
942
1222
|
const baseClient = useMastraClient();
|
|
943
1223
|
const [isRunning, setIsRunning] = useState(false);
|
|
944
1224
|
const generate = async ({
|
|
945
1225
|
coreUserMessages,
|
|
946
|
-
|
|
1226
|
+
requestContext,
|
|
947
1227
|
threadId,
|
|
948
1228
|
modelSettings,
|
|
949
1229
|
signal,
|
|
@@ -981,7 +1261,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
981
1261
|
topP
|
|
982
1262
|
},
|
|
983
1263
|
instructions,
|
|
984
|
-
|
|
1264
|
+
requestContext,
|
|
985
1265
|
...threadId ? { threadId, resourceId: agentId } : {},
|
|
986
1266
|
providerOptions
|
|
987
1267
|
});
|
|
@@ -997,7 +1277,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
997
1277
|
setMessages((prev) => [...prev, ...mastraUIMessages]);
|
|
998
1278
|
}
|
|
999
1279
|
};
|
|
1000
|
-
const stream = async ({ coreUserMessages,
|
|
1280
|
+
const stream = async ({ coreUserMessages, requestContext, threadId, onChunk, modelSettings, signal }) => {
|
|
1001
1281
|
const {
|
|
1002
1282
|
frequencyPenalty,
|
|
1003
1283
|
presencePenalty,
|
|
@@ -1008,7 +1288,8 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1008
1288
|
topP,
|
|
1009
1289
|
instructions,
|
|
1010
1290
|
providerOptions,
|
|
1011
|
-
maxSteps
|
|
1291
|
+
maxSteps,
|
|
1292
|
+
requireToolApproval
|
|
1012
1293
|
} = modelSettings || {};
|
|
1013
1294
|
setIsRunning(true);
|
|
1014
1295
|
const clientWithAbort = new MastraClient({
|
|
@@ -1016,9 +1297,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1016
1297
|
abortSignal: signal
|
|
1017
1298
|
});
|
|
1018
1299
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1300
|
+
const runId = agentId;
|
|
1019
1301
|
const response = await agent.stream({
|
|
1020
1302
|
messages: coreUserMessages,
|
|
1021
|
-
runId
|
|
1303
|
+
runId,
|
|
1022
1304
|
maxSteps,
|
|
1023
1305
|
modelSettings: {
|
|
1024
1306
|
frequencyPenalty,
|
|
@@ -1030,19 +1312,16 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1030
1312
|
topP
|
|
1031
1313
|
},
|
|
1032
1314
|
instructions,
|
|
1033
|
-
|
|
1315
|
+
requestContext,
|
|
1034
1316
|
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1035
|
-
providerOptions
|
|
1317
|
+
providerOptions,
|
|
1318
|
+
requireToolApproval
|
|
1036
1319
|
});
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
throw new Error("[Stream] No response body");
|
|
1040
|
-
}
|
|
1320
|
+
_onChunk.current = onChunk;
|
|
1321
|
+
_currentRunId.current = runId;
|
|
1041
1322
|
await response.processDataStream({
|
|
1042
1323
|
onChunk: async (chunk) => {
|
|
1043
|
-
|
|
1044
|
-
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1045
|
-
});
|
|
1324
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1046
1325
|
onChunk?.(chunk);
|
|
1047
1326
|
}
|
|
1048
1327
|
});
|
|
@@ -1050,7 +1329,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1050
1329
|
};
|
|
1051
1330
|
const network = async ({
|
|
1052
1331
|
coreUserMessages,
|
|
1053
|
-
|
|
1332
|
+
requestContext,
|
|
1054
1333
|
threadId,
|
|
1055
1334
|
onNetworkChunk,
|
|
1056
1335
|
modelSettings,
|
|
@@ -1076,30 +1355,71 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1076
1355
|
topP
|
|
1077
1356
|
},
|
|
1078
1357
|
runId: agentId,
|
|
1079
|
-
|
|
1358
|
+
requestContext,
|
|
1080
1359
|
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
1081
1360
|
});
|
|
1082
1361
|
const transformer = new AISdkNetworkTransformer();
|
|
1083
1362
|
await response.processDataStream({
|
|
1084
1363
|
onChunk: async (chunk) => {
|
|
1085
|
-
|
|
1086
|
-
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1087
|
-
});
|
|
1364
|
+
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1088
1365
|
onNetworkChunk?.(chunk);
|
|
1089
1366
|
}
|
|
1090
1367
|
});
|
|
1091
1368
|
setIsRunning(false);
|
|
1092
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
|
+
};
|
|
1093
1409
|
const sendMessage = async ({ mode = "stream", ...args }) => {
|
|
1094
1410
|
const nextMessage = { role: "user", content: [{ type: "text", text: args.message }] };
|
|
1095
|
-
const
|
|
1096
|
-
|
|
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]);
|
|
1097
1417
|
if (mode === "generate") {
|
|
1098
|
-
await generate({ ...args, coreUserMessages
|
|
1418
|
+
await generate({ ...args, coreUserMessages });
|
|
1099
1419
|
} else if (mode === "stream") {
|
|
1100
|
-
await stream({ ...args, coreUserMessages
|
|
1420
|
+
await stream({ ...args, coreUserMessages });
|
|
1101
1421
|
} else if (mode === "network") {
|
|
1102
|
-
await network({ ...args, coreUserMessages
|
|
1422
|
+
await network({ ...args, coreUserMessages });
|
|
1103
1423
|
}
|
|
1104
1424
|
};
|
|
1105
1425
|
return {
|
|
@@ -1107,7 +1427,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1107
1427
|
sendMessage,
|
|
1108
1428
|
isRunning,
|
|
1109
1429
|
messages,
|
|
1110
|
-
|
|
1430
|
+
approveToolCall,
|
|
1431
|
+
declineToolCall,
|
|
1432
|
+
cancelRun: handleCancelRun,
|
|
1433
|
+
toolCallApprovals
|
|
1111
1434
|
};
|
|
1112
1435
|
};
|
|
1113
1436
|
|
|
@@ -1426,5 +1749,5 @@ const MessageStreaming = ({ className, ...props }) => {
|
|
|
1426
1749
|
return /* @__PURE__ */ jsx("span", { className: className || MessageStreamingClass, ...props });
|
|
1427
1750
|
};
|
|
1428
1751
|
|
|
1429
|
-
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 };
|
|
1430
1753
|
//# sourceMappingURL=index.js.map
|