@mastra/react 0.0.0-fix-runtimeContext-passing-chatRoute-20251008220150 → 0.0.0-unified-sidebar-20251010130811
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 +9 -3
- package/dist/index.cjs.js +617 -455
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +618 -455
- package/dist/index.es.js.map +1 -1
- package/dist/src/agent/hooks.d.ts +15 -17
- package/dist/src/lib/ai-sdk/index.d.ts +3 -3
- package/dist/src/lib/ai-sdk/memory/resolveInitialMessages.d.ts +2 -0
- package/dist/src/lib/ai-sdk/transformers/AISdkNetworkTransformer.d.ts +9 -0
- package/dist/src/lib/ai-sdk/transformers/types.d.ts +10 -0
- package/dist/src/lib/ai-sdk/types.d.ts +14 -0
- package/dist/src/lib/ai-sdk/{toAssistantUIMessage.d.ts → utils/toAssistantUIMessage.d.ts} +1 -1
- package/dist/src/lib/ai-sdk/{toUIMessage.d.ts → utils/toUIMessage.d.ts} +6 -5
- package/dist/src/mastra-client-context.d.ts +1 -0
- package/package.json +3 -3
- package/dist/src/lib/ai-sdk/toNetworkUIMessage.d.ts +0 -6
- package/dist/src/lib/ai-sdk/toNetworkUIMessage.test.d.ts +0 -1
- package/dist/src/lib/ai-sdk/toUIMessage.test.d.ts +0 -1
- /package/dist/src/lib/ai-sdk/{toAssistantUIMessage.test.d.ts → utils/toAssistantUIMessage.test.d.ts} +0 -0
package/dist/index.cjs.js
CHANGED
|
@@ -25,165 +25,6 @@ const MastraReactProvider = ({ children, baseUrl, headers }) => {
|
|
|
25
25
|
return /* @__PURE__ */ jsxRuntime.jsx(MastraClientProvider, { baseUrl, headers, children });
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const useChat = ({ agentId, initializeMessages }) => {
|
|
29
|
-
const [messages, setMessages] = react.useState(initializeMessages || []);
|
|
30
|
-
const baseClient = useMastraClient();
|
|
31
|
-
const [isRunning, setIsRunning] = react.useState(false);
|
|
32
|
-
const generate = async ({
|
|
33
|
-
coreUserMessages,
|
|
34
|
-
runtimeContext,
|
|
35
|
-
threadId,
|
|
36
|
-
modelSettings,
|
|
37
|
-
signal,
|
|
38
|
-
onFinish
|
|
39
|
-
}) => {
|
|
40
|
-
const {
|
|
41
|
-
frequencyPenalty,
|
|
42
|
-
presencePenalty,
|
|
43
|
-
maxRetries,
|
|
44
|
-
maxTokens,
|
|
45
|
-
temperature,
|
|
46
|
-
topK,
|
|
47
|
-
topP,
|
|
48
|
-
instructions,
|
|
49
|
-
providerOptions
|
|
50
|
-
} = modelSettings || {};
|
|
51
|
-
setIsRunning(true);
|
|
52
|
-
const clientWithAbort = new clientJs.MastraClient({
|
|
53
|
-
...baseClient.options,
|
|
54
|
-
abortSignal: signal
|
|
55
|
-
});
|
|
56
|
-
const agent = clientWithAbort.getAgent(agentId);
|
|
57
|
-
const response = await agent.generate({
|
|
58
|
-
messages: coreUserMessages,
|
|
59
|
-
runId: agentId,
|
|
60
|
-
modelSettings: {
|
|
61
|
-
frequencyPenalty,
|
|
62
|
-
presencePenalty,
|
|
63
|
-
maxRetries,
|
|
64
|
-
maxOutputTokens: maxTokens,
|
|
65
|
-
temperature,
|
|
66
|
-
topK,
|
|
67
|
-
topP
|
|
68
|
-
},
|
|
69
|
-
instructions,
|
|
70
|
-
runtimeContext,
|
|
71
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
72
|
-
providerOptions
|
|
73
|
-
});
|
|
74
|
-
setIsRunning(false);
|
|
75
|
-
const uiMessages = response && "uiMessages" in response.response && response.response.uiMessages ? response.response.uiMessages : [];
|
|
76
|
-
const formatted = onFinish({ messages: uiMessages, tripwireReason: response.tripwireReason });
|
|
77
|
-
setMessages((prev) => [...prev, ...formatted]);
|
|
78
|
-
};
|
|
79
|
-
const stream = async ({
|
|
80
|
-
coreUserMessages,
|
|
81
|
-
runtimeContext,
|
|
82
|
-
threadId,
|
|
83
|
-
onChunk,
|
|
84
|
-
modelSettings,
|
|
85
|
-
signal
|
|
86
|
-
}) => {
|
|
87
|
-
const {
|
|
88
|
-
frequencyPenalty,
|
|
89
|
-
presencePenalty,
|
|
90
|
-
maxRetries,
|
|
91
|
-
maxTokens,
|
|
92
|
-
temperature,
|
|
93
|
-
topK,
|
|
94
|
-
topP,
|
|
95
|
-
instructions,
|
|
96
|
-
providerOptions
|
|
97
|
-
} = modelSettings || {};
|
|
98
|
-
setIsRunning(true);
|
|
99
|
-
const clientWithAbort = new clientJs.MastraClient({
|
|
100
|
-
...baseClient.options,
|
|
101
|
-
abortSignal: signal
|
|
102
|
-
});
|
|
103
|
-
const agent = clientWithAbort.getAgent(agentId);
|
|
104
|
-
const response = await agent.stream({
|
|
105
|
-
messages: coreUserMessages,
|
|
106
|
-
runId: agentId,
|
|
107
|
-
modelSettings: {
|
|
108
|
-
frequencyPenalty,
|
|
109
|
-
presencePenalty,
|
|
110
|
-
maxRetries,
|
|
111
|
-
maxOutputTokens: maxTokens,
|
|
112
|
-
temperature,
|
|
113
|
-
topK,
|
|
114
|
-
topP
|
|
115
|
-
},
|
|
116
|
-
instructions,
|
|
117
|
-
runtimeContext,
|
|
118
|
-
...threadId ? { threadId, resourceId: agentId } : {},
|
|
119
|
-
providerOptions
|
|
120
|
-
});
|
|
121
|
-
if (!response.body) {
|
|
122
|
-
setIsRunning(false);
|
|
123
|
-
throw new Error("[Stream] No response body");
|
|
124
|
-
}
|
|
125
|
-
await response.processDataStream({
|
|
126
|
-
onChunk: (chunk) => {
|
|
127
|
-
reactDom.flushSync(() => {
|
|
128
|
-
setMessages((prev) => onChunk(chunk, prev));
|
|
129
|
-
});
|
|
130
|
-
return Promise.resolve();
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
setIsRunning(false);
|
|
134
|
-
};
|
|
135
|
-
const network = async ({
|
|
136
|
-
coreUserMessages,
|
|
137
|
-
runtimeContext,
|
|
138
|
-
threadId,
|
|
139
|
-
onNetworkChunk,
|
|
140
|
-
modelSettings,
|
|
141
|
-
signal
|
|
142
|
-
}) => {
|
|
143
|
-
const { frequencyPenalty, presencePenalty, maxRetries, maxTokens, temperature, topK, topP, maxSteps } = modelSettings || {};
|
|
144
|
-
setIsRunning(true);
|
|
145
|
-
const clientWithAbort = new clientJs.MastraClient({
|
|
146
|
-
...baseClient.options,
|
|
147
|
-
abortSignal: signal
|
|
148
|
-
});
|
|
149
|
-
const agent = clientWithAbort.getAgent(agentId);
|
|
150
|
-
const response = await agent.network({
|
|
151
|
-
messages: coreUserMessages,
|
|
152
|
-
maxSteps,
|
|
153
|
-
modelSettings: {
|
|
154
|
-
frequencyPenalty,
|
|
155
|
-
presencePenalty,
|
|
156
|
-
maxRetries,
|
|
157
|
-
maxOutputTokens: maxTokens,
|
|
158
|
-
temperature,
|
|
159
|
-
topK,
|
|
160
|
-
topP
|
|
161
|
-
},
|
|
162
|
-
runId: agentId,
|
|
163
|
-
runtimeContext,
|
|
164
|
-
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
165
|
-
});
|
|
166
|
-
await response.processDataStream({
|
|
167
|
-
onChunk: (chunk) => {
|
|
168
|
-
reactDom.flushSync(() => {
|
|
169
|
-
setMessages((prev) => onNetworkChunk(chunk, prev));
|
|
170
|
-
});
|
|
171
|
-
return Promise.resolve();
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
setIsRunning(false);
|
|
175
|
-
};
|
|
176
|
-
return {
|
|
177
|
-
network,
|
|
178
|
-
stream,
|
|
179
|
-
generate,
|
|
180
|
-
isRunning,
|
|
181
|
-
messages,
|
|
182
|
-
setMessages,
|
|
183
|
-
cancelRun: () => setIsRunning(false)
|
|
184
|
-
};
|
|
185
|
-
};
|
|
186
|
-
|
|
187
28
|
const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
|
|
188
29
|
if (chunk.type === "workflow-start") {
|
|
189
30
|
return {
|
|
@@ -255,17 +96,32 @@ const mapWorkflowStreamChunkToWatchResult = (prev, chunk) => {
|
|
|
255
96
|
}
|
|
256
97
|
return prev;
|
|
257
98
|
};
|
|
258
|
-
const toUIMessage = ({
|
|
259
|
-
chunk,
|
|
260
|
-
conversation
|
|
261
|
-
}) => {
|
|
99
|
+
const toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
262
100
|
const result = [...conversation];
|
|
263
101
|
switch (chunk.type) {
|
|
102
|
+
case "tripwire": {
|
|
103
|
+
const newMessage = {
|
|
104
|
+
id: `tripwire-${chunk.runId + Date.now()}`,
|
|
105
|
+
role: "assistant",
|
|
106
|
+
parts: [
|
|
107
|
+
{
|
|
108
|
+
type: "text",
|
|
109
|
+
text: chunk.payload.tripwireReason
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
metadata: {
|
|
113
|
+
...metadata,
|
|
114
|
+
status: "warning"
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
return [...result, newMessage];
|
|
118
|
+
}
|
|
264
119
|
case "start": {
|
|
265
120
|
const newMessage = {
|
|
266
|
-
id: chunk.runId
|
|
121
|
+
id: `start-${chunk.runId + Date.now()}`,
|
|
267
122
|
role: "assistant",
|
|
268
|
-
parts: []
|
|
123
|
+
parts: [],
|
|
124
|
+
metadata
|
|
269
125
|
};
|
|
270
126
|
return [...result, newMessage];
|
|
271
127
|
}
|
|
@@ -315,7 +171,7 @@ const toUIMessage = ({
|
|
|
315
171
|
const lastMessage = result[result.length - 1];
|
|
316
172
|
if (!lastMessage || lastMessage.role !== "assistant") {
|
|
317
173
|
const newMessage = {
|
|
318
|
-
id: chunk.runId
|
|
174
|
+
id: `reasoning-${chunk.runId + Date.now()}`,
|
|
319
175
|
role: "assistant",
|
|
320
176
|
parts: [
|
|
321
177
|
{
|
|
@@ -324,7 +180,8 @@ const toUIMessage = ({
|
|
|
324
180
|
state: "streaming",
|
|
325
181
|
providerMetadata: chunk.payload.providerMetadata
|
|
326
182
|
}
|
|
327
|
-
]
|
|
183
|
+
],
|
|
184
|
+
metadata
|
|
328
185
|
};
|
|
329
186
|
return [...result, newMessage];
|
|
330
187
|
}
|
|
@@ -359,7 +216,7 @@ const toUIMessage = ({
|
|
|
359
216
|
const lastMessage = result[result.length - 1];
|
|
360
217
|
if (!lastMessage || lastMessage.role !== "assistant") {
|
|
361
218
|
const newMessage = {
|
|
362
|
-
id: chunk.runId
|
|
219
|
+
id: `tool-call-${chunk.runId + Date.now()}`,
|
|
363
220
|
role: "assistant",
|
|
364
221
|
parts: [
|
|
365
222
|
{
|
|
@@ -370,7 +227,8 @@ const toUIMessage = ({
|
|
|
370
227
|
input: chunk.payload.args,
|
|
371
228
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
372
229
|
}
|
|
373
|
-
]
|
|
230
|
+
],
|
|
231
|
+
metadata
|
|
374
232
|
};
|
|
375
233
|
return [...result, newMessage];
|
|
376
234
|
}
|
|
@@ -412,13 +270,14 @@ const toUIMessage = ({
|
|
|
412
270
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
413
271
|
};
|
|
414
272
|
} else {
|
|
273
|
+
const isWorkflow = Boolean(chunk.payload.result?.result?.steps);
|
|
415
274
|
parts[toolPartIndex] = {
|
|
416
275
|
type: "dynamic-tool",
|
|
417
276
|
toolName: toolPart.toolName,
|
|
418
277
|
toolCallId: toolPart.toolCallId,
|
|
419
278
|
state: "output-available",
|
|
420
279
|
input: toolPart.input,
|
|
421
|
-
output:
|
|
280
|
+
output: isWorkflow ? chunk.payload.result?.result : chunk.payload.result,
|
|
422
281
|
callProviderMetadata: chunk.payload.providerMetadata
|
|
423
282
|
};
|
|
424
283
|
}
|
|
@@ -546,283 +405,26 @@ const toUIMessage = ({
|
|
|
546
405
|
];
|
|
547
406
|
}
|
|
548
407
|
case "error": {
|
|
549
|
-
return result;
|
|
550
|
-
}
|
|
551
|
-
// For all other chunk types, return conversation unchanged
|
|
552
|
-
default:
|
|
553
|
-
return result;
|
|
554
|
-
}
|
|
555
|
-
};
|
|
556
|
-
|
|
557
|
-
const toNetworkUIMessage = ({
|
|
558
|
-
chunk,
|
|
559
|
-
conversation
|
|
560
|
-
}) => {
|
|
561
|
-
const result = [...conversation];
|
|
562
|
-
if (chunk.type === "agent-execution-start" || chunk.type === "workflow-execution-start") {
|
|
563
|
-
const primitiveId = chunk.payload?.args?.primitiveId;
|
|
564
|
-
const runId = chunk.payload.runId;
|
|
565
|
-
if (!primitiveId || !runId) return result;
|
|
566
|
-
const newMessage = {
|
|
567
|
-
id: runId,
|
|
568
|
-
role: "assistant",
|
|
569
|
-
parts: [
|
|
570
|
-
{
|
|
571
|
-
type: "dynamic-tool",
|
|
572
|
-
toolName: primitiveId,
|
|
573
|
-
toolCallId: runId,
|
|
574
|
-
state: "input-available",
|
|
575
|
-
input: chunk.payload.args,
|
|
576
|
-
output: {
|
|
577
|
-
networkMetadata: {
|
|
578
|
-
selectionReason: chunk.payload?.args?.selectionReason || "",
|
|
579
|
-
from: chunk.type === "agent-execution-start" ? "AGENT" : "WORKFLOW"
|
|
580
|
-
},
|
|
581
|
-
result: void 0
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
]
|
|
585
|
-
};
|
|
586
|
-
return [...result, newMessage];
|
|
587
|
-
}
|
|
588
|
-
if (chunk.type.startsWith("agent-execution-event-")) {
|
|
589
|
-
const agentChunk = chunk.payload;
|
|
590
|
-
const lastMessage = result[result.length - 1];
|
|
591
|
-
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
592
|
-
const parts = [...lastMessage.parts];
|
|
593
|
-
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
594
|
-
if (toolPartIndex === -1) return result;
|
|
595
|
-
const toolPart = parts[toolPartIndex];
|
|
596
|
-
if (toolPart.type !== "dynamic-tool") return result;
|
|
597
|
-
if (agentChunk.type === "text-delta") {
|
|
598
|
-
const currentInput = toolPart.input;
|
|
599
|
-
const messages = currentInput?.messages || [];
|
|
600
|
-
const lastMessage2 = messages[messages.length - 1];
|
|
601
|
-
const nextMessages = lastMessage2?.type === "text" ? [
|
|
602
|
-
...messages.slice(0, -1),
|
|
603
|
-
{ type: "text", content: (lastMessage2?.content || "") + agentChunk.payload.text }
|
|
604
|
-
] : [...messages, { type: "text", content: agentChunk.payload.text }];
|
|
605
|
-
parts[toolPartIndex] = {
|
|
606
|
-
...toolPart,
|
|
607
|
-
input: {
|
|
608
|
-
...currentInput,
|
|
609
|
-
messages: nextMessages
|
|
610
|
-
}
|
|
611
|
-
};
|
|
612
|
-
} else if (agentChunk.type === "tool-call") {
|
|
613
|
-
const currentInput = toolPart.input;
|
|
614
|
-
const messages = currentInput?.messages || [];
|
|
615
|
-
parts[toolPartIndex] = {
|
|
616
|
-
...toolPart,
|
|
617
|
-
input: {
|
|
618
|
-
...currentInput,
|
|
619
|
-
messages: [
|
|
620
|
-
...messages,
|
|
621
|
-
{
|
|
622
|
-
type: "tool",
|
|
623
|
-
toolCallId: agentChunk.payload.toolCallId,
|
|
624
|
-
toolName: agentChunk.payload.toolName,
|
|
625
|
-
toolInput: agentChunk.payload.args
|
|
626
|
-
}
|
|
627
|
-
]
|
|
628
|
-
}
|
|
629
|
-
};
|
|
630
|
-
} else if (agentChunk.type === "tool-result") {
|
|
631
|
-
const currentInput = toolPart.input;
|
|
632
|
-
const messages = currentInput?.messages || [];
|
|
633
|
-
const lastToolIndex = messages.length - 1;
|
|
634
|
-
if (lastToolIndex >= 0 && messages[lastToolIndex]?.type === "tool") {
|
|
635
|
-
parts[toolPartIndex] = {
|
|
636
|
-
...toolPart,
|
|
637
|
-
input: {
|
|
638
|
-
...currentInput,
|
|
639
|
-
messages: [
|
|
640
|
-
...messages.slice(0, -1),
|
|
641
|
-
{
|
|
642
|
-
...messages[lastToolIndex],
|
|
643
|
-
toolOutput: agentChunk.payload.result
|
|
644
|
-
}
|
|
645
|
-
]
|
|
646
|
-
}
|
|
647
|
-
};
|
|
648
|
-
}
|
|
649
|
-
} else if (agentChunk.type === "tool-output") {
|
|
650
|
-
if (agentChunk.payload?.output?.type?.startsWith("workflow-")) {
|
|
651
|
-
const currentOutput = toolPart.output || {};
|
|
652
|
-
const existingWorkflowState = currentOutput.result || {};
|
|
653
|
-
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
|
|
654
|
-
existingWorkflowState,
|
|
655
|
-
agentChunk.payload.output
|
|
656
|
-
);
|
|
657
|
-
parts[toolPartIndex] = {
|
|
658
|
-
...toolPart,
|
|
659
|
-
output: {
|
|
660
|
-
networkMetadata: currentOutput.networkMetadata,
|
|
661
|
-
result: updatedWorkflowState
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
return [
|
|
667
|
-
...result.slice(0, -1),
|
|
668
|
-
{
|
|
669
|
-
...lastMessage,
|
|
670
|
-
parts
|
|
671
|
-
}
|
|
672
|
-
];
|
|
673
|
-
}
|
|
674
|
-
if (chunk.type.startsWith("workflow-execution-event-")) {
|
|
675
|
-
const workflowChunk = chunk.payload;
|
|
676
|
-
const lastMessage = result[result.length - 1];
|
|
677
|
-
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
678
|
-
const parts = [...lastMessage.parts];
|
|
679
|
-
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
680
|
-
if (toolPartIndex === -1) return result;
|
|
681
|
-
const toolPart = parts[toolPartIndex];
|
|
682
|
-
if (toolPart.type !== "dynamic-tool") return result;
|
|
683
|
-
const currentOutput = toolPart.output || {};
|
|
684
|
-
const existingWorkflowState = currentOutput.result || {};
|
|
685
|
-
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(existingWorkflowState, workflowChunk);
|
|
686
|
-
parts[toolPartIndex] = {
|
|
687
|
-
...toolPart,
|
|
688
|
-
output: {
|
|
689
|
-
networkMetadata: currentOutput.networkMetadata,
|
|
690
|
-
result: updatedWorkflowState
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
return [
|
|
694
|
-
...result.slice(0, -1),
|
|
695
|
-
{
|
|
696
|
-
...lastMessage,
|
|
697
|
-
parts
|
|
698
|
-
}
|
|
699
|
-
];
|
|
700
|
-
}
|
|
701
|
-
if (chunk.type === "tool-execution-start") {
|
|
702
|
-
const { args: argsData } = chunk.payload;
|
|
703
|
-
const lastMessage = result[result.length - 1];
|
|
704
|
-
const nestedArgs = argsData.args || {};
|
|
705
|
-
if (!lastMessage || lastMessage.role !== "assistant") {
|
|
706
408
|
const newMessage = {
|
|
707
|
-
id: chunk.runId
|
|
409
|
+
id: `error-${chunk.runId + Date.now()}`,
|
|
708
410
|
role: "assistant",
|
|
709
411
|
parts: [
|
|
710
412
|
{
|
|
711
|
-
type: "
|
|
712
|
-
|
|
713
|
-
toolCallId: argsData.toolCallId || "unknown",
|
|
714
|
-
state: "input-available",
|
|
715
|
-
input: nestedArgs,
|
|
716
|
-
output: {
|
|
717
|
-
networkMetadata: {
|
|
718
|
-
selectionReason: argsData.selectionReason || ""
|
|
719
|
-
},
|
|
720
|
-
result: void 0
|
|
721
|
-
}
|
|
413
|
+
type: "text",
|
|
414
|
+
text: chunk.payload.error
|
|
722
415
|
}
|
|
723
|
-
]
|
|
416
|
+
],
|
|
417
|
+
metadata: {
|
|
418
|
+
...metadata,
|
|
419
|
+
status: "error"
|
|
420
|
+
}
|
|
724
421
|
};
|
|
725
422
|
return [...result, newMessage];
|
|
726
423
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
toolName: argsData.toolName || "unknown",
|
|
731
|
-
toolCallId: argsData.toolCallId || "unknown",
|
|
732
|
-
state: "input-available",
|
|
733
|
-
input: nestedArgs,
|
|
734
|
-
output: {
|
|
735
|
-
networkMetadata: {
|
|
736
|
-
selectionReason: argsData.selectionReason || ""
|
|
737
|
-
},
|
|
738
|
-
result: void 0
|
|
739
|
-
}
|
|
740
|
-
});
|
|
741
|
-
return [
|
|
742
|
-
...result.slice(0, -1),
|
|
743
|
-
{
|
|
744
|
-
...lastMessage,
|
|
745
|
-
parts
|
|
746
|
-
}
|
|
747
|
-
];
|
|
748
|
-
}
|
|
749
|
-
if (chunk.type === "tool-execution-end") {
|
|
750
|
-
const lastMessage = result[result.length - 1];
|
|
751
|
-
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
752
|
-
const parts = [...lastMessage.parts];
|
|
753
|
-
const toolPartIndex = parts.findIndex(
|
|
754
|
-
(part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
755
|
-
);
|
|
756
|
-
if (toolPartIndex !== -1) {
|
|
757
|
-
const toolPart = parts[toolPartIndex];
|
|
758
|
-
if (toolPart.type === "dynamic-tool") {
|
|
759
|
-
const currentOutput = toolPart.output;
|
|
760
|
-
parts[toolPartIndex] = {
|
|
761
|
-
type: "dynamic-tool",
|
|
762
|
-
toolName: toolPart.toolName,
|
|
763
|
-
toolCallId: toolPart.toolCallId,
|
|
764
|
-
state: "output-available",
|
|
765
|
-
input: toolPart.input,
|
|
766
|
-
output: {
|
|
767
|
-
networkMetadata: currentOutput?.networkMetadata,
|
|
768
|
-
result: chunk.payload.result
|
|
769
|
-
}
|
|
770
|
-
};
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
return [
|
|
774
|
-
...result.slice(0, -1),
|
|
775
|
-
{
|
|
776
|
-
...lastMessage,
|
|
777
|
-
parts
|
|
778
|
-
}
|
|
779
|
-
];
|
|
780
|
-
}
|
|
781
|
-
if (chunk.type === "agent-execution-end" || chunk.type === "workflow-execution-end") {
|
|
782
|
-
const lastMessage = result[result.length - 1];
|
|
783
|
-
if (!lastMessage || lastMessage.role !== "assistant") return result;
|
|
784
|
-
const parts = [...lastMessage.parts];
|
|
785
|
-
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
786
|
-
if (toolPartIndex !== -1) {
|
|
787
|
-
const toolPart = parts[toolPartIndex];
|
|
788
|
-
if (toolPart.type === "dynamic-tool") {
|
|
789
|
-
const currentOutput = toolPart.output;
|
|
790
|
-
parts[toolPartIndex] = {
|
|
791
|
-
type: "dynamic-tool",
|
|
792
|
-
toolName: toolPart.toolName,
|
|
793
|
-
toolCallId: toolPart.toolCallId,
|
|
794
|
-
state: "output-available",
|
|
795
|
-
input: toolPart.input,
|
|
796
|
-
output: {
|
|
797
|
-
networkMetadata: currentOutput?.networkMetadata,
|
|
798
|
-
result: currentOutput?.result || chunk.payload?.result || ""
|
|
799
|
-
}
|
|
800
|
-
};
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
return [
|
|
804
|
-
...result.slice(0, -1),
|
|
805
|
-
{
|
|
806
|
-
...lastMessage,
|
|
807
|
-
parts
|
|
808
|
-
}
|
|
809
|
-
];
|
|
810
|
-
}
|
|
811
|
-
if (chunk.type === "network-execution-event-step-finish") {
|
|
812
|
-
const newMessage = {
|
|
813
|
-
id: chunk.runId,
|
|
814
|
-
role: "assistant",
|
|
815
|
-
parts: [
|
|
816
|
-
{
|
|
817
|
-
type: "text",
|
|
818
|
-
text: chunk.payload?.result || "",
|
|
819
|
-
state: "done"
|
|
820
|
-
}
|
|
821
|
-
]
|
|
822
|
-
};
|
|
823
|
-
return [...result, newMessage];
|
|
424
|
+
// For all other chunk types, return conversation unchanged
|
|
425
|
+
default:
|
|
426
|
+
return result;
|
|
824
427
|
}
|
|
825
|
-
return result;
|
|
826
428
|
};
|
|
827
429
|
|
|
828
430
|
const toAssistantUIMessage = (message) => {
|
|
@@ -831,13 +433,15 @@ const toAssistantUIMessage = (message) => {
|
|
|
831
433
|
if (part.type === "text") {
|
|
832
434
|
return {
|
|
833
435
|
type: "text",
|
|
834
|
-
text: part.text
|
|
436
|
+
text: part.text,
|
|
437
|
+
metadata: message.metadata
|
|
835
438
|
};
|
|
836
439
|
}
|
|
837
440
|
if (part.type === "reasoning") {
|
|
838
441
|
return {
|
|
839
442
|
type: "reasoning",
|
|
840
|
-
text: part.text
|
|
443
|
+
text: part.text,
|
|
444
|
+
metadata: message.metadata
|
|
841
445
|
};
|
|
842
446
|
}
|
|
843
447
|
if (part.type === "source-url") {
|
|
@@ -846,7 +450,8 @@ const toAssistantUIMessage = (message) => {
|
|
|
846
450
|
sourceType: "url",
|
|
847
451
|
id: part.sourceId,
|
|
848
452
|
url: part.url,
|
|
849
|
-
title: part.title
|
|
453
|
+
title: part.title,
|
|
454
|
+
metadata: message.metadata
|
|
850
455
|
};
|
|
851
456
|
}
|
|
852
457
|
if (part.type === "source-document") {
|
|
@@ -854,16 +459,18 @@ const toAssistantUIMessage = (message) => {
|
|
|
854
459
|
type: "file",
|
|
855
460
|
filename: part.filename,
|
|
856
461
|
mimeType: part.mediaType,
|
|
857
|
-
data: ""
|
|
462
|
+
data: "",
|
|
858
463
|
// Source documents don't have inline data
|
|
464
|
+
metadata: message.metadata
|
|
859
465
|
};
|
|
860
466
|
}
|
|
861
467
|
if (part.type === "file") {
|
|
862
468
|
return {
|
|
863
469
|
type: "file",
|
|
864
470
|
mimeType: part.mediaType,
|
|
865
|
-
data: part.url
|
|
471
|
+
data: part.url,
|
|
866
472
|
// Use URL as data source
|
|
473
|
+
metadata: message.metadata
|
|
867
474
|
};
|
|
868
475
|
}
|
|
869
476
|
if (part.type === "dynamic-tool") {
|
|
@@ -871,22 +478,27 @@ const toAssistantUIMessage = (message) => {
|
|
|
871
478
|
type: "tool-call",
|
|
872
479
|
toolCallId: part.toolCallId,
|
|
873
480
|
toolName: part.toolName,
|
|
874
|
-
argsText: JSON.stringify(part.input)
|
|
481
|
+
argsText: JSON.stringify(part.input),
|
|
482
|
+
args: part.input,
|
|
483
|
+
metadata: message.metadata
|
|
875
484
|
};
|
|
876
|
-
if (part.state === "output-
|
|
877
|
-
return { ...baseToolCall, result: part.output };
|
|
878
|
-
} else if (part.state === "output-error" && "errorText" in part) {
|
|
485
|
+
if (part.state === "output-error" && "errorText" in part) {
|
|
879
486
|
return { ...baseToolCall, result: part.errorText, isError: true };
|
|
880
487
|
}
|
|
488
|
+
if ("output" in part) {
|
|
489
|
+
return { ...baseToolCall, result: part.output };
|
|
490
|
+
}
|
|
881
491
|
return baseToolCall;
|
|
882
492
|
}
|
|
883
|
-
if (part.type.startsWith("tool-")) {
|
|
493
|
+
if (part.type.startsWith("tool-") && part.state !== "input-available") {
|
|
884
494
|
const toolName = "toolName" in part && typeof part.toolName === "string" ? part.toolName : part.type.substring(5);
|
|
885
495
|
const baseToolCall = {
|
|
886
496
|
type: "tool-call",
|
|
887
497
|
toolCallId: "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : "",
|
|
888
498
|
toolName,
|
|
889
|
-
argsText: "input" in part ? JSON.stringify(part.input) : "{}"
|
|
499
|
+
argsText: "input" in part ? JSON.stringify(part.input) : "{}",
|
|
500
|
+
args: "input" in part ? part.input : {},
|
|
501
|
+
metadata: message.metadata
|
|
890
502
|
};
|
|
891
503
|
if ("output" in part) {
|
|
892
504
|
return { ...baseToolCall, result: part.output };
|
|
@@ -897,7 +509,8 @@ const toAssistantUIMessage = (message) => {
|
|
|
897
509
|
}
|
|
898
510
|
return {
|
|
899
511
|
type: "text",
|
|
900
|
-
text: ""
|
|
512
|
+
text: "",
|
|
513
|
+
metadata: message.metadata
|
|
901
514
|
};
|
|
902
515
|
});
|
|
903
516
|
let status;
|
|
@@ -922,25 +535,574 @@ const toAssistantUIMessage = (message) => {
|
|
|
922
535
|
status = { type: "complete", reason: "stop" };
|
|
923
536
|
}
|
|
924
537
|
}
|
|
925
|
-
const metadata = extendedMessage.metadata ? {
|
|
926
|
-
custom: extendedMessage.metadata
|
|
927
|
-
} : void 0;
|
|
928
538
|
const threadMessage = {
|
|
929
539
|
role: message.role,
|
|
930
540
|
content,
|
|
931
541
|
id: message.id,
|
|
932
542
|
createdAt: extendedMessage.createdAt,
|
|
933
543
|
status,
|
|
934
|
-
metadata,
|
|
935
544
|
attachments: extendedMessage.experimental_attachments
|
|
936
545
|
};
|
|
937
546
|
return threadMessage;
|
|
938
547
|
};
|
|
939
548
|
|
|
549
|
+
class AISdkNetworkTransformer {
|
|
550
|
+
transform({ chunk, conversation, metadata }) {
|
|
551
|
+
const newConversation = [...conversation];
|
|
552
|
+
if (chunk.type.startsWith("agent-execution-")) {
|
|
553
|
+
return this.handleAgentConversation(chunk, newConversation, metadata);
|
|
554
|
+
}
|
|
555
|
+
if (chunk.type.startsWith("workflow-execution-")) {
|
|
556
|
+
return this.handleWorkflowConversation(chunk, newConversation, metadata);
|
|
557
|
+
}
|
|
558
|
+
if (chunk.type.startsWith("tool-execution-")) {
|
|
559
|
+
return this.handleToolConversation(chunk, newConversation, metadata);
|
|
560
|
+
}
|
|
561
|
+
if (chunk.type === "network-execution-event-step-finish") {
|
|
562
|
+
const newMessage = {
|
|
563
|
+
id: `network-execution-event-step-finish-${chunk.runId}-${Date.now()}`,
|
|
564
|
+
role: "assistant",
|
|
565
|
+
parts: [
|
|
566
|
+
{
|
|
567
|
+
type: "text",
|
|
568
|
+
text: chunk.payload?.result || "",
|
|
569
|
+
state: "done"
|
|
570
|
+
}
|
|
571
|
+
],
|
|
572
|
+
metadata
|
|
573
|
+
};
|
|
574
|
+
return [...newConversation, newMessage];
|
|
575
|
+
}
|
|
576
|
+
return newConversation;
|
|
577
|
+
}
|
|
578
|
+
handleAgentConversation = (chunk, newConversation, metadata) => {
|
|
579
|
+
if (chunk.type === "agent-execution-start") {
|
|
580
|
+
const primitiveId = chunk.payload?.args?.primitiveId;
|
|
581
|
+
const runId = chunk.payload.runId;
|
|
582
|
+
if (!primitiveId || !runId) return newConversation;
|
|
583
|
+
const newMessage = {
|
|
584
|
+
id: `agent-execution-start-${runId}-${Date.now()}`,
|
|
585
|
+
role: "assistant",
|
|
586
|
+
parts: [
|
|
587
|
+
{
|
|
588
|
+
type: "dynamic-tool",
|
|
589
|
+
toolName: primitiveId,
|
|
590
|
+
toolCallId: runId,
|
|
591
|
+
state: "input-available",
|
|
592
|
+
input: chunk.payload.args
|
|
593
|
+
}
|
|
594
|
+
],
|
|
595
|
+
metadata: {
|
|
596
|
+
...metadata,
|
|
597
|
+
selectionReason: chunk.payload?.args?.selectionReason || "",
|
|
598
|
+
agentInput: chunk.payload?.args?.task,
|
|
599
|
+
mode: "network",
|
|
600
|
+
from: "AGENT"
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
return [...newConversation, newMessage];
|
|
604
|
+
}
|
|
605
|
+
if (chunk.type === "agent-execution-end") {
|
|
606
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
607
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
608
|
+
const parts = [...lastMessage.parts];
|
|
609
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
610
|
+
if (toolPartIndex !== -1) {
|
|
611
|
+
const toolPart = parts[toolPartIndex];
|
|
612
|
+
if (toolPart.type === "dynamic-tool") {
|
|
613
|
+
const currentOutput = toolPart.output;
|
|
614
|
+
parts[toolPartIndex] = {
|
|
615
|
+
type: "dynamic-tool",
|
|
616
|
+
toolName: toolPart.toolName,
|
|
617
|
+
toolCallId: toolPart.toolCallId,
|
|
618
|
+
state: "output-available",
|
|
619
|
+
input: toolPart.input,
|
|
620
|
+
output: {
|
|
621
|
+
...currentOutput,
|
|
622
|
+
result: currentOutput?.result || chunk.payload?.result || ""
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
return [
|
|
628
|
+
...newConversation.slice(0, -1),
|
|
629
|
+
{
|
|
630
|
+
...lastMessage,
|
|
631
|
+
parts
|
|
632
|
+
}
|
|
633
|
+
];
|
|
634
|
+
}
|
|
635
|
+
if (chunk.type.startsWith("agent-execution-event-")) {
|
|
636
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
637
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
638
|
+
const agentChunk = chunk.payload;
|
|
639
|
+
const parts = [...lastMessage.parts];
|
|
640
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
641
|
+
if (toolPartIndex === -1) return newConversation;
|
|
642
|
+
const toolPart = parts[toolPartIndex];
|
|
643
|
+
if (agentChunk.type === "text-delta") {
|
|
644
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
645
|
+
const lastChildMessage = childMessages[childMessages.length - 1];
|
|
646
|
+
const textMessage = { type: "text", content: (lastChildMessage?.content || "") + agentChunk.payload.text };
|
|
647
|
+
const nextMessages = lastChildMessage?.type === "text" ? [...childMessages.slice(0, -1), textMessage] : [...childMessages, textMessage];
|
|
648
|
+
parts[toolPartIndex] = {
|
|
649
|
+
...toolPart,
|
|
650
|
+
output: {
|
|
651
|
+
childMessages: nextMessages
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
} else if (agentChunk.type === "tool-call") {
|
|
655
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
656
|
+
parts[toolPartIndex] = {
|
|
657
|
+
...toolPart,
|
|
658
|
+
output: {
|
|
659
|
+
...toolPart?.output,
|
|
660
|
+
childMessages: [
|
|
661
|
+
...childMessages,
|
|
662
|
+
{
|
|
663
|
+
type: "tool",
|
|
664
|
+
toolCallId: agentChunk.payload.toolCallId,
|
|
665
|
+
toolName: agentChunk.payload.toolName,
|
|
666
|
+
args: agentChunk.payload.args
|
|
667
|
+
}
|
|
668
|
+
]
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
} else if (agentChunk.type === "tool-output") {
|
|
672
|
+
if (agentChunk.payload?.output?.type?.startsWith("workflow-")) {
|
|
673
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
674
|
+
const lastToolIndex = childMessages.length - 1;
|
|
675
|
+
const currentMessage = childMessages[lastToolIndex];
|
|
676
|
+
const actualExistingWorkflowState = currentMessage?.toolOutput || {};
|
|
677
|
+
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(
|
|
678
|
+
actualExistingWorkflowState,
|
|
679
|
+
agentChunk.payload.output
|
|
680
|
+
);
|
|
681
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
682
|
+
parts[toolPartIndex] = {
|
|
683
|
+
...toolPart,
|
|
684
|
+
output: {
|
|
685
|
+
...toolPart?.output,
|
|
686
|
+
childMessages: [
|
|
687
|
+
...childMessages.slice(0, -1),
|
|
688
|
+
{
|
|
689
|
+
...currentMessage,
|
|
690
|
+
toolOutput: updatedWorkflowState
|
|
691
|
+
}
|
|
692
|
+
]
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
} else if (agentChunk.type === "tool-result") {
|
|
698
|
+
const childMessages = toolPart?.output?.childMessages || [];
|
|
699
|
+
const lastToolIndex = childMessages.length - 1;
|
|
700
|
+
const isWorkflow = Boolean(agentChunk.payload?.result?.result?.steps);
|
|
701
|
+
if (lastToolIndex >= 0 && childMessages[lastToolIndex]?.type === "tool") {
|
|
702
|
+
parts[toolPartIndex] = {
|
|
703
|
+
...toolPart,
|
|
704
|
+
output: {
|
|
705
|
+
...toolPart?.output,
|
|
706
|
+
childMessages: [
|
|
707
|
+
...childMessages.slice(0, -1),
|
|
708
|
+
{
|
|
709
|
+
...childMessages[lastToolIndex],
|
|
710
|
+
toolOutput: isWorkflow ? agentChunk.payload.result.result : agentChunk.payload.result
|
|
711
|
+
}
|
|
712
|
+
]
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return [
|
|
718
|
+
...newConversation.slice(0, -1),
|
|
719
|
+
{
|
|
720
|
+
...lastMessage,
|
|
721
|
+
parts
|
|
722
|
+
}
|
|
723
|
+
];
|
|
724
|
+
}
|
|
725
|
+
return newConversation;
|
|
726
|
+
};
|
|
727
|
+
handleWorkflowConversation = (chunk, newConversation, metadata) => {
|
|
728
|
+
if (chunk.type === "workflow-execution-start") {
|
|
729
|
+
const primitiveId = chunk.payload?.args?.primitiveId;
|
|
730
|
+
const runId = chunk.payload.runId;
|
|
731
|
+
if (!primitiveId || !runId) return newConversation;
|
|
732
|
+
let agentInput;
|
|
733
|
+
try {
|
|
734
|
+
agentInput = JSON.parse(chunk?.payload?.args?.prompt);
|
|
735
|
+
} catch (e) {
|
|
736
|
+
agentInput = chunk?.payload?.args?.prompt;
|
|
737
|
+
}
|
|
738
|
+
const newMessage = {
|
|
739
|
+
id: `workflow-start-${runId}-${Date.now()}`,
|
|
740
|
+
role: "assistant",
|
|
741
|
+
parts: [
|
|
742
|
+
{
|
|
743
|
+
type: "dynamic-tool",
|
|
744
|
+
toolName: primitiveId,
|
|
745
|
+
toolCallId: runId,
|
|
746
|
+
state: "input-available",
|
|
747
|
+
input: chunk.payload.args
|
|
748
|
+
}
|
|
749
|
+
],
|
|
750
|
+
metadata: {
|
|
751
|
+
...metadata,
|
|
752
|
+
selectionReason: chunk.payload?.args?.selectionReason || "",
|
|
753
|
+
from: "WORKFLOW",
|
|
754
|
+
mode: "network",
|
|
755
|
+
agentInput
|
|
756
|
+
}
|
|
757
|
+
};
|
|
758
|
+
return [...newConversation, newMessage];
|
|
759
|
+
}
|
|
760
|
+
if (chunk.type.startsWith("workflow-execution-event-")) {
|
|
761
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
762
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
763
|
+
const parts = [...lastMessage.parts];
|
|
764
|
+
const toolPartIndex = parts.findIndex((part) => part.type === "dynamic-tool");
|
|
765
|
+
if (toolPartIndex === -1) return newConversation;
|
|
766
|
+
const toolPart = parts[toolPartIndex];
|
|
767
|
+
if (toolPart.type !== "dynamic-tool") return newConversation;
|
|
768
|
+
const existingWorkflowState = toolPart.output || {};
|
|
769
|
+
const updatedWorkflowState = mapWorkflowStreamChunkToWatchResult(existingWorkflowState, chunk.payload);
|
|
770
|
+
parts[toolPartIndex] = {
|
|
771
|
+
...toolPart,
|
|
772
|
+
output: updatedWorkflowState
|
|
773
|
+
};
|
|
774
|
+
return [
|
|
775
|
+
...newConversation.slice(0, -1),
|
|
776
|
+
{
|
|
777
|
+
...lastMessage,
|
|
778
|
+
parts
|
|
779
|
+
}
|
|
780
|
+
];
|
|
781
|
+
}
|
|
782
|
+
return newConversation;
|
|
783
|
+
};
|
|
784
|
+
handleToolConversation = (chunk, newConversation, metadata) => {
|
|
785
|
+
if (chunk.type === "tool-execution-start") {
|
|
786
|
+
const { args: argsData } = chunk.payload;
|
|
787
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
788
|
+
const nestedArgs = argsData.args || {};
|
|
789
|
+
if (!lastMessage || lastMessage.role !== "assistant") {
|
|
790
|
+
const newMessage = {
|
|
791
|
+
id: `tool-start-${chunk.runId}-${Date.now()}`,
|
|
792
|
+
role: "assistant",
|
|
793
|
+
parts: [
|
|
794
|
+
{
|
|
795
|
+
type: "dynamic-tool",
|
|
796
|
+
toolName: argsData.toolName || "unknown",
|
|
797
|
+
toolCallId: argsData.toolCallId || "unknown",
|
|
798
|
+
state: "input-available",
|
|
799
|
+
input: nestedArgs
|
|
800
|
+
}
|
|
801
|
+
],
|
|
802
|
+
metadata: {
|
|
803
|
+
...metadata,
|
|
804
|
+
selectionReason: metadata?.mode === "network" ? metadata.selectionReason || argsData.selectionReason : "",
|
|
805
|
+
mode: "network",
|
|
806
|
+
agentInput: nestedArgs
|
|
807
|
+
}
|
|
808
|
+
};
|
|
809
|
+
return [...newConversation, newMessage];
|
|
810
|
+
}
|
|
811
|
+
const parts = [...lastMessage.parts];
|
|
812
|
+
parts.push({
|
|
813
|
+
type: "dynamic-tool",
|
|
814
|
+
toolName: argsData.toolName || "unknown",
|
|
815
|
+
toolCallId: argsData.toolCallId || "unknown",
|
|
816
|
+
state: "input-available",
|
|
817
|
+
input: nestedArgs
|
|
818
|
+
});
|
|
819
|
+
return [
|
|
820
|
+
...newConversation.slice(0, -1),
|
|
821
|
+
{
|
|
822
|
+
...lastMessage,
|
|
823
|
+
parts
|
|
824
|
+
}
|
|
825
|
+
];
|
|
826
|
+
}
|
|
827
|
+
if (chunk.type === "tool-execution-end") {
|
|
828
|
+
const lastMessage = newConversation[newConversation.length - 1];
|
|
829
|
+
if (!lastMessage || lastMessage.role !== "assistant") return newConversation;
|
|
830
|
+
const parts = [...lastMessage.parts];
|
|
831
|
+
const toolPartIndex = parts.findIndex(
|
|
832
|
+
(part) => part.type === "dynamic-tool" && "toolCallId" in part && part.toolCallId === chunk.payload.toolCallId
|
|
833
|
+
);
|
|
834
|
+
if (toolPartIndex !== -1) {
|
|
835
|
+
const toolPart = parts[toolPartIndex];
|
|
836
|
+
if (toolPart.type === "dynamic-tool") {
|
|
837
|
+
const currentOutput = toolPart.output;
|
|
838
|
+
parts[toolPartIndex] = {
|
|
839
|
+
type: "dynamic-tool",
|
|
840
|
+
toolName: toolPart.toolName,
|
|
841
|
+
toolCallId: toolPart.toolCallId,
|
|
842
|
+
state: "output-available",
|
|
843
|
+
input: toolPart.input,
|
|
844
|
+
output: currentOutput?.result || chunk.payload?.result || ""
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return [
|
|
849
|
+
...newConversation.slice(0, -1),
|
|
850
|
+
{
|
|
851
|
+
...lastMessage,
|
|
852
|
+
parts
|
|
853
|
+
}
|
|
854
|
+
];
|
|
855
|
+
}
|
|
856
|
+
return newConversation;
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
const resolveInitialMessages = (messages) => {
|
|
861
|
+
return messages.map((message) => {
|
|
862
|
+
const networkPart = message.parts.find((part) => part.type === "text" && part.text.includes('"isNetwork":true'));
|
|
863
|
+
if (networkPart && networkPart.type === "text") {
|
|
864
|
+
try {
|
|
865
|
+
const json = JSON.parse(networkPart.text);
|
|
866
|
+
if (json.isNetwork === true) {
|
|
867
|
+
const selectionReason = json.selectionReason || "";
|
|
868
|
+
const primitiveType = json.primitiveType || "";
|
|
869
|
+
const primitiveId = json.primitiveId || "";
|
|
870
|
+
const finalResult = json.finalResult;
|
|
871
|
+
const toolCalls = finalResult?.toolCalls || [];
|
|
872
|
+
const childMessages = [];
|
|
873
|
+
for (const toolCall of toolCalls) {
|
|
874
|
+
if (toolCall.type === "tool-call" && toolCall.payload) {
|
|
875
|
+
const toolCallId = toolCall.payload.toolCallId;
|
|
876
|
+
let toolResult;
|
|
877
|
+
for (const message2 of finalResult?.messages || []) {
|
|
878
|
+
for (const part of message2.content || []) {
|
|
879
|
+
if (typeof part === "object" && part.type === "tool-result" && part.toolCallId === toolCallId) {
|
|
880
|
+
toolResult = part;
|
|
881
|
+
break;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
const isWorkflow = Boolean(toolResult?.result?.result?.steps);
|
|
886
|
+
childMessages.push({
|
|
887
|
+
type: "tool",
|
|
888
|
+
toolCallId: toolCall.payload.toolCallId,
|
|
889
|
+
toolName: toolCall.payload.toolName,
|
|
890
|
+
args: toolCall.payload.args,
|
|
891
|
+
toolOutput: isWorkflow ? toolResult?.result?.result : toolResult?.result
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
if (finalResult && finalResult.text) {
|
|
896
|
+
childMessages.push({
|
|
897
|
+
type: "text",
|
|
898
|
+
content: finalResult.text
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
const result = {
|
|
902
|
+
childMessages,
|
|
903
|
+
result: finalResult?.text || ""
|
|
904
|
+
};
|
|
905
|
+
console.log("json", json);
|
|
906
|
+
const nextMessage = {
|
|
907
|
+
role: "assistant",
|
|
908
|
+
parts: [
|
|
909
|
+
{
|
|
910
|
+
type: "dynamic-tool",
|
|
911
|
+
toolCallId: primitiveId,
|
|
912
|
+
toolName: primitiveId,
|
|
913
|
+
state: "output-available",
|
|
914
|
+
input: json.input,
|
|
915
|
+
output: result
|
|
916
|
+
}
|
|
917
|
+
],
|
|
918
|
+
id: message.id,
|
|
919
|
+
metadata: {
|
|
920
|
+
...message.metadata,
|
|
921
|
+
mode: "network",
|
|
922
|
+
selectionReason,
|
|
923
|
+
agentInput: json.input,
|
|
924
|
+
from: primitiveType === "agent" ? "AGENT" : "WORKFLOW"
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
return nextMessage;
|
|
928
|
+
}
|
|
929
|
+
} catch (error) {
|
|
930
|
+
return message;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
return message;
|
|
934
|
+
});
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
const useChat = ({ agentId, initializeMessages }) => {
|
|
938
|
+
const [messages, setMessages] = react.useState(
|
|
939
|
+
() => resolveInitialMessages(initializeMessages?.() || [])
|
|
940
|
+
);
|
|
941
|
+
const baseClient = useMastraClient();
|
|
942
|
+
const [isRunning, setIsRunning] = react.useState(false);
|
|
943
|
+
const generate = async ({
|
|
944
|
+
coreUserMessages,
|
|
945
|
+
runtimeContext,
|
|
946
|
+
threadId,
|
|
947
|
+
modelSettings,
|
|
948
|
+
signal,
|
|
949
|
+
onFinish
|
|
950
|
+
}) => {
|
|
951
|
+
const {
|
|
952
|
+
frequencyPenalty,
|
|
953
|
+
presencePenalty,
|
|
954
|
+
maxRetries,
|
|
955
|
+
maxTokens,
|
|
956
|
+
temperature,
|
|
957
|
+
topK,
|
|
958
|
+
topP,
|
|
959
|
+
instructions,
|
|
960
|
+
providerOptions,
|
|
961
|
+
maxSteps
|
|
962
|
+
} = modelSettings || {};
|
|
963
|
+
setIsRunning(true);
|
|
964
|
+
const clientWithAbort = new clientJs.MastraClient({
|
|
965
|
+
...baseClient.options,
|
|
966
|
+
abortSignal: signal
|
|
967
|
+
});
|
|
968
|
+
const agent = clientWithAbort.getAgent(agentId);
|
|
969
|
+
const response = await agent.generate({
|
|
970
|
+
messages: coreUserMessages,
|
|
971
|
+
runId: agentId,
|
|
972
|
+
maxSteps,
|
|
973
|
+
modelSettings: {
|
|
974
|
+
frequencyPenalty,
|
|
975
|
+
presencePenalty,
|
|
976
|
+
maxRetries,
|
|
977
|
+
maxOutputTokens: maxTokens,
|
|
978
|
+
temperature,
|
|
979
|
+
topK,
|
|
980
|
+
topP
|
|
981
|
+
},
|
|
982
|
+
instructions,
|
|
983
|
+
runtimeContext,
|
|
984
|
+
...threadId ? { threadId, resourceId: agentId } : {},
|
|
985
|
+
providerOptions
|
|
986
|
+
});
|
|
987
|
+
setIsRunning(false);
|
|
988
|
+
if (response && "uiMessages" in response.response && response.response.uiMessages) {
|
|
989
|
+
onFinish?.(response.response.uiMessages);
|
|
990
|
+
const mastraUIMessages = (response.response.uiMessages || []).map((message) => ({
|
|
991
|
+
...message,
|
|
992
|
+
metadata: {
|
|
993
|
+
mode: "generate"
|
|
994
|
+
}
|
|
995
|
+
}));
|
|
996
|
+
setMessages((prev) => [...prev, ...mastraUIMessages]);
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
const stream = async ({ coreUserMessages, runtimeContext, threadId, onChunk, modelSettings, signal }) => {
|
|
1000
|
+
const {
|
|
1001
|
+
frequencyPenalty,
|
|
1002
|
+
presencePenalty,
|
|
1003
|
+
maxRetries,
|
|
1004
|
+
maxTokens,
|
|
1005
|
+
temperature,
|
|
1006
|
+
topK,
|
|
1007
|
+
topP,
|
|
1008
|
+
instructions,
|
|
1009
|
+
providerOptions,
|
|
1010
|
+
maxSteps
|
|
1011
|
+
} = modelSettings || {};
|
|
1012
|
+
setIsRunning(true);
|
|
1013
|
+
const clientWithAbort = new clientJs.MastraClient({
|
|
1014
|
+
...baseClient.options,
|
|
1015
|
+
abortSignal: signal
|
|
1016
|
+
});
|
|
1017
|
+
const agent = clientWithAbort.getAgent(agentId);
|
|
1018
|
+
const response = await agent.stream({
|
|
1019
|
+
messages: coreUserMessages,
|
|
1020
|
+
runId: agentId,
|
|
1021
|
+
maxSteps,
|
|
1022
|
+
modelSettings: {
|
|
1023
|
+
frequencyPenalty,
|
|
1024
|
+
presencePenalty,
|
|
1025
|
+
maxRetries,
|
|
1026
|
+
maxOutputTokens: maxTokens,
|
|
1027
|
+
temperature,
|
|
1028
|
+
topK,
|
|
1029
|
+
topP
|
|
1030
|
+
},
|
|
1031
|
+
instructions,
|
|
1032
|
+
runtimeContext,
|
|
1033
|
+
...threadId ? { threadId, resourceId: agentId } : {},
|
|
1034
|
+
providerOptions
|
|
1035
|
+
});
|
|
1036
|
+
if (!response.body) {
|
|
1037
|
+
setIsRunning(false);
|
|
1038
|
+
throw new Error("[Stream] No response body");
|
|
1039
|
+
}
|
|
1040
|
+
await response.processDataStream({
|
|
1041
|
+
onChunk: async (chunk) => {
|
|
1042
|
+
reactDom.flushSync(() => {
|
|
1043
|
+
setMessages((prev) => toUIMessage({ chunk, conversation: prev, metadata: { mode: "stream" } }));
|
|
1044
|
+
});
|
|
1045
|
+
onChunk?.(chunk);
|
|
1046
|
+
}
|
|
1047
|
+
});
|
|
1048
|
+
setIsRunning(false);
|
|
1049
|
+
};
|
|
1050
|
+
const network = async ({
|
|
1051
|
+
coreUserMessages,
|
|
1052
|
+
runtimeContext,
|
|
1053
|
+
threadId,
|
|
1054
|
+
onNetworkChunk,
|
|
1055
|
+
modelSettings,
|
|
1056
|
+
signal
|
|
1057
|
+
}) => {
|
|
1058
|
+
const { frequencyPenalty, presencePenalty, maxRetries, maxTokens, temperature, topK, topP, maxSteps } = modelSettings || {};
|
|
1059
|
+
setIsRunning(true);
|
|
1060
|
+
const clientWithAbort = new clientJs.MastraClient({
|
|
1061
|
+
...baseClient.options,
|
|
1062
|
+
abortSignal: signal
|
|
1063
|
+
});
|
|
1064
|
+
const agent = clientWithAbort.getAgent(agentId);
|
|
1065
|
+
const response = await agent.network({
|
|
1066
|
+
messages: coreUserMessages,
|
|
1067
|
+
maxSteps,
|
|
1068
|
+
modelSettings: {
|
|
1069
|
+
frequencyPenalty,
|
|
1070
|
+
presencePenalty,
|
|
1071
|
+
maxRetries,
|
|
1072
|
+
maxOutputTokens: maxTokens,
|
|
1073
|
+
temperature,
|
|
1074
|
+
topK,
|
|
1075
|
+
topP
|
|
1076
|
+
},
|
|
1077
|
+
runId: agentId,
|
|
1078
|
+
runtimeContext,
|
|
1079
|
+
...threadId ? { thread: threadId, resourceId: agentId } : {}
|
|
1080
|
+
});
|
|
1081
|
+
const transformer = new AISdkNetworkTransformer();
|
|
1082
|
+
await response.processDataStream({
|
|
1083
|
+
onChunk: async (chunk) => {
|
|
1084
|
+
reactDom.flushSync(() => {
|
|
1085
|
+
setMessages((prev) => transformer.transform({ chunk, conversation: prev, metadata: { mode: "network" } }));
|
|
1086
|
+
});
|
|
1087
|
+
onNetworkChunk?.(chunk);
|
|
1088
|
+
}
|
|
1089
|
+
});
|
|
1090
|
+
setIsRunning(false);
|
|
1091
|
+
};
|
|
1092
|
+
return {
|
|
1093
|
+
network,
|
|
1094
|
+
stream,
|
|
1095
|
+
generate,
|
|
1096
|
+
isRunning,
|
|
1097
|
+
messages,
|
|
1098
|
+
setMessages,
|
|
1099
|
+
cancelRun: () => setIsRunning(false)
|
|
1100
|
+
};
|
|
1101
|
+
};
|
|
1102
|
+
|
|
940
1103
|
exports.MastraReactProvider = MastraReactProvider;
|
|
941
1104
|
exports.mapWorkflowStreamChunkToWatchResult = mapWorkflowStreamChunkToWatchResult;
|
|
942
1105
|
exports.toAssistantUIMessage = toAssistantUIMessage;
|
|
943
|
-
exports.toNetworkUIMessage = toNetworkUIMessage;
|
|
944
1106
|
exports.toUIMessage = toUIMessage;
|
|
945
1107
|
exports.useChat = useChat;
|
|
946
1108
|
exports.useMastraClient = useMastraClient;
|