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