@assistant-ui/core 0.3.14 → 0.3.15
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/dist/adapters/voice.js +11 -0
- package/dist/adapters/voice.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +2 -1
- package/dist/internal.js +2 -1
- package/dist/model-context/frame/host.d.ts +1 -1
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +17 -3
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts +4 -0
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +50 -3
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/frame/types.d.ts +4 -1
- package/dist/model-context/frame/types.d.ts.map +1 -1
- package/dist/model-context/frame/types.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts +1 -1
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
- package/dist/react/client/RemoteThreadList.js +95 -23
- package/dist/react/client/RemoteThreadList.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.js +7 -1
- package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +2 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +6 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +6 -0
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +192 -50
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.js +2 -0
- package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +1 -1
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +38 -5
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +27 -18
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +2 -0
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +25 -6
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -60
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -145
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
- package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -155
- package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
- package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +3 -0
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/store/clients/external-thread.js +1 -1
- package/dist/store/clients/external-thread.js.map +1 -1
- package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -1
- package/dist/store/runtime-clients/handle-runtime-action.js +2 -0
- package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -1
- package/dist/types/message.d.ts +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/silent-runtime-action.d.ts +6 -0
- package/dist/utils/silent-runtime-action.d.ts.map +1 -0
- package/dist/utils/silent-runtime-action.js +7 -0
- package/dist/utils/silent-runtime-action.js.map +1 -0
- package/package.json +4 -4
- package/src/adapters/voice.test.ts +66 -1
- package/src/adapters/voice.ts +8 -0
- package/src/internal.ts +1 -0
- package/src/model-context/frame/host.test.ts +64 -5
- package/src/model-context/frame/host.ts +16 -3
- package/src/model-context/frame/provider.test.ts +347 -20
- package/src/model-context/frame/provider.ts +58 -2
- package/src/model-context/frame/types.ts +5 -0
- package/src/react/client/RemoteThreadList.test.ts +196 -0
- package/src/react/client/RemoteThreadList.ts +93 -24
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
- package/src/react/primitive-hooks/useActionBarCopy.ts +13 -3
- package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
- package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +12 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +268 -63
- package/src/react/runtimes/RemoteThreadResource.ts +2 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +58 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +3 -1
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +68 -6
- package/src/react/runtimes/useLocalRuntime.test.tsx +5 -5
- package/src/runtime/utils/message-repository.ts +26 -18
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +4 -0
- package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
- package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
- package/src/runtimes/local/local-thread-runtime-core.test.ts +319 -0
- package/src/runtimes/local/local-thread-runtime-core.ts +38 -8
- package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -209
- package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
- package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -221
- package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
- package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
- package/src/runtimes/remote-thread-list/types.ts +4 -0
- package/src/store/clients/external-thread.ts +1 -1
- package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
- package/src/store/runtime-clients/handle-runtime-action.ts +3 -0
- package/src/tests/MessageRepository.test.ts +48 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
- package/src/tests/empty-thread-core.test.ts +6 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +20 -0
- package/src/tests/external-thread-isEmpty.test.tsx +100 -0
- package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
- package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
- package/src/types/message.ts +1 -1
- package/src/utils/silent-runtime-action.ts +6 -0
|
@@ -3,6 +3,7 @@ import { generateId } from "../../utils/id.js";
|
|
|
3
3
|
import { OptimisticState } from "../../runtimes/remote-thread-list/optimistic-state.js";
|
|
4
4
|
import { EMPTY_THREAD_CORE } from "../../runtimes/remote-thread-list/empty-thread-core.js";
|
|
5
5
|
import { classifyThreads, createThreadMappingId, getThreadData, normalizeCursor, updateStatusReducer } from "../../runtimes/remote-thread-list/remote-thread-state.js";
|
|
6
|
+
import { ThreadListAdapterChangedError } from "../../runtimes/remote-thread-list/adapter-changed.js";
|
|
6
7
|
import { useStableRuntimeAdapters } from "./useRuntimeAdapters.js";
|
|
7
8
|
import { RuntimeAdapterProvider } from "./RuntimeAdapterProvider.js";
|
|
8
9
|
import { isTitleSourceMessage } from "./RemoteThreadResource.js";
|
|
@@ -15,6 +16,45 @@ import { create } from "zustand";
|
|
|
15
16
|
//#region src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx
|
|
16
17
|
const threadNotFoundError = (threadIdOrRemoteId, action) => /* @__PURE__ */ new Error(`Thread "${threadIdOrRemoteId}" not found while ${action}.`);
|
|
17
18
|
const threadStatusError = (threadIdOrRemoteId, status, action) => /* @__PURE__ */ new Error(`Thread "${threadIdOrRemoteId}" has status "${status}", so it cannot ${action}.`);
|
|
19
|
+
const EMPTY_REMOTE_STATE = {
|
|
20
|
+
isLoading: true,
|
|
21
|
+
isLoadingMore: false,
|
|
22
|
+
cursor: void 0,
|
|
23
|
+
newThreadId: void 0,
|
|
24
|
+
threadIds: [],
|
|
25
|
+
archivedThreadIds: [],
|
|
26
|
+
threadIdMap: {},
|
|
27
|
+
threadData: {}
|
|
28
|
+
};
|
|
29
|
+
const addNewThread = (state) => {
|
|
30
|
+
let id;
|
|
31
|
+
do
|
|
32
|
+
id = `__LOCALID_${generateId()}`;
|
|
33
|
+
while (state.threadIdMap[id]);
|
|
34
|
+
const mappingId = createThreadMappingId(id);
|
|
35
|
+
return {
|
|
36
|
+
id,
|
|
37
|
+
state: {
|
|
38
|
+
...state,
|
|
39
|
+
newThreadId: id,
|
|
40
|
+
threadIdMap: {
|
|
41
|
+
...state.threadIdMap,
|
|
42
|
+
[id]: mappingId
|
|
43
|
+
},
|
|
44
|
+
threadData: {
|
|
45
|
+
...state.threadData,
|
|
46
|
+
[mappingId]: {
|
|
47
|
+
status: "new",
|
|
48
|
+
id,
|
|
49
|
+
remoteId: void 0,
|
|
50
|
+
externalId: void 0,
|
|
51
|
+
title: void 0,
|
|
52
|
+
custom: void 0
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
};
|
|
18
58
|
var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
19
59
|
_options;
|
|
20
60
|
_hookManager;
|
|
@@ -22,19 +62,13 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
22
62
|
_loadThreadsPromise;
|
|
23
63
|
_loadMorePromise;
|
|
24
64
|
_loadGeneration = 0;
|
|
65
|
+
_adapterGeneration = 0;
|
|
66
|
+
_replaceListOnNextLoad = false;
|
|
67
|
+
_staleThreadIdsOnReplace;
|
|
25
68
|
_switchGeneration = 0;
|
|
26
69
|
_switchTask;
|
|
27
70
|
_mainThreadId;
|
|
28
|
-
_state = new OptimisticState(
|
|
29
|
-
isLoading: true,
|
|
30
|
-
isLoadingMore: false,
|
|
31
|
-
cursor: void 0,
|
|
32
|
-
newThreadId: void 0,
|
|
33
|
-
threadIds: [],
|
|
34
|
-
archivedThreadIds: [],
|
|
35
|
-
threadIdMap: {},
|
|
36
|
-
threadData: {}
|
|
37
|
-
});
|
|
71
|
+
_state = new OptimisticState(EMPTY_REMOTE_STATE);
|
|
38
72
|
_useAdaptersProvider = ({ children }) => {
|
|
39
73
|
const useAdapters = this._options.adapter.unstable_useAdapters;
|
|
40
74
|
if (useAdapters === void 0) return children;
|
|
@@ -62,6 +96,7 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
62
96
|
getLoadThreadsPromise() {
|
|
63
97
|
if (!this._loadThreadsPromise) {
|
|
64
98
|
const generation = this._loadGeneration;
|
|
99
|
+
let replacedList = false;
|
|
65
100
|
this._loadThreadsPromise = this._state.optimisticUpdate({
|
|
66
101
|
execute: () => this._options.adapter.list(),
|
|
67
102
|
loading: (state) => {
|
|
@@ -72,6 +107,11 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
72
107
|
},
|
|
73
108
|
then: (state, l) => {
|
|
74
109
|
if (generation !== this._loadGeneration) return state;
|
|
110
|
+
if (this._replaceListOnNextLoad) {
|
|
111
|
+
this._replaceListOnNextLoad = false;
|
|
112
|
+
replacedList = true;
|
|
113
|
+
return this._replaceWithThreads(state, l.threads, normalizeCursor(l.nextCursor));
|
|
114
|
+
}
|
|
75
115
|
const fresh = classifyThreads(l.threads, {
|
|
76
116
|
threadIds: [],
|
|
77
117
|
archivedThreadIds: [],
|
|
@@ -98,11 +138,23 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
98
138
|
if (generation !== this._loadGeneration) return;
|
|
99
139
|
console.error("[assistant-ui] thread list load failed:", error);
|
|
100
140
|
this._loadThreadsPromise = void 0;
|
|
101
|
-
this.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
141
|
+
if (!this._replaceListOnNextLoad) {
|
|
142
|
+
this._state.update({
|
|
143
|
+
...this._state.baseValue,
|
|
144
|
+
isLoading: false
|
|
145
|
+
});
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
this._replaceListOnNextLoad = false;
|
|
149
|
+
replacedList = true;
|
|
150
|
+
this._state.update(this._replaceWithThreads(this._state.baseValue, [], void 0));
|
|
151
|
+
}).then(() => {
|
|
152
|
+
if (!replacedList) return;
|
|
153
|
+
const threadId = this._options.threadId;
|
|
154
|
+
if (threadId === void 0) return;
|
|
155
|
+
if (this.getItemById(threadId)?.id === this._mainThreadId) return;
|
|
156
|
+
this._switchToThreadFromProp(threadId).catch(() => {});
|
|
157
|
+
});
|
|
106
158
|
}
|
|
107
159
|
return this._loadThreadsPromise;
|
|
108
160
|
}
|
|
@@ -139,6 +191,7 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
139
191
|
};
|
|
140
192
|
}
|
|
141
193
|
}).catch((error) => {
|
|
194
|
+
if (generation !== this._loadGeneration) return;
|
|
142
195
|
console.error("[assistant-ui] thread list loadMore failed:", error);
|
|
143
196
|
}).then(() => {
|
|
144
197
|
if (this._loadMorePromise === dedup) this._loadMorePromise = void 0;
|
|
@@ -156,6 +209,9 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
156
209
|
this._hookManager = new RemoteThreadListHookInstanceManager(options.runtimeHook, this);
|
|
157
210
|
this._hookManager.__internal_setDefaultAdapters(this._runtimeAdapters);
|
|
158
211
|
this._hookManager.__internal_subscribeRunningChanged(() => this._notifySubscribers());
|
|
212
|
+
this._hookManager.__internal_subscribeRuntimeReplaced(() => {
|
|
213
|
+
queueMicrotask(() => this._notifySubscribers());
|
|
214
|
+
});
|
|
159
215
|
this.useProvider = create(() => ({ Provider: this.resolveProvider(options.adapter) }));
|
|
160
216
|
this.__internal_setOptions(options);
|
|
161
217
|
this.switchToNewThread();
|
|
@@ -172,8 +228,13 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
172
228
|
this._hookManager.setRuntimeHook(options.runtimeHook);
|
|
173
229
|
if (adapterChanged) {
|
|
174
230
|
this._loadGeneration++;
|
|
231
|
+
this._adapterGeneration++;
|
|
232
|
+
this._switchGeneration++;
|
|
233
|
+
this._switchTask = void 0;
|
|
175
234
|
this._loadThreadsPromise = void 0;
|
|
176
235
|
this._loadMorePromise = void 0;
|
|
236
|
+
this._replaceListOnNextLoad = true;
|
|
237
|
+
this._staleThreadIdsOnReplace = new Set(Object.values(this._state.baseValue.threadData).filter((item) => item.status !== "new").map((item) => item.id));
|
|
177
238
|
this._state.update({
|
|
178
239
|
...this._state.baseValue,
|
|
179
240
|
cursor: void 0
|
|
@@ -181,6 +242,71 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
181
242
|
}
|
|
182
243
|
if (controlledThreadIdChanged) this._switchToThreadFromProp(options.threadId).catch(() => {});
|
|
183
244
|
}
|
|
245
|
+
_requireAdapterGeneration(generation) {
|
|
246
|
+
if (generation !== this._adapterGeneration) throw new ThreadListAdapterChangedError();
|
|
247
|
+
}
|
|
248
|
+
_requireAdapterSettled() {
|
|
249
|
+
if (this._replaceListOnNextLoad) throw new ThreadListAdapterChangedError();
|
|
250
|
+
}
|
|
251
|
+
_replaceWithThreads(state, threads, cursor) {
|
|
252
|
+
const fresh = classifyThreads(threads, {
|
|
253
|
+
threadIds: [],
|
|
254
|
+
archivedThreadIds: [],
|
|
255
|
+
threadIdMap: {},
|
|
256
|
+
threadData: {}
|
|
257
|
+
});
|
|
258
|
+
const threadIdMap = { ...fresh.threadIdMap };
|
|
259
|
+
const threadData = { ...fresh.threadData };
|
|
260
|
+
const threadIds = [...fresh.threadIds];
|
|
261
|
+
const archivedThreadIds = [...fresh.archivedThreadIds];
|
|
262
|
+
if (state.newThreadId) {
|
|
263
|
+
const mappingId = state.threadIdMap[state.newThreadId];
|
|
264
|
+
const draft = mappingId ? state.threadData[mappingId] : void 0;
|
|
265
|
+
if (draft?.status === "new") {
|
|
266
|
+
threadIdMap[state.newThreadId] = mappingId;
|
|
267
|
+
threadData[mappingId] = draft;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
const stale = this._staleThreadIdsOnReplace;
|
|
271
|
+
if (stale) for (const item of Object.values(state.threadData)) {
|
|
272
|
+
if (stale.has(item.id)) continue;
|
|
273
|
+
if (item.status !== "new" && item.remoteId === void 0) continue;
|
|
274
|
+
const mappingId = createThreadMappingId(item.id);
|
|
275
|
+
if (threadData[mappingId]) continue;
|
|
276
|
+
threadIdMap[item.id] = mappingId;
|
|
277
|
+
if (item.remoteId !== void 0) threadIdMap[item.remoteId] = mappingId;
|
|
278
|
+
threadData[mappingId] = item;
|
|
279
|
+
if (item.remoteId === void 0) continue;
|
|
280
|
+
if (item.status === "regular" && !threadIds.includes(item.remoteId)) threadIds.push(item.remoteId);
|
|
281
|
+
else if (item.status === "archived" && !archivedThreadIds.includes(item.remoteId)) archivedThreadIds.push(item.remoteId);
|
|
282
|
+
}
|
|
283
|
+
this._staleThreadIdsOnReplace = void 0;
|
|
284
|
+
let nextState = {
|
|
285
|
+
...state,
|
|
286
|
+
isLoading: false,
|
|
287
|
+
cursor,
|
|
288
|
+
threadIds,
|
|
289
|
+
archivedThreadIds,
|
|
290
|
+
threadIdMap,
|
|
291
|
+
threadData,
|
|
292
|
+
newThreadId: state.newThreadId !== void 0 && threadIdMap[state.newThreadId] === void 0 ? void 0 : state.newThreadId
|
|
293
|
+
};
|
|
294
|
+
if (getThreadData(nextState, this._mainThreadId) === void 0) {
|
|
295
|
+
const preservedDraft = nextState.newThreadId;
|
|
296
|
+
if (preservedDraft !== void 0) this._mainThreadId = preservedDraft;
|
|
297
|
+
else {
|
|
298
|
+
const seeded = addNewThread(nextState);
|
|
299
|
+
this._mainThreadId = seeded.id;
|
|
300
|
+
nextState = seeded.state;
|
|
301
|
+
}
|
|
302
|
+
if (this._options.threadId === void 0) this._notifyThreadIdChange();
|
|
303
|
+
else this._lastNotifiedThreadId = void 0;
|
|
304
|
+
}
|
|
305
|
+
const nextIds = new Set(Object.values(nextState.threadData).map((item) => item.id));
|
|
306
|
+
for (const item of Object.values(state.threadData)) if (!nextIds.has(item.id)) this._hookManager.stopThreadRuntime(item.id);
|
|
307
|
+
this._hookManager.startThreadRuntime(this._mainThreadId).then(() => this._notifySubscribers(), () => void 0);
|
|
308
|
+
return nextState;
|
|
309
|
+
}
|
|
184
310
|
__internal_load() {
|
|
185
311
|
this.getLoadThreadsPromise();
|
|
186
312
|
if (this._initialThreadLoaded) return;
|
|
@@ -275,6 +401,7 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
275
401
|
return task;
|
|
276
402
|
}
|
|
277
403
|
async _switchToThread(threadIdOrRemoteId, options, generation, emitThreadIdChange) {
|
|
404
|
+
if (this._replaceListOnNextLoad && threadIdOrRemoteId !== this._state.value.newThreadId) throw new ThreadListAdapterChangedError();
|
|
278
405
|
let data = this.getItemById(threadIdOrRemoteId);
|
|
279
406
|
if (!data) {
|
|
280
407
|
const remoteMetadata = await this._options.adapter.fetch(threadIdOrRemoteId);
|
|
@@ -350,38 +477,22 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
350
477
|
const state = this._state.baseValue;
|
|
351
478
|
let id = this._state.value.newThreadId;
|
|
352
479
|
if (id === void 0) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const mappingId = createThreadMappingId(id);
|
|
357
|
-
this._state.update({
|
|
358
|
-
...state,
|
|
359
|
-
newThreadId: id,
|
|
360
|
-
threadIdMap: {
|
|
361
|
-
...state.threadIdMap,
|
|
362
|
-
[id]: mappingId
|
|
363
|
-
},
|
|
364
|
-
threadData: {
|
|
365
|
-
...state.threadData,
|
|
366
|
-
[mappingId]: {
|
|
367
|
-
status: "new",
|
|
368
|
-
id,
|
|
369
|
-
remoteId: void 0,
|
|
370
|
-
externalId: void 0,
|
|
371
|
-
title: void 0,
|
|
372
|
-
custom: void 0
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
});
|
|
480
|
+
const next = addNewThread(state);
|
|
481
|
+
id = next.id;
|
|
482
|
+
this._state.update(next.state);
|
|
376
483
|
}
|
|
377
484
|
return this._switchToThread(id, void 0, generation, emitThreadIdChange);
|
|
378
485
|
}
|
|
379
486
|
initialize = async (threadId) => {
|
|
487
|
+
const adapter = this._options.adapter;
|
|
488
|
+
const adapterGeneration = this._adapterGeneration;
|
|
380
489
|
if (this._state.value.newThreadId !== threadId) {
|
|
490
|
+
this._requireAdapterSettled();
|
|
381
491
|
const data = this.getItemById(threadId);
|
|
382
492
|
if (!data) throw threadNotFoundError(threadId, "initializing it");
|
|
383
493
|
if (data.status === "new") throw threadStatusError(threadId, data.status, "be initialized here");
|
|
384
494
|
const { remoteId, externalId } = await data.initializeTask;
|
|
495
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
385
496
|
return {
|
|
386
497
|
remoteId,
|
|
387
498
|
externalId
|
|
@@ -389,7 +500,8 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
389
500
|
}
|
|
390
501
|
const { remoteId, externalId } = await this._state.optimisticUpdate({
|
|
391
502
|
execute: () => {
|
|
392
|
-
|
|
503
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
504
|
+
return adapter.initialize(threadId);
|
|
393
505
|
},
|
|
394
506
|
optimistic: (state) => {
|
|
395
507
|
return updateStatusReducer(state, threadId, "regular");
|
|
@@ -408,6 +520,7 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
408
520
|
};
|
|
409
521
|
},
|
|
410
522
|
then: (state, { remoteId, externalId }) => {
|
|
523
|
+
if (adapterGeneration !== this._adapterGeneration) return state;
|
|
411
524
|
const data = getThreadData(state, threadId);
|
|
412
525
|
if (!data) return state;
|
|
413
526
|
const mappingId = createThreadMappingId(threadId);
|
|
@@ -432,22 +545,28 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
432
545
|
};
|
|
433
546
|
}
|
|
434
547
|
});
|
|
548
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
435
549
|
return {
|
|
436
550
|
remoteId,
|
|
437
551
|
externalId
|
|
438
552
|
};
|
|
439
553
|
};
|
|
440
554
|
generateTitle = async (threadId) => {
|
|
555
|
+
this._requireAdapterSettled();
|
|
556
|
+
const adapter = this._options.adapter;
|
|
557
|
+
const adapterGeneration = this._adapterGeneration;
|
|
441
558
|
const data = this.getItemById(threadId);
|
|
442
559
|
if (!data) throw threadNotFoundError(threadId, "generating its title");
|
|
443
560
|
if (data.status === "new") throw threadStatusError(threadId, data.status, "generate a title");
|
|
444
561
|
const { remoteId } = await data.initializeTask;
|
|
562
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
445
563
|
const runtimeCore = this._hookManager.getThreadRuntimeCore(data.id);
|
|
446
564
|
if (!runtimeCore) return;
|
|
447
565
|
const messages = runtimeCore.messages.filter(isTitleSourceMessage);
|
|
448
|
-
const stream = await
|
|
566
|
+
const stream = await adapter.generateTitle(remoteId, messages);
|
|
449
567
|
const messageStream = AssistantMessageStream.fromAssistantStream(stream);
|
|
450
568
|
for await (const result of messageStream) {
|
|
569
|
+
if (adapterGeneration !== this._adapterGeneration) return;
|
|
451
570
|
const newTitle = result.parts.filter((c) => c.type === "text")[0]?.text;
|
|
452
571
|
const state = this._state.baseValue;
|
|
453
572
|
const currentData = getThreadData(state, data.id);
|
|
@@ -464,14 +583,18 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
464
583
|
});
|
|
465
584
|
}
|
|
466
585
|
};
|
|
467
|
-
rename(threadIdOrRemoteId, newTitle) {
|
|
586
|
+
async rename(threadIdOrRemoteId, newTitle) {
|
|
587
|
+
this._requireAdapterSettled();
|
|
588
|
+
const adapter = this._options.adapter;
|
|
589
|
+
const adapterGeneration = this._adapterGeneration;
|
|
468
590
|
const data = this.getItemById(threadIdOrRemoteId);
|
|
469
591
|
if (!data) throw threadNotFoundError(threadIdOrRemoteId, "renaming it");
|
|
470
592
|
if (data.status === "new") throw threadStatusError(threadIdOrRemoteId, data.status, "be renamed");
|
|
471
593
|
return this._state.optimisticUpdate({
|
|
472
594
|
execute: async () => {
|
|
473
595
|
const { remoteId } = await data.initializeTask;
|
|
474
|
-
|
|
596
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
597
|
+
return adapter.rename(remoteId, newTitle);
|
|
475
598
|
},
|
|
476
599
|
optimistic: (state) => {
|
|
477
600
|
const data = getThreadData(state, threadIdOrRemoteId);
|
|
@@ -489,15 +612,18 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
489
612
|
}
|
|
490
613
|
});
|
|
491
614
|
}
|
|
492
|
-
updateCustom(threadIdOrRemoteId, custom) {
|
|
615
|
+
async updateCustom(threadIdOrRemoteId, custom) {
|
|
616
|
+
this._requireAdapterSettled();
|
|
617
|
+
const adapter = this._options.adapter;
|
|
618
|
+
const adapterGeneration = this._adapterGeneration;
|
|
493
619
|
const data = this.getItemById(threadIdOrRemoteId);
|
|
494
620
|
if (!data) throw threadNotFoundError(threadIdOrRemoteId, "updating its custom metadata");
|
|
495
621
|
if (data.status === "new") throw threadStatusError(threadIdOrRemoteId, data.status, "update custom metadata");
|
|
496
|
-
if (!
|
|
622
|
+
if (!adapter.updateCustom) throw new Error("Remote thread list adapter does not support updating custom metadata");
|
|
497
623
|
return this._state.optimisticUpdate({
|
|
498
624
|
execute: async () => {
|
|
499
625
|
const { remoteId } = await data.initializeTask;
|
|
500
|
-
|
|
626
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
501
627
|
if (!adapter.updateCustom) throw new Error("Remote thread list adapter does not support updating custom metadata");
|
|
502
628
|
return adapter.updateCustom(remoteId, custom);
|
|
503
629
|
},
|
|
@@ -533,21 +659,29 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
533
659
|
}
|
|
534
660
|
}
|
|
535
661
|
async archive(threadIdOrRemoteId) {
|
|
662
|
+
this._requireAdapterSettled();
|
|
663
|
+
const adapter = this._options.adapter;
|
|
664
|
+
const adapterGeneration = this._adapterGeneration;
|
|
536
665
|
const data = this.getItemById(threadIdOrRemoteId);
|
|
537
666
|
if (!data) throw threadNotFoundError(threadIdOrRemoteId, "archiving it");
|
|
538
667
|
if (data.status !== "regular") throw threadStatusError(threadIdOrRemoteId, data.status, "be archived");
|
|
539
668
|
await this._ensureThreadIsNotMain(data.id);
|
|
669
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
540
670
|
return this._state.optimisticUpdate({
|
|
541
671
|
execute: async () => {
|
|
542
672
|
const { remoteId } = await data.initializeTask;
|
|
543
|
-
|
|
673
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
674
|
+
return adapter.archive(remoteId);
|
|
544
675
|
},
|
|
545
676
|
optimistic: (state) => {
|
|
546
677
|
return updateStatusReducer(state, data.id, "archived");
|
|
547
678
|
}
|
|
548
679
|
});
|
|
549
680
|
}
|
|
550
|
-
unarchive(threadIdOrRemoteId) {
|
|
681
|
+
async unarchive(threadIdOrRemoteId) {
|
|
682
|
+
this._requireAdapterSettled();
|
|
683
|
+
const adapter = this._options.adapter;
|
|
684
|
+
const adapterGeneration = this._adapterGeneration;
|
|
551
685
|
const data = this.getItemById(threadIdOrRemoteId);
|
|
552
686
|
if (!data) throw threadNotFoundError(threadIdOrRemoteId, "unarchiving it");
|
|
553
687
|
if (data.status !== "archived") throw threadStatusError(threadIdOrRemoteId, data.status, "be unarchived");
|
|
@@ -555,9 +689,10 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
555
689
|
execute: async () => {
|
|
556
690
|
try {
|
|
557
691
|
const { remoteId } = await data.initializeTask;
|
|
558
|
-
|
|
692
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
693
|
+
return await adapter.unarchive(remoteId);
|
|
559
694
|
} catch (error) {
|
|
560
|
-
await this._ensureThreadIsNotMain(data.id);
|
|
695
|
+
if (adapterGeneration === this._adapterGeneration) await this._ensureThreadIsNotMain(data.id);
|
|
561
696
|
throw error;
|
|
562
697
|
}
|
|
563
698
|
},
|
|
@@ -567,15 +702,20 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
567
702
|
});
|
|
568
703
|
}
|
|
569
704
|
async delete(threadIdOrRemoteId) {
|
|
705
|
+
this._requireAdapterSettled();
|
|
706
|
+
const adapter = this._options.adapter;
|
|
707
|
+
const adapterGeneration = this._adapterGeneration;
|
|
570
708
|
const data = this.getItemById(threadIdOrRemoteId);
|
|
571
709
|
if (!data) throw threadNotFoundError(threadIdOrRemoteId, "deleting it");
|
|
572
710
|
if (data.status !== "regular" && data.status !== "archived") throw threadStatusError(threadIdOrRemoteId, data.status, "be deleted");
|
|
573
711
|
await this._ensureThreadIsNotMain(data.id);
|
|
712
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
574
713
|
this._hookManager.stopThreadRuntime(data.id);
|
|
575
714
|
return this._state.optimisticUpdate({
|
|
576
715
|
execute: async () => {
|
|
577
716
|
const { remoteId } = await data.initializeTask;
|
|
578
|
-
|
|
717
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
718
|
+
return await adapter.delete(remoteId);
|
|
579
719
|
},
|
|
580
720
|
optimistic: (state) => {
|
|
581
721
|
return updateStatusReducer(state, data.id, "deleted");
|
|
@@ -586,10 +726,12 @@ var RemoteThreadListThreadListRuntimeCore = class extends BaseSubscribable {
|
|
|
586
726
|
this._hookManager.__internal_dispose();
|
|
587
727
|
}
|
|
588
728
|
async detach(threadIdOrRemoteId) {
|
|
729
|
+
const adapterGeneration = this._adapterGeneration;
|
|
589
730
|
const data = this.getItemById(threadIdOrRemoteId);
|
|
590
731
|
if (!data) throw threadNotFoundError(threadIdOrRemoteId, "detaching it");
|
|
591
732
|
if (data.status !== "regular" && data.status !== "archived") throw threadStatusError(threadIdOrRemoteId, data.status, "be detached");
|
|
592
733
|
await this._ensureThreadIsNotMain(data.id);
|
|
734
|
+
this._requireAdapterGeneration(adapterGeneration);
|
|
593
735
|
this._hookManager.stopThreadRuntime(data.id);
|
|
594
736
|
}
|
|
595
737
|
useBoundIds = create(() => []);
|