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