@mastra/react 0.4.3-alpha.5 → 0.4.3-alpha.8
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 +41 -0
- package/dist/agent/hooks.d.ts +3 -3
- package/dist/agent/hooks.d.ts.map +1 -1
- package/dist/index.cjs +121 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +121 -15
- package/dist/index.js.map +1 -1
- package/dist/lib/ai-sdk/utils/toUIMessage.d.ts.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @mastra/react
|
|
2
2
|
|
|
3
|
+
## 0.4.3-alpha.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`0c1ed1d`](https://github.com/mastra-ai/mastra/commit/0c1ed1d00c7d87b5ac99ca95896211a2fa9189fa), [`849efb9`](https://github.com/mastra-ai/mastra/commit/849efb9fca6dc976589c1f90a303fea618769109)]:
|
|
8
|
+
- @mastra/core@1.38.0-alpha.8
|
|
9
|
+
- @mastra/client-js@1.22.0-alpha.8
|
|
10
|
+
|
|
11
|
+
## 0.4.3-alpha.7
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies:
|
|
16
|
+
- @mastra/core@1.38.0-alpha.7
|
|
17
|
+
- @mastra/client-js@1.22.0-alpha.7
|
|
18
|
+
|
|
19
|
+
## 0.4.3-alpha.6
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Fixed canonical user signal echoes so messages sent through the agent-signals path appear in chat history when they move from pending to active. ([#17309](https://github.com/mastra-ai/mastra/pull/17309))
|
|
24
|
+
|
|
25
|
+
- Separated thread subscription cleanup from active-run aborts so closing or switching a listener only unsubscribes that listener, while explicit cancel still aborts the active run. ([#17310](https://github.com/mastra-ai/mastra/pull/17310))
|
|
26
|
+
|
|
27
|
+
- Added subscription-native tool approval APIs so approving or declining a tool call resumes through the active thread subscription instead of requiring a separate continuation stream. New messages are queued while a tool approval is waiting, preventing overlapping runs from duplicating approval requests. ([#17311](https://github.com/mastra-ai/mastra/pull/17311))
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
await agent.sendToolApproval({
|
|
31
|
+
resourceId: 'user-123',
|
|
32
|
+
threadId: 'thread-123',
|
|
33
|
+
toolCallId: 'tool-call-123',
|
|
34
|
+
approved: true,
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- Enabled Studio via the CLI and deployers to use agent signal subscriptions by default while preserving `MASTRA_AGENT_SIGNALS=false`, `enableThreadSignals: false`, and explicit legacy Stream as opt-outs. The React `useChat()` hook remains opt-in for SDK consumers via `enableThreadSignals: true`. ([#17313](https://github.com/mastra-ai/mastra/pull/17313))
|
|
39
|
+
|
|
40
|
+
- Updated dependencies [[`bb3fce8`](https://github.com/mastra-ai/mastra/commit/bb3fce8f8d80079170c0f98cb2efbb29ae34375d), [`19a8658`](https://github.com/mastra-ai/mastra/commit/19a86589c788ef48bb6c1b0612cc82a201857379), [`a659a77`](https://github.com/mastra-ai/mastra/commit/a659a779bdebe3a52a518c56d2260592d0240fe0), [`3332be9`](https://github.com/mastra-ai/mastra/commit/3332be9701ecd77aba840959d9a1d1ce7aef02d3)]:
|
|
41
|
+
- @mastra/client-js@1.22.0-alpha.6
|
|
42
|
+
- @mastra/core@1.38.0-alpha.6
|
|
43
|
+
|
|
3
44
|
## 0.4.3-alpha.5
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
package/dist/agent/hooks.d.ts
CHANGED
|
@@ -23,9 +23,8 @@ export interface MastraChatProps {
|
|
|
23
23
|
onSignalEcho?: (signalId: string) => void;
|
|
24
24
|
onThreadSignalsUnsupported?: () => void;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
* Defaults to `false
|
|
28
|
-
* unless they explicitly enable the signals path.
|
|
26
|
+
* Use the agent-signals streaming path (sendSignal + subscribeToThread).
|
|
27
|
+
* Defaults to `false`; set to `true` to opt into thread signals.
|
|
29
28
|
*/
|
|
30
29
|
enableThreadSignals?: boolean;
|
|
31
30
|
}
|
|
@@ -65,6 +64,7 @@ export declare const useChat: ({ agentId, resourceId, threadId, initialMessages,
|
|
|
65
64
|
setMessages: import("react").Dispatch<import("react").SetStateAction<MastraUIMessage[]>>;
|
|
66
65
|
sendMessage: ({ mode, ...args }: SendMessageArgs) => Promise<void>;
|
|
67
66
|
isRunning: boolean;
|
|
67
|
+
isAwaitingToolApproval: boolean;
|
|
68
68
|
messages: MastraUIMessage[];
|
|
69
69
|
approveToolCall: (toolCallId: string) => Promise<void>;
|
|
70
70
|
declineToolCall: (toolCallId: string) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/agent/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAQrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,KAAK,UAAU,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/agent/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -303,7 +303,7 @@ function signalContentsToUserMessages(contents, metadata) {
|
|
|
303
303
|
var toUIMessage = ({ chunk, conversation, metadata }) => {
|
|
304
304
|
const result = [...conversation];
|
|
305
305
|
if (chunk.type.startsWith("data-")) {
|
|
306
|
-
if (chunk.type === "data-user-message" && "data" in chunk && chunk.data?.type === "user-message") {
|
|
306
|
+
if (chunk.type === "data-user-message" && "data" in chunk && (chunk.data?.type === "user-message" || chunk.data?.type === "user")) {
|
|
307
307
|
const signalId = chunk.data.id;
|
|
308
308
|
if (typeof signalId === "string" && result.some((message) => message.id === signalId)) {
|
|
309
309
|
return result;
|
|
@@ -2022,6 +2022,27 @@ function convertSignalDataToBase64String(content) {
|
|
|
2022
2022
|
}
|
|
2023
2023
|
|
|
2024
2024
|
// src/agent/hooks.ts
|
|
2025
|
+
var extractPendingToolApprovalIdsFromMessages = (messages) => {
|
|
2026
|
+
const pendingToolApprovalIds = /* @__PURE__ */ new Set();
|
|
2027
|
+
for (const message of messages) {
|
|
2028
|
+
const metadata = message.metadata;
|
|
2029
|
+
const metadataSources = [
|
|
2030
|
+
metadata?.pendingToolApprovals,
|
|
2031
|
+
metadata?.requireApprovalMetadata,
|
|
2032
|
+
metadata?.suspendedTools
|
|
2033
|
+
];
|
|
2034
|
+
for (const source of metadataSources) {
|
|
2035
|
+
if (!source || typeof source !== "object") continue;
|
|
2036
|
+
for (const suspensionData of Object.values(source)) {
|
|
2037
|
+
const toolCallId = suspensionData?.toolCallId;
|
|
2038
|
+
if (typeof toolCallId === "string" && toolCallId.length > 0) {
|
|
2039
|
+
pendingToolApprovalIds.add(toolCallId);
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
return pendingToolApprovalIds;
|
|
2045
|
+
};
|
|
2025
2046
|
var isThreadSignalUnsupportedError = (error) => {
|
|
2026
2047
|
const candidate = error;
|
|
2027
2048
|
const status = candidate?.status;
|
|
@@ -2050,17 +2071,24 @@ var useChat = ({
|
|
|
2050
2071
|
const _requestContext = react.useRef(propsRequestContext);
|
|
2051
2072
|
const _streamAbortRef = react.useRef(null);
|
|
2052
2073
|
const _threadSubscriptionAbortRef = react.useRef(null);
|
|
2074
|
+
const _threadSubscriptionRef = react.useRef(
|
|
2075
|
+
null
|
|
2076
|
+
);
|
|
2053
2077
|
const _threadSubscriptionKeyRef = react.useRef(void 0);
|
|
2054
2078
|
const _threadSubscriptionPromiseRef = react.useRef(null);
|
|
2055
2079
|
const _threadSignalsUnsupportedRef = react.useRef(false);
|
|
2056
2080
|
const [messages, setMessages] = react.useState([]);
|
|
2057
2081
|
const [toolCallApprovals, setToolCallApprovals] = react.useState({});
|
|
2058
2082
|
const [networkToolCallApprovals, setNetworkToolCallApprovals] = react.useState({});
|
|
2083
|
+
const pendingToolApprovalIdsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
2084
|
+
const [isAwaitingToolApproval, setIsAwaitingToolApproval] = react.useState(false);
|
|
2059
2085
|
const baseClient = useMastraClient();
|
|
2060
2086
|
const [isRunning, setIsRunning] = react.useState(false);
|
|
2061
2087
|
react.useEffect(() => {
|
|
2062
2088
|
const formattedMessages = resolveInitialMessages(initialMessages || []);
|
|
2063
2089
|
setMessages(formattedMessages);
|
|
2090
|
+
pendingToolApprovalIdsRef.current = extractPendingToolApprovalIdsFromMessages(formattedMessages);
|
|
2091
|
+
setIsAwaitingToolApproval(pendingToolApprovalIdsRef.current.size > 0);
|
|
2064
2092
|
_currentRunId.current = extractRunIdFromMessages(formattedMessages);
|
|
2065
2093
|
}, [initialMessages]);
|
|
2066
2094
|
react.useEffect(() => {
|
|
@@ -2116,7 +2144,13 @@ var useChat = ({
|
|
|
2116
2144
|
return preview || "Attachment";
|
|
2117
2145
|
};
|
|
2118
2146
|
const closeThreadSubscription = react.useCallback(() => {
|
|
2119
|
-
|
|
2147
|
+
const subscription = _threadSubscriptionRef.current;
|
|
2148
|
+
if (subscription?.unsubscribe) {
|
|
2149
|
+
subscription.unsubscribe();
|
|
2150
|
+
} else {
|
|
2151
|
+
_threadSubscriptionAbortRef.current?.abort();
|
|
2152
|
+
}
|
|
2153
|
+
_threadSubscriptionRef.current = null;
|
|
2120
2154
|
_threadSubscriptionAbortRef.current = null;
|
|
2121
2155
|
_threadSubscriptionKeyRef.current = void 0;
|
|
2122
2156
|
_threadSubscriptionPromiseRef.current = null;
|
|
@@ -2133,7 +2167,17 @@ var useChat = ({
|
|
|
2133
2167
|
_currentRunId.current = chunk.runId;
|
|
2134
2168
|
}
|
|
2135
2169
|
}
|
|
2170
|
+
if (chunk.type === "tool-call-approval" || chunk.type === "tool-call-suspended") {
|
|
2171
|
+
const toolCallId = chunk.payload?.toolCallId;
|
|
2172
|
+
if (typeof toolCallId === "string") {
|
|
2173
|
+
pendingToolApprovalIdsRef.current.add(toolCallId);
|
|
2174
|
+
setIsAwaitingToolApproval(true);
|
|
2175
|
+
}
|
|
2176
|
+
setIsRunning(false);
|
|
2177
|
+
}
|
|
2136
2178
|
if (chunk.type === "finish" || chunk.type === "abort" || chunk.type === "error") {
|
|
2179
|
+
pendingToolApprovalIdsRef.current.clear();
|
|
2180
|
+
setIsAwaitingToolApproval(false);
|
|
2137
2181
|
setIsRunning(false);
|
|
2138
2182
|
}
|
|
2139
2183
|
void (onChunk ?? _onChunk.current)?.(chunk);
|
|
@@ -2147,7 +2191,7 @@ var useChat = ({
|
|
|
2147
2191
|
await _threadSubscriptionPromiseRef.current;
|
|
2148
2192
|
return;
|
|
2149
2193
|
}
|
|
2150
|
-
|
|
2194
|
+
closeThreadSubscription();
|
|
2151
2195
|
const subscriptionAbort = new AbortController();
|
|
2152
2196
|
_threadSubscriptionAbortRef.current = subscriptionAbort;
|
|
2153
2197
|
_threadSubscriptionKeyRef.current = subscriptionKey;
|
|
@@ -2157,7 +2201,17 @@ var useChat = ({
|
|
|
2157
2201
|
});
|
|
2158
2202
|
const subscriptionAgent = clientWithAbort.getAgent(agentId);
|
|
2159
2203
|
_threadSubscriptionPromiseRef.current = subscriptionAgent.subscribeToThread({ resourceId: resourceId2, threadId: threadId2 }).then((response) => {
|
|
2160
|
-
|
|
2204
|
+
const subscription = response;
|
|
2205
|
+
if (_threadSubscriptionAbortRef.current !== subscriptionAbort) {
|
|
2206
|
+
if (subscription.unsubscribe) {
|
|
2207
|
+
subscription.unsubscribe();
|
|
2208
|
+
} else {
|
|
2209
|
+
subscriptionAbort.abort();
|
|
2210
|
+
}
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
_threadSubscriptionRef.current = subscription;
|
|
2214
|
+
void subscription.processDataStream({
|
|
2161
2215
|
onChunk: (chunk) => processStreamChunk(chunk)
|
|
2162
2216
|
}).catch((error) => {
|
|
2163
2217
|
if (error.name !== "AbortError") {
|
|
@@ -2165,6 +2219,9 @@ var useChat = ({
|
|
|
2165
2219
|
setIsRunning(false);
|
|
2166
2220
|
}
|
|
2167
2221
|
}).finally(() => {
|
|
2222
|
+
if (_threadSubscriptionRef.current === subscription) {
|
|
2223
|
+
_threadSubscriptionRef.current = null;
|
|
2224
|
+
}
|
|
2168
2225
|
if (_threadSubscriptionAbortRef.current === subscriptionAbort) {
|
|
2169
2226
|
_threadSubscriptionAbortRef.current = null;
|
|
2170
2227
|
_threadSubscriptionKeyRef.current = void 0;
|
|
@@ -2175,6 +2232,7 @@ var useChat = ({
|
|
|
2175
2232
|
if (isThreadSignalUnsupportedError(error)) {
|
|
2176
2233
|
markThreadSignalsUnsupported();
|
|
2177
2234
|
if (_threadSubscriptionAbortRef.current === subscriptionAbort) {
|
|
2235
|
+
_threadSubscriptionRef.current = null;
|
|
2178
2236
|
_threadSubscriptionAbortRef.current = null;
|
|
2179
2237
|
_threadSubscriptionKeyRef.current = void 0;
|
|
2180
2238
|
_threadSubscriptionPromiseRef.current = null;
|
|
@@ -2189,7 +2247,7 @@ var useChat = ({
|
|
|
2189
2247
|
});
|
|
2190
2248
|
await _threadSubscriptionPromiseRef.current;
|
|
2191
2249
|
},
|
|
2192
|
-
[agentId, baseClient, markThreadSignalsUnsupported, processStreamChunk]
|
|
2250
|
+
[agentId, baseClient, closeThreadSubscription, markThreadSignalsUnsupported, processStreamChunk]
|
|
2193
2251
|
);
|
|
2194
2252
|
react.useEffect(() => {
|
|
2195
2253
|
_threadSignalsUnsupportedRef.current = false;
|
|
@@ -2410,6 +2468,9 @@ var useChat = ({
|
|
|
2410
2468
|
}
|
|
2411
2469
|
}
|
|
2412
2470
|
});
|
|
2471
|
+
if (pendingToolApprovalIdsRef.current.size > 0) {
|
|
2472
|
+
setIsRunning(false);
|
|
2473
|
+
}
|
|
2413
2474
|
} catch (error) {
|
|
2414
2475
|
onSignalEcho?.(resolvedSignalId);
|
|
2415
2476
|
if (isThreadSignalUnsupportedError(error)) {
|
|
@@ -2473,8 +2534,14 @@ var useChat = ({
|
|
|
2473
2534
|
const handleCancelRun = () => {
|
|
2474
2535
|
_streamAbortRef.current?.abort();
|
|
2475
2536
|
_streamAbortRef.current = null;
|
|
2537
|
+
const threadSubscription = _threadSubscriptionRef.current;
|
|
2538
|
+
void Promise.resolve(threadSubscription?.abort?.()).catch((error) => {
|
|
2539
|
+
console.error("[useChat] Failed to abort thread subscription", error);
|
|
2540
|
+
});
|
|
2476
2541
|
closeThreadSubscription();
|
|
2477
2542
|
setMessages((prev) => finishStreamingAssistantMessage(prev));
|
|
2543
|
+
pendingToolApprovalIdsRef.current.clear();
|
|
2544
|
+
setIsAwaitingToolApproval(false);
|
|
2478
2545
|
setIsRunning(false);
|
|
2479
2546
|
_currentRunId.current = void 0;
|
|
2480
2547
|
_onChunk.current = void 0;
|
|
@@ -2490,18 +2557,37 @@ var useChat = ({
|
|
|
2490
2557
|
setIsRunning(true);
|
|
2491
2558
|
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "approved" } }));
|
|
2492
2559
|
const agent = baseClient.getAgent(agentId);
|
|
2560
|
+
if (_threadSubscriptionKeyRef.current && threadId) {
|
|
2561
|
+
try {
|
|
2562
|
+
await agent.sendToolApproval({
|
|
2563
|
+
resourceId: resourceId || agentId,
|
|
2564
|
+
threadId,
|
|
2565
|
+
toolCallId,
|
|
2566
|
+
approved: true,
|
|
2567
|
+
requestContext: _requestContext.current
|
|
2568
|
+
});
|
|
2569
|
+
pendingToolApprovalIdsRef.current.delete(toolCallId);
|
|
2570
|
+
setIsAwaitingToolApproval(pendingToolApprovalIdsRef.current.size > 0);
|
|
2571
|
+
setIsRunning(false);
|
|
2572
|
+
} catch (error) {
|
|
2573
|
+
setToolCallApprovals((prev) => {
|
|
2574
|
+
const next = { ...prev };
|
|
2575
|
+
delete next[toolCallId];
|
|
2576
|
+
return next;
|
|
2577
|
+
});
|
|
2578
|
+
setIsRunning(false);
|
|
2579
|
+
throw error;
|
|
2580
|
+
}
|
|
2581
|
+
return;
|
|
2582
|
+
}
|
|
2493
2583
|
const response = await agent.approveToolCall({
|
|
2494
2584
|
runId: currentRunId,
|
|
2495
2585
|
toolCallId,
|
|
2496
2586
|
requestContext: _requestContext.current
|
|
2497
2587
|
});
|
|
2498
|
-
if (_threadSubscriptionKeyRef.current) {
|
|
2499
|
-
return;
|
|
2500
|
-
}
|
|
2501
2588
|
await response.processDataStream({
|
|
2502
2589
|
onChunk: async (chunk) => {
|
|
2503
|
-
|
|
2504
|
-
void (onChunk ?? _onChunk.current)?.(chunk);
|
|
2590
|
+
await processStreamChunk(chunk, onChunk);
|
|
2505
2591
|
}
|
|
2506
2592
|
});
|
|
2507
2593
|
setIsRunning(false);
|
|
@@ -2514,18 +2600,37 @@ var useChat = ({
|
|
|
2514
2600
|
setIsRunning(true);
|
|
2515
2601
|
setToolCallApprovals((prev) => ({ ...prev, [toolCallId]: { status: "declined" } }));
|
|
2516
2602
|
const agent = baseClient.getAgent(agentId);
|
|
2603
|
+
if (_threadSubscriptionKeyRef.current && threadId) {
|
|
2604
|
+
try {
|
|
2605
|
+
await agent.sendToolApproval({
|
|
2606
|
+
resourceId: resourceId || agentId,
|
|
2607
|
+
threadId,
|
|
2608
|
+
toolCallId,
|
|
2609
|
+
approved: false,
|
|
2610
|
+
requestContext: _requestContext.current
|
|
2611
|
+
});
|
|
2612
|
+
pendingToolApprovalIdsRef.current.delete(toolCallId);
|
|
2613
|
+
setIsAwaitingToolApproval(pendingToolApprovalIdsRef.current.size > 0);
|
|
2614
|
+
setIsRunning(false);
|
|
2615
|
+
} catch (error) {
|
|
2616
|
+
setToolCallApprovals((prev) => {
|
|
2617
|
+
const next = { ...prev };
|
|
2618
|
+
delete next[toolCallId];
|
|
2619
|
+
return next;
|
|
2620
|
+
});
|
|
2621
|
+
setIsRunning(false);
|
|
2622
|
+
throw error;
|
|
2623
|
+
}
|
|
2624
|
+
return;
|
|
2625
|
+
}
|
|
2517
2626
|
const response = await agent.declineToolCall({
|
|
2518
2627
|
runId: currentRunId,
|
|
2519
2628
|
toolCallId,
|
|
2520
2629
|
requestContext: _requestContext.current
|
|
2521
2630
|
});
|
|
2522
|
-
if (_threadSubscriptionKeyRef.current) {
|
|
2523
|
-
return;
|
|
2524
|
-
}
|
|
2525
2631
|
await response.processDataStream({
|
|
2526
2632
|
onChunk: async (chunk) => {
|
|
2527
|
-
|
|
2528
|
-
void (onChunk ?? _onChunk.current)?.(chunk);
|
|
2633
|
+
await processStreamChunk(chunk, onChunk);
|
|
2529
2634
|
}
|
|
2530
2635
|
});
|
|
2531
2636
|
setIsRunning(false);
|
|
@@ -2655,6 +2760,7 @@ var useChat = ({
|
|
|
2655
2760
|
setMessages,
|
|
2656
2761
|
sendMessage,
|
|
2657
2762
|
isRunning,
|
|
2763
|
+
isAwaitingToolApproval,
|
|
2658
2764
|
messages,
|
|
2659
2765
|
approveToolCall,
|
|
2660
2766
|
declineToolCall,
|