@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.cjs
CHANGED
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
const react = require('react');
|
|
7
7
|
const clientJs = require('@mastra/client-js');
|
|
8
|
-
const reactDom = require('react-dom');
|
|
9
8
|
const lucideReact = require('lucide-react');
|
|
10
9
|
const tailwindMerge = require('tailwind-merge');
|
|
11
10
|
const hastUtilToJsxRuntime = require('hast-util-to-jsx-runtime');
|
|
@@ -254,6 +253,7 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
254
253
|
}
|
|
255
254
|
];
|
|
256
255
|
}
|
|
256
|
+
case "tool-error":
|
|
257
257
|
case "tool-result": {
|
|
258
258
|
const lastMessage = result[result.length - 1];
|
|
259
259
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
@@ -264,25 +264,35 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
264
264
|
if (toolPartIndex !== -1) {
|
|
265
265
|
const toolPart = parts[toolPartIndex];
|
|
266
266
|
if (toolPart.type === "dynamic-tool") {
|
|
267
|
-
if (chunk.payload.isError) {
|
|
267
|
+
if (chunk.type === "tool-result" && chunk.payload.isError || chunk.type === "tool-error") {
|
|
268
|
+
const error = chunk.type === "tool-error" ? chunk.payload.error : chunk.payload.result;
|
|
268
269
|
parts[toolPartIndex] = {
|
|
269
270
|
type: "dynamic-tool",
|
|
270
271
|
toolName: toolPart.toolName,
|
|
271
272
|
toolCallId: toolPart.toolCallId,
|
|
272
273
|
state: "output-error",
|
|
273
274
|
input: toolPart.input,
|
|
274
|
-
errorText: String(
|
|
275
|
+
errorText: String(error),
|
|
275
276
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
276
277
|
};
|
|
277
278
|
} else {
|
|
278
279
|
const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
|
|
280
|
+
const isAgent = chunk?.from === "AGENT";
|
|
281
|
+
let output;
|
|
282
|
+
if (isWorkflow) {
|
|
283
|
+
output = chunk.payload.result?.result;
|
|
284
|
+
} else if (isAgent) {
|
|
285
|
+
output = parts[toolPartIndex].output ?? chunk.payload.result;
|
|
286
|
+
} else {
|
|
287
|
+
output = chunk.payload.result;
|
|
288
|
+
}
|
|
279
289
|
parts[toolPartIndex] = {
|
|
280
290
|
type: "dynamic-tool",
|
|
281
291
|
toolName: toolPart.toolName,
|
|
282
292
|
toolCallId: toolPart.toolCallId,
|
|
283
293
|
state: "output-available",
|
|
284
294
|
input: toolPart.input,
|
|
285
|
-
output
|
|
295
|
+
output,
|
|
286
296
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
287
297
|
};
|
|
288
298
|
}
|
|
@@ -316,6 +326,8 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
316
326
|
...toolPart,
|
|
317
327
|
output: updatedWorkflowState
|
|
318
328
|
};
|
|
329
|
+
} else if (chunk.payload.output?.from === "AGENT" || chunk.payload.output?.from === "USER" && chunk.payload.output?.payload?.output?.type?.startsWith("workflow-")) {
|
|
330
|
+
return toUIMessageFromAgent(chunk.payload.output, conversation);
|
|
319
331
|
} else {
|
|
320
332
|
const currentOutput = toolPart.output || [];
|
|
321
333
|
const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
|
|
@@ -389,6 +401,29 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
389
401
|
}
|
|
390
402
|
];
|
|
391
403
|
}
|
|
404
|
+
case "tool-call-approval": {
|
|
405
|
+
const lastMessage = result[result.length - 1];
|
|
406
|
+
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
407
|
+
const lastRequireApprovalMetadata = lastMessage.metadata?.mode === "stream" ? lastMessage.metadata?.requireApprovalMetadata : {};
|
|
408
|
+
return [
|
|
409
|
+
...result.slice(0, -1),
|
|
410
|
+
{
|
|
411
|
+
...lastMessage,
|
|
412
|
+
metadata: {
|
|
413
|
+
...lastMessage.metadata,
|
|
414
|
+
mode: "stream",
|
|
415
|
+
requireApprovalMetadata: {
|
|
416
|
+
...lastRequireApprovalMetadata,
|
|
417
|
+
[chunk.payload.toolCallId]: {
|
|
418
|
+
toolCallId: chunk.payload.toolCallId,
|
|
419
|
+
toolName: chunk.payload.toolName,
|
|
420
|
+
args: chunk.payload.args
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
];
|
|
426
|
+
}
|
|
392
427
|
case "finish": {
|
|
393
428
|
const lastMessage = result[result.length - 1];
|
|
394
429
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
@@ -431,6 +466,105 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
431
466
|
return result;
|
|
432
467
|
}
|
|
433
468
|
};
|
|
469
|
+
const toUIMessageFromAgent = (chunk, conversation, metadata) => {
|
|
470
|
+
const lastMessage = conversation[conversation.length - 1];
|
|
471
|
+
if (!lastMessage || lastMessage.role !== "assistant") return conversation;
|
|
472
|
+
const parts = [...lastMessage.parts];
|
|
473
|
+
if (chunk.type === "text-delta") {
|
|
474
|
+
const agentChunk = chunk.payload;
|
|
475
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
476
|
+
if (toolPartIndex === -1) return conversation;
|
|
477
|
+
const toolPart = parts[toolPartIndex];
|
|
478
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
479
|
+
const lastChildMessage = childMessages[childMessages.length - 1];
|
|
480
|
+
const textMessage = { type: "text", content: (lastChildMessage?.content || "") + agentChunk.text };
|
|
481
|
+
const nextMessages = lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
|
|
482
|
+
parts[toolPartIndex] = {
|
|
483
|
+
...toolPart,
|
|
484
|
+
output: {
|
|
485
|
+
childMessages: nextMessages
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
} else if (chunk.type === "tool-call") {
|
|
489
|
+
const agentChunk = chunk.payload;
|
|
490
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
491
|
+
if (toolPartIndex === -1) return conversation;
|
|
492
|
+
const toolPart = parts[toolPartIndex];
|
|
493
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
494
|
+
parts[toolPartIndex] = {
|
|
495
|
+
...toolPart,
|
|
496
|
+
output: {
|
|
497
|
+
...toolPart?.output,
|
|
498
|
+
childMessages: [
|
|
499
|
+
...childMessages,
|
|
500
|
+
{
|
|
501
|
+
type: "tool",
|
|
502
|
+
toolCallId: agentChunk.toolCallId,
|
|
503
|
+
toolName: agentChunk.toolName,
|
|
504
|
+
args: agentChunk.args
|
|
505
|
+
}
|
|
506
|
+
]
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
} else if (chunk.type === "tool-output") {
|
|
510
|
+
const agentChunk = chunk.payload;
|
|
511
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
512
|
+
if (toolPartIndex === -1) return conversation;
|
|
513
|
+
const toolPart = parts[toolPartIndex];
|
|
514
|
+
if (agentChunk?.output?.type?.startsWith("workflow-")) {
|
|
515
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
516
|
+
const lastToolIndex = childMessages.length - 1;
|
|
517
|
+
const currentMessage = childMessages[lastToolIndex];
|
|
518
|
+
const actualExistingWorkflowState = currentMessage?.toolOutput || {};
|
|
519
|
+
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(actualExistingWorkflowState, agentChunk.output);
|
|
520
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
521
|
+
parts[toolPartIndex] = {
|
|
522
|
+
...toolPart,
|
|
523
|
+
output: {
|
|
524
|
+
...toolPart?.output,
|
|
525
|
+
childMessages: [
|
|
526
|
+
...childMessages.slice(0, -1),
|
|
527
|
+
{
|
|
528
|
+
...currentMessage,
|
|
529
|
+
toolOutput: { ...updatedWorkflowState, runId: agentChunk.output.runId }
|
|
530
|
+
}
|
|
531
|
+
]
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
} else if (chunk.type === "tool-result") {
|
|
537
|
+
const agentChunk = chunk.payload;
|
|
538
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
539
|
+
if (toolPartIndex === -1) return conversation;
|
|
540
|
+
const toolPart = parts[toolPartIndex];
|
|
541
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
542
|
+
const lastToolIndex = childMessages.length - 1;
|
|
543
|
+
const isWorkflow = agentChunk?.toolName?.startsWith("workflow-");
|
|
544
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
545
|
+
parts[toolPartIndex] = {
|
|
546
|
+
...toolPart,
|
|
547
|
+
output: {
|
|
548
|
+
...toolPart?.output,
|
|
549
|
+
childMessages: [
|
|
550
|
+
...childMessages.slice(0, -1),
|
|
551
|
+
{
|
|
552
|
+
...childMessages[lastToolIndex],
|
|
553
|
+
toolOutput: isWorkflow ? { ...agentChunk.result?.result, runId: agentChunk.result?.runId } : agentChunk.result
|
|
554
|
+
}
|
|
555
|
+
]
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return [
|
|
561
|
+
...conversation.slice(0, -1),
|
|
562
|
+
{
|
|
563
|
+
...lastMessage,
|
|
564
|
+
parts
|
|
565
|
+
}
|
|
566
|
+
];
|
|
567
|
+
};
|
|
434
568
|
|
|
435
569
|
const toAssistantUIMessage = (message) => {
|
|
436
570
|
const extendedMessage = message;
|
|
@@ -470,13 +604,23 @@ const toAssistantUIMessage = (message) => {
|
|
|
470
604
|
};
|
|
471
605
|
}
|
|
472
606
|
if (part.type === "file") {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
607
|
+
const type = part.mediaType.includes("image/") ? "image" : "file";
|
|
608
|
+
if (type === "file") {
|
|
609
|
+
return {
|
|
610
|
+
type,
|
|
611
|
+
mimeType: part.mediaType,
|
|
612
|
+
data: part.url,
|
|
613
|
+
// Use URL as data source
|
|
614
|
+
metadata: message.metadata
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
if (type === "image") {
|
|
618
|
+
return {
|
|
619
|
+
type,
|
|
620
|
+
image: part.url,
|
|
621
|
+
metadata: message.metadata
|
|
622
|
+
};
|
|
623
|
+
}
|
|
480
624
|
}
|
|
481
625
|
if (part.type === "dynamic-tool") {
|
|
482
626
|
const baseToolCall = {
|
|
@@ -551,9 +695,116 @@ const toAssistantUIMessage = (message) => {
|
|
|
551
695
|
return threadMessage;
|
|
552
696
|
};
|
|
553
697
|
|
|
698
|
+
const resolveInitialMessages = (messages) => {
|
|
699
|
+
return messages.map((message) => {
|
|
700
|
+
const networkPart = message.parts.find((part) => part.type === "text" && part.text.includes('"isNetwork":true'));
|
|
701
|
+
if (networkPart && networkPart.type === "text") {
|
|
702
|
+
try {
|
|
703
|
+
const json = JSON.parse(networkPart.text);
|
|
704
|
+
if (json.isNetwork === true) {
|
|
705
|
+
const selectionReason = json.selectionReason || "";
|
|
706
|
+
const primitiveType = json.primitiveType || "";
|
|
707
|
+
const primitiveId = json.primitiveId || "";
|
|
708
|
+
const finalResult = json.finalResult;
|
|
709
|
+
const toolCalls = finalResult?.toolCalls || [];
|
|
710
|
+
const childMessages = [];
|
|
711
|
+
for (const toolCall of toolCalls) {
|
|
712
|
+
if (toolCall.type === "tool-call" && toolCall.payload) {
|
|
713
|
+
const toolCallId = toolCall.payload.toolCallId;
|
|
714
|
+
let toolResult;
|
|
715
|
+
for (const message2 of finalResult?.messages || []) {
|
|
716
|
+
for (const part of message2.content || []) {
|
|
717
|
+
if (typeof part === "object" && part.type === "tool-result" && part.toolCallId === toolCallId) {
|
|
718
|
+
toolResult = part;
|
|
719
|
+
break;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
const isWorkflow = Boolean(toolResult?.result?.result?.steps);
|
|
724
|
+
childMessages.push({
|
|
725
|
+
type: "tool",
|
|
726
|
+
toolCallId: toolCall.payload.toolCallId,
|
|
727
|
+
toolName: toolCall.payload.toolName,
|
|
728
|
+
args: toolCall.payload.args,
|
|
729
|
+
toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
if (finalResult && finalResult.text) {
|
|
734
|
+
childMessages.push({
|
|
735
|
+
type: "text",
|
|
736
|
+
content: finalResult.text
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
const result = {
|
|
740
|
+
childMessages,
|
|
741
|
+
result: finalResult?.text || ""
|
|
742
|
+
};
|
|
743
|
+
console.log("json", json);
|
|
744
|
+
const nextMessage = {
|
|
745
|
+
role: "assistant",
|
|
746
|
+
parts: [
|
|
747
|
+
{
|
|
748
|
+
type: "dynamic-tool",
|
|
749
|
+
toolCallId: primitiveId,
|
|
750
|
+
toolName: primitiveId,
|
|
751
|
+
state: "output-available",
|
|
752
|
+
input: json.input,
|
|
753
|
+
output: result
|
|
754
|
+
}
|
|
755
|
+
],
|
|
756
|
+
id: message.id,
|
|
757
|
+
metadata: {
|
|
758
|
+
...message.metadata,
|
|
759
|
+
mode: "network",
|
|
760
|
+
selectionReason,
|
|
761
|
+
agentInput: json.input,
|
|
762
|
+
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
return nextMessage;
|
|
766
|
+
}
|
|
767
|
+
} catch (error) {
|
|
768
|
+
return message;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
return message;
|
|
772
|
+
});
|
|
773
|
+
};
|
|
774
|
+
const resolveToChildMessages = (messages) => {
|
|
775
|
+
const assistantMessage = messages.find((message) => message.role === "assistant");
|
|
776
|
+
if (!assistantMessage) return [];
|
|
777
|
+
const parts = assistantMessage.parts;
|
|
778
|
+
let childMessages = [];
|
|
779
|
+
for (const part of parts) {
|
|
780
|
+
const toolPart = part;
|
|
781
|
+
if (part.type.startsWith("tool-")) {
|
|
782
|
+
const toolName = part.type.substring("tool-".length);
|
|
783
|
+
const isWorkflow = toolName.startsWith("workflow-");
|
|
784
|
+
childMessages.push({
|
|
785
|
+
type: "tool",
|
|
786
|
+
toolCallId: toolPart.toolCallId,
|
|
787
|
+
toolName,
|
|
788
|
+
args: toolPart.input,
|
|
789
|
+
toolOutput: isWorkflow ? { ...toolPart.output?.result, runId: toolPart.output?.runId } : toolPart.output
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
if (part.type === "text") {
|
|
793
|
+
childMessages.push({
|
|
794
|
+
type: "text",
|
|
795
|
+
content: toolPart.text
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return childMessages;
|
|
800
|
+
};
|
|
801
|
+
|
|
554
802
|
class AISdkNetworkTransformer {
|
|
555
803
|
transform({ chunk, conversation, metadata }) {
|
|
556
804
|
const newConversation = [...conversation];
|
|
805
|
+
if (chunk.type === "routing-agent-text-delta") {
|
|
806
|
+
return this.handleRoutingAgentConversation(chunk, newConversation);
|
|
807
|
+
}
|
|
557
808
|
if (chunk.type.startsWith("agent-execution-")) {
|
|
558
809
|
return this.handleAgentConversation(chunk, newConversation, metadata);
|
|
559
810
|
}
|
|
@@ -564,22 +815,80 @@ class AISdkNetworkTransformer {
|
|
|
564
815
|
return this.handleToolConversation(chunk, newConversation, metadata);
|
|
565
816
|
}
|
|
566
817
|
if (chunk.type === "network-execution-event-step-finish") {
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
818
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
819
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
820
|
+
const agentChunk = chunk.payload;
|
|
821
|
+
const parts = [...lastMessage.parts];
|
|
822
|
+
const textPartIndex = parts.findIndex((part) => part.type === "text");
|
|
823
|
+
if (textPartIndex === -1) {
|
|
824
|
+
parts.push({
|
|
825
|
+
type: "text",
|
|
826
|
+
text: agentChunk.result,
|
|
827
|
+
state: "done"
|
|
828
|
+
});
|
|
829
|
+
return [
|
|
830
|
+
...newConversation.slice(0, -1),
|
|
571
831
|
{
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
state: "done"
|
|
832
|
+
...lastMessage,
|
|
833
|
+
parts
|
|
575
834
|
}
|
|
576
|
-
]
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
835
|
+
];
|
|
836
|
+
}
|
|
837
|
+
const textPart = parts[textPartIndex];
|
|
838
|
+
if (textPart.type === "text") {
|
|
839
|
+
parts[textPartIndex] = {
|
|
840
|
+
...textPart,
|
|
841
|
+
state: "done"
|
|
842
|
+
};
|
|
843
|
+
return [
|
|
844
|
+
...newConversation.slice(0, -1),
|
|
845
|
+
{
|
|
846
|
+
...lastMessage,
|
|
847
|
+
parts
|
|
848
|
+
}
|
|
849
|
+
];
|
|
850
|
+
}
|
|
851
|
+
return newConversation;
|
|
580
852
|
}
|
|
581
853
|
return newConversation;
|
|
582
854
|
}
|
|
855
|
+
handleRoutingAgentConversation = (chunk, newConversation) => {
|
|
856
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
857
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
858
|
+
const agentChunk = chunk.payload;
|
|
859
|
+
const parts = [...lastMessage.parts];
|
|
860
|
+
const textPartIndex = parts.findIndex((part) => part.type === "text");
|
|
861
|
+
if (textPartIndex === -1) {
|
|
862
|
+
parts.push({
|
|
863
|
+
type: "text",
|
|
864
|
+
text: agentChunk.text,
|
|
865
|
+
state: "streaming"
|
|
866
|
+
});
|
|
867
|
+
return [
|
|
868
|
+
...newConversation.slice(0, -1),
|
|
869
|
+
{
|
|
870
|
+
...lastMessage,
|
|
871
|
+
parts
|
|
872
|
+
}
|
|
873
|
+
];
|
|
874
|
+
}
|
|
875
|
+
const textPart = parts[textPartIndex];
|
|
876
|
+
if (textPart.type === "text") {
|
|
877
|
+
parts[textPartIndex] = {
|
|
878
|
+
...textPart,
|
|
879
|
+
text: textPart.text + agentChunk.text,
|
|
880
|
+
state: "streaming"
|
|
881
|
+
};
|
|
882
|
+
return [
|
|
883
|
+
...newConversation.slice(0, -1),
|
|
884
|
+
{
|
|
885
|
+
...lastMessage,
|
|
886
|
+
parts
|
|
887
|
+
}
|
|
888
|
+
];
|
|
889
|
+
}
|
|
890
|
+
return newConversation;
|
|
891
|
+
};
|
|
583
892
|
handleAgentConversation = (chunk, newConversation, metadata) => {
|
|
584
893
|
if (chunk.type === "agent-execution-start") {
|
|
585
894
|
const primitiveId = chunk.payload?.args?.primitiveId;
|
|
@@ -862,92 +1171,63 @@ class AISdkNetworkTransformer {
|
|
|
862
1171
|
};
|
|
863
1172
|
}
|
|
864
1173
|
|
|
865
|
-
const
|
|
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
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
if (finalResult && finalResult.text) {
|
|
901
|
-
childMessages.push({
|
|
902
|
-
type: "text",
|
|
903
|
-
content: finalResult.text
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
const result = {
|
|
907
|
-
childMessages,
|
|
908
|
-
result: finalResult?.text || ""
|
|
909
|
-
};
|
|
910
|
-
console.log("json", json);
|
|
911
|
-
const nextMessage = {
|
|
912
|
-
role: "assistant",
|
|
913
|
-
parts: [
|
|
914
|
-
{
|
|
915
|
-
type: "dynamic-tool",
|
|
916
|
-
toolCallId: primitiveId,
|
|
917
|
-
toolName: primitiveId,
|
|
918
|
-
state: "output-available",
|
|
919
|
-
input: json.input,
|
|
920
|
-
output: result
|
|
921
|
-
}
|
|
922
|
-
],
|
|
923
|
-
id: message.id,
|
|
924
|
-
metadata: {
|
|
925
|
-
...message.metadata,
|
|
926
|
-
mode: "network",
|
|
927
|
-
selectionReason,
|
|
928
|
-
agentInput: json.input,
|
|
929
|
-
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
930
|
-
}
|
|
931
|
-
};
|
|
932
|
-
return nextMessage;
|
|
933
|
-
}
|
|
934
|
-
} catch (error) {
|
|
935
|
-
return message;
|
|
1174
|
+
const fromCoreUserMessageToUIMessage = (coreUserMessage) => {
|
|
1175
|
+
const id = `user-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
1176
|
+
const parts = typeof coreUserMessage.content === "string" ? [
|
|
1177
|
+
{
|
|
1178
|
+
type: "text",
|
|
1179
|
+
text: coreUserMessage.content
|
|
1180
|
+
}
|
|
1181
|
+
] : coreUserMessage.content.map((part) => {
|
|
1182
|
+
switch (part.type) {
|
|
1183
|
+
case "text": {
|
|
1184
|
+
return {
|
|
1185
|
+
type: "text",
|
|
1186
|
+
text: part.text
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
case "image": {
|
|
1190
|
+
const url = typeof part.image === "string" ? part.image : part.image instanceof URL ? part.image.toString() : "";
|
|
1191
|
+
return {
|
|
1192
|
+
type: "file",
|
|
1193
|
+
mediaType: part.mimeType ?? "image/*",
|
|
1194
|
+
url
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
case "file": {
|
|
1198
|
+
const url = typeof part.data === "string" ? part.data : part.data instanceof URL ? part.data.toString() : "";
|
|
1199
|
+
return {
|
|
1200
|
+
type: "file",
|
|
1201
|
+
mediaType: part.mimeType,
|
|
1202
|
+
url,
|
|
1203
|
+
...part.filename !== void 0 ? { filename: part.filename } : {}
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
default: {
|
|
1207
|
+
const exhaustiveCheck = part;
|
|
1208
|
+
throw new Error(`Unhandled content part type: ${exhaustiveCheck.type}`);
|
|
936
1209
|
}
|
|
937
1210
|
}
|
|
938
|
-
return message;
|
|
939
1211
|
});
|
|
1212
|
+
return {
|
|
1213
|
+
id,
|
|
1214
|
+
role: "user",
|
|
1215
|
+
parts
|
|
1216
|
+
};
|
|
940
1217
|
};
|
|
941
1218
|
|
|
942
1219
|
const useChat = ({ agentId, initializeMessages }) => {
|
|
1220
|
+
const _currentRunId = react.useRef(void 0);
|
|
1221
|
+
const _onChunk = react.useRef(void 0);
|
|
943
1222
|
const [messages, setMessages] = react.useState(
|
|
944
1223
|
() => resolveInitialMessages(initializeMessages?.() || [])
|
|
945
1224
|
);
|
|
1225
|
+
const [toolCallApprovals, setToolCallApprovals] = react.useState({});
|
|
946
1226
|
const baseClient = useMastraClient();
|
|
947
1227
|
const [isRunning, setIsRunning] = react.useState(false);
|
|
948
1228
|
const generate = async ({
|
|
949
1229
|
coreUserMessages,
|
|
950
|
-
|
|
1230
|
+
requestContext,
|
|
951
1231
|
threadId,
|
|
952
1232
|
modelSettings,
|
|
953
1233
|
signal,
|
|
@@ -985,7 +1265,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
985
1265
|
topP
|
|
986
1266
|
},
|
|
987
1267
|
instructions,
|
|
988
|
-
|
|
1268
|
+
requestContext,
|
|
989
1269
|
...threadId ? { threadId, resourceId: agentId } : {},
|
|
990
1270
|
providerOptions
|
|
991
1271
|
});
|
|
@@ -1001,7 +1281,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1001
1281
|
setMessages((prev) => [...prev, ...mastraUIMessages]);
|
|
1002
1282
|
}
|
|
1003
1283
|
};
|
|
1004
|
-
const stream = async ({ coreUserMessages,
|
|
1284
|
+
const stream = async ({ coreUserMessages, requestContext, threadId, onChunk, modelSettings, signal }) => {
|
|
1005
1285
|
const {
|
|
1006
1286
|
frequencyPenalty,
|
|
1007
1287
|
presencePenalty,
|
|
@@ -1012,7 +1292,8 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1012
1292
|
topP,
|
|
1013
1293
|
instructions,
|
|
1014
1294
|
providerOptions,
|
|
1015
|
-
maxSteps
|
|
1295
|
+
maxSteps,
|
|
1296
|
+
requireToolApproval
|
|
1016
1297
|
} = modelSettings || {};
|
|
1017
1298
|
setIsRunning(true);
|
|
1018
1299
|
const clientWithAbort = new clientJs.MastraClient({
|
|
@@ -1020,9 +1301,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1020
1301
|
abortSignal: signal
|
|
1021
1302
|
});
|
|
1022
1303
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1304
|
+
const runId = agentId;
|
|
1023
1305
|
const response = await agent.stream({
|
|
1024
1306
|
messages: coreUserMessages,
|
|
1025
|
-
runId
|
|
1307
|
+
runId,
|
|
1026
1308
|
maxSteps,
|
|
1027
1309
|
modelSettings: {
|
|
1028
1310
|
frequencyPenalty,
|
|
@@ -1034,19 +1316,16 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1034
1316
|
topP
|
|
1035
1317
|
},
|
|
1036
1318
|
instructions,
|
|
1037
|
-
|
|
1319
|
+
requestContext,
|
|
1038
1320
|
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1039
|
-
providerOptions
|
|
1321
|
+
providerOptions,
|
|
1322
|
+
requireToolApproval
|
|
1040
1323
|
});
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
throw new Error("[Stream] No response body");
|
|
1044
|
-
}
|
|
1324
|
+
_onChunk.current = onChunk;
|
|
1325
|
+
_currentRunId.current = runId;
|
|
1045
1326
|
await response.processDataStream({
|
|
1046
1327
|
onChunk: async (chunk) => {
|
|
1047
|
-
|
|
1048
|
-
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1049
|
-
});
|
|
1328
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1050
1329
|
onChunk?.(chunk);
|
|
1051
1330
|
}
|
|
1052
1331
|
});
|
|
@@ -1054,7 +1333,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1054
1333
|
};
|
|
1055
1334
|
const network = async ({
|
|
1056
1335
|
coreUserMessages,
|
|
1057
|
-
|
|
1336
|
+
requestContext,
|
|
1058
1337
|
threadId,
|
|
1059
1338
|
onNetworkChunk,
|
|
1060
1339
|
modelSettings,
|
|
@@ -1080,30 +1359,71 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1080
1359
|
topP
|
|
1081
1360
|
},
|
|
1082
1361
|
runId: agentId,
|
|
1083
|
-
|
|
1362
|
+
requestContext,
|
|
1084
1363
|
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
1085
1364
|
});
|
|
1086
1365
|
const transformer = new AISdkNetworkTransformer();
|
|
1087
1366
|
await response.processDataStream({
|
|
1088
1367
|
onChunk: async (chunk) => {
|
|
1089
|
-
|
|
1090
|
-
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1091
|
-
});
|
|
1368
|
+
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1092
1369
|
onNetworkChunk?.(chunk);
|
|
1093
1370
|
}
|
|
1094
1371
|
});
|
|
1095
1372
|
setIsRunning(false);
|
|
1096
1373
|
};
|
|
1374
|
+
const handleCancelRun = () => {
|
|
1375
|
+
setIsRunning(false);
|
|
1376
|
+
_currentRunId.current = void 0;
|
|
1377
|
+
_onChunk.current = void 0;
|
|
1378
|
+
};
|
|
1379
|
+
const approveToolCall = async (toolCallId) => {
|
|
1380
|
+
const onChunk = _onChunk.current;
|
|
1381
|
+
const currentRunId = _currentRunId.current;
|
|
1382
|
+
if (!currentRunId)
|
|
1383
|
+
return console.info("[approveToolCall] approveToolCall can only be called after a stream has started");
|
|
1384
|
+
setIsRunning(true);
|
|
1385
|
+
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "approved" } }));
|
|
1386
|
+
const agent = baseClient.getAgent(agentId);
|
|
1387
|
+
const response = await agent.approveToolCall({ runId: currentRunId, toolCallId });
|
|
1388
|
+
await response.processDataStream({
|
|
1389
|
+
onChunk: async (chunk) => {
|
|
1390
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1391
|
+
onChunk?.(chunk);
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
1394
|
+
setIsRunning(false);
|
|
1395
|
+
};
|
|
1396
|
+
const declineToolCall = async (toolCallId) => {
|
|
1397
|
+
const onChunk = _onChunk.current;
|
|
1398
|
+
const currentRunId = _currentRunId.current;
|
|
1399
|
+
if (!currentRunId)
|
|
1400
|
+
return console.info("[declineToolCall] declineToolCall can only be called after a stream has started");
|
|
1401
|
+
setIsRunning(true);
|
|
1402
|
+
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "declined" } }));
|
|
1403
|
+
const agent = baseClient.getAgent(agentId);
|
|
1404
|
+
const response = await agent.declineToolCall({ runId: currentRunId, toolCallId });
|
|
1405
|
+
await response.processDataStream({
|
|
1406
|
+
onChunk: async (chunk) => {
|
|
1407
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1408
|
+
onChunk?.(chunk);
|
|
1409
|
+
}
|
|
1410
|
+
});
|
|
1411
|
+
setIsRunning(false);
|
|
1412
|
+
};
|
|
1097
1413
|
const sendMessage = async ({ mode = "stream", ...args }) => {
|
|
1098
1414
|
const nextMessage = { role: "user", content: [{ type: "text", text: args.message }] };
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1415
|
+
const coreUserMessages = [nextMessage];
|
|
1416
|
+
if (args.coreUserMessages) {
|
|
1417
|
+
coreUserMessages.push(...args.coreUserMessages);
|
|
1418
|
+
}
|
|
1419
|
+
const uiMessages = coreUserMessages.map(fromCoreUserMessageToUIMessage);
|
|
1420
|
+
setMessages((s) => [...s, ...uiMessages]);
|
|
1101
1421
|
if (mode === "generate") {
|
|
1102
|
-
await generate({ ...args, coreUserMessages
|
|
1422
|
+
await generate({ ...args, coreUserMessages });
|
|
1103
1423
|
} else if (mode === "stream") {
|
|
1104
|
-
await stream({ ...args, coreUserMessages
|
|
1424
|
+
await stream({ ...args, coreUserMessages });
|
|
1105
1425
|
} else if (mode === "network") {
|
|
1106
|
-
await network({ ...args, coreUserMessages
|
|
1426
|
+
await network({ ...args, coreUserMessages });
|
|
1107
1427
|
}
|
|
1108
1428
|
};
|
|
1109
1429
|
return {
|
|
@@ -1111,7 +1431,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1111
1431
|
sendMessage,
|
|
1112
1432
|
isRunning,
|
|
1113
1433
|
messages,
|
|
1114
|
-
|
|
1434
|
+
approveToolCall,
|
|
1435
|
+
declineToolCall,
|
|
1436
|
+
cancelRun: handleCancelRun,
|
|
1437
|
+
toolCallApprovals
|
|
1115
1438
|
};
|
|
1116
1439
|
};
|
|
1117
1440
|
|
|
@@ -1485,6 +1808,7 @@ exports.TooltipContentClass = TooltipContentClass;
|
|
|
1485
1808
|
exports.TooltipTrigger = TooltipTrigger;
|
|
1486
1809
|
exports.WorkflowIcon = WorkflowIcon;
|
|
1487
1810
|
exports.mapWorkflowStreamChunkToWatchResult = mapWorkflowStreamChunkToWatchResult;
|
|
1811
|
+
exports.resolveToChildMessages = resolveToChildMessages;
|
|
1488
1812
|
exports.toAssistantUIMessage = toAssistantUIMessage;
|
|
1489
1813
|
exports.toUIMessage = toUIMessage;
|
|
1490
1814
|
exports.useChat = useChat;
|