@assistant-ui/react 0.12.3 → 0.12.5
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/client/ExternalThread.d.ts +16 -0
- package/dist/client/ExternalThread.d.ts.map +1 -0
- package/dist/client/ExternalThread.js +329 -0
- package/dist/client/ExternalThread.js.map +1 -0
- package/dist/client/InMemoryThreadList.d.ts +9 -0
- package/dist/client/InMemoryThreadList.d.ts.map +1 -0
- package/dist/client/InMemoryThreadList.js +129 -0
- package/dist/client/InMemoryThreadList.js.map +1 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +6 -0
- package/dist/client/index.js.map +1 -0
- package/dist/devtools/index.d.ts +1 -1
- package/dist/devtools/index.d.ts.map +1 -1
- package/dist/devtools/index.js +1 -1
- package/dist/devtools/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.js +7 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
- package/package.json +8 -8
- package/src/client/ExternalThread.ts +491 -0
- package/src/client/InMemoryThreadList.ts +197 -0
- package/src/client/index.ts +12 -0
- package/src/devtools/index.ts +1 -1
- package/src/index.ts +1 -0
- package/src/legacy-runtime/AssistantRuntimeProvider.tsx +7 -1
- package/src/primitives/message/MessagePartsGrouped.tsx +1 -1
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { resource, tapState, tapMemo } from "@assistant-ui/tap";
|
|
2
|
+
import {
|
|
3
|
+
type ClientOutput,
|
|
4
|
+
tapClientLookup,
|
|
5
|
+
Derived,
|
|
6
|
+
attachDefaultPeers,
|
|
7
|
+
tapClientResource,
|
|
8
|
+
} from "@assistant-ui/store";
|
|
9
|
+
import { withKey } from "@assistant-ui/tap";
|
|
10
|
+
import type { ResourceElement } from "@assistant-ui/tap";
|
|
11
|
+
import type { ThreadState } from "../types/scopes/thread";
|
|
12
|
+
import { Suggestions } from "./Suggestions";
|
|
13
|
+
import { ModelContext } from "./ModelContextClient";
|
|
14
|
+
import { Tools } from "./Tools";
|
|
15
|
+
|
|
16
|
+
export type InMemoryThreadListProps = {
|
|
17
|
+
thread: (threadId: string) => ResourceElement<ClientOutput<"thread">>;
|
|
18
|
+
onSwitchToThread?: (threadId: string) => void;
|
|
19
|
+
onSwitchToNewThread?: () => void;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type ThreadData = {
|
|
23
|
+
id: string;
|
|
24
|
+
title?: string;
|
|
25
|
+
status: "regular" | "archived";
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// ThreadListItem Client
|
|
29
|
+
const ThreadListItemClient = resource(
|
|
30
|
+
(props: {
|
|
31
|
+
data: ThreadData;
|
|
32
|
+
onSwitchTo: () => void;
|
|
33
|
+
onArchive: () => void;
|
|
34
|
+
onUnarchive: () => void;
|
|
35
|
+
onDelete: () => void;
|
|
36
|
+
}): ClientOutput<"threadListItem"> => {
|
|
37
|
+
const { data, onSwitchTo, onArchive, onUnarchive, onDelete } = props;
|
|
38
|
+
const state = tapMemo(
|
|
39
|
+
() => ({
|
|
40
|
+
id: data.id,
|
|
41
|
+
remoteId: undefined,
|
|
42
|
+
externalId: undefined,
|
|
43
|
+
title: data.title,
|
|
44
|
+
status: data.status,
|
|
45
|
+
}),
|
|
46
|
+
[data.id, data.title, data.status],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
state,
|
|
51
|
+
methods: {
|
|
52
|
+
getState: () => state,
|
|
53
|
+
switchTo: onSwitchTo,
|
|
54
|
+
rename: () => {},
|
|
55
|
+
archive: onArchive,
|
|
56
|
+
unarchive: onUnarchive,
|
|
57
|
+
delete: onDelete,
|
|
58
|
+
generateTitle: () => {},
|
|
59
|
+
initialize: async () => ({ remoteId: data.id, externalId: undefined }),
|
|
60
|
+
detach: () => {},
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// InMemoryThreadList Client
|
|
67
|
+
export const InMemoryThreadList = resource(
|
|
68
|
+
(props: InMemoryThreadListProps): ClientOutput<"threads"> => {
|
|
69
|
+
const {
|
|
70
|
+
thread: threadFactory,
|
|
71
|
+
onSwitchToThread,
|
|
72
|
+
onSwitchToNewThread,
|
|
73
|
+
} = props;
|
|
74
|
+
|
|
75
|
+
const [mainThreadId, setMainThreadId] = tapState("main");
|
|
76
|
+
const [threads, setThreads] = tapState<readonly ThreadData[]>(() => [
|
|
77
|
+
{ id: "main", title: "Main Thread", status: "regular" },
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
const handleSwitchToThread = (threadId: string) => {
|
|
81
|
+
setMainThreadId(threadId);
|
|
82
|
+
onSwitchToThread?.(threadId);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const handleArchive = (threadId: string) => {
|
|
86
|
+
setThreads((prev) =>
|
|
87
|
+
prev.map((t) =>
|
|
88
|
+
t.id === threadId ? { ...t, status: "archived" as const } : t,
|
|
89
|
+
),
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const handleUnarchive = (threadId: string) => {
|
|
94
|
+
setThreads((prev) =>
|
|
95
|
+
prev.map((t) =>
|
|
96
|
+
t.id === threadId ? { ...t, status: "regular" as const } : t,
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const handleDelete = (threadId: string) => {
|
|
102
|
+
setThreads((prev) => prev.filter((t) => t.id !== threadId));
|
|
103
|
+
if (mainThreadId === threadId) {
|
|
104
|
+
const remaining = threads.filter((t) => t.id !== threadId);
|
|
105
|
+
setMainThreadId(remaining[0]?.id || "main");
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const handleSwitchToNewThread = () => {
|
|
110
|
+
const newId = `thread-${Date.now()}`;
|
|
111
|
+
setThreads((prev) => [
|
|
112
|
+
...prev,
|
|
113
|
+
{ id: newId, title: "New Thread", status: "regular" },
|
|
114
|
+
]);
|
|
115
|
+
setMainThreadId(newId);
|
|
116
|
+
onSwitchToNewThread?.();
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const threadListItems = tapClientLookup(
|
|
120
|
+
() =>
|
|
121
|
+
threads.map((t) =>
|
|
122
|
+
withKey(
|
|
123
|
+
t.id,
|
|
124
|
+
ThreadListItemClient({
|
|
125
|
+
data: t,
|
|
126
|
+
onSwitchTo: () => handleSwitchToThread(t.id),
|
|
127
|
+
onArchive: () => handleArchive(t.id),
|
|
128
|
+
onUnarchive: () => handleUnarchive(t.id),
|
|
129
|
+
onDelete: () => handleDelete(t.id),
|
|
130
|
+
}),
|
|
131
|
+
),
|
|
132
|
+
),
|
|
133
|
+
[threads],
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// Create the main thread
|
|
137
|
+
const mainThreadClient = tapClientResource(threadFactory(mainThreadId));
|
|
138
|
+
|
|
139
|
+
const state = tapMemo(() => {
|
|
140
|
+
const regularThreads = threads.filter((t) => t.status === "regular");
|
|
141
|
+
const archivedThreads = threads.filter((t) => t.status === "archived");
|
|
142
|
+
const mainThreadState = mainThreadClient.state as ThreadState;
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
mainThreadId,
|
|
146
|
+
newThreadId: null,
|
|
147
|
+
isLoading: false,
|
|
148
|
+
threadIds: regularThreads.map((t) => t.id),
|
|
149
|
+
archivedThreadIds: archivedThreads.map((t) => t.id),
|
|
150
|
+
threadItems: threadListItems.state,
|
|
151
|
+
main: mainThreadState,
|
|
152
|
+
};
|
|
153
|
+
}, [mainThreadId, threads, threadListItems.state, mainThreadClient.state]);
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
state,
|
|
157
|
+
methods: {
|
|
158
|
+
getState: () => state,
|
|
159
|
+
switchToThread: handleSwitchToThread,
|
|
160
|
+
switchToNewThread: handleSwitchToNewThread,
|
|
161
|
+
item: (selector) => {
|
|
162
|
+
if (selector === "main") {
|
|
163
|
+
const index = threads.findIndex((t) => t.id === mainThreadId);
|
|
164
|
+
return threadListItems.get({ index: index === -1 ? 0 : index });
|
|
165
|
+
}
|
|
166
|
+
if ("id" in selector) {
|
|
167
|
+
const index = threads.findIndex((t) => t.id === selector.id);
|
|
168
|
+
return threadListItems.get({ index });
|
|
169
|
+
}
|
|
170
|
+
return threadListItems.get(selector);
|
|
171
|
+
},
|
|
172
|
+
thread: () => mainThreadClient.methods,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
attachDefaultPeers(InMemoryThreadList, {
|
|
179
|
+
thread: Derived({
|
|
180
|
+
source: "threads",
|
|
181
|
+
query: { type: "main" },
|
|
182
|
+
get: (aui) => aui.threads().thread("main"),
|
|
183
|
+
}),
|
|
184
|
+
threadListItem: Derived({
|
|
185
|
+
source: "threads",
|
|
186
|
+
query: { type: "main" },
|
|
187
|
+
get: (aui) => aui.threads().item("main"),
|
|
188
|
+
}),
|
|
189
|
+
composer: Derived({
|
|
190
|
+
source: "thread",
|
|
191
|
+
query: {},
|
|
192
|
+
get: (aui) => aui.threads().thread("main").composer,
|
|
193
|
+
}),
|
|
194
|
+
modelContext: ModelContext(),
|
|
195
|
+
tools: Tools({}),
|
|
196
|
+
suggestions: Suggestions(),
|
|
197
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { ModelContext as ModelContextClient } from "./ModelContextClient";
|
|
2
|
+
export { Tools } from "./Tools";
|
|
3
|
+
export { Suggestions, type SuggestionConfig } from "./Suggestions";
|
|
4
|
+
export {
|
|
5
|
+
ExternalThread,
|
|
6
|
+
type ExternalThreadProps,
|
|
7
|
+
type ExternalThreadMessage,
|
|
8
|
+
} from "./ExternalThread";
|
|
9
|
+
export {
|
|
10
|
+
InMemoryThreadList,
|
|
11
|
+
type InMemoryThreadListProps,
|
|
12
|
+
} from "./InMemoryThreadList";
|
package/src/devtools/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { DevToolsHooks } from "./DevToolsHooks";
|
|
1
|
+
export { DevToolsHooks, DevToolsProviderApi } from "./DevToolsHooks";
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { FC, memo, PropsWithChildren } from "react";
|
|
3
|
+
import { FC, memo, PropsWithChildren, useEffect } from "react";
|
|
4
4
|
import { useAui, AuiProvider, AssistantClient } from "@assistant-ui/store";
|
|
5
5
|
import { AssistantRuntime } from "./runtime/AssistantRuntime";
|
|
6
6
|
import { AssistantRuntimeCore } from "./runtime-cores/core/AssistantRuntimeCore";
|
|
7
7
|
import { RuntimeAdapter } from "./RuntimeAdapter";
|
|
8
8
|
import { ThreadPrimitiveViewportProvider } from "../context/providers/ThreadViewportProvider";
|
|
9
|
+
import { DevToolsProviderApi } from "../devtools";
|
|
9
10
|
|
|
10
11
|
export namespace AssistantRuntimeProvider {
|
|
11
12
|
export type Props = PropsWithChildren<{
|
|
@@ -30,6 +31,11 @@ export const AssistantRuntimeProviderImpl: FC<
|
|
|
30
31
|
> = ({ children, aui: parent = null, runtime }) => {
|
|
31
32
|
const aui = useAui({ threads: RuntimeAdapter(runtime) }, { parent: parent });
|
|
32
33
|
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (process.env["NODE_ENV"] === "production") return;
|
|
36
|
+
return DevToolsProviderApi.register(aui);
|
|
37
|
+
}, [aui]);
|
|
38
|
+
|
|
33
39
|
const RenderComponent = getRenderComponent(runtime);
|
|
34
40
|
|
|
35
41
|
return (
|
|
@@ -265,7 +265,7 @@ const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
|
|
265
265
|
|
|
266
266
|
const type = part.type;
|
|
267
267
|
if (type === "tool-call") {
|
|
268
|
-
const addResult =
|
|
268
|
+
const addResult = aui.part().addToolResult;
|
|
269
269
|
const resume = aui.part().resumeToolCall;
|
|
270
270
|
if ("Override" in tools)
|
|
271
271
|
return <tools.Override {...part} addResult={addResult} resume={resume} />;
|