@assistant-ui/ai-sdk 0.0.7 → 0.0.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/README.md +1 -1
- package/dist/adapters/aiSDKFormatAdapter.d.ts +2 -2
- package/dist/adapters/aiSDKFormatAdapter.d.ts.map +1 -0
- package/dist/adapters/vercelAttachmentAdapter.d.ts +1 -3
- package/dist/adapters/vercelAttachmentAdapter.d.ts.map +1 -1
- package/dist/adapters/vercelAttachmentAdapter.js +3 -3
- package/dist/adapters/vercelAttachmentAdapter.js.map +1 -1
- package/dist/aiSDKExtras.d.ts +4 -6
- package/dist/aiSDKExtras.d.ts.map +1 -1
- package/dist/converters/convertMessage.d.ts +32 -24
- package/dist/converters/convertMessage.d.ts.map +1 -1
- package/dist/converters/convertMessage.js +43 -9
- package/dist/converters/convertMessage.js.map +1 -1
- package/dist/converters/modelContentEnvelope.d.ts +6 -7
- package/dist/converters/modelContentEnvelope.d.ts.map +1 -1
- package/dist/converters/toCreateMessage.d.ts +2 -4
- package/dist/converters/toCreateMessage.d.ts.map +1 -1
- package/dist/converters/toolOutputConversion.d.ts +20 -22
- package/dist/converters/toolOutputConversion.d.ts.map +1 -1
- package/dist/hooks.d.ts +2 -4
- package/dist/hooks.d.ts.map +1 -1
- package/dist/index.d.ts +17 -14
- package/dist/index.d.ts.map +1 -0
- package/dist/index.native.d.ts +15 -12
- package/dist/index.native.d.ts.map +1 -0
- package/dist/model-context/injectInteractableContext.d.ts +2 -4
- package/dist/model-context/injectInteractableContext.d.ts.map +1 -1
- package/dist/model-context/injectQuoteContext.d.ts +1 -3
- package/dist/model-context/injectQuoteContext.d.ts.map +1 -1
- package/dist/runtime/AISDKChat.d.ts +2 -4
- package/dist/runtime/AISDKChat.d.ts.map +1 -1
- package/dist/runtime/AISDKChat.js +1 -1
- package/dist/runtime/AISDKThreads.d.ts +29 -31
- package/dist/runtime/AISDKThreads.d.ts.map +1 -1
- package/dist/runtime/AISDKThreads.js +22 -23
- package/dist/runtime/AISDKThreads.js.map +1 -1
- package/dist/runtime/sdkIdentity.d.ts +1 -3
- package/dist/runtime/sdkIdentity.d.ts.map +1 -1
- package/dist/runtime/sdkIdentity.js +1 -1
- package/dist/runtime/useAISDKRuntime.d.ts +69 -70
- package/dist/runtime/useAISDKRuntime.d.ts.map +1 -1
- package/dist/runtime/useAISDKRuntime.js +112 -56
- package/dist/runtime/useAISDKRuntime.js.map +1 -1
- package/dist/runtime/useChatRuntime.d.ts +6 -8
- package/dist/runtime/useChatRuntime.d.ts.map +1 -1
- package/dist/runtime/useChatRuntime.js +14 -10
- package/dist/runtime/useChatRuntime.js.map +1 -1
- package/dist/runtime/useChatThread.d.ts +94 -89
- package/dist/runtime/useChatThread.d.ts.map +1 -1
- package/dist/runtime/useChatThread.js +4 -5
- package/dist/runtime/useChatThread.js.map +1 -1
- package/dist/runtime/useExternalHistory.d.ts +7 -7
- package/dist/runtime/useExternalHistory.d.ts.map +1 -1
- package/dist/runtime/useExternalHistory.js +229 -59
- package/dist/runtime/useExternalHistory.js.map +1 -1
- package/dist/runtime/useResourceCleanup.d.ts +1 -3
- package/dist/runtime/useResourceCleanup.d.ts.map +1 -1
- package/dist/runtime/useResourceCleanup.js +38 -14
- package/dist/runtime/useResourceCleanup.js.map +1 -1
- package/dist/runtime/useStreamingTiming.d.ts +3 -5
- package/dist/runtime/useStreamingTiming.d.ts.map +1 -1
- package/dist/runtime/useStreamingTiming.js +1 -1
- package/dist/tools/frontendTools.d.ts +21 -23
- package/dist/tools/frontendTools.d.ts.map +1 -1
- package/dist/tools/generativeTools.d.ts +24 -26
- package/dist/tools/generativeTools.d.ts.map +1 -1
- package/dist/tools/mcp-stdio.node.d.ts +2 -2
- package/dist/tools/mcp-stdio.node.d.ts.map +1 -0
- package/dist/tools/mcp-stdio.unsupported.d.ts +2 -4
- package/dist/tools/mcp-stdio.unsupported.d.ts.map +1 -1
- package/dist/transport/AssistantChatTransport.d.ts +14 -16
- package/dist/transport/AssistantChatTransport.d.ts.map +1 -1
- package/dist/transport/resumable.d.ts +25 -27
- package/dist/transport/resumable.d.ts.map +1 -1
- package/dist/usage.d.ts +8 -10
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js.map +1 -1
- package/dist/utils/getVercelAIMessages.d.ts +2 -4
- package/dist/utils/getVercelAIMessages.d.ts.map +1 -1
- package/dist/utils/sliceMessagesUntil.d.ts +1 -3
- package/dist/utils/sliceMessagesUntil.d.ts.map +1 -1
- package/package.json +9 -8
- package/src/adapters/vercelAttachmentAdapter.test.ts +23 -0
- package/src/adapters/vercelAttachmentAdapter.ts +2 -2
- package/src/converters/convertMessage.test.ts +478 -3
- package/src/converters/convertMessage.ts +100 -14
- package/src/index.native.ts +1 -1
- package/src/index.ts +1 -1
- package/src/runtime/AISDKThreads.cloud.test.ts +60 -2
- package/src/runtime/AISDKThreads.test.ts +79 -46
- package/src/runtime/AISDKThreads.ts +1 -1
- package/src/runtime/useAISDKRuntime.approval.integration.test.tsx +51 -0
- package/src/runtime/useAISDKRuntime.approval.test.tsx +225 -9
- package/src/runtime/useAISDKRuntime.test.ts +275 -5
- package/src/runtime/useAISDKRuntime.ts +141 -37
- package/src/runtime/useAISDKRuntime.voice.test.tsx +50 -1
- package/src/runtime/useChatRuntime.integration.test.tsx +56 -0
- package/src/runtime/useChatRuntime.test.ts +5 -1
- package/src/runtime/useChatRuntime.ts +6 -2
- package/src/runtime/useChatThread.transport.test.tsx +149 -0
- package/src/runtime/useChatThread.ts +33 -5
- package/src/runtime/useExternalHistory.test.ts +943 -3
- package/src/runtime/useExternalHistory.ts +366 -14
- package/src/runtime/useResourceCleanup.ts +41 -15
- package/src/usage.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { MessageRepository, readToolInteractionLog } from "@assistant-ui/core/internal";
|
|
3
3
|
import { getExternalStoreMessages } from "@assistant-ui/core";
|
|
4
|
-
import {
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
|
|
5
5
|
import { useAui } from "@assistant-ui/store";
|
|
6
6
|
//#region src/runtime/useExternalHistory.ts
|
|
7
7
|
const toExportedMessageRepository = (toThreadMessages, messages) => {
|
|
@@ -26,8 +26,106 @@ const toExportedMessageRepository = (toThreadMessages, messages) => {
|
|
|
26
26
|
};
|
|
27
27
|
const isAwaitingToolApproval = (message) => message.status?.type === "requires-action" && message.status.reason === "tool-calls";
|
|
28
28
|
const isTerminalMessage = (message) => message.status === void 0 || message.status.type === "complete" || message.status.type === "incomplete";
|
|
29
|
+
const TOOL_ARTIFACTS_METADATA_KEY = "__aui_toolArtifacts";
|
|
30
|
+
const TOOL_INTERACTIONS_METADATA_KEY = "__aui_toolInteractions";
|
|
31
|
+
const TOOL_APPROVAL_RESPONSES_METADATA_KEY = "__aui_toolApprovalResponses";
|
|
32
|
+
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
33
|
+
const collectToolArtifacts = (message, toolArtifacts) => {
|
|
34
|
+
if (!toolArtifacts) return void 0;
|
|
35
|
+
const entries = message.content.flatMap((part) => {
|
|
36
|
+
if (part.type !== "tool-call") return [];
|
|
37
|
+
const artifact = toolArtifacts.get(part.toolCallId);
|
|
38
|
+
return artifact === void 0 ? [] : [[part.toolCallId, artifact]];
|
|
39
|
+
});
|
|
40
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
41
|
+
};
|
|
42
|
+
const collectToolInteractions = (message, toolInteractions) => {
|
|
43
|
+
if (!toolInteractions) return void 0;
|
|
44
|
+
const entries = message.content.flatMap((part) => {
|
|
45
|
+
if (part.type !== "tool-call") return [];
|
|
46
|
+
const interactions = toolInteractions.get(part.toolCallId);
|
|
47
|
+
return interactions === void 0 ? [] : [[part.toolCallId, interactions]];
|
|
48
|
+
});
|
|
49
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
50
|
+
};
|
|
51
|
+
const collectToolApprovalResponses = (message, toolApprovalResponses) => {
|
|
52
|
+
if (!toolApprovalResponses) return void 0;
|
|
53
|
+
const entries = message.content.flatMap((part) => {
|
|
54
|
+
if (part.type !== "tool-call" || !part.approval) return [];
|
|
55
|
+
const response = toolApprovalResponses.get(part.approval.id);
|
|
56
|
+
if (!response) return [];
|
|
57
|
+
return [[part.approval.id, {
|
|
58
|
+
approved: response.approved,
|
|
59
|
+
...response.optionId != null && { optionId: response.optionId },
|
|
60
|
+
...response.text != null && { text: response.text },
|
|
61
|
+
...response.reason != null && { reason: response.reason }
|
|
62
|
+
}]];
|
|
63
|
+
});
|
|
64
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
65
|
+
};
|
|
66
|
+
const addToolData = (message, toolArtifacts, toolInteractions, toolApprovalResponses) => {
|
|
67
|
+
if (!toolArtifacts && !toolInteractions && !toolApprovalResponses || !isRecord(message) || !Array.isArray(message.parts)) return message;
|
|
68
|
+
const toolCallIds = message.parts.flatMap((part) => {
|
|
69
|
+
if (!isRecord(part) || typeof part.toolCallId !== "string") return [];
|
|
70
|
+
return [part.toolCallId];
|
|
71
|
+
});
|
|
72
|
+
const artifacts = toolArtifacts ? Object.fromEntries(toolCallIds.flatMap((toolCallId) => Object.hasOwn(toolArtifacts, toolCallId) ? [[toolCallId, toolArtifacts[toolCallId]]] : [])) : void 0;
|
|
73
|
+
const interactions = toolInteractions ? Object.fromEntries(toolCallIds.flatMap((toolCallId) => Object.hasOwn(toolInteractions, toolCallId) ? [[toolCallId, toolInteractions[toolCallId]]] : [])) : void 0;
|
|
74
|
+
const approvalIds = message.parts.flatMap((part) => {
|
|
75
|
+
if (!isRecord(part) || !isRecord(part.approval)) return [];
|
|
76
|
+
const approvalId = part.approval.id;
|
|
77
|
+
return typeof approvalId === "string" ? [approvalId] : [];
|
|
78
|
+
});
|
|
79
|
+
const approvalResponses = toolApprovalResponses ? Object.fromEntries(approvalIds.flatMap((approvalId) => Object.hasOwn(toolApprovalResponses, approvalId) ? [[approvalId, toolApprovalResponses[approvalId]]] : [])) : void 0;
|
|
80
|
+
const hasArtifacts = !!artifacts && Object.keys(artifacts).length > 0;
|
|
81
|
+
const hasInteractions = !!interactions && Object.keys(interactions).length > 0;
|
|
82
|
+
const hasApprovalResponses = !!approvalResponses && Object.keys(approvalResponses).length > 0;
|
|
83
|
+
if (!hasArtifacts && !hasInteractions && !hasApprovalResponses) return message;
|
|
84
|
+
const metadata = isRecord(message.metadata) ? message.metadata : {};
|
|
85
|
+
return {
|
|
86
|
+
...message,
|
|
87
|
+
metadata: {
|
|
88
|
+
...metadata,
|
|
89
|
+
...hasArtifacts && { [TOOL_ARTIFACTS_METADATA_KEY]: artifacts },
|
|
90
|
+
...hasInteractions && { [TOOL_INTERACTIONS_METADATA_KEY]: interactions },
|
|
91
|
+
...hasApprovalResponses && { [TOOL_APPROVAL_RESPONSES_METADATA_KEY]: approvalResponses }
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const restoreToolData = (message, toolArtifacts, toolInteractions, toolApprovalResponses) => {
|
|
96
|
+
if (!isRecord(message) || !isRecord(message.metadata)) return message;
|
|
97
|
+
const metadata = message.metadata;
|
|
98
|
+
const hasArtifacts = Object.hasOwn(metadata, TOOL_ARTIFACTS_METADATA_KEY);
|
|
99
|
+
const hasInteractions = Object.hasOwn(metadata, TOOL_INTERACTIONS_METADATA_KEY);
|
|
100
|
+
const hasApprovalResponses = Object.hasOwn(metadata, TOOL_APPROVAL_RESPONSES_METADATA_KEY);
|
|
101
|
+
if (!hasArtifacts && !hasInteractions && !hasApprovalResponses) return message;
|
|
102
|
+
const artifacts = metadata[TOOL_ARTIFACTS_METADATA_KEY];
|
|
103
|
+
if (toolArtifacts && isRecord(artifacts)) for (const [toolCallId, artifact] of Object.entries(artifacts)) toolArtifacts.set(toolCallId, artifact);
|
|
104
|
+
const interactions = metadata[TOOL_INTERACTIONS_METADATA_KEY];
|
|
105
|
+
if (toolInteractions && isRecord(interactions)) for (const [toolCallId, value] of Object.entries(interactions)) {
|
|
106
|
+
const log = readToolInteractionLog(value);
|
|
107
|
+
if (log) toolInteractions.set(toolCallId, log);
|
|
108
|
+
}
|
|
109
|
+
const approvalResponses = metadata[TOOL_APPROVAL_RESPONSES_METADATA_KEY];
|
|
110
|
+
if (toolApprovalResponses && isRecord(approvalResponses)) for (const [approvalId, value] of Object.entries(approvalResponses)) {
|
|
111
|
+
if (!isRecord(value) || typeof value.approved !== "boolean") continue;
|
|
112
|
+
toolApprovalResponses.set(approvalId, {
|
|
113
|
+
approvalId,
|
|
114
|
+
approved: value.approved,
|
|
115
|
+
...typeof value.optionId === "string" && { optionId: value.optionId },
|
|
116
|
+
...typeof value.text === "string" && { text: value.text },
|
|
117
|
+
...typeof value.reason === "string" && { reason: value.reason }
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const { [TOOL_ARTIFACTS_METADATA_KEY]: _, [TOOL_INTERACTIONS_METADATA_KEY]: __, [TOOL_APPROVAL_RESPONSES_METADATA_KEY]: ___, ...restMetadata } = metadata;
|
|
121
|
+
const { metadata: _metadata, ...restMessage } = message;
|
|
122
|
+
return Object.keys(restMetadata).length === 0 ? restMessage : {
|
|
123
|
+
...restMessage,
|
|
124
|
+
metadata: restMetadata
|
|
125
|
+
};
|
|
126
|
+
};
|
|
29
127
|
const encodeContent = (storageFormatAdapter, item) => JSON.stringify(storageFormatAdapter.encode(item));
|
|
30
|
-
const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storageFormatAdapter, onSetMessages) => {
|
|
128
|
+
const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storageFormatAdapter, onSetMessages, toolArtifacts, onToolArtifactsRestored, toolInteractions, onToolInteractionsRestored, toolApprovalResponses, onToolApprovalResponsesRestored) => {
|
|
31
129
|
const loadedRef = useRef(false);
|
|
32
130
|
const [itemEpoch, setItemEpoch] = useState(0);
|
|
33
131
|
const aui = useAui();
|
|
@@ -51,12 +149,26 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
|
|
|
51
149
|
const loadHistory = async () => {
|
|
52
150
|
try {
|
|
53
151
|
const repo = await formatAdapter.load();
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
152
|
+
toolArtifacts?.clear();
|
|
153
|
+
toolInteractions?.clear();
|
|
154
|
+
toolApprovalResponses?.clear();
|
|
155
|
+
const restoredMessages = repo?.messages.map((item) => ({
|
|
156
|
+
...item,
|
|
157
|
+
message: restoreToolData(item.message, toolArtifacts, toolInteractions, toolApprovalResponses)
|
|
158
|
+
})) ?? [];
|
|
159
|
+
onToolArtifactsRestored?.();
|
|
160
|
+
onToolInteractionsRestored?.();
|
|
161
|
+
onToolApprovalResponsesRestored?.();
|
|
162
|
+
if (repo && restoredMessages.length > 0) {
|
|
163
|
+
const restoredRepo = {
|
|
164
|
+
...repo,
|
|
165
|
+
messages: restoredMessages
|
|
166
|
+
};
|
|
167
|
+
for (const [index, m] of repo.messages.entries()) persistedInnerMessages.current.set(storageFormatAdapter.getId(m.message), {
|
|
168
|
+
source: restoredMessages[index].message,
|
|
57
169
|
content: encodeContent(storageFormatAdapter, m)
|
|
58
170
|
});
|
|
59
|
-
const converted = toExportedMessageRepository(toThreadMessages,
|
|
171
|
+
const converted = toExportedMessageRepository(toThreadMessages, restoredRepo);
|
|
60
172
|
runtimeRef.current.thread.import(converted);
|
|
61
173
|
const tempRepo = new MessageRepository();
|
|
62
174
|
tempRepo.import(converted);
|
|
@@ -96,7 +208,13 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
|
|
|
96
208
|
optionalThreadListItem,
|
|
97
209
|
aui,
|
|
98
210
|
itemEpoch,
|
|
99
|
-
storageFormatAdapter
|
|
211
|
+
storageFormatAdapter,
|
|
212
|
+
toolArtifacts,
|
|
213
|
+
onToolArtifactsRestored,
|
|
214
|
+
toolInteractions,
|
|
215
|
+
onToolInteractionsRestored,
|
|
216
|
+
toolApprovalResponses,
|
|
217
|
+
onToolApprovalResponsesRestored
|
|
100
218
|
]);
|
|
101
219
|
const runStartRef = useRef(null);
|
|
102
220
|
const persistTimerRef = useRef(null);
|
|
@@ -104,11 +222,55 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
|
|
|
104
222
|
const stepBoundariesRef = useRef([]);
|
|
105
223
|
const wasRunningRef = useRef(false);
|
|
106
224
|
const toolCallCountRef = useRef(0);
|
|
225
|
+
const persistToolInteractions = useCallback((messageId) => {
|
|
226
|
+
const persistence = persistInFlightRef.current.then(async () => {
|
|
227
|
+
if (!formatAdapter?.update) return;
|
|
228
|
+
const messages_0 = runtimeRef.current.thread.getState().messages;
|
|
229
|
+
const message = messages_0.find((item_0) => item_0.id === messageId || getExternalStoreMessages(item_0).some((innerMessage) => storageFormatAdapter.getId(innerMessage) === messageId));
|
|
230
|
+
if (!message) return;
|
|
231
|
+
const previousMessages = messages_0.slice(0, messages_0.indexOf(message)).flatMap(getExternalStoreMessages);
|
|
232
|
+
let parentId = previousMessages.at(-1) ? storageFormatAdapter.getId(previousMessages.at(-1)) : null;
|
|
233
|
+
const storedToolArtifacts = collectToolArtifacts(message, toolArtifacts);
|
|
234
|
+
const storedToolInteractions = collectToolInteractions(message, toolInteractions);
|
|
235
|
+
const storedToolApprovalResponses = collectToolApprovalResponses(message, toolApprovalResponses);
|
|
236
|
+
for (const innerMessage_0 of getExternalStoreMessages(message)) {
|
|
237
|
+
const item_1 = {
|
|
238
|
+
parentId,
|
|
239
|
+
message: addToolData(innerMessage_0, storedToolArtifacts, storedToolInteractions, storedToolApprovalResponses)
|
|
240
|
+
};
|
|
241
|
+
const innerId = storageFormatAdapter.getId(item_1.message);
|
|
242
|
+
const persisted = persistedInnerMessages.current.get(innerId);
|
|
243
|
+
if (persisted) {
|
|
244
|
+
const content = encodeContent(storageFormatAdapter, item_1);
|
|
245
|
+
if (content === persisted.content) persisted.source = item_1.message;
|
|
246
|
+
else {
|
|
247
|
+
await formatAdapter.update(item_1, innerId);
|
|
248
|
+
persistedInnerMessages.current.set(innerId, {
|
|
249
|
+
source: item_1.message,
|
|
250
|
+
content
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
parentId = innerId;
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
persistInFlightRef.current = persistence.catch(() => {});
|
|
258
|
+
return persistence.catch((error_0) => {
|
|
259
|
+
console.error("Failed to persist tool data:", error_0);
|
|
260
|
+
});
|
|
261
|
+
}, [
|
|
262
|
+
formatAdapter,
|
|
263
|
+
runtimeRef,
|
|
264
|
+
storageFormatAdapter,
|
|
265
|
+
toolArtifacts,
|
|
266
|
+
toolInteractions,
|
|
267
|
+
toolApprovalResponses
|
|
268
|
+
]);
|
|
107
269
|
useEffect(() => {
|
|
108
270
|
if (!formatAdapter) return;
|
|
109
271
|
const adapter = formatAdapter;
|
|
110
272
|
const idleScheduledInnerIds = /* @__PURE__ */ new Set();
|
|
111
|
-
const unpersistedInnerIds = (
|
|
273
|
+
const unpersistedInnerIds = (message_0) => isTerminalMessage(message_0) ? getExternalStoreMessages(message_0).map((innerMessage_1) => storageFormatAdapter.getId(innerMessage_1)).filter((innerId_0) => !persistedInnerMessages.current.has(innerId_0)) : [];
|
|
112
274
|
const unsubscribe = runtimeRef.current.thread.subscribe(() => {
|
|
113
275
|
const threadState_0 = runtimeRef.current.thread.getState();
|
|
114
276
|
const { isRunning } = threadState_0;
|
|
@@ -141,8 +303,8 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
|
|
|
141
303
|
if (runStartRef.current != null) stepBoundariesRef.current.push(Date.now() - runStartRef.current);
|
|
142
304
|
} else {
|
|
143
305
|
const pending = threadState_0.messages.flatMap(unpersistedInnerIds);
|
|
144
|
-
if (pending.every((
|
|
145
|
-
for (const
|
|
306
|
+
if (pending.every((innerId_1) => idleScheduledInnerIds.has(innerId_1))) return;
|
|
307
|
+
for (const innerId_2 of pending) idleScheduledInnerIds.add(innerId_2);
|
|
146
308
|
}
|
|
147
309
|
if (persistTimerRef.current) clearTimeout(persistTimerRef.current);
|
|
148
310
|
persistTimerRef.current = setTimeout(() => {
|
|
@@ -188,58 +350,61 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
|
|
|
188
350
|
...stepTimestamps != null ? { stepTimestamps } : void 0
|
|
189
351
|
};
|
|
190
352
|
persistInFlightRef.current = persistInFlightRef.current.then(async () => {
|
|
191
|
-
const { messages:
|
|
353
|
+
const { messages: messages_1 } = latest;
|
|
192
354
|
let lastInnerMessageId = null;
|
|
193
355
|
const getLastInnerId = (msgs) => msgs.length > 0 ? storageFormatAdapter.getId(msgs.at(-1)) : null;
|
|
194
|
-
const toBatchItems = (msgs_0) => msgs_0.map((msg, idx) => ({
|
|
356
|
+
const toBatchItems = (msgs_0, toolArtifacts_0, toolInteractions_0, toolApprovalResponses_0) => msgs_0.map((msg, idx) => ({
|
|
195
357
|
parentId: idx === 0 ? lastInnerMessageId : storageFormatAdapter.getId(msgs_0[idx - 1]),
|
|
196
|
-
message: msg
|
|
358
|
+
message: addToolData(msg, toolArtifacts_0, toolInteractions_0, toolApprovalResponses_0)
|
|
197
359
|
}));
|
|
198
|
-
for (const
|
|
199
|
-
const innerMessages = getExternalStoreMessages(
|
|
200
|
-
const isTerminal = isTerminalMessage(
|
|
201
|
-
const isAwaitingToolCalls = isAwaitingToolApproval(
|
|
360
|
+
for (const message_1 of messages_1) {
|
|
361
|
+
const innerMessages = getExternalStoreMessages(message_1);
|
|
362
|
+
const isTerminal = isTerminalMessage(message_1);
|
|
363
|
+
const isAwaitingToolCalls = isAwaitingToolApproval(message_1);
|
|
202
364
|
if (!(isTerminal || isAwaitingToolCalls && adapter.update !== void 0)) {
|
|
203
365
|
lastInnerMessageId = getLastInnerId(innerMessages) ?? lastInnerMessageId;
|
|
204
366
|
continue;
|
|
205
367
|
}
|
|
206
|
-
if (!historyIds.current.has(
|
|
207
|
-
historyIds.current.add(
|
|
208
|
-
deferredTelemetryIds.current.add(
|
|
368
|
+
if (!historyIds.current.has(message_1.id)) {
|
|
369
|
+
historyIds.current.add(message_1.id);
|
|
370
|
+
deferredTelemetryIds.current.add(message_1.id);
|
|
209
371
|
}
|
|
210
|
-
const batchItems = toBatchItems(innerMessages);
|
|
211
|
-
for (const
|
|
212
|
-
const
|
|
213
|
-
const
|
|
214
|
-
if (!
|
|
215
|
-
await adapter.append(
|
|
216
|
-
persistedInnerMessages.current.set(
|
|
217
|
-
source:
|
|
218
|
-
content: encodeContent(storageFormatAdapter,
|
|
372
|
+
const batchItems = toBatchItems(innerMessages, collectToolArtifacts(message_1, toolArtifacts), collectToolInteractions(message_1, toolInteractions), collectToolApprovalResponses(message_1, toolApprovalResponses));
|
|
373
|
+
for (const item_2 of batchItems) {
|
|
374
|
+
const innerId_3 = storageFormatAdapter.getId(item_2.message);
|
|
375
|
+
const persisted_0 = persistedInnerMessages.current.get(innerId_3);
|
|
376
|
+
if (!persisted_0) {
|
|
377
|
+
await adapter.append(item_2);
|
|
378
|
+
persistedInnerMessages.current.set(innerId_3, {
|
|
379
|
+
source: item_2.message,
|
|
380
|
+
content: encodeContent(storageFormatAdapter, item_2)
|
|
219
381
|
});
|
|
220
|
-
} else if (
|
|
221
|
-
const
|
|
222
|
-
if (
|
|
382
|
+
} else if (persisted_0.source !== item_2.message && durationMs !== void 0 && adapter.update) {
|
|
383
|
+
const content_0 = encodeContent(storageFormatAdapter, item_2);
|
|
384
|
+
if (content_0 === persisted_0.content) persisted_0.source = item_2.message;
|
|
223
385
|
else try {
|
|
224
|
-
await adapter.update(
|
|
225
|
-
persistedInnerMessages.current.set(
|
|
226
|
-
source:
|
|
227
|
-
content
|
|
386
|
+
await adapter.update(item_2, innerId_3);
|
|
387
|
+
persistedInnerMessages.current.set(innerId_3, {
|
|
388
|
+
source: item_2.message,
|
|
389
|
+
content: content_0
|
|
228
390
|
});
|
|
229
391
|
} catch {}
|
|
230
392
|
}
|
|
231
393
|
}
|
|
232
394
|
lastInnerMessageId = getLastInnerId(innerMessages) ?? lastInnerMessageId;
|
|
233
|
-
if (deferredTelemetryIds.current.has(
|
|
234
|
-
deferredTelemetryIds.current.delete(
|
|
235
|
-
adapter.reportTelemetry?.(batchItems, {
|
|
395
|
+
if (deferredTelemetryIds.current.has(message_1.id) && isTerminal) {
|
|
396
|
+
deferredTelemetryIds.current.delete(message_1.id);
|
|
397
|
+
adapter.reportTelemetry?.(batchItems.map((item_3, index_0) => ({
|
|
398
|
+
...item_3,
|
|
399
|
+
message: innerMessages[index_0]
|
|
400
|
+
})), {
|
|
236
401
|
...telemetryOptions,
|
|
237
|
-
message:
|
|
402
|
+
message: message_1
|
|
238
403
|
});
|
|
239
404
|
}
|
|
240
405
|
}
|
|
241
|
-
}).catch((
|
|
242
|
-
console.error("Failed to persist message history:",
|
|
406
|
+
}).catch((error_1) => {
|
|
407
|
+
console.error("Failed to persist message history:", error_1);
|
|
243
408
|
});
|
|
244
409
|
}
|
|
245
410
|
return () => {
|
|
@@ -253,31 +418,34 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
|
|
|
253
418
|
}, [
|
|
254
419
|
formatAdapter,
|
|
255
420
|
storageFormatAdapter,
|
|
256
|
-
runtimeRef
|
|
421
|
+
runtimeRef,
|
|
422
|
+
toolArtifacts,
|
|
423
|
+
toolInteractions,
|
|
424
|
+
toolApprovalResponses
|
|
257
425
|
]);
|
|
258
426
|
return {
|
|
259
427
|
isLoading,
|
|
260
|
-
deleteMessage: useCallback(async (
|
|
428
|
+
deleteMessage: useCallback(async (messageId_0) => {
|
|
261
429
|
const deleteMessages = formatAdapter?.delete?.bind(formatAdapter);
|
|
262
430
|
if (!deleteMessages) return;
|
|
263
|
-
const
|
|
264
|
-
const messageIndex =
|
|
431
|
+
const messages_2 = runtimeRef.current.thread.getState().messages;
|
|
432
|
+
const messageIndex = messages_2.findIndex((m_2) => m_2.id === messageId_0);
|
|
265
433
|
if (messageIndex === -1) return;
|
|
266
|
-
const previousInnerMessages =
|
|
267
|
-
let
|
|
268
|
-
const itemsToDelete = getExternalStoreMessages(
|
|
269
|
-
const
|
|
270
|
-
parentId,
|
|
271
|
-
message:
|
|
434
|
+
const previousInnerMessages = messages_2.slice(0, messageIndex).flatMap(getExternalStoreMessages);
|
|
435
|
+
let parentId_0 = previousInnerMessages.at(-1) ? storageFormatAdapter.getId(previousInnerMessages.at(-1)) : null;
|
|
436
|
+
const itemsToDelete = getExternalStoreMessages(messages_2[messageIndex]).map((message_2) => {
|
|
437
|
+
const item_4 = {
|
|
438
|
+
parentId: parentId_0,
|
|
439
|
+
message: message_2
|
|
272
440
|
};
|
|
273
|
-
|
|
274
|
-
return
|
|
441
|
+
parentId_0 = storageFormatAdapter.getId(message_2);
|
|
442
|
+
return item_4;
|
|
275
443
|
});
|
|
276
444
|
const deletion = persistInFlightRef.current.then(async () => {
|
|
277
445
|
await deleteMessages(itemsToDelete);
|
|
278
|
-
historyIds.current.delete(
|
|
279
|
-
deferredTelemetryIds.current.delete(
|
|
280
|
-
for (const
|
|
446
|
+
historyIds.current.delete(messageId_0);
|
|
447
|
+
deferredTelemetryIds.current.delete(messageId_0);
|
|
448
|
+
for (const item_5 of itemsToDelete) persistedInnerMessages.current.delete(storageFormatAdapter.getId(item_5.message));
|
|
281
449
|
});
|
|
282
450
|
persistInFlightRef.current = deletion.catch(() => {});
|
|
283
451
|
await deletion;
|
|
@@ -285,7 +453,9 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
|
|
|
285
453
|
formatAdapter,
|
|
286
454
|
runtimeRef,
|
|
287
455
|
storageFormatAdapter
|
|
288
|
-
])
|
|
456
|
+
]),
|
|
457
|
+
persistToolInteractions,
|
|
458
|
+
persistToolApprovalResponses: persistToolInteractions
|
|
289
459
|
};
|
|
290
460
|
};
|
|
291
461
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useExternalHistory.js","names":["AssistantRuntime","ThreadHistoryAdapter","ThreadMessage","MessageFormatAdapter","MessageFormatItem","MessageFormatRepository","ExportedMessageRepository","getExternalStoreMessages","MessageRepository","useAui","useRef","useEffect","useState","RefObject","useCallback","useMemo","toExportedMessageRepository","toThreadMessages","messages","TMessage","survivingIds","Set","survivors","flatMap","m","message","console","warn","parentId","has","add","id","headId","isAwaitingToolApproval","status","type","reason","isTerminalMessage","undefined","encodeContent","storageFormatAdapter","item","JSON","stringify","encode","useExternalHistory","runtimeRef","historyAdapter","onSetMessages","loadedRef","itemEpoch","setItemEpoch","aui","optionalThreadListItem","threadListItem","source","hasLoaded","setHasLoaded","historyIds","deferredTelemetryIds","persistedInnerMessages","Map","content","onSetMessagesRef","current","formatAdapter","withFormat","Error","isLoading","loadHistory","repo","load","length","set","getId","converted","thread","import","tempRepo","getMessages","error","pin","remoteId","getState","subscribe","n","threadState","isRunning","runStartRef","persistTimerRef","ReturnType","setTimeout","persistInFlightRef","Promise","resolve","stepBoundariesRef","wasRunningRef","toolCallCountRef","adapter","idleScheduledInnerIds","unpersistedInnerIds","map","innerMessage","filter","innerId","unsubscribe","wasRunning","lastMsg","at","role","currentToolCallCount","p","push","Date","now","clearTimeout","pending","every","persistSettled","initialThreadState","ignoreRunning","latest","boundaries","durationMs","lastAssistant","findLast","tcCount","totalSteps","stepDur","i","Math","round","stepTimestamps","endMs","start_ms","end_ms","telemetryOptions","then","lastInnerMessageId","getLastInnerId","msgs","toBatchItems","msg","idx","innerMessages","isTerminal","isAwaitingToolCalls","isReady","update","batchItems","persisted","get","append","delete","reportTelemetry","catch","deleteMessage","messageId","deleteMessages","bind","messageIndex","findIndex","previousInnerMessages","slice","itemsToDelete","deletion"],"sources":["../../src/runtime/useExternalHistory.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n AssistantRuntime,\n ThreadHistoryAdapter,\n ThreadMessage,\n MessageFormatAdapter,\n MessageFormatItem,\n MessageFormatRepository,\n ExportedMessageRepository,\n} from \"@assistant-ui/core\";\nimport { getExternalStoreMessages } from \"@assistant-ui/core\";\nimport { MessageRepository } from \"@assistant-ui/core/internal\";\nimport { useAui } from \"@assistant-ui/store\";\nimport {\n useRef,\n useEffect,\n useState,\n type RefObject,\n useCallback,\n useMemo,\n} from \"react\";\n\nexport const toExportedMessageRepository = <TMessage>(\n toThreadMessages: (messages: TMessage[]) => ThreadMessage[],\n messages: MessageFormatRepository<TMessage>,\n): ExportedMessageRepository => {\n const survivingIds = new Set<string>();\n const survivors = messages.messages.flatMap((m) => {\n const message = toThreadMessages([m.message])[0];\n if (!message) {\n console.warn(\"Skipping a stored message that could not be loaded.\");\n return [];\n }\n if (m.parentId && !survivingIds.has(m.parentId)) return [];\n survivingIds.add(message.id);\n return [{ ...m, message }];\n });\n\n return {\n headId:\n messages.headId && survivingIds.has(messages.headId)\n ? messages.headId\n : null,\n messages: survivors,\n };\n};\n\nconst isAwaitingToolApproval = (message: ThreadMessage) =>\n message.status?.type === \"requires-action\" &&\n message.status.reason === \"tool-calls\";\n\nconst isTerminalMessage = (message: ThreadMessage) =>\n message.status === undefined ||\n message.status.type === \"complete\" ||\n message.status.type === \"incomplete\";\n\nconst encodeContent = <TMessage>(\n storageFormatAdapter: MessageFormatAdapter<TMessage, any>,\n item: MessageFormatItem<TMessage>,\n) => JSON.stringify(storageFormatAdapter.encode(item));\n\nexport const useExternalHistory = <TMessage>(\n runtimeRef: RefObject<AssistantRuntime>,\n historyAdapter: ThreadHistoryAdapter | undefined,\n toThreadMessages: (messages: TMessage[]) => ThreadMessage[],\n storageFormatAdapter: MessageFormatAdapter<TMessage, any>,\n onSetMessages: (messages: TMessage[]) => void,\n) => {\n const loadedRef = useRef(false);\n const [itemEpoch, setItemEpoch] = useState(0);\n\n const aui = useAui();\n const optionalThreadListItem = useCallback(\n () => (aui.threadListItem.source ? aui.threadListItem : null),\n [aui],\n );\n\n const [hasLoaded, setHasLoaded] = useState(false);\n\n const historyIds = useRef(new Set<string>());\n const deferredTelemetryIds = useRef(new Set<string>());\n // `content` is a snapshot taken at write time rather than a re-encode of `source`, because a retained message object can be mutated in place by the runtime that produced it.\n const persistedInnerMessages = useRef(\n new Map<string, { source: TMessage; content: string }>(),\n );\n\n const onSetMessagesRef = useRef(onSetMessages);\n useEffect(() => {\n onSetMessagesRef.current = onSetMessages;\n });\n\n const formatAdapter = useMemo(() => {\n if (!historyAdapter) return undefined;\n if (!historyAdapter.withFormat) {\n throw new Error(\n \"useAISDKRuntime: ThreadHistoryAdapter is missing the required `withFormat` method.\",\n );\n }\n return historyAdapter.withFormat<TMessage, any>(storageFormatAdapter);\n }, [historyAdapter, storageFormatAdapter]);\n\n const isLoading = formatAdapter != null && !hasLoaded;\n\n useEffect(() => {\n if (!formatAdapter || loadedRef.current) return undefined;\n\n const loadHistory = async () => {\n try {\n const repo = await formatAdapter.load();\n if (repo && repo.messages.length > 0) {\n for (const m of repo.messages) {\n persistedInnerMessages.current.set(\n storageFormatAdapter.getId(m.message),\n {\n source: m.message,\n content: encodeContent(storageFormatAdapter, m),\n },\n );\n }\n const converted = toExportedMessageRepository(toThreadMessages, repo);\n runtimeRef.current.thread.import(converted);\n\n const tempRepo = new MessageRepository();\n tempRepo.import(converted);\n const messages = tempRepo.getMessages();\n\n onSetMessagesRef.current(\n messages.flatMap(getExternalStoreMessages<TMessage>),\n );\n\n historyIds.current = new Set();\n for (const m of converted.messages) {\n historyIds.current.add(m.message.id);\n if (isAwaitingToolApproval(m.message)) {\n deferredTelemetryIds.current.add(m.message.id);\n }\n }\n }\n } catch (error) {\n console.error(\"Failed to load message history:\", error);\n } finally {\n setHasLoaded(true);\n }\n };\n\n formatAdapter.pin?.();\n\n const remoteId = optionalThreadListItem()?.getState().remoteId;\n if (!remoteId) {\n // History loads asynchronously against the thread list item; without a\n // remote id there is nothing to await, so the flag settles here.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setHasLoaded(true);\n return aui.subscribe(() => {\n if (optionalThreadListItem()?.getState().remoteId) {\n setItemEpoch((n) => n + 1);\n }\n });\n }\n\n const threadState = runtimeRef.current.thread.getState();\n if (threadState.isRunning || threadState.messages.length > 0) {\n loadedRef.current = true;\n setHasLoaded(true);\n return undefined;\n }\n\n loadedRef.current = true;\n void loadHistory();\n return undefined;\n }, [\n formatAdapter,\n toThreadMessages,\n runtimeRef,\n optionalThreadListItem,\n aui,\n itemEpoch,\n storageFormatAdapter,\n ]);\n\n const runStartRef = useRef<number | null>(null);\n const persistTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const persistInFlightRef = useRef<Promise<void>>(Promise.resolve());\n const stepBoundariesRef = useRef<number[]>([]);\n const wasRunningRef = useRef(false);\n const toolCallCountRef = useRef(0);\n\n useEffect(() => {\n if (!formatAdapter) return;\n const adapter = formatAdapter;\n\n const idleScheduledInnerIds = new Set<string>();\n const unpersistedInnerIds = (message: ThreadMessage) =>\n isTerminalMessage(message)\n ? getExternalStoreMessages<TMessage>(message)\n .map((innerMessage) => storageFormatAdapter.getId(innerMessage))\n .filter((innerId) => !persistedInnerMessages.current.has(innerId))\n : [];\n\n const unsubscribe = runtimeRef.current.thread.subscribe(() => {\n const threadState = runtimeRef.current.thread.getState();\n const { isRunning } = threadState;\n const wasRunning = wasRunningRef.current;\n wasRunningRef.current = isRunning;\n\n // Track step boundaries by content changes (more reliable than isRunning)\n if (runStartRef.current != null) {\n const lastMsg = threadState.messages.at(-1);\n if (lastMsg?.role === \"assistant\") {\n const currentToolCallCount = lastMsg.content.filter(\n (p) => p.type === \"tool-call\",\n ).length;\n while (toolCallCountRef.current < currentToolCallCount) {\n stepBoundariesRef.current.push(Date.now() - runStartRef.current);\n toolCallCountRef.current++;\n }\n }\n }\n\n if (isRunning) {\n if (runStartRef.current == null) {\n runStartRef.current = Date.now();\n stepBoundariesRef.current = [];\n toolCallCountRef.current = 0;\n adapter.pin?.();\n }\n // Cancel any pending persist — isRunning went back to true\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n }\n return;\n }\n\n if (wasRunning) {\n // Record step boundary offset (synchronous for accuracy)\n if (runStartRef.current != null) {\n stepBoundariesRef.current.push(Date.now() - runStartRef.current);\n }\n } else {\n const pending = threadState.messages.flatMap(unpersistedInnerIds);\n if (pending.every((innerId) => idleScheduledInnerIds.has(innerId)))\n return;\n for (const innerId of pending) idleScheduledInnerIds.add(innerId);\n }\n\n // Debounce: wait one macrotask so agentic step flickers are absorbed\n if (persistTimerRef.current) clearTimeout(persistTimerRef.current);\n persistTimerRef.current = setTimeout(() => {\n persistSettled(false);\n }, 0);\n });\n\n const initialThreadState = runtimeRef.current.thread.getState();\n wasRunningRef.current = initialThreadState.isRunning;\n if (initialThreadState.isRunning) {\n if (runStartRef.current == null) {\n runStartRef.current = Date.now();\n stepBoundariesRef.current = [];\n toolCallCountRef.current = 0;\n adapter.pin?.();\n }\n } else if (initialThreadState.messages.length > 0) {\n persistSettled(true);\n }\n\n function persistSettled(ignoreRunning: boolean) {\n persistTimerRef.current = null;\n const latest = runtimeRef.current.thread.getState();\n if (!ignoreRunning && latest.isRunning) return;\n\n const boundaries = stepBoundariesRef.current;\n const durationMs = boundaries.length > 0 ? boundaries.at(-1) : undefined;\n\n // Fallback: if only 1 boundary but message has multiple steps, distribute evenly\n if (boundaries.length === 1 && durationMs != null) {\n const lastAssistant = latest.messages.findLast(\n (m) => m.role === \"assistant\",\n );\n if (lastAssistant) {\n const tcCount = lastAssistant.content.filter(\n (p) => p.type === \"tool-call\",\n ).length;\n if (tcCount > 0) {\n const totalSteps = tcCount + 1;\n const stepDur = durationMs / totalSteps;\n boundaries.length = 0;\n for (let i = 0; i < totalSteps; i++) {\n boundaries.push(Math.round((i + 1) * stepDur));\n }\n }\n }\n }\n\n // Build per-step timestamps when there are multiple steps\n const stepTimestamps =\n boundaries.length > 1\n ? boundaries.map((endMs, i) => ({\n start_ms: i === 0 ? 0 : boundaries[i - 1]!,\n end_ms: endMs,\n }))\n : undefined;\n\n runStartRef.current = null;\n stepBoundariesRef.current = [];\n\n const telemetryOptions = {\n ...(durationMs != null ? { durationMs } : undefined),\n ...(stepTimestamps != null ? { stepTimestamps } : undefined),\n };\n\n persistInFlightRef.current = persistInFlightRef.current\n .then(async () => {\n const { messages } = latest;\n let lastInnerMessageId: string | null = null;\n\n const getLastInnerId = (msgs: TMessage[]): string | null =>\n msgs.length > 0 ? storageFormatAdapter.getId(msgs.at(-1)!) : null;\n\n const toBatchItems = (msgs: TMessage[]) =>\n msgs.map((msg, idx) => ({\n parentId:\n idx === 0\n ? lastInnerMessageId\n : storageFormatAdapter.getId(msgs[idx - 1]!),\n message: msg,\n }));\n\n for (const message of messages) {\n const innerMessages = getExternalStoreMessages<TMessage>(message);\n\n const isTerminal = isTerminalMessage(message);\n const isAwaitingToolCalls = isAwaitingToolApproval(message);\n // A paused message's later content can only reach storage via update, so it is persisted early only when the adapter supports update.\n const isReady =\n isTerminal ||\n (isAwaitingToolCalls && adapter.update !== undefined);\n\n if (!isReady) {\n lastInnerMessageId =\n getLastInnerId(innerMessages) ?? lastInnerMessageId;\n continue;\n }\n\n if (!historyIds.current.has(message.id)) {\n historyIds.current.add(message.id);\n deferredTelemetryIds.current.add(message.id);\n }\n\n const batchItems = toBatchItems(innerMessages);\n for (const item of batchItems) {\n const innerId = storageFormatAdapter.getId(item.message);\n const persisted = persistedInnerMessages.current.get(innerId);\n if (!persisted) {\n await adapter.append(item);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content: encodeContent(storageFormatAdapter, item),\n });\n } else if (\n persisted.source !== item.message &&\n durationMs !== undefined &&\n adapter.update\n ) {\n const content = encodeContent(storageFormatAdapter, item);\n if (content === persisted.content) {\n persisted.source = item.message;\n } else {\n try {\n await adapter.update(item, innerId);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content,\n });\n } catch {\n // A failed update leaves the stale baseline behind so the next run stop retries it.\n }\n }\n }\n }\n\n lastInnerMessageId =\n getLastInnerId(innerMessages) ?? lastInnerMessageId;\n\n if (deferredTelemetryIds.current.has(message.id) && isTerminal) {\n deferredTelemetryIds.current.delete(message.id);\n adapter.reportTelemetry?.(batchItems, {\n ...telemetryOptions,\n message,\n });\n }\n }\n })\n .catch((error) => {\n console.error(\"Failed to persist message history:\", error);\n });\n }\n\n return () => {\n unsubscribe();\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n persistSettled(false);\n }\n };\n }, [formatAdapter, storageFormatAdapter, runtimeRef]);\n\n const deleteMessage = useCallback(\n async (messageId: string) => {\n const deleteMessages = formatAdapter?.delete?.bind(formatAdapter);\n if (!deleteMessages) return;\n\n const messages = runtimeRef.current.thread.getState().messages;\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) return;\n\n const previousInnerMessages = messages\n .slice(0, messageIndex)\n .flatMap(getExternalStoreMessages<TMessage>);\n let parentId = previousInnerMessages.at(-1)\n ? storageFormatAdapter.getId(previousInnerMessages.at(-1)!)\n : null;\n const itemsToDelete = getExternalStoreMessages<TMessage>(\n messages[messageIndex]!,\n ).map((message) => {\n const item = { parentId, message };\n parentId = storageFormatAdapter.getId(message);\n return item;\n });\n\n const deletion = persistInFlightRef.current.then(async () => {\n await deleteMessages(itemsToDelete);\n\n historyIds.current.delete(messageId);\n deferredTelemetryIds.current.delete(messageId);\n for (const item of itemsToDelete) {\n persistedInnerMessages.current.delete(\n storageFormatAdapter.getId(item.message),\n );\n }\n });\n\n persistInFlightRef.current = deletion.catch(() => {});\n await deletion;\n },\n [formatAdapter, runtimeRef, storageFormatAdapter],\n );\n\n return { isLoading, deleteMessage };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useExternalHistory.js","names":["AssistantRuntime","ThreadHistoryAdapter","ThreadMessage","MessageFormatAdapter","MessageFormatItem","MessageFormatRepository","ExportedMessageRepository","RespondToToolApprovalOptions","Unstable_ToolInteractionLog","getExternalStoreMessages","MessageRepository","readToolInteractionLog","useAui","useRef","useEffect","useState","RefObject","useCallback","useMemo","toExportedMessageRepository","toThreadMessages","messages","TMessage","survivingIds","Set","survivors","flatMap","m","message","console","warn","parentId","has","add","id","headId","isAwaitingToolApproval","status","type","reason","isTerminalMessage","undefined","TOOL_ARTIFACTS_METADATA_KEY","TOOL_INTERACTIONS_METADATA_KEY","TOOL_APPROVAL_RESPONSES_METADATA_KEY","StoredToolApprovalResponse","Omit","isRecord","value","Record","Array","isArray","collectToolArtifacts","toolArtifacts","ReadonlyMap","entries","content","part","artifact","get","toolCallId","const","length","Object","fromEntries","collectToolInteractions","toolInteractions","interactions","collectToolApprovalResponses","toolApprovalResponses","approval","response","approved","optionId","text","addToolData","parts","toolCallIds","artifacts","hasOwn","approvalIds","approvalId","approvalResponses","hasArtifacts","keys","hasInteractions","hasApprovalResponses","metadata","restoreToolData","Map","set","log","_","__","___","restMetadata","_metadata","restMessage","encodeContent","storageFormatAdapter","item","JSON","stringify","encode","useExternalHistory","runtimeRef","historyAdapter","onSetMessages","onToolArtifactsRestored","onToolInteractionsRestored","onToolApprovalResponsesRestored","loadedRef","itemEpoch","setItemEpoch","aui","optionalThreadListItem","threadListItem","source","hasLoaded","setHasLoaded","historyIds","deferredTelemetryIds","persistedInnerMessages","onSetMessagesRef","current","formatAdapter","withFormat","Error","isLoading","loadHistory","repo","load","clear","restoredMessages","map","restoredRepo","index","getId","converted","thread","import","tempRepo","getMessages","error","pin","remoteId","getState","subscribe","n","threadState","isRunning","runStartRef","persistTimerRef","ReturnType","setTimeout","persistInFlightRef","Promise","resolve","stepBoundariesRef","wasRunningRef","toolCallCountRef","persistToolInteractions","messageId","persistence","then","update","find","some","innerMessage","previousMessages","slice","indexOf","at","storedToolArtifacts","storedToolInteractions","storedToolApprovalResponses","innerId","persisted","catch","adapter","idleScheduledInnerIds","unpersistedInnerIds","filter","unsubscribe","wasRunning","lastMsg","role","currentToolCallCount","p","push","Date","now","clearTimeout","pending","every","persistSettled","initialThreadState","ignoreRunning","latest","boundaries","durationMs","lastAssistant","findLast","tcCount","totalSteps","stepDur","i","Math","round","stepTimestamps","endMs","start_ms","end_ms","telemetryOptions","lastInnerMessageId","getLastInnerId","msgs","toBatchItems","msg","idx","innerMessages","isTerminal","isAwaitingToolCalls","isReady","batchItems","append","delete","reportTelemetry","deleteMessage","deleteMessages","bind","messageIndex","findIndex","previousInnerMessages","itemsToDelete","deletion","persistToolApprovalResponses"],"sources":["../../src/runtime/useExternalHistory.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n AssistantRuntime,\n ThreadHistoryAdapter,\n ThreadMessage,\n MessageFormatAdapter,\n MessageFormatItem,\n MessageFormatRepository,\n ExportedMessageRepository,\n RespondToToolApprovalOptions,\n Unstable_ToolInteractionLog,\n} from \"@assistant-ui/core\";\nimport { getExternalStoreMessages } from \"@assistant-ui/core\";\nimport {\n MessageRepository,\n readToolInteractionLog,\n} from \"@assistant-ui/core/internal\";\nimport { useAui } from \"@assistant-ui/store\";\nimport {\n useRef,\n useEffect,\n useState,\n type RefObject,\n useCallback,\n useMemo,\n} from \"react\";\n\nexport const toExportedMessageRepository = <TMessage>(\n toThreadMessages: (messages: TMessage[]) => ThreadMessage[],\n messages: MessageFormatRepository<TMessage>,\n): ExportedMessageRepository => {\n const survivingIds = new Set<string>();\n const survivors = messages.messages.flatMap((m) => {\n const message = toThreadMessages([m.message])[0];\n if (!message) {\n console.warn(\"Skipping a stored message that could not be loaded.\");\n return [];\n }\n if (m.parentId && !survivingIds.has(m.parentId)) return [];\n survivingIds.add(message.id);\n return [{ ...m, message }];\n });\n\n return {\n headId:\n messages.headId && survivingIds.has(messages.headId)\n ? messages.headId\n : null,\n messages: survivors,\n };\n};\n\nconst isAwaitingToolApproval = (message: ThreadMessage) =>\n message.status?.type === \"requires-action\" &&\n message.status.reason === \"tool-calls\";\n\nconst isTerminalMessage = (message: ThreadMessage) =>\n message.status === undefined ||\n message.status.type === \"complete\" ||\n message.status.type === \"incomplete\";\n\nconst TOOL_ARTIFACTS_METADATA_KEY = \"__aui_toolArtifacts\";\nconst TOOL_INTERACTIONS_METADATA_KEY = \"__aui_toolInteractions\";\nconst TOOL_APPROVAL_RESPONSES_METADATA_KEY = \"__aui_toolApprovalResponses\";\n\ntype StoredToolApprovalResponse = Omit<\n RespondToToolApprovalOptions,\n \"approvalId\"\n>;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nconst collectToolArtifacts = (\n message: ThreadMessage,\n toolArtifacts: ReadonlyMap<string, unknown> | undefined,\n) => {\n if (!toolArtifacts) return undefined;\n const entries = message.content.flatMap((part) => {\n if (part.type !== \"tool-call\") return [];\n const artifact = toolArtifacts.get(part.toolCallId);\n return artifact === undefined ? [] : [[part.toolCallId, artifact] as const];\n });\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n};\n\nconst collectToolInteractions = (\n message: ThreadMessage,\n toolInteractions:\n | ReadonlyMap<string, Unstable_ToolInteractionLog>\n | undefined,\n) => {\n if (!toolInteractions) return undefined;\n const entries = message.content.flatMap((part) => {\n if (part.type !== \"tool-call\") return [];\n const interactions = toolInteractions.get(part.toolCallId);\n return interactions === undefined\n ? []\n : [[part.toolCallId, interactions] as const];\n });\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n};\n\nconst collectToolApprovalResponses = (\n message: ThreadMessage,\n toolApprovalResponses:\n | ReadonlyMap<string, RespondToToolApprovalOptions>\n | undefined,\n) => {\n if (!toolApprovalResponses) return undefined;\n const entries = message.content.flatMap((part) => {\n if (part.type !== \"tool-call\" || !part.approval) return [];\n const response = toolApprovalResponses.get(part.approval.id);\n if (!response) return [];\n return [\n [\n part.approval.id,\n {\n approved: response.approved,\n ...(response.optionId != null && { optionId: response.optionId }),\n ...(response.text != null && { text: response.text }),\n ...(response.reason != null && { reason: response.reason }),\n },\n ] as const,\n ];\n });\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n};\n\nconst addToolData = <TMessage>(\n message: TMessage,\n toolArtifacts: Record<string, unknown> | undefined,\n toolInteractions: Record<string, Unstable_ToolInteractionLog> | undefined,\n toolApprovalResponses: Record<string, StoredToolApprovalResponse> | undefined,\n): TMessage => {\n if (\n (!toolArtifacts && !toolInteractions && !toolApprovalResponses) ||\n !isRecord(message) ||\n !Array.isArray(message.parts)\n )\n return message;\n const toolCallIds = message.parts.flatMap((part) => {\n if (!isRecord(part) || typeof part.toolCallId !== \"string\") return [];\n return [part.toolCallId];\n });\n const artifacts = toolArtifacts\n ? Object.fromEntries(\n toolCallIds.flatMap((toolCallId) =>\n Object.hasOwn(toolArtifacts, toolCallId)\n ? [[toolCallId, toolArtifacts[toolCallId]] as const]\n : [],\n ),\n )\n : undefined;\n const interactions = toolInteractions\n ? Object.fromEntries(\n toolCallIds.flatMap((toolCallId) =>\n Object.hasOwn(toolInteractions, toolCallId)\n ? [[toolCallId, toolInteractions[toolCallId]] as const]\n : [],\n ),\n )\n : undefined;\n const approvalIds = message.parts.flatMap((part) => {\n if (!isRecord(part) || !isRecord(part.approval)) return [];\n const approvalId = part.approval.id;\n return typeof approvalId === \"string\" ? [approvalId] : [];\n });\n const approvalResponses = toolApprovalResponses\n ? Object.fromEntries(\n approvalIds.flatMap((approvalId) =>\n Object.hasOwn(toolApprovalResponses, approvalId)\n ? [[approvalId, toolApprovalResponses[approvalId]] as const]\n : [],\n ),\n )\n : undefined;\n const hasArtifacts = !!artifacts && Object.keys(artifacts).length > 0;\n const hasInteractions =\n !!interactions && Object.keys(interactions).length > 0;\n const hasApprovalResponses =\n !!approvalResponses && Object.keys(approvalResponses).length > 0;\n if (!hasArtifacts && !hasInteractions && !hasApprovalResponses)\n return message;\n const metadata = isRecord(message.metadata) ? message.metadata : {};\n return {\n ...message,\n metadata: {\n ...metadata,\n ...(hasArtifacts && { [TOOL_ARTIFACTS_METADATA_KEY]: artifacts }),\n ...(hasInteractions && {\n [TOOL_INTERACTIONS_METADATA_KEY]: interactions,\n }),\n ...(hasApprovalResponses && {\n [TOOL_APPROVAL_RESPONSES_METADATA_KEY]: approvalResponses,\n }),\n },\n } as TMessage;\n};\n\nconst restoreToolData = <TMessage>(\n message: TMessage,\n toolArtifacts: Map<string, unknown> | undefined,\n toolInteractions: Map<string, Unstable_ToolInteractionLog> | undefined,\n toolApprovalResponses: Map<string, RespondToToolApprovalOptions> | undefined,\n): TMessage => {\n if (!isRecord(message) || !isRecord(message.metadata)) return message;\n const metadata = message.metadata;\n const hasArtifacts = Object.hasOwn(metadata, TOOL_ARTIFACTS_METADATA_KEY);\n const hasInteractions = Object.hasOwn(\n metadata,\n TOOL_INTERACTIONS_METADATA_KEY,\n );\n const hasApprovalResponses = Object.hasOwn(\n metadata,\n TOOL_APPROVAL_RESPONSES_METADATA_KEY,\n );\n if (!hasArtifacts && !hasInteractions && !hasApprovalResponses)\n return message;\n const artifacts = metadata[TOOL_ARTIFACTS_METADATA_KEY];\n if (toolArtifacts && isRecord(artifacts)) {\n for (const [toolCallId, artifact] of Object.entries(artifacts)) {\n toolArtifacts.set(toolCallId, artifact);\n }\n }\n const interactions = metadata[TOOL_INTERACTIONS_METADATA_KEY];\n if (toolInteractions && isRecord(interactions)) {\n for (const [toolCallId, value] of Object.entries(interactions)) {\n const log = readToolInteractionLog(value);\n if (log) toolInteractions.set(toolCallId, log);\n }\n }\n const approvalResponses = metadata[TOOL_APPROVAL_RESPONSES_METADATA_KEY];\n if (toolApprovalResponses && isRecord(approvalResponses)) {\n for (const [approvalId, value] of Object.entries(approvalResponses)) {\n if (!isRecord(value) || typeof value.approved !== \"boolean\") continue;\n toolApprovalResponses.set(approvalId, {\n approvalId,\n approved: value.approved,\n ...(typeof value.optionId === \"string\" && {\n optionId: value.optionId,\n }),\n ...(typeof value.text === \"string\" && { text: value.text }),\n ...(typeof value.reason === \"string\" && { reason: value.reason }),\n });\n }\n }\n const {\n [TOOL_ARTIFACTS_METADATA_KEY]: _,\n [TOOL_INTERACTIONS_METADATA_KEY]: __,\n [TOOL_APPROVAL_RESPONSES_METADATA_KEY]: ___,\n ...restMetadata\n } = metadata;\n const { metadata: _metadata, ...restMessage } = message;\n return (\n Object.keys(restMetadata).length === 0\n ? restMessage\n : { ...restMessage, metadata: restMetadata }\n ) as TMessage;\n};\n\nconst encodeContent = <TMessage>(\n storageFormatAdapter: MessageFormatAdapter<TMessage, any>,\n item: MessageFormatItem<TMessage>,\n) => JSON.stringify(storageFormatAdapter.encode(item));\n\nexport const useExternalHistory = <TMessage>(\n runtimeRef: RefObject<AssistantRuntime>,\n historyAdapter: ThreadHistoryAdapter | undefined,\n toThreadMessages: (messages: TMessage[]) => ThreadMessage[],\n storageFormatAdapter: MessageFormatAdapter<TMessage, any>,\n onSetMessages: (messages: TMessage[]) => void,\n toolArtifacts?: Map<string, unknown>,\n onToolArtifactsRestored?: () => void,\n toolInteractions?: Map<string, Unstable_ToolInteractionLog>,\n onToolInteractionsRestored?: () => void,\n toolApprovalResponses?: Map<string, RespondToToolApprovalOptions>,\n onToolApprovalResponsesRestored?: () => void,\n) => {\n const loadedRef = useRef(false);\n const [itemEpoch, setItemEpoch] = useState(0);\n\n const aui = useAui();\n const optionalThreadListItem = useCallback(\n () => (aui.threadListItem.source ? aui.threadListItem : null),\n [aui],\n );\n\n const [hasLoaded, setHasLoaded] = useState(false);\n\n const historyIds = useRef(new Set<string>());\n const deferredTelemetryIds = useRef(new Set<string>());\n // `content` is a snapshot taken at write time rather than a re-encode of `source`, because a retained message object can be mutated in place by the runtime that produced it.\n const persistedInnerMessages = useRef(\n new Map<string, { source: TMessage; content: string }>(),\n );\n\n const onSetMessagesRef = useRef(onSetMessages);\n useEffect(() => {\n onSetMessagesRef.current = onSetMessages;\n });\n\n const formatAdapter = useMemo(() => {\n if (!historyAdapter) return undefined;\n if (!historyAdapter.withFormat) {\n throw new Error(\n \"useAISDKRuntime: ThreadHistoryAdapter is missing the required `withFormat` method.\",\n );\n }\n return historyAdapter.withFormat<TMessage, any>(storageFormatAdapter);\n }, [historyAdapter, storageFormatAdapter]);\n\n const isLoading = formatAdapter != null && !hasLoaded;\n\n useEffect(() => {\n if (!formatAdapter || loadedRef.current) return undefined;\n\n const loadHistory = async () => {\n try {\n const repo = await formatAdapter.load();\n toolArtifacts?.clear();\n toolInteractions?.clear();\n toolApprovalResponses?.clear();\n const restoredMessages =\n repo?.messages.map((item) => ({\n ...item,\n message: restoreToolData(\n item.message,\n toolArtifacts,\n toolInteractions,\n toolApprovalResponses,\n ),\n })) ?? [];\n onToolArtifactsRestored?.();\n onToolInteractionsRestored?.();\n onToolApprovalResponsesRestored?.();\n if (repo && restoredMessages.length > 0) {\n const restoredRepo = { ...repo, messages: restoredMessages };\n for (const [index, m] of repo.messages.entries()) {\n persistedInnerMessages.current.set(\n storageFormatAdapter.getId(m.message),\n {\n source: restoredMessages[index]!.message,\n content: encodeContent(storageFormatAdapter, m),\n },\n );\n }\n const converted = toExportedMessageRepository(\n toThreadMessages,\n restoredRepo,\n );\n runtimeRef.current.thread.import(converted);\n\n const tempRepo = new MessageRepository();\n tempRepo.import(converted);\n const messages = tempRepo.getMessages();\n\n onSetMessagesRef.current(\n messages.flatMap(getExternalStoreMessages<TMessage>),\n );\n\n historyIds.current = new Set();\n for (const m of converted.messages) {\n historyIds.current.add(m.message.id);\n if (isAwaitingToolApproval(m.message)) {\n deferredTelemetryIds.current.add(m.message.id);\n }\n }\n }\n } catch (error) {\n console.error(\"Failed to load message history:\", error);\n } finally {\n setHasLoaded(true);\n }\n };\n\n formatAdapter.pin?.();\n\n const remoteId = optionalThreadListItem()?.getState().remoteId;\n if (!remoteId) {\n // History loads asynchronously against the thread list item; without a\n // remote id there is nothing to await, so the flag settles here.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setHasLoaded(true);\n return aui.subscribe(() => {\n if (optionalThreadListItem()?.getState().remoteId) {\n setItemEpoch((n) => n + 1);\n }\n });\n }\n\n const threadState = runtimeRef.current.thread.getState();\n if (threadState.isRunning || threadState.messages.length > 0) {\n loadedRef.current = true;\n setHasLoaded(true);\n return undefined;\n }\n\n loadedRef.current = true;\n void loadHistory();\n return undefined;\n }, [\n formatAdapter,\n toThreadMessages,\n runtimeRef,\n optionalThreadListItem,\n aui,\n itemEpoch,\n storageFormatAdapter,\n toolArtifacts,\n onToolArtifactsRestored,\n toolInteractions,\n onToolInteractionsRestored,\n toolApprovalResponses,\n onToolApprovalResponsesRestored,\n ]);\n\n const runStartRef = useRef<number | null>(null);\n const persistTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const persistInFlightRef = useRef<Promise<void>>(Promise.resolve());\n const stepBoundariesRef = useRef<number[]>([]);\n const wasRunningRef = useRef(false);\n const toolCallCountRef = useRef(0);\n\n const persistToolInteractions = useCallback(\n (messageId: string) => {\n const persistence = persistInFlightRef.current.then(async () => {\n if (!formatAdapter?.update) return;\n const messages = runtimeRef.current.thread.getState().messages;\n const message = messages.find(\n (item) =>\n item.id === messageId ||\n getExternalStoreMessages<TMessage>(item).some(\n (innerMessage) =>\n storageFormatAdapter.getId(innerMessage) === messageId,\n ),\n );\n if (!message) return;\n\n const previousMessages = messages\n .slice(0, messages.indexOf(message))\n .flatMap(getExternalStoreMessages<TMessage>);\n let parentId = previousMessages.at(-1)\n ? storageFormatAdapter.getId(previousMessages.at(-1)!)\n : null;\n const storedToolArtifacts = collectToolArtifacts(\n message,\n toolArtifacts,\n );\n const storedToolInteractions = collectToolInteractions(\n message,\n toolInteractions,\n );\n const storedToolApprovalResponses = collectToolApprovalResponses(\n message,\n toolApprovalResponses,\n );\n\n for (const innerMessage of getExternalStoreMessages<TMessage>(\n message,\n )) {\n const item = {\n parentId,\n message: addToolData(\n innerMessage,\n storedToolArtifacts,\n storedToolInteractions,\n storedToolApprovalResponses,\n ),\n };\n const innerId = storageFormatAdapter.getId(item.message);\n const persisted = persistedInnerMessages.current.get(innerId);\n if (persisted) {\n const content = encodeContent(storageFormatAdapter, item);\n if (content === persisted.content) {\n persisted.source = item.message;\n } else {\n await formatAdapter.update(item, innerId);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content,\n });\n }\n }\n parentId = innerId;\n }\n });\n persistInFlightRef.current = persistence.catch(() => {});\n return persistence.catch((error) => {\n console.error(\"Failed to persist tool data:\", error);\n });\n },\n [\n formatAdapter,\n runtimeRef,\n storageFormatAdapter,\n toolArtifacts,\n toolInteractions,\n toolApprovalResponses,\n ],\n );\n\n useEffect(() => {\n if (!formatAdapter) return;\n const adapter = formatAdapter;\n\n const idleScheduledInnerIds = new Set<string>();\n const unpersistedInnerIds = (message: ThreadMessage) =>\n isTerminalMessage(message)\n ? getExternalStoreMessages<TMessage>(message)\n .map((innerMessage) => storageFormatAdapter.getId(innerMessage))\n .filter((innerId) => !persistedInnerMessages.current.has(innerId))\n : [];\n\n const unsubscribe = runtimeRef.current.thread.subscribe(() => {\n const threadState = runtimeRef.current.thread.getState();\n const { isRunning } = threadState;\n const wasRunning = wasRunningRef.current;\n wasRunningRef.current = isRunning;\n\n // Track step boundaries by content changes (more reliable than isRunning)\n if (runStartRef.current != null) {\n const lastMsg = threadState.messages.at(-1);\n if (lastMsg?.role === \"assistant\") {\n const currentToolCallCount = lastMsg.content.filter(\n (p) => p.type === \"tool-call\",\n ).length;\n while (toolCallCountRef.current < currentToolCallCount) {\n stepBoundariesRef.current.push(Date.now() - runStartRef.current);\n toolCallCountRef.current++;\n }\n }\n }\n\n if (isRunning) {\n if (runStartRef.current == null) {\n runStartRef.current = Date.now();\n stepBoundariesRef.current = [];\n toolCallCountRef.current = 0;\n adapter.pin?.();\n }\n // Cancel any pending persist — isRunning went back to true\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n }\n return;\n }\n\n if (wasRunning) {\n // Record step boundary offset (synchronous for accuracy)\n if (runStartRef.current != null) {\n stepBoundariesRef.current.push(Date.now() - runStartRef.current);\n }\n } else {\n const pending = threadState.messages.flatMap(unpersistedInnerIds);\n if (pending.every((innerId) => idleScheduledInnerIds.has(innerId)))\n return;\n for (const innerId of pending) idleScheduledInnerIds.add(innerId);\n }\n\n // Debounce: wait one macrotask so agentic step flickers are absorbed\n if (persistTimerRef.current) clearTimeout(persistTimerRef.current);\n persistTimerRef.current = setTimeout(() => {\n persistSettled(false);\n }, 0);\n });\n\n const initialThreadState = runtimeRef.current.thread.getState();\n wasRunningRef.current = initialThreadState.isRunning;\n if (initialThreadState.isRunning) {\n if (runStartRef.current == null) {\n runStartRef.current = Date.now();\n stepBoundariesRef.current = [];\n toolCallCountRef.current = 0;\n adapter.pin?.();\n }\n } else if (initialThreadState.messages.length > 0) {\n persistSettled(true);\n }\n\n function persistSettled(ignoreRunning: boolean) {\n persistTimerRef.current = null;\n const latest = runtimeRef.current.thread.getState();\n if (!ignoreRunning && latest.isRunning) return;\n\n const boundaries = stepBoundariesRef.current;\n const durationMs = boundaries.length > 0 ? boundaries.at(-1) : undefined;\n\n // Fallback: if only 1 boundary but message has multiple steps, distribute evenly\n if (boundaries.length === 1 && durationMs != null) {\n const lastAssistant = latest.messages.findLast(\n (m) => m.role === \"assistant\",\n );\n if (lastAssistant) {\n const tcCount = lastAssistant.content.filter(\n (p) => p.type === \"tool-call\",\n ).length;\n if (tcCount > 0) {\n const totalSteps = tcCount + 1;\n const stepDur = durationMs / totalSteps;\n boundaries.length = 0;\n for (let i = 0; i < totalSteps; i++) {\n boundaries.push(Math.round((i + 1) * stepDur));\n }\n }\n }\n }\n\n // Build per-step timestamps when there are multiple steps\n const stepTimestamps =\n boundaries.length > 1\n ? boundaries.map((endMs, i) => ({\n start_ms: i === 0 ? 0 : boundaries[i - 1]!,\n end_ms: endMs,\n }))\n : undefined;\n\n runStartRef.current = null;\n stepBoundariesRef.current = [];\n\n const telemetryOptions = {\n ...(durationMs != null ? { durationMs } : undefined),\n ...(stepTimestamps != null ? { stepTimestamps } : undefined),\n };\n\n persistInFlightRef.current = persistInFlightRef.current\n .then(async () => {\n const { messages } = latest;\n let lastInnerMessageId: string | null = null;\n\n const getLastInnerId = (msgs: TMessage[]): string | null =>\n msgs.length > 0 ? storageFormatAdapter.getId(msgs.at(-1)!) : null;\n\n const toBatchItems = (\n msgs: TMessage[],\n toolArtifacts: Record<string, unknown> | undefined,\n toolInteractions:\n | Record<string, Unstable_ToolInteractionLog>\n | undefined,\n toolApprovalResponses:\n | Record<string, StoredToolApprovalResponse>\n | undefined,\n ) =>\n msgs.map((msg, idx) => ({\n parentId:\n idx === 0\n ? lastInnerMessageId\n : storageFormatAdapter.getId(msgs[idx - 1]!),\n message: addToolData(\n msg,\n toolArtifacts,\n toolInteractions,\n toolApprovalResponses,\n ),\n }));\n\n for (const message of messages) {\n const innerMessages = getExternalStoreMessages<TMessage>(message);\n\n const isTerminal = isTerminalMessage(message);\n const isAwaitingToolCalls = isAwaitingToolApproval(message);\n // A paused message's later content can only reach storage via update, so it is persisted early only when the adapter supports update.\n const isReady =\n isTerminal ||\n (isAwaitingToolCalls && adapter.update !== undefined);\n\n if (!isReady) {\n lastInnerMessageId =\n getLastInnerId(innerMessages) ?? lastInnerMessageId;\n continue;\n }\n\n if (!historyIds.current.has(message.id)) {\n historyIds.current.add(message.id);\n deferredTelemetryIds.current.add(message.id);\n }\n\n const batchItems = toBatchItems(\n innerMessages,\n collectToolArtifacts(message, toolArtifacts),\n collectToolInteractions(message, toolInteractions),\n collectToolApprovalResponses(message, toolApprovalResponses),\n );\n for (const item of batchItems) {\n const innerId = storageFormatAdapter.getId(item.message);\n const persisted = persistedInnerMessages.current.get(innerId);\n if (!persisted) {\n await adapter.append(item);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content: encodeContent(storageFormatAdapter, item),\n });\n } else if (\n persisted.source !== item.message &&\n durationMs !== undefined &&\n adapter.update\n ) {\n const content = encodeContent(storageFormatAdapter, item);\n if (content === persisted.content) {\n persisted.source = item.message;\n } else {\n try {\n await adapter.update(item, innerId);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content,\n });\n } catch {\n // A failed update leaves the stale baseline behind so the next run stop retries it.\n }\n }\n }\n }\n\n lastInnerMessageId =\n getLastInnerId(innerMessages) ?? lastInnerMessageId;\n\n if (deferredTelemetryIds.current.has(message.id) && isTerminal) {\n deferredTelemetryIds.current.delete(message.id);\n adapter.reportTelemetry?.(\n batchItems.map((item, index) => ({\n ...item,\n message: innerMessages[index]!,\n })),\n {\n ...telemetryOptions,\n message,\n },\n );\n }\n }\n })\n .catch((error) => {\n console.error(\"Failed to persist message history:\", error);\n });\n }\n\n return () => {\n unsubscribe();\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n persistSettled(false);\n }\n };\n }, [\n formatAdapter,\n storageFormatAdapter,\n runtimeRef,\n toolArtifacts,\n toolInteractions,\n toolApprovalResponses,\n ]);\n\n const deleteMessage = useCallback(\n async (messageId: string) => {\n const deleteMessages = formatAdapter?.delete?.bind(formatAdapter);\n if (!deleteMessages) return;\n\n const messages = runtimeRef.current.thread.getState().messages;\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) return;\n\n const previousInnerMessages = messages\n .slice(0, messageIndex)\n .flatMap(getExternalStoreMessages<TMessage>);\n let parentId = previousInnerMessages.at(-1)\n ? storageFormatAdapter.getId(previousInnerMessages.at(-1)!)\n : null;\n const itemsToDelete = getExternalStoreMessages<TMessage>(\n messages[messageIndex]!,\n ).map((message) => {\n const item = { parentId, message };\n parentId = storageFormatAdapter.getId(message);\n return item;\n });\n\n const deletion = persistInFlightRef.current.then(async () => {\n await deleteMessages(itemsToDelete);\n\n historyIds.current.delete(messageId);\n deferredTelemetryIds.current.delete(messageId);\n for (const item of itemsToDelete) {\n persistedInnerMessages.current.delete(\n storageFormatAdapter.getId(item.message),\n );\n }\n });\n\n persistInFlightRef.current = deletion.catch(() => {});\n await deletion;\n },\n [formatAdapter, runtimeRef, storageFormatAdapter],\n );\n\n return {\n isLoading,\n deleteMessage,\n persistToolInteractions,\n persistToolApprovalResponses: persistToolInteractions,\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const useResourceCleanup: (enabled: boolean, cleanup: () => void) => void;
|
|
3
|
-
//#endregion
|
|
1
|
+
export declare const useResourceCleanup: (enabled: boolean, cleanup: () => void, hostDestroySignal?: AbortSignal) => void;
|
|
4
2
|
//# sourceMappingURL=useResourceCleanup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useResourceCleanup.d.ts","
|
|
1
|
+
{"version":3,"file":"useResourceCleanup.d.ts","sourceRoot":"","sources":["../../src/runtime/useResourceCleanup.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,GAC7B,SAAS,OAAO,EAChB,SAAS,MAAM,IAAI,EACnB,oBAAoB,WAAW,SAmDhC,CAAC"}
|