@mastra/react 0.0.0-monorepo-binary-20251013210052 → 0.0.0-new-button-export-20251219130424
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 +417 -2
- package/dist/index.cjs +630 -154
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +631 -156
- package/dist/index.js.map +1 -1
- package/dist/react.css +1 -1
- package/dist/src/agent/hooks.d.ts +13 -3
- 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 +39 -1
- 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 +23 -14
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 {
|
|
4
|
+
import { v4 } from '@lukeed/uuid';
|
|
5
5
|
import { ChevronDownIcon, CheckIcon, CopyIcon } from 'lucide-react';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
|
|
@@ -47,7 +47,7 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
|
|
|
47
47
|
return {
|
|
48
48
|
...prev,
|
|
49
49
|
status: chunk.payload.workflowStatus,
|
|
50
|
-
...finalStatus === "success" && lastStep?.status === "success" ? { result: lastStep?.output } : finalStatus === "failed" && lastStep?.status === "failed" ? { error: lastStep?.error } : {}
|
|
50
|
+
...finalStatus === "success" && lastStep?.status === "success" ? { result: lastStep?.output } : finalStatus === "failed" && lastStep?.status === "failed" ? { error: lastStep?.error } : finalStatus === "tripwire" && chunk.payload.tripwire ? { tripwire: chunk.payload.tripwire } : {}
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
const { stepCallId, stepName, ...newPayload } = chunk.payload ?? {};
|
|
@@ -99,6 +99,34 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
|
|
|
99
99
|
};
|
|
100
100
|
const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
101
101
|
const result = [...conversation];
|
|
102
|
+
if (chunk.type.startsWith("data-")) {
|
|
103
|
+
const lastMessage = result[result.length - 1];
|
|
104
|
+
if (!lastMessage || lastMessage.role !== "assistant") {
|
|
105
|
+
const newMessage = {
|
|
106
|
+
id: `data-${chunk.runId}-${Date.now()}`,
|
|
107
|
+
role: "assistant",
|
|
108
|
+
parts: [
|
|
109
|
+
{
|
|
110
|
+
type: chunk.type,
|
|
111
|
+
data: "data" in chunk ? chunk.data : void 0
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
metadata
|
|
115
|
+
};
|
|
116
|
+
return [...result, newMessage];
|
|
117
|
+
}
|
|
118
|
+
const updatedMessage = {
|
|
119
|
+
...lastMessage,
|
|
120
|
+
parts: [
|
|
121
|
+
...lastMessage.parts,
|
|
122
|
+
{
|
|
123
|
+
type: chunk.type,
|
|
124
|
+
data: "data" in chunk ? chunk.data : void 0
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
};
|
|
128
|
+
return [...result.slice(0, -1), updatedMessage];
|
|
129
|
+
}
|
|
102
130
|
switch (chunk.type) {
|
|
103
131
|
case "tripwire": {
|
|
104
132
|
const newMessage = {
|
|
@@ -107,19 +135,24 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
107
135
|
parts: [
|
|
108
136
|
{
|
|
109
137
|
type: "text",
|
|
110
|
-
text: chunk.payload.
|
|
138
|
+
text: chunk.payload.reason
|
|
111
139
|
}
|
|
112
140
|
],
|
|
113
141
|
metadata: {
|
|
114
142
|
...metadata,
|
|
115
|
-
status: "
|
|
143
|
+
status: "tripwire",
|
|
144
|
+
tripwire: {
|
|
145
|
+
retry: chunk.payload.retry,
|
|
146
|
+
tripwirePayload: chunk.payload.metadata,
|
|
147
|
+
processorId: chunk.payload.processorId
|
|
148
|
+
}
|
|
116
149
|
}
|
|
117
150
|
};
|
|
118
151
|
return [...result, newMessage];
|
|
119
152
|
}
|
|
120
153
|
case "start": {
|
|
121
154
|
const newMessage = {
|
|
122
|
-
id: `start-${chunk.runId + Date.now()}`,
|
|
155
|
+
id: typeof chunk.payload.messageId === "string" ? chunk.payload.messageId : `start-${chunk.runId + Date.now()}`,
|
|
123
156
|
role: "assistant",
|
|
124
157
|
parts: [],
|
|
125
158
|
metadata
|
|
@@ -250,35 +283,48 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
250
283
|
}
|
|
251
284
|
];
|
|
252
285
|
}
|
|
286
|
+
case "tool-error":
|
|
253
287
|
case "tool-result": {
|
|
254
288
|
const lastMessage = result[result.length - 1];
|
|
255
289
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
256
290
|
const parts = [...lastMessage.parts];
|
|
257
291
|
const toolPartIndex = parts.findIndex(
|
|
258
|
-
(part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
292
|
+
(part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
259
293
|
);
|
|
260
294
|
if (toolPartIndex !== -1) {
|
|
261
295
|
const toolPart = parts[toolPartIndex];
|
|
262
|
-
if (toolPart.type === "dynamic-tool") {
|
|
263
|
-
|
|
296
|
+
if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
|
|
297
|
+
const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
|
|
298
|
+
const toolCallId = toolPart.toolCallId;
|
|
299
|
+
if (chunk.type === "tool-result" && chunk.payload.isError || chunk.type === "tool-error") {
|
|
300
|
+
const error = chunk.type === "tool-error" ? chunk.payload.error : chunk.payload.result;
|
|
264
301
|
parts[toolPartIndex] = {
|
|
265
302
|
type: "dynamic-tool",
|
|
266
|
-
toolName
|
|
267
|
-
toolCallId
|
|
303
|
+
toolName,
|
|
304
|
+
toolCallId,
|
|
268
305
|
state: "output-error",
|
|
269
306
|
input: toolPart.input,
|
|
270
|
-
errorText: String(
|
|
307
|
+
errorText: String(error),
|
|
271
308
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
272
309
|
};
|
|
273
310
|
} else {
|
|
274
311
|
const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
|
|
312
|
+
const isAgent = chunk?.from === "AGENT";
|
|
313
|
+
let output;
|
|
314
|
+
if (isWorkflow) {
|
|
315
|
+
output = chunk.payload.result?.result;
|
|
316
|
+
} else if (isAgent) {
|
|
317
|
+
output = parts[toolPartIndex].output ?? chunk.payload.result;
|
|
318
|
+
} else {
|
|
319
|
+
output = chunk.payload.result;
|
|
320
|
+
}
|
|
275
321
|
parts[toolPartIndex] = {
|
|
276
322
|
type: "dynamic-tool",
|
|
277
|
-
toolName
|
|
278
|
-
toolCallId
|
|
323
|
+
toolName,
|
|
324
|
+
toolCallId,
|
|
279
325
|
state: "output-available",
|
|
280
326
|
input: toolPart.input,
|
|
281
|
-
output
|
|
327
|
+
output,
|
|
282
328
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
283
329
|
};
|
|
284
330
|
}
|
|
@@ -297,11 +343,14 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
297
343
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
298
344
|
const parts = [...lastMessage.parts];
|
|
299
345
|
const toolPartIndex = parts.findIndex(
|
|
300
|
-
(part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
346
|
+
(part) => (part.type === "dynamic-tool" || typeof part.type === "string" && part.type.startsWith("tool-")) && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
301
347
|
);
|
|
302
348
|
if (toolPartIndex !== -1) {
|
|
303
349
|
const toolPart = parts[toolPartIndex];
|
|
304
|
-
if (toolPart.type === "dynamic-tool") {
|
|
350
|
+
if (toolPart.type === "dynamic-tool" || typeof toolPart.type === "string" && toolPart.type.startsWith("tool-")) {
|
|
351
|
+
const toolName = "toolName" in toolPart && typeof toolPart.toolName === "string" ? toolPart.toolName : typeof toolPart.type === "string" && toolPart.type.startsWith("tool-") ? toolPart.type.substring(5) : "";
|
|
352
|
+
const toolCallId = toolPart.toolCallId;
|
|
353
|
+
const input = toolPart.input;
|
|
305
354
|
if (chunk.payload.output?.type?.startsWith("workflow-")) {
|
|
306
355
|
const existingWorkflowState = toolPart.output || {};
|
|
307
356
|
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
|
|
@@ -309,14 +358,24 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
309
358
|
chunk.payload.output
|
|
310
359
|
);
|
|
311
360
|
parts[toolPartIndex] = {
|
|
312
|
-
|
|
361
|
+
type: "dynamic-tool",
|
|
362
|
+
toolName,
|
|
363
|
+
toolCallId,
|
|
364
|
+
state: "input-streaming",
|
|
365
|
+
input,
|
|
313
366
|
output: updatedWorkflowState
|
|
314
367
|
};
|
|
368
|
+
} else if (chunk.payload.output?.from === "AGENT" || chunk.payload.output?.from === "USER" && chunk.payload.output?.payload?.output?.type?.startsWith("workflow-")) {
|
|
369
|
+
return toUIMessageFromAgent(chunk.payload.output, conversation);
|
|
315
370
|
} else {
|
|
316
371
|
const currentOutput = toolPart.output || [];
|
|
317
372
|
const existingOutput = Array.isArray(currentOutput) ? currentOutput : [];
|
|
318
373
|
parts[toolPartIndex] = {
|
|
319
|
-
|
|
374
|
+
type: "dynamic-tool",
|
|
375
|
+
toolName,
|
|
376
|
+
toolCallId,
|
|
377
|
+
state: "input-streaming",
|
|
378
|
+
input,
|
|
320
379
|
output: [...existingOutput, chunk.payload.output]
|
|
321
380
|
};
|
|
322
381
|
}
|
|
@@ -385,15 +444,61 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
385
444
|
}
|
|
386
445
|
];
|
|
387
446
|
}
|
|
447
|
+
case "tool-call-approval": {
|
|
448
|
+
const lastMessage = result[result.length - 1];
|
|
449
|
+
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
450
|
+
const lastRequireApprovalMetadata = lastMessage.metadata?.mode === "stream" ? lastMessage.metadata?.requireApprovalMetadata : {};
|
|
451
|
+
return [
|
|
452
|
+
...result.slice(0, -1),
|
|
453
|
+
{
|
|
454
|
+
...lastMessage,
|
|
455
|
+
metadata: {
|
|
456
|
+
...lastMessage.metadata,
|
|
457
|
+
mode: "stream",
|
|
458
|
+
requireApprovalMetadata: {
|
|
459
|
+
...lastRequireApprovalMetadata,
|
|
460
|
+
[chunk.payload.toolName]: {
|
|
461
|
+
toolCallId: chunk.payload.toolCallId,
|
|
462
|
+
toolName: chunk.payload.toolName,
|
|
463
|
+
args: chunk.payload.args
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
];
|
|
469
|
+
}
|
|
470
|
+
case "tool-call-suspended": {
|
|
471
|
+
const lastMessage = result[result.length - 1];
|
|
472
|
+
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
473
|
+
const lastSuspendedTools = lastMessage.metadata?.mode === "stream" ? lastMessage.metadata?.suspendedTools : {};
|
|
474
|
+
return [
|
|
475
|
+
...result.slice(0, -1),
|
|
476
|
+
{
|
|
477
|
+
...lastMessage,
|
|
478
|
+
metadata: {
|
|
479
|
+
...lastMessage.metadata,
|
|
480
|
+
mode: "stream",
|
|
481
|
+
suspendedTools: {
|
|
482
|
+
...lastSuspendedTools,
|
|
483
|
+
[chunk.payload.toolName]: {
|
|
484
|
+
toolCallId: chunk.payload.toolCallId,
|
|
485
|
+
toolName: chunk.payload.toolName,
|
|
486
|
+
args: chunk.payload.args,
|
|
487
|
+
suspendPayload: chunk.payload.suspendPayload
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
];
|
|
493
|
+
}
|
|
388
494
|
case "finish": {
|
|
389
495
|
const lastMessage = result[result.length - 1];
|
|
390
496
|
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
391
497
|
const parts = lastMessage.parts.map((part) => {
|
|
392
|
-
if (part
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return { ...part, state: "done" };
|
|
498
|
+
if (typeof part === "object" && part !== null && "type" in part && "state" in part && part.state === "streaming") {
|
|
499
|
+
if (part.type === "text" || part.type === "reasoning") {
|
|
500
|
+
return { ...part, state: "done" };
|
|
501
|
+
}
|
|
397
502
|
}
|
|
398
503
|
return part;
|
|
399
504
|
});
|
|
@@ -427,6 +532,105 @@ const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
|
427
532
|
return result;
|
|
428
533
|
}
|
|
429
534
|
};
|
|
535
|
+
const toUIMessageFromAgent = (chunk, conversation, metadata) => {
|
|
536
|
+
const lastMessage = conversation[conversation.length - 1];
|
|
537
|
+
if (!lastMessage || lastMessage.role !== "assistant") return conversation;
|
|
538
|
+
const parts = [...lastMessage.parts];
|
|
539
|
+
if (chunk.type === "text-delta") {
|
|
540
|
+
const agentChunk = chunk.payload;
|
|
541
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
542
|
+
if (toolPartIndex === -1) return conversation;
|
|
543
|
+
const toolPart = parts[toolPartIndex];
|
|
544
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
545
|
+
const lastChildMessage = childMessages[childMessages.length - 1];
|
|
546
|
+
const textMessage = { type: "text", content: (lastChildMessage?.content || "") + agentChunk.text };
|
|
547
|
+
const nextMessages = lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
|
|
548
|
+
parts[toolPartIndex] = {
|
|
549
|
+
...toolPart,
|
|
550
|
+
output: {
|
|
551
|
+
childMessages: nextMessages
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
} else if (chunk.type === "tool-call") {
|
|
555
|
+
const agentChunk = chunk.payload;
|
|
556
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
557
|
+
if (toolPartIndex === -1) return conversation;
|
|
558
|
+
const toolPart = parts[toolPartIndex];
|
|
559
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
560
|
+
parts[toolPartIndex] = {
|
|
561
|
+
...toolPart,
|
|
562
|
+
output: {
|
|
563
|
+
...toolPart?.output,
|
|
564
|
+
childMessages: [
|
|
565
|
+
...childMessages,
|
|
566
|
+
{
|
|
567
|
+
type: "tool",
|
|
568
|
+
toolCallId: agentChunk.toolCallId,
|
|
569
|
+
toolName: agentChunk.toolName,
|
|
570
|
+
args: agentChunk.args
|
|
571
|
+
}
|
|
572
|
+
]
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
} else if (chunk.type === "tool-output") {
|
|
576
|
+
const agentChunk = chunk.payload;
|
|
577
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
578
|
+
if (toolPartIndex === -1) return conversation;
|
|
579
|
+
const toolPart = parts[toolPartIndex];
|
|
580
|
+
if (agentChunk?.output?.type?.startsWith("workflow-")) {
|
|
581
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
582
|
+
const lastToolIndex = childMessages.length - 1;
|
|
583
|
+
const currentMessage = childMessages[lastToolIndex];
|
|
584
|
+
const actualExistingWorkflowState = currentMessage?.toolOutput || {};
|
|
585
|
+
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(actualExistingWorkflowState, agentChunk.output);
|
|
586
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
587
|
+
parts[toolPartIndex] = {
|
|
588
|
+
...toolPart,
|
|
589
|
+
output: {
|
|
590
|
+
...toolPart?.output,
|
|
591
|
+
childMessages: [
|
|
592
|
+
...childMessages.slice(0, -1),
|
|
593
|
+
{
|
|
594
|
+
...currentMessage,
|
|
595
|
+
toolOutput: { ...updatedWorkflowState, runId: agentChunk.output.runId }
|
|
596
|
+
}
|
|
597
|
+
]
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
} else if (chunk.type === "tool-result") {
|
|
603
|
+
const agentChunk = chunk.payload;
|
|
604
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
605
|
+
if (toolPartIndex === -1) return conversation;
|
|
606
|
+
const toolPart = parts[toolPartIndex];
|
|
607
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
608
|
+
const lastToolIndex = childMessages.length - 1;
|
|
609
|
+
const isWorkflow = agentChunk?.toolName?.startsWith("workflow-");
|
|
610
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
611
|
+
parts[toolPartIndex] = {
|
|
612
|
+
...toolPart,
|
|
613
|
+
output: {
|
|
614
|
+
...toolPart?.output,
|
|
615
|
+
childMessages: [
|
|
616
|
+
...childMessages.slice(0, -1),
|
|
617
|
+
{
|
|
618
|
+
...childMessages[lastToolIndex],
|
|
619
|
+
toolOutput: isWorkflow ? { ...agentChunk.result?.result, runId: agentChunk.result?.runId } : agentChunk.result
|
|
620
|
+
}
|
|
621
|
+
]
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return [
|
|
627
|
+
...conversation.slice(0, -1),
|
|
628
|
+
{
|
|
629
|
+
...lastMessage,
|
|
630
|
+
parts
|
|
631
|
+
}
|
|
632
|
+
];
|
|
633
|
+
};
|
|
430
634
|
|
|
431
635
|
const toAssistantUIMessage = (message) => {
|
|
432
636
|
const extendedMessage = message;
|
|
@@ -466,13 +670,23 @@ const toAssistantUIMessage = (message) => {
|
|
|
466
670
|
};
|
|
467
671
|
}
|
|
468
672
|
if (part.type === "file") {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
673
|
+
const type = part.mediaType.includes("image/") ? "image" : "file";
|
|
674
|
+
if (type === "file") {
|
|
675
|
+
return {
|
|
676
|
+
type,
|
|
677
|
+
mimeType: part.mediaType,
|
|
678
|
+
data: part.url,
|
|
679
|
+
// Use URL as data source
|
|
680
|
+
metadata: message.metadata
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
if (type === "image") {
|
|
684
|
+
return {
|
|
685
|
+
type,
|
|
686
|
+
image: part.url,
|
|
687
|
+
metadata: message.metadata
|
|
688
|
+
};
|
|
689
|
+
}
|
|
476
690
|
}
|
|
477
691
|
if (part.type === "dynamic-tool") {
|
|
478
692
|
const baseToolCall = {
|
|
@@ -492,13 +706,14 @@ const toAssistantUIMessage = (message) => {
|
|
|
492
706
|
return baseToolCall;
|
|
493
707
|
}
|
|
494
708
|
if (part.type.startsWith("tool-") && part.state !== "input-available") {
|
|
495
|
-
const
|
|
709
|
+
const toolName2 = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.substring(5);
|
|
710
|
+
const { suspendedToolRunId, ...cleanInput } = "input" in part ? part.input : {};
|
|
496
711
|
const baseToolCall = {
|
|
497
712
|
type: "tool-call",
|
|
498
713
|
toolCallId: "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : "",
|
|
499
|
-
toolName,
|
|
500
|
-
argsText:
|
|
501
|
-
args:
|
|
714
|
+
toolName: toolName2,
|
|
715
|
+
argsText: JSON.stringify(cleanInput ?? {}),
|
|
716
|
+
args: cleanInput ?? {},
|
|
502
717
|
metadata: message.metadata
|
|
503
718
|
};
|
|
504
719
|
if ("output" in part) {
|
|
@@ -508,6 +723,31 @@ const toAssistantUIMessage = (message) => {
|
|
|
508
723
|
}
|
|
509
724
|
return baseToolCall;
|
|
510
725
|
}
|
|
726
|
+
const toolName = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.startsWith("tool-") ? part.type.substring(5) : "";
|
|
727
|
+
const requireApprovalMetadata = extendedMessage.metadata?.requireApprovalMetadata;
|
|
728
|
+
const suspendedTools = extendedMessage.metadata?.suspendedTools;
|
|
729
|
+
const partToolCallId = "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : void 0;
|
|
730
|
+
const suspensionData = toolName ? requireApprovalMetadata?.[toolName] ?? suspendedTools?.[toolName] : void 0;
|
|
731
|
+
if (suspensionData) {
|
|
732
|
+
const { suspendedToolRunId, ...cleanInput } = "input" in part ? part.input : {};
|
|
733
|
+
return {
|
|
734
|
+
type: "tool-call",
|
|
735
|
+
toolCallId: partToolCallId,
|
|
736
|
+
toolName,
|
|
737
|
+
argsText: JSON.stringify(cleanInput ?? {}),
|
|
738
|
+
args: cleanInput,
|
|
739
|
+
metadata: extendedMessage.metadata
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
if (part.type.startsWith("data-")) {
|
|
743
|
+
return {
|
|
744
|
+
type: "data",
|
|
745
|
+
name: part.type.substring(5),
|
|
746
|
+
// Extract name from 'data-{name}'
|
|
747
|
+
data: part.data,
|
|
748
|
+
metadata: message.metadata
|
|
749
|
+
};
|
|
750
|
+
}
|
|
511
751
|
return {
|
|
512
752
|
type: "text",
|
|
513
753
|
text: "",
|
|
@@ -547,9 +787,146 @@ const toAssistantUIMessage = (message) => {
|
|
|
547
787
|
return threadMessage;
|
|
548
788
|
};
|
|
549
789
|
|
|
790
|
+
const resolveInitialMessages = (messages) => {
|
|
791
|
+
return messages.map((message) => {
|
|
792
|
+
const networkPart = message.parts.find(
|
|
793
|
+
(part) => typeof part === "object" && part !== null && "type" in part && part.type === "text" && "text" in part && typeof part.text === "string" && part.text.includes('"isNetwork":true')
|
|
794
|
+
);
|
|
795
|
+
if (networkPart && networkPart.type === "text") {
|
|
796
|
+
try {
|
|
797
|
+
const json = JSON.parse(networkPart.text);
|
|
798
|
+
if (json.isNetwork === true) {
|
|
799
|
+
const selectionReason = json.selectionReason || "";
|
|
800
|
+
const primitiveType = json.primitiveType || "";
|
|
801
|
+
const primitiveId = json.primitiveId || "";
|
|
802
|
+
const finalResult = json.finalResult;
|
|
803
|
+
const messages2 = finalResult?.messages || [];
|
|
804
|
+
const childMessages = [];
|
|
805
|
+
const toolResultMap = /* @__PURE__ */ new Map();
|
|
806
|
+
for (const msg of messages2) {
|
|
807
|
+
if (Array.isArray(msg.content)) {
|
|
808
|
+
for (const part of msg.content) {
|
|
809
|
+
if (typeof part === "object" && part.type === "tool-result") {
|
|
810
|
+
toolResultMap.set(part.toolCallId, part);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
for (const msg of messages2) {
|
|
816
|
+
if (msg.type === "tool-call" && Array.isArray(msg.content)) {
|
|
817
|
+
for (const part of msg.content) {
|
|
818
|
+
if (typeof part === "object" && part.type === "tool-call") {
|
|
819
|
+
const toolCallContent = part;
|
|
820
|
+
const toolResult = toolResultMap.get(toolCallContent.toolCallId);
|
|
821
|
+
const isWorkflow = Boolean(toolResult?.result?.result?.steps);
|
|
822
|
+
childMessages.push({
|
|
823
|
+
type: "tool",
|
|
824
|
+
toolCallId: toolCallContent.toolCallId,
|
|
825
|
+
toolName: toolCallContent.toolName,
|
|
826
|
+
args: toolCallContent.args,
|
|
827
|
+
toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
if (finalResult && finalResult.text) {
|
|
834
|
+
childMessages.push({
|
|
835
|
+
type: "text",
|
|
836
|
+
content: finalResult.text
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
const result = {
|
|
840
|
+
childMessages,
|
|
841
|
+
result: finalResult?.text || ""
|
|
842
|
+
};
|
|
843
|
+
const nextMessage = {
|
|
844
|
+
role: "assistant",
|
|
845
|
+
parts: [
|
|
846
|
+
{
|
|
847
|
+
type: "dynamic-tool",
|
|
848
|
+
toolCallId: primitiveId,
|
|
849
|
+
toolName: primitiveId,
|
|
850
|
+
state: "output-available",
|
|
851
|
+
input: json.input,
|
|
852
|
+
output: result
|
|
853
|
+
}
|
|
854
|
+
],
|
|
855
|
+
id: message.id,
|
|
856
|
+
metadata: {
|
|
857
|
+
...message.metadata,
|
|
858
|
+
mode: "network",
|
|
859
|
+
selectionReason,
|
|
860
|
+
agentInput: json.input,
|
|
861
|
+
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
return nextMessage;
|
|
865
|
+
}
|
|
866
|
+
} catch (error) {
|
|
867
|
+
return message;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
const extendedMessage = message;
|
|
871
|
+
const pendingToolApprovals = extendedMessage.metadata?.pendingToolApprovals;
|
|
872
|
+
if (pendingToolApprovals && typeof pendingToolApprovals === "object") {
|
|
873
|
+
return {
|
|
874
|
+
...message,
|
|
875
|
+
metadata: {
|
|
876
|
+
...message.metadata,
|
|
877
|
+
mode: "stream",
|
|
878
|
+
requireApprovalMetadata: pendingToolApprovals
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
const suspendedTools = extendedMessage.metadata?.suspendedTools;
|
|
883
|
+
if (suspendedTools && typeof suspendedTools === "object") {
|
|
884
|
+
return {
|
|
885
|
+
...message,
|
|
886
|
+
metadata: {
|
|
887
|
+
...message.metadata,
|
|
888
|
+
mode: "stream",
|
|
889
|
+
suspendedTools
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
return message;
|
|
894
|
+
});
|
|
895
|
+
};
|
|
896
|
+
const resolveToChildMessages = (messages) => {
|
|
897
|
+
const assistantMessage = messages.find((message) => message.role === "assistant");
|
|
898
|
+
if (!assistantMessage) return [];
|
|
899
|
+
const parts = assistantMessage.parts;
|
|
900
|
+
let childMessages = [];
|
|
901
|
+
for (const part of parts) {
|
|
902
|
+
const toolPart = part;
|
|
903
|
+
if (part.type.startsWith("tool-")) {
|
|
904
|
+
const toolName = part.type.substring("tool-".length);
|
|
905
|
+
const isWorkflow = toolName.startsWith("workflow-");
|
|
906
|
+
childMessages.push({
|
|
907
|
+
type: "tool",
|
|
908
|
+
toolCallId: toolPart.toolCallId,
|
|
909
|
+
toolName,
|
|
910
|
+
args: toolPart.input,
|
|
911
|
+
toolOutput: isWorkflow ? { ...toolPart.output?.result, runId: toolPart.output?.runId } : toolPart.output
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
if (part.type === "text") {
|
|
915
|
+
childMessages.push({
|
|
916
|
+
type: "text",
|
|
917
|
+
content: toolPart.text
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return childMessages;
|
|
922
|
+
};
|
|
923
|
+
|
|
550
924
|
class AISdkNetworkTransformer {
|
|
551
925
|
transform({ chunk, conversation, metadata }) {
|
|
552
926
|
const newConversation = [...conversation];
|
|
927
|
+
if (chunk.type === "routing-agent-text-delta") {
|
|
928
|
+
return this.handleRoutingAgentConversation(chunk, newConversation);
|
|
929
|
+
}
|
|
553
930
|
if (chunk.type.startsWith("agent-execution-")) {
|
|
554
931
|
return this.handleAgentConversation(chunk, newConversation, metadata);
|
|
555
932
|
}
|
|
@@ -560,22 +937,80 @@ class AISdkNetworkTransformer {
|
|
|
560
937
|
return this.handleToolConversation(chunk, newConversation, metadata);
|
|
561
938
|
}
|
|
562
939
|
if (chunk.type === "network-execution-event-step-finish") {
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
940
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
941
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
942
|
+
const agentChunk = chunk.payload;
|
|
943
|
+
const parts = [...lastMessage.parts];
|
|
944
|
+
const textPartIndex = parts.findIndex((part) => part.type === "text");
|
|
945
|
+
if (textPartIndex === -1) {
|
|
946
|
+
parts.push({
|
|
947
|
+
type: "text",
|
|
948
|
+
text: agentChunk.result,
|
|
949
|
+
state: "done"
|
|
950
|
+
});
|
|
951
|
+
return [
|
|
952
|
+
...newConversation.slice(0, -1),
|
|
567
953
|
{
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
state: "done"
|
|
954
|
+
...lastMessage,
|
|
955
|
+
parts
|
|
571
956
|
}
|
|
572
|
-
]
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
957
|
+
];
|
|
958
|
+
}
|
|
959
|
+
const textPart = parts[textPartIndex];
|
|
960
|
+
if (textPart.type === "text") {
|
|
961
|
+
parts[textPartIndex] = {
|
|
962
|
+
...textPart,
|
|
963
|
+
state: "done"
|
|
964
|
+
};
|
|
965
|
+
return [
|
|
966
|
+
...newConversation.slice(0, -1),
|
|
967
|
+
{
|
|
968
|
+
...lastMessage,
|
|
969
|
+
parts
|
|
970
|
+
}
|
|
971
|
+
];
|
|
972
|
+
}
|
|
973
|
+
return newConversation;
|
|
576
974
|
}
|
|
577
975
|
return newConversation;
|
|
578
976
|
}
|
|
977
|
+
handleRoutingAgentConversation = (chunk, newConversation) => {
|
|
978
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
979
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
980
|
+
const agentChunk = chunk.payload;
|
|
981
|
+
const parts = [...lastMessage.parts];
|
|
982
|
+
const textPartIndex = parts.findIndex((part) => part.type === "text");
|
|
983
|
+
if (textPartIndex === -1) {
|
|
984
|
+
parts.push({
|
|
985
|
+
type: "text",
|
|
986
|
+
text: agentChunk.text,
|
|
987
|
+
state: "streaming"
|
|
988
|
+
});
|
|
989
|
+
return [
|
|
990
|
+
...newConversation.slice(0, -1),
|
|
991
|
+
{
|
|
992
|
+
...lastMessage,
|
|
993
|
+
parts
|
|
994
|
+
}
|
|
995
|
+
];
|
|
996
|
+
}
|
|
997
|
+
const textPart = parts[textPartIndex];
|
|
998
|
+
if (textPart.type === "text") {
|
|
999
|
+
parts[textPartIndex] = {
|
|
1000
|
+
...textPart,
|
|
1001
|
+
text: textPart.text + agentChunk.text,
|
|
1002
|
+
state: "streaming"
|
|
1003
|
+
};
|
|
1004
|
+
return [
|
|
1005
|
+
...newConversation.slice(0, -1),
|
|
1006
|
+
{
|
|
1007
|
+
...lastMessage,
|
|
1008
|
+
parts
|
|
1009
|
+
}
|
|
1010
|
+
];
|
|
1011
|
+
}
|
|
1012
|
+
return newConversation;
|
|
1013
|
+
};
|
|
579
1014
|
handleAgentConversation = (chunk, newConversation, metadata) => {
|
|
580
1015
|
if (chunk.type === "agent-execution-start") {
|
|
581
1016
|
const primitiveId = chunk.payload?.args?.primitiveId;
|
|
@@ -858,96 +1293,80 @@ class AISdkNetworkTransformer {
|
|
|
858
1293
|
};
|
|
859
1294
|
}
|
|
860
1295
|
|
|
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;
|
|
1296
|
+
const fromCoreUserMessageToUIMessage = (coreUserMessage) => {
|
|
1297
|
+
const id = `user-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
1298
|
+
const parts = typeof coreUserMessage.content === "string" ? [
|
|
1299
|
+
{
|
|
1300
|
+
type: "text",
|
|
1301
|
+
text: coreUserMessage.content
|
|
1302
|
+
}
|
|
1303
|
+
] : coreUserMessage.content.map((part) => {
|
|
1304
|
+
switch (part.type) {
|
|
1305
|
+
case "text": {
|
|
1306
|
+
return {
|
|
1307
|
+
type: "text",
|
|
1308
|
+
text: part.text
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
case "image": {
|
|
1312
|
+
const url = typeof part.image === "string" ? part.image : part.image instanceof URL ? part.image.toString() : "";
|
|
1313
|
+
return {
|
|
1314
|
+
type: "file",
|
|
1315
|
+
mediaType: part.mimeType ?? "image/*",
|
|
1316
|
+
url
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1319
|
+
case "file": {
|
|
1320
|
+
const url = typeof part.data === "string" ? part.data : part.data instanceof URL ? part.data.toString() : "";
|
|
1321
|
+
return {
|
|
1322
|
+
type: "file",
|
|
1323
|
+
mediaType: part.mimeType,
|
|
1324
|
+
url,
|
|
1325
|
+
...part.filename !== void 0 ? { filename: part.filename } : {}
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
default: {
|
|
1329
|
+
const exhaustiveCheck = part;
|
|
1330
|
+
throw new Error(`Unhandled content part type: ${exhaustiveCheck.type}`);
|
|
932
1331
|
}
|
|
933
1332
|
}
|
|
934
|
-
return message;
|
|
935
1333
|
});
|
|
1334
|
+
return {
|
|
1335
|
+
id,
|
|
1336
|
+
role: "user",
|
|
1337
|
+
parts
|
|
1338
|
+
};
|
|
936
1339
|
};
|
|
937
1340
|
|
|
938
|
-
const useChat = ({ agentId, initializeMessages }) => {
|
|
939
|
-
const
|
|
940
|
-
(
|
|
941
|
-
|
|
1341
|
+
const useChat = ({ agentId, resourceId, initializeMessages }) => {
|
|
1342
|
+
const extractRunIdFromMessages = (messages2) => {
|
|
1343
|
+
for (const message of messages2) {
|
|
1344
|
+
const pendingToolApprovals = message.metadata?.pendingToolApprovals;
|
|
1345
|
+
if (pendingToolApprovals && typeof pendingToolApprovals === "object") {
|
|
1346
|
+
const suspensionData = Object.values(pendingToolApprovals)[0];
|
|
1347
|
+
if (suspensionData?.runId) {
|
|
1348
|
+
return suspensionData.runId;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
return void 0;
|
|
1353
|
+
};
|
|
1354
|
+
const initialMessages = initializeMessages?.() || [];
|
|
1355
|
+
const initialRunId = extractRunIdFromMessages(initialMessages);
|
|
1356
|
+
const _currentRunId = useRef(initialRunId);
|
|
1357
|
+
const _onChunk = useRef(void 0);
|
|
1358
|
+
const [messages, setMessages] = useState(() => resolveInitialMessages(initialMessages));
|
|
1359
|
+
const [toolCallApprovals, setToolCallApprovals] = useState({});
|
|
942
1360
|
const baseClient = useMastraClient();
|
|
943
1361
|
const [isRunning, setIsRunning] = useState(false);
|
|
944
1362
|
const generate = async ({
|
|
945
1363
|
coreUserMessages,
|
|
946
|
-
|
|
1364
|
+
requestContext,
|
|
947
1365
|
threadId,
|
|
948
1366
|
modelSettings,
|
|
949
1367
|
signal,
|
|
950
|
-
onFinish
|
|
1368
|
+
onFinish,
|
|
1369
|
+
tracingOptions
|
|
951
1370
|
}) => {
|
|
952
1371
|
const {
|
|
953
1372
|
frequencyPenalty,
|
|
@@ -969,7 +1388,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
969
1388
|
const agent = clientWithAbort.getAgent(agentId);
|
|
970
1389
|
const response = await agent.generate({
|
|
971
1390
|
messages: coreUserMessages,
|
|
972
|
-
runId:
|
|
1391
|
+
runId: v4(),
|
|
973
1392
|
maxSteps,
|
|
974
1393
|
modelSettings: {
|
|
975
1394
|
frequencyPenalty,
|
|
@@ -981,9 +1400,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
981
1400
|
topP
|
|
982
1401
|
},
|
|
983
1402
|
instructions,
|
|
984
|
-
|
|
985
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
986
|
-
providerOptions
|
|
1403
|
+
requestContext,
|
|
1404
|
+
...threadId ? { threadId, resourceId: resourceId || agentId } : {},
|
|
1405
|
+
providerOptions,
|
|
1406
|
+
tracingOptions
|
|
987
1407
|
});
|
|
988
1408
|
setIsRunning(false);
|
|
989
1409
|
if (response && "uiMessages" in response.response && response.response.uiMessages) {
|
|
@@ -997,7 +1417,15 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
997
1417
|
setMessages((prev) => [...prev, ...mastraUIMessages]);
|
|
998
1418
|
}
|
|
999
1419
|
};
|
|
1000
|
-
const stream = async ({
|
|
1420
|
+
const stream = async ({
|
|
1421
|
+
coreUserMessages,
|
|
1422
|
+
requestContext,
|
|
1423
|
+
threadId,
|
|
1424
|
+
onChunk,
|
|
1425
|
+
modelSettings,
|
|
1426
|
+
signal,
|
|
1427
|
+
tracingOptions
|
|
1428
|
+
}) => {
|
|
1001
1429
|
const {
|
|
1002
1430
|
frequencyPenalty,
|
|
1003
1431
|
presencePenalty,
|
|
@@ -1008,7 +1436,8 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1008
1436
|
topP,
|
|
1009
1437
|
instructions,
|
|
1010
1438
|
providerOptions,
|
|
1011
|
-
maxSteps
|
|
1439
|
+
maxSteps,
|
|
1440
|
+
requireToolApproval
|
|
1012
1441
|
} = modelSettings || {};
|
|
1013
1442
|
setIsRunning(true);
|
|
1014
1443
|
const clientWithAbort = new MastraClient({
|
|
@@ -1016,9 +1445,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1016
1445
|
abortSignal: signal
|
|
1017
1446
|
});
|
|
1018
1447
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1448
|
+
const runId = v4();
|
|
1019
1449
|
const response = await agent.stream({
|
|
1020
1450
|
messages: coreUserMessages,
|
|
1021
|
-
runId
|
|
1451
|
+
runId,
|
|
1022
1452
|
maxSteps,
|
|
1023
1453
|
modelSettings: {
|
|
1024
1454
|
frequencyPenalty,
|
|
@@ -1030,19 +1460,17 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1030
1460
|
topP
|
|
1031
1461
|
},
|
|
1032
1462
|
instructions,
|
|
1033
|
-
|
|
1034
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1035
|
-
providerOptions
|
|
1463
|
+
requestContext,
|
|
1464
|
+
...threadId ? { threadId, resourceId: resourceId || agentId } : {},
|
|
1465
|
+
providerOptions,
|
|
1466
|
+
requireToolApproval,
|
|
1467
|
+
tracingOptions
|
|
1036
1468
|
});
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
throw new Error("[Stream] No response body");
|
|
1040
|
-
}
|
|
1469
|
+
_onChunk.current = onChunk;
|
|
1470
|
+
_currentRunId.current = runId;
|
|
1041
1471
|
await response.processDataStream({
|
|
1042
1472
|
onChunk: async (chunk) => {
|
|
1043
|
-
|
|
1044
|
-
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1045
|
-
});
|
|
1473
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1046
1474
|
onChunk?.(chunk);
|
|
1047
1475
|
}
|
|
1048
1476
|
});
|
|
@@ -1050,11 +1478,12 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1050
1478
|
};
|
|
1051
1479
|
const network = async ({
|
|
1052
1480
|
coreUserMessages,
|
|
1053
|
-
|
|
1481
|
+
requestContext,
|
|
1054
1482
|
threadId,
|
|
1055
1483
|
onNetworkChunk,
|
|
1056
1484
|
modelSettings,
|
|
1057
|
-
signal
|
|
1485
|
+
signal,
|
|
1486
|
+
tracingOptions
|
|
1058
1487
|
}) => {
|
|
1059
1488
|
const { frequencyPenalty, presencePenalty, maxRetries, maxTokens, temperature, topK, topP, maxSteps } = modelSettings || {};
|
|
1060
1489
|
setIsRunning(true);
|
|
@@ -1063,6 +1492,7 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1063
1492
|
abortSignal: signal
|
|
1064
1493
|
});
|
|
1065
1494
|
const agent = clientWithAbort.getAgent(agentId);
|
|
1495
|
+
const runId = v4();
|
|
1066
1496
|
const response = await agent.network({
|
|
1067
1497
|
messages: coreUserMessages,
|
|
1068
1498
|
maxSteps,
|
|
@@ -1075,31 +1505,73 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1075
1505
|
topK,
|
|
1076
1506
|
topP
|
|
1077
1507
|
},
|
|
1078
|
-
runId
|
|
1079
|
-
|
|
1080
|
-
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
1508
|
+
runId,
|
|
1509
|
+
requestContext,
|
|
1510
|
+
...threadId ? { thread: threadId, resourceId: resourceId || agentId } : {},
|
|
1511
|
+
tracingOptions
|
|
1081
1512
|
});
|
|
1082
1513
|
const transformer = new AISdkNetworkTransformer();
|
|
1083
1514
|
await response.processDataStream({
|
|
1084
1515
|
onChunk: async (chunk) => {
|
|
1085
|
-
|
|
1086
|
-
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1087
|
-
});
|
|
1516
|
+
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1088
1517
|
onNetworkChunk?.(chunk);
|
|
1089
1518
|
}
|
|
1090
1519
|
});
|
|
1091
1520
|
setIsRunning(false);
|
|
1092
1521
|
};
|
|
1522
|
+
const handleCancelRun = () => {
|
|
1523
|
+
setIsRunning(false);
|
|
1524
|
+
_currentRunId.current = void 0;
|
|
1525
|
+
_onChunk.current = void 0;
|
|
1526
|
+
};
|
|
1527
|
+
const approveToolCall = async (toolCallId) => {
|
|
1528
|
+
const onChunk = _onChunk.current;
|
|
1529
|
+
const currentRunId = _currentRunId.current;
|
|
1530
|
+
if (!currentRunId)
|
|
1531
|
+
return console.info("[approveToolCall] approveToolCall can only be called after a stream has started");
|
|
1532
|
+
setIsRunning(true);
|
|
1533
|
+
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "approved" } }));
|
|
1534
|
+
const agent = baseClient.getAgent(agentId);
|
|
1535
|
+
const response = await agent.approveToolCall({ runId: currentRunId, toolCallId });
|
|
1536
|
+
await response.processDataStream({
|
|
1537
|
+
onChunk: async (chunk) => {
|
|
1538
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1539
|
+
onChunk?.(chunk);
|
|
1540
|
+
}
|
|
1541
|
+
});
|
|
1542
|
+
setIsRunning(false);
|
|
1543
|
+
};
|
|
1544
|
+
const declineToolCall = async (toolCallId) => {
|
|
1545
|
+
const onChunk = _onChunk.current;
|
|
1546
|
+
const currentRunId = _currentRunId.current;
|
|
1547
|
+
if (!currentRunId)
|
|
1548
|
+
return console.info("[declineToolCall] declineToolCall can only be called after a stream has started");
|
|
1549
|
+
setIsRunning(true);
|
|
1550
|
+
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "declined" } }));
|
|
1551
|
+
const agent = baseClient.getAgent(agentId);
|
|
1552
|
+
const response = await agent.declineToolCall({ runId: currentRunId, toolCallId });
|
|
1553
|
+
await response.processDataStream({
|
|
1554
|
+
onChunk: async (chunk) => {
|
|
1555
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1556
|
+
onChunk?.(chunk);
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
setIsRunning(false);
|
|
1560
|
+
};
|
|
1093
1561
|
const sendMessage = async ({ mode = "stream", ...args }) => {
|
|
1094
1562
|
const nextMessage = { role: "user", content: [{ type: "text", text: args.message }] };
|
|
1095
|
-
const
|
|
1096
|
-
|
|
1563
|
+
const coreUserMessages = [nextMessage];
|
|
1564
|
+
if (args.coreUserMessages) {
|
|
1565
|
+
coreUserMessages.push(...args.coreUserMessages);
|
|
1566
|
+
}
|
|
1567
|
+
const uiMessages = coreUserMessages.map(fromCoreUserMessageToUIMessage);
|
|
1568
|
+
setMessages((s) => [...s, ...uiMessages]);
|
|
1097
1569
|
if (mode === "generate") {
|
|
1098
|
-
await generate({ ...args, coreUserMessages
|
|
1570
|
+
await generate({ ...args, coreUserMessages });
|
|
1099
1571
|
} else if (mode === "stream") {
|
|
1100
|
-
await stream({ ...args, coreUserMessages
|
|
1572
|
+
await stream({ ...args, coreUserMessages });
|
|
1101
1573
|
} else if (mode === "network") {
|
|
1102
|
-
await network({ ...args, coreUserMessages
|
|
1574
|
+
await network({ ...args, coreUserMessages });
|
|
1103
1575
|
}
|
|
1104
1576
|
};
|
|
1105
1577
|
return {
|
|
@@ -1107,7 +1579,10 @@ const useChat = ({ agentId, initializeMessages }) => {
|
|
|
1107
1579
|
sendMessage,
|
|
1108
1580
|
isRunning,
|
|
1109
1581
|
messages,
|
|
1110
|
-
|
|
1582
|
+
approveToolCall,
|
|
1583
|
+
declineToolCall,
|
|
1584
|
+
cancelRun: handleCancelRun,
|
|
1585
|
+
toolCallApprovals
|
|
1111
1586
|
};
|
|
1112
1587
|
};
|
|
1113
1588
|
|
|
@@ -1426,5 +1901,5 @@ const MessageStreaming = ({ className, ...props }) => {
|
|
|
1426
1901
|
return /* @__PURE__ */ jsx("span", { className: className || MessageStreamingClass, ...props });
|
|
1427
1902
|
};
|
|
1428
1903
|
|
|
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 };
|
|
1904
|
+
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
1905
|
//# sourceMappingURL=index.js.map
|