@assistant-ui/react 0.12.15 → 0.12.17
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.d.ts +1 -4
- package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
- package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.js +2 -527
- package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +96 -96
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts +1 -16
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.js +1 -14
- package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.d.ts +1 -13
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.js +2 -82
- package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts +1 -23
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js +1 -410
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.d.ts +1 -16
- package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.js +1 -48
- package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +1 -33
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +1 -307
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.d.ts +1 -3
- package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.js +1 -17
- package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts +2 -26
- package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.js +1 -13
- package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.d.ts +1 -3
- package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.js +1 -51
- package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts +1 -96
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.js +1 -110
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts +1 -112
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js +1 -439
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts +1 -12
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js +1 -102
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.d.ts +1 -3
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.js +1 -46
- package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.js +7 -20
- package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarEdit.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarEdit.js +3 -8
- package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +4 -7
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +5 -7
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarReload.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarReload.js +3 -10
- package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.js +5 -4
- package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
- package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerCancel.js +3 -8
- package/dist/primitives/composer/ComposerCancel.js.map +1 -1
- package/dist/primitives/composer/ComposerSend.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerSend.js +3 -8
- package/dist/primitives/composer/ComposerSend.js.map +1 -1
- package/dist/utils/createActionButton.js +1 -1
- package/dist/utils/createActionButton.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +1 -1
- package/src/internal.ts +1 -1
- package/src/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.ts +2 -784
- package/src/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.tsx +5 -43
- package/src/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.ts +2 -100
- package/src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts +4 -580
- package/src/legacy-runtime/runtime-cores/external-store/createMessageConverter.ts +1 -76
- package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.ts +4 -483
- package/src/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.ts +1 -27
- package/src/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.ts +2 -35
- package/src/legacy-runtime/runtime-cores/local/useLocalRuntime.ts +1 -67
- package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.tsx +1 -178
- package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.tsx +1 -529
- package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.tsx +1 -152
- package/src/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.ts +1 -80
- package/src/primitives/actionBar/ActionBarCopy.tsx +7 -26
- package/src/primitives/actionBar/ActionBarEdit.ts +3 -10
- package/src/primitives/actionBar/ActionBarFeedbackNegative.tsx +4 -9
- package/src/primitives/actionBar/ActionBarFeedbackPositive.tsx +5 -9
- package/src/primitives/actionBar/ActionBarReload.ts +3 -16
- package/src/primitives/composer/ComposerAddAttachment.ts +5 -4
- package/src/primitives/composer/ComposerCancel.ts +3 -10
- package/src/primitives/composer/ComposerSend.ts +3 -13
- package/src/tests/BaseComposerRuntimeCore.test.ts +2 -3
- package/src/utils/createActionButton.tsx +1 -1
package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.tsx
CHANGED
|
@@ -1,180 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
FC,
|
|
5
|
-
useCallback,
|
|
6
|
-
useRef,
|
|
7
|
-
useEffect,
|
|
8
|
-
memo,
|
|
9
|
-
PropsWithChildren,
|
|
10
|
-
ComponentType,
|
|
11
|
-
useMemo,
|
|
12
|
-
} from "react";
|
|
13
|
-
import { UseBoundStore, StoreApi, create } from "zustand";
|
|
14
|
-
import { useAui } from "@assistant-ui/store";
|
|
15
|
-
import { ThreadListItemRuntimeProvider } from "../../../context/providers";
|
|
16
|
-
import {
|
|
17
|
-
ThreadListRuntimeCore,
|
|
18
|
-
ThreadRuntimeCore,
|
|
19
|
-
ThreadRuntimeImpl,
|
|
20
|
-
} from "../../../internal";
|
|
21
|
-
import { BaseSubscribable } from "@assistant-ui/core/internal";
|
|
22
|
-
import { AssistantRuntime } from "../../runtime";
|
|
23
|
-
import { ThreadListRuntimeImpl } from "../../runtime/ThreadListRuntime";
|
|
24
|
-
|
|
25
|
-
type RemoteThreadListHook = () => AssistantRuntime;
|
|
26
|
-
|
|
27
|
-
type RemoteThreadListHookInstance = {
|
|
28
|
-
runtime?: ThreadRuntimeCore;
|
|
29
|
-
};
|
|
30
|
-
export class RemoteThreadListHookInstanceManager extends BaseSubscribable {
|
|
31
|
-
private useRuntimeHook: UseBoundStore<
|
|
32
|
-
StoreApi<{ useRuntime: RemoteThreadListHook }>
|
|
33
|
-
>;
|
|
34
|
-
private instances = new Map<string, RemoteThreadListHookInstance>();
|
|
35
|
-
private useAliveThreadsKeysChanged = create(() => ({}));
|
|
36
|
-
private parent: ThreadListRuntimeCore;
|
|
37
|
-
|
|
38
|
-
constructor(
|
|
39
|
-
runtimeHook: RemoteThreadListHook,
|
|
40
|
-
parent: ThreadListRuntimeCore,
|
|
41
|
-
) {
|
|
42
|
-
super();
|
|
43
|
-
this.parent = parent;
|
|
44
|
-
this.useRuntimeHook = create(() => ({ useRuntime: runtimeHook }));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public startThreadRuntime(threadId: string) {
|
|
48
|
-
if (!this.instances.has(threadId)) {
|
|
49
|
-
this.instances.set(threadId, {});
|
|
50
|
-
this.useAliveThreadsKeysChanged.setState({}, true);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return new Promise<ThreadRuntimeCore>((resolve, reject) => {
|
|
54
|
-
const callback = () => {
|
|
55
|
-
const instance = this.instances.get(threadId);
|
|
56
|
-
if (!instance) {
|
|
57
|
-
dispose();
|
|
58
|
-
reject(new Error("Thread was deleted before runtime was started"));
|
|
59
|
-
} else if (!instance.runtime) {
|
|
60
|
-
return; // misc update
|
|
61
|
-
} else {
|
|
62
|
-
dispose();
|
|
63
|
-
resolve(instance.runtime);
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
const dispose = this.subscribe(callback);
|
|
67
|
-
callback();
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
public getThreadRuntimeCore(threadId: string) {
|
|
72
|
-
const instance = this.instances.get(threadId);
|
|
73
|
-
if (!instance) return undefined;
|
|
74
|
-
return instance.runtime;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
public stopThreadRuntime(threadId: string) {
|
|
78
|
-
this.instances.delete(threadId);
|
|
79
|
-
this.useAliveThreadsKeysChanged.setState({}, true);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
public setRuntimeHook(newRuntimeHook: RemoteThreadListHook) {
|
|
83
|
-
const prevRuntimeHook = this.useRuntimeHook.getState().useRuntime;
|
|
84
|
-
if (prevRuntimeHook !== newRuntimeHook) {
|
|
85
|
-
this.useRuntimeHook.setState({ useRuntime: newRuntimeHook }, true);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private _InnerActiveThreadProvider: FC<{
|
|
90
|
-
threadId: string;
|
|
91
|
-
}> = ({ threadId }) => {
|
|
92
|
-
const { useRuntime } = this.useRuntimeHook();
|
|
93
|
-
const runtime = useRuntime();
|
|
94
|
-
|
|
95
|
-
const threadBinding = (runtime.thread as ThreadRuntimeImpl)
|
|
96
|
-
.__internal_threadBinding;
|
|
97
|
-
|
|
98
|
-
const updateRuntime = useCallback(() => {
|
|
99
|
-
const aliveThread = this.instances.get(threadId);
|
|
100
|
-
if (!aliveThread)
|
|
101
|
-
throw new Error("Thread not found. This is a bug in assistant-ui.");
|
|
102
|
-
|
|
103
|
-
aliveThread.runtime = threadBinding.getState();
|
|
104
|
-
this._notifySubscribers();
|
|
105
|
-
}, [threadId, threadBinding]);
|
|
106
|
-
|
|
107
|
-
const isMounted = useRef(false);
|
|
108
|
-
if (!isMounted.current) {
|
|
109
|
-
updateRuntime();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
useEffect(() => {
|
|
113
|
-
isMounted.current = true;
|
|
114
|
-
updateRuntime();
|
|
115
|
-
return threadBinding.outerSubscribe(updateRuntime);
|
|
116
|
-
}, [threadBinding, updateRuntime]);
|
|
117
|
-
|
|
118
|
-
const aui = useAui();
|
|
119
|
-
const initPromiseRef = useRef<Promise<unknown> | undefined>(undefined);
|
|
120
|
-
|
|
121
|
-
useEffect(() => {
|
|
122
|
-
const runtimeCore = threadBinding.getState();
|
|
123
|
-
const setGetInitializePromise = (runtimeCore as Record<string, unknown>)[
|
|
124
|
-
"__internal_setGetInitializePromise"
|
|
125
|
-
];
|
|
126
|
-
if (typeof setGetInitializePromise === "function") {
|
|
127
|
-
setGetInitializePromise.call(runtimeCore, () => initPromiseRef.current);
|
|
128
|
-
}
|
|
129
|
-
}, [threadBinding]);
|
|
130
|
-
|
|
131
|
-
useEffect(() => {
|
|
132
|
-
return runtime.threads.main.unstable_on("initialize", () => {
|
|
133
|
-
const state = aui.threadListItem().getState();
|
|
134
|
-
if (state.status === "new") {
|
|
135
|
-
initPromiseRef.current = aui.threadListItem().initialize();
|
|
136
|
-
|
|
137
|
-
const dispose = runtime.thread.unstable_on("runEnd", () => {
|
|
138
|
-
dispose();
|
|
139
|
-
|
|
140
|
-
aui.threadListItem().generateTitle();
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
}, [runtime, aui]);
|
|
145
|
-
|
|
146
|
-
return null;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
private _OuterActiveThreadProvider: FC<{
|
|
150
|
-
threadId: string;
|
|
151
|
-
provider: ComponentType<PropsWithChildren>;
|
|
152
|
-
}> = memo(({ threadId, provider: Provider }) => {
|
|
153
|
-
const runtime = useMemo(
|
|
154
|
-
() => new ThreadListRuntimeImpl(this.parent).getItemById(threadId),
|
|
155
|
-
[threadId],
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
return (
|
|
159
|
-
<ThreadListItemRuntimeProvider runtime={runtime}>
|
|
160
|
-
<Provider>
|
|
161
|
-
<this._InnerActiveThreadProvider threadId={threadId} />
|
|
162
|
-
</Provider>
|
|
163
|
-
</ThreadListItemRuntimeProvider>
|
|
164
|
-
);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
public __internal_RenderThreadRuntimes: FC<{
|
|
168
|
-
provider: ComponentType<PropsWithChildren>;
|
|
169
|
-
}> = ({ provider }) => {
|
|
170
|
-
this.useAliveThreadsKeysChanged(); // trigger re-render on alive threads change
|
|
171
|
-
|
|
172
|
-
return Array.from(this.instances.keys()).map((threadId) => (
|
|
173
|
-
<this._OuterActiveThreadProvider
|
|
174
|
-
key={threadId}
|
|
175
|
-
threadId={threadId}
|
|
176
|
-
provider={provider}
|
|
177
|
-
/>
|
|
178
|
-
));
|
|
179
|
-
};
|
|
180
|
-
}
|
|
3
|
+
export { RemoteThreadListHookInstanceManager } from "@assistant-ui/core/react";
|
|
@@ -1,531 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
generateId,
|
|
6
|
-
BaseSubscribable,
|
|
7
|
-
OptimisticState,
|
|
8
|
-
EMPTY_THREAD_CORE,
|
|
9
|
-
type RemoteThreadData,
|
|
10
|
-
type THREAD_MAPPING_ID,
|
|
11
|
-
type RemoteThreadState,
|
|
12
|
-
createThreadMappingId,
|
|
13
|
-
getThreadData,
|
|
14
|
-
updateStatusReducer,
|
|
15
|
-
type RemoteThreadListOptions,
|
|
16
|
-
} from "@assistant-ui/core/internal";
|
|
17
|
-
import { RemoteThreadListHookInstanceManager } from "./RemoteThreadListHookInstanceManager";
|
|
18
|
-
import {
|
|
19
|
-
ComponentType,
|
|
20
|
-
FC,
|
|
21
|
-
Fragment,
|
|
22
|
-
PropsWithChildren,
|
|
23
|
-
useEffect,
|
|
24
|
-
useId,
|
|
25
|
-
} from "react";
|
|
26
|
-
import { create } from "zustand";
|
|
27
|
-
import { AssistantMessageStream } from "assistant-stream";
|
|
28
|
-
import { ModelContextProvider } from "../../../model-context";
|
|
29
|
-
import { RuntimeAdapterProvider } from "../adapters/RuntimeAdapterProvider";
|
|
30
|
-
|
|
31
|
-
export class RemoteThreadListThreadListRuntimeCore
|
|
32
|
-
extends BaseSubscribable
|
|
33
|
-
implements ThreadListRuntimeCore
|
|
34
|
-
{
|
|
35
|
-
private _options!: RemoteThreadListOptions;
|
|
36
|
-
private readonly _hookManager: RemoteThreadListHookInstanceManager;
|
|
37
|
-
|
|
38
|
-
private _loadThreadsPromise: Promise<void> | undefined;
|
|
39
|
-
|
|
40
|
-
private _mainThreadId!: string;
|
|
41
|
-
private readonly _state = new OptimisticState<RemoteThreadState>({
|
|
42
|
-
isLoading: false,
|
|
43
|
-
newThreadId: undefined,
|
|
44
|
-
threadIds: [],
|
|
45
|
-
archivedThreadIds: [],
|
|
46
|
-
threadIdMap: {},
|
|
47
|
-
threadData: {},
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
public get threadItems() {
|
|
51
|
-
return this._state.value.threadData;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public getLoadThreadsPromise() {
|
|
55
|
-
// TODO this needs to be cached in case this promise is loaded during suspense
|
|
56
|
-
if (!this._loadThreadsPromise) {
|
|
57
|
-
this._loadThreadsPromise = this._state
|
|
58
|
-
.optimisticUpdate({
|
|
59
|
-
execute: () => this._options.adapter.list(),
|
|
60
|
-
loading: (state) => {
|
|
61
|
-
return {
|
|
62
|
-
...state,
|
|
63
|
-
isLoading: true,
|
|
64
|
-
};
|
|
65
|
-
},
|
|
66
|
-
then: (state, l) => {
|
|
67
|
-
const newThreadIds = [];
|
|
68
|
-
const newArchivedThreadIds = [];
|
|
69
|
-
const newThreadIdMap = {} as Record<string, THREAD_MAPPING_ID>;
|
|
70
|
-
const newThreadData = {} as Record<
|
|
71
|
-
THREAD_MAPPING_ID,
|
|
72
|
-
RemoteThreadData
|
|
73
|
-
>;
|
|
74
|
-
|
|
75
|
-
for (const thread of l.threads) {
|
|
76
|
-
switch (thread.status) {
|
|
77
|
-
case "regular":
|
|
78
|
-
newThreadIds.push(thread.remoteId);
|
|
79
|
-
break;
|
|
80
|
-
case "archived":
|
|
81
|
-
newArchivedThreadIds.push(thread.remoteId);
|
|
82
|
-
break;
|
|
83
|
-
default: {
|
|
84
|
-
const _exhaustiveCheck: never = thread.status;
|
|
85
|
-
throw new Error(`Unsupported state: ${_exhaustiveCheck}`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const mappingId = createThreadMappingId(thread.remoteId);
|
|
90
|
-
newThreadIdMap[thread.remoteId] = mappingId;
|
|
91
|
-
newThreadData[mappingId] = {
|
|
92
|
-
id: thread.remoteId,
|
|
93
|
-
remoteId: thread.remoteId,
|
|
94
|
-
externalId: thread.externalId,
|
|
95
|
-
status: thread.status,
|
|
96
|
-
title: thread.title,
|
|
97
|
-
initializeTask: Promise.resolve({
|
|
98
|
-
remoteId: thread.remoteId,
|
|
99
|
-
externalId: thread.externalId,
|
|
100
|
-
}),
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
...state,
|
|
106
|
-
threadIds: newThreadIds,
|
|
107
|
-
archivedThreadIds: newArchivedThreadIds,
|
|
108
|
-
threadIdMap: {
|
|
109
|
-
...state.threadIdMap,
|
|
110
|
-
...newThreadIdMap,
|
|
111
|
-
},
|
|
112
|
-
threadData: {
|
|
113
|
-
...state.threadData,
|
|
114
|
-
...newThreadData,
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
},
|
|
118
|
-
})
|
|
119
|
-
.then(() => {});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return this._loadThreadsPromise;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
constructor(
|
|
126
|
-
options: RemoteThreadListOptions,
|
|
127
|
-
private readonly contextProvider: ModelContextProvider,
|
|
128
|
-
) {
|
|
129
|
-
super();
|
|
130
|
-
|
|
131
|
-
this._state.subscribe(() => this._notifySubscribers());
|
|
132
|
-
this._hookManager = new RemoteThreadListHookInstanceManager(
|
|
133
|
-
options.runtimeHook,
|
|
134
|
-
this,
|
|
135
|
-
);
|
|
136
|
-
this.useProvider = create(() => ({
|
|
137
|
-
Provider: (options.adapter.unstable_Provider ??
|
|
138
|
-
Fragment) as ComponentType<PropsWithChildren>,
|
|
139
|
-
}));
|
|
140
|
-
this.__internal_setOptions(options);
|
|
141
|
-
this.switchToNewThread();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
private useProvider;
|
|
145
|
-
|
|
146
|
-
public __internal_setOptions(options: RemoteThreadListOptions) {
|
|
147
|
-
if (this._options === options) return;
|
|
148
|
-
|
|
149
|
-
this._options = options;
|
|
150
|
-
|
|
151
|
-
const Provider = (options.adapter.unstable_Provider ??
|
|
152
|
-
Fragment) as ComponentType<PropsWithChildren>;
|
|
153
|
-
if (Provider !== this.useProvider.getState().Provider) {
|
|
154
|
-
this.useProvider.setState({ Provider }, true);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
this._hookManager.setRuntimeHook(options.runtimeHook);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
public __internal_load() {
|
|
161
|
-
this.getLoadThreadsPromise(); // begin loading on initial bind
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
public get isLoading() {
|
|
165
|
-
return this._state.value.isLoading;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
public get threadIds() {
|
|
169
|
-
return this._state.value.threadIds;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public get archivedThreadIds() {
|
|
173
|
-
return this._state.value.archivedThreadIds;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
public get newThreadId() {
|
|
177
|
-
return this._state.value.newThreadId;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
public get mainThreadId(): string {
|
|
181
|
-
return this._mainThreadId;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
public getMainThreadRuntimeCore() {
|
|
185
|
-
const result = this._hookManager.getThreadRuntimeCore(this._mainThreadId);
|
|
186
|
-
if (!result) return EMPTY_THREAD_CORE;
|
|
187
|
-
return result;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
public getThreadRuntimeCore(threadIdOrRemoteId: string) {
|
|
191
|
-
const data = this.getItemById(threadIdOrRemoteId);
|
|
192
|
-
if (!data) throw new Error("Thread not found");
|
|
193
|
-
|
|
194
|
-
const result = this._hookManager.getThreadRuntimeCore(data.id);
|
|
195
|
-
if (!result) throw new Error("Thread not found");
|
|
196
|
-
return result;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
public getItemById(threadIdOrRemoteId: string) {
|
|
200
|
-
return getThreadData(this._state.value, threadIdOrRemoteId);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
public async switchToThread(threadIdOrRemoteId: string): Promise<void> {
|
|
204
|
-
let data = this.getItemById(threadIdOrRemoteId);
|
|
205
|
-
|
|
206
|
-
if (!data) {
|
|
207
|
-
const remoteMetadata =
|
|
208
|
-
await this._options.adapter.fetch(threadIdOrRemoteId);
|
|
209
|
-
const state = this._state.value;
|
|
210
|
-
const mappingId = createThreadMappingId(remoteMetadata.remoteId);
|
|
211
|
-
|
|
212
|
-
const newThreadData = {
|
|
213
|
-
...state.threadData,
|
|
214
|
-
[mappingId]: {
|
|
215
|
-
id: mappingId,
|
|
216
|
-
initializeTask: Promise.resolve({
|
|
217
|
-
remoteId: remoteMetadata.remoteId,
|
|
218
|
-
externalId: remoteMetadata.externalId,
|
|
219
|
-
}),
|
|
220
|
-
remoteId: remoteMetadata.remoteId,
|
|
221
|
-
externalId: remoteMetadata.externalId,
|
|
222
|
-
status: remoteMetadata.status,
|
|
223
|
-
title: remoteMetadata.title,
|
|
224
|
-
} as RemoteThreadData,
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const newThreadIdMap = {
|
|
228
|
-
...state.threadIdMap,
|
|
229
|
-
[remoteMetadata.remoteId]: mappingId,
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
const newThreadIds =
|
|
233
|
-
remoteMetadata.status === "regular"
|
|
234
|
-
? [...state.threadIds, remoteMetadata.remoteId]
|
|
235
|
-
: state.threadIds;
|
|
236
|
-
|
|
237
|
-
const newArchivedThreadIds =
|
|
238
|
-
remoteMetadata.status === "archived"
|
|
239
|
-
? [...state.archivedThreadIds, remoteMetadata.remoteId]
|
|
240
|
-
: state.archivedThreadIds;
|
|
241
|
-
|
|
242
|
-
this._state.update({
|
|
243
|
-
...state,
|
|
244
|
-
threadIds: newThreadIds,
|
|
245
|
-
archivedThreadIds: newArchivedThreadIds,
|
|
246
|
-
threadIdMap: newThreadIdMap,
|
|
247
|
-
threadData: newThreadData,
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
data = this.getItemById(threadIdOrRemoteId);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
if (!data) throw new Error("Thread not found");
|
|
254
|
-
if (this._mainThreadId === data.id) return;
|
|
255
|
-
|
|
256
|
-
const task = this._hookManager.startThreadRuntime(data.id);
|
|
257
|
-
if (this.mainThreadId !== undefined) {
|
|
258
|
-
await task;
|
|
259
|
-
} else {
|
|
260
|
-
task.then(() => this._notifySubscribers());
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (data.status === "archived") await this.unarchive(data.id);
|
|
264
|
-
this._mainThreadId = data.id;
|
|
265
|
-
|
|
266
|
-
this._notifySubscribers();
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
public async switchToNewThread(): Promise<void> {
|
|
270
|
-
// an initialization transaction is in progress, wait for it to settle
|
|
271
|
-
while (
|
|
272
|
-
this._state.baseValue.newThreadId !== undefined &&
|
|
273
|
-
this._state.value.newThreadId === undefined
|
|
274
|
-
) {
|
|
275
|
-
await this._state.waitForUpdate();
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
const state = this._state.value;
|
|
279
|
-
let id: string | undefined = this._state.value.newThreadId;
|
|
280
|
-
if (id === undefined) {
|
|
281
|
-
do {
|
|
282
|
-
id = `__LOCALID_${generateId()}`;
|
|
283
|
-
} while (state.threadIdMap[id]);
|
|
284
|
-
|
|
285
|
-
const mappingId = createThreadMappingId(id);
|
|
286
|
-
this._state.update({
|
|
287
|
-
...state,
|
|
288
|
-
newThreadId: id,
|
|
289
|
-
threadIdMap: {
|
|
290
|
-
...state.threadIdMap,
|
|
291
|
-
[id]: mappingId,
|
|
292
|
-
},
|
|
293
|
-
threadData: {
|
|
294
|
-
...state.threadData,
|
|
295
|
-
[mappingId]: {
|
|
296
|
-
status: "new",
|
|
297
|
-
id,
|
|
298
|
-
remoteId: undefined,
|
|
299
|
-
externalId: undefined,
|
|
300
|
-
title: undefined,
|
|
301
|
-
} satisfies RemoteThreadData,
|
|
302
|
-
},
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
return this.switchToThread(id);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
public initialize = async (threadId: string) => {
|
|
310
|
-
if (this._state.value.newThreadId !== threadId) {
|
|
311
|
-
const data = this.getItemById(threadId);
|
|
312
|
-
if (!data) throw new Error("Thread not found");
|
|
313
|
-
if (data.status === "new") throw new Error("Unexpected new state");
|
|
314
|
-
return data.initializeTask;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return this._state.optimisticUpdate({
|
|
318
|
-
execute: () => {
|
|
319
|
-
return this._options.adapter.initialize(threadId);
|
|
320
|
-
},
|
|
321
|
-
optimistic: (state) => {
|
|
322
|
-
return updateStatusReducer(state, threadId, "regular");
|
|
323
|
-
},
|
|
324
|
-
loading: (state, task) => {
|
|
325
|
-
const mappingId = createThreadMappingId(threadId);
|
|
326
|
-
return {
|
|
327
|
-
...state,
|
|
328
|
-
threadData: {
|
|
329
|
-
...state.threadData,
|
|
330
|
-
[mappingId]: {
|
|
331
|
-
...state.threadData[mappingId],
|
|
332
|
-
initializeTask: task,
|
|
333
|
-
},
|
|
334
|
-
},
|
|
335
|
-
};
|
|
336
|
-
},
|
|
337
|
-
then: (state, { remoteId, externalId }) => {
|
|
338
|
-
const data = getThreadData(state, threadId);
|
|
339
|
-
if (!data) return state;
|
|
340
|
-
|
|
341
|
-
const mappingId = createThreadMappingId(threadId);
|
|
342
|
-
return {
|
|
343
|
-
...state,
|
|
344
|
-
threadIdMap: {
|
|
345
|
-
...state.threadIdMap,
|
|
346
|
-
[remoteId]: mappingId,
|
|
347
|
-
},
|
|
348
|
-
threadData: {
|
|
349
|
-
...state.threadData,
|
|
350
|
-
[mappingId]: {
|
|
351
|
-
...data,
|
|
352
|
-
initializeTask: Promise.resolve({ remoteId, externalId }),
|
|
353
|
-
remoteId,
|
|
354
|
-
externalId,
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
|
-
};
|
|
358
|
-
},
|
|
359
|
-
});
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
public generateTitle = async (threadId: string) => {
|
|
363
|
-
const data = this.getItemById(threadId);
|
|
364
|
-
if (!data) throw new Error("Thread not found");
|
|
365
|
-
if (data.status === "new") throw new Error("Thread is not yet initialized");
|
|
366
|
-
|
|
367
|
-
const { remoteId } = await data.initializeTask;
|
|
368
|
-
|
|
369
|
-
const runtimeCore = this._hookManager.getThreadRuntimeCore(data.id);
|
|
370
|
-
if (!runtimeCore) return; // thread is no longer running
|
|
371
|
-
|
|
372
|
-
const messages = runtimeCore.messages;
|
|
373
|
-
const stream = await this._options.adapter.generateTitle(
|
|
374
|
-
remoteId,
|
|
375
|
-
messages,
|
|
376
|
-
);
|
|
377
|
-
const messageStream = AssistantMessageStream.fromAssistantStream(stream);
|
|
378
|
-
for await (const result of messageStream) {
|
|
379
|
-
const newTitle = result.parts.filter((c) => c.type === "text")[0]?.text;
|
|
380
|
-
const state = this._state.baseValue;
|
|
381
|
-
const currentData = getThreadData(state, data.id);
|
|
382
|
-
if (!currentData) continue;
|
|
383
|
-
this._state.update({
|
|
384
|
-
...state,
|
|
385
|
-
threadData: {
|
|
386
|
-
...state.threadData,
|
|
387
|
-
[currentData.id]: {
|
|
388
|
-
...currentData,
|
|
389
|
-
title: newTitle,
|
|
390
|
-
},
|
|
391
|
-
},
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
public rename(threadIdOrRemoteId: string, newTitle: string): Promise<void> {
|
|
397
|
-
const data = this.getItemById(threadIdOrRemoteId);
|
|
398
|
-
if (!data) throw new Error("Thread not found");
|
|
399
|
-
if (data.status === "new") throw new Error("Thread is not yet initialized");
|
|
400
|
-
|
|
401
|
-
return this._state.optimisticUpdate({
|
|
402
|
-
execute: async () => {
|
|
403
|
-
const { remoteId } = await data.initializeTask;
|
|
404
|
-
return this._options.adapter.rename(remoteId, newTitle);
|
|
405
|
-
},
|
|
406
|
-
optimistic: (state) => {
|
|
407
|
-
const data = getThreadData(state, threadIdOrRemoteId);
|
|
408
|
-
if (!data) return state;
|
|
409
|
-
|
|
410
|
-
return {
|
|
411
|
-
...state,
|
|
412
|
-
threadData: {
|
|
413
|
-
...state.threadData,
|
|
414
|
-
[data.id]: {
|
|
415
|
-
...data,
|
|
416
|
-
title: newTitle,
|
|
417
|
-
},
|
|
418
|
-
},
|
|
419
|
-
};
|
|
420
|
-
},
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
private async _ensureThreadIsNotMain(threadId: string) {
|
|
425
|
-
if (threadId === this.newThreadId)
|
|
426
|
-
throw new Error("Cannot ensure new thread is not main");
|
|
427
|
-
|
|
428
|
-
if (threadId === this._mainThreadId) {
|
|
429
|
-
await this.switchToNewThread();
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
public async archive(threadIdOrRemoteId: string) {
|
|
434
|
-
const data = this.getItemById(threadIdOrRemoteId);
|
|
435
|
-
if (!data) throw new Error("Thread not found");
|
|
436
|
-
if (data.status !== "regular")
|
|
437
|
-
throw new Error("Thread is not yet initialized or already archived");
|
|
438
|
-
|
|
439
|
-
await this._ensureThreadIsNotMain(data.id);
|
|
440
|
-
|
|
441
|
-
return this._state.optimisticUpdate({
|
|
442
|
-
execute: async () => {
|
|
443
|
-
const { remoteId } = await data.initializeTask;
|
|
444
|
-
return this._options.adapter.archive(remoteId);
|
|
445
|
-
},
|
|
446
|
-
optimistic: (state) => {
|
|
447
|
-
return updateStatusReducer(state, data.id, "archived");
|
|
448
|
-
},
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
public unarchive(threadIdOrRemoteId: string): Promise<void> {
|
|
453
|
-
const data = this.getItemById(threadIdOrRemoteId);
|
|
454
|
-
if (!data) throw new Error("Thread not found");
|
|
455
|
-
if (data.status !== "archived") throw new Error("Thread is not archived");
|
|
456
|
-
|
|
457
|
-
return this._state.optimisticUpdate({
|
|
458
|
-
execute: async () => {
|
|
459
|
-
try {
|
|
460
|
-
const { remoteId } = await data.initializeTask;
|
|
461
|
-
return await this._options.adapter.unarchive(remoteId);
|
|
462
|
-
} catch (error) {
|
|
463
|
-
await this._ensureThreadIsNotMain(data.id);
|
|
464
|
-
throw error;
|
|
465
|
-
}
|
|
466
|
-
},
|
|
467
|
-
optimistic: (state) => {
|
|
468
|
-
return updateStatusReducer(state, data.id, "regular");
|
|
469
|
-
},
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
public async delete(threadIdOrRemoteId: string) {
|
|
474
|
-
const data = this.getItemById(threadIdOrRemoteId);
|
|
475
|
-
if (!data) throw new Error("Thread not found");
|
|
476
|
-
if (data.status !== "regular" && data.status !== "archived")
|
|
477
|
-
throw new Error("Thread is not yet initialized");
|
|
478
|
-
|
|
479
|
-
await this._ensureThreadIsNotMain(data.id);
|
|
480
|
-
|
|
481
|
-
return this._state.optimisticUpdate({
|
|
482
|
-
execute: async () => {
|
|
483
|
-
const { remoteId } = await data.initializeTask;
|
|
484
|
-
return await this._options.adapter.delete(remoteId);
|
|
485
|
-
},
|
|
486
|
-
optimistic: (state) => {
|
|
487
|
-
return updateStatusReducer(state, data.id, "deleted");
|
|
488
|
-
},
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
public async detach(threadIdOrRemoteId: string): Promise<void> {
|
|
493
|
-
const data = this.getItemById(threadIdOrRemoteId);
|
|
494
|
-
if (!data) throw new Error("Thread not found");
|
|
495
|
-
if (data.status !== "regular" && data.status !== "archived")
|
|
496
|
-
throw new Error("Thread is not yet initialized");
|
|
497
|
-
|
|
498
|
-
await this._ensureThreadIsNotMain(data.id);
|
|
499
|
-
this._hookManager.stopThreadRuntime(data.id);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
private useBoundIds = create<string[]>(() => []);
|
|
503
|
-
|
|
504
|
-
public __internal_RenderComponent: FC = () => {
|
|
505
|
-
const id = useId();
|
|
506
|
-
useEffect(() => {
|
|
507
|
-
this.useBoundIds.setState((s) => [...s, id], true);
|
|
508
|
-
return () => {
|
|
509
|
-
this.useBoundIds.setState((s) => s.filter((i) => i !== id), true);
|
|
510
|
-
};
|
|
511
|
-
}, [id]);
|
|
512
|
-
|
|
513
|
-
const boundIds = this.useBoundIds();
|
|
514
|
-
const { Provider } = this.useProvider();
|
|
515
|
-
|
|
516
|
-
const adapters = {
|
|
517
|
-
modelContext: this.contextProvider,
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
return (
|
|
521
|
-
(boundIds.length === 0 || boundIds[0] === id) && (
|
|
522
|
-
// only render if the component is the first one mounted
|
|
523
|
-
<RuntimeAdapterProvider adapters={adapters}>
|
|
524
|
-
<this._hookManager.__internal_RenderThreadRuntimes
|
|
525
|
-
provider={Provider}
|
|
526
|
-
/>
|
|
527
|
-
</RuntimeAdapterProvider>
|
|
528
|
-
)
|
|
529
|
-
);
|
|
530
|
-
};
|
|
531
|
-
}
|
|
3
|
+
export { RemoteThreadListThreadListRuntimeCore } from "@assistant-ui/core/react";
|