@assistant-ui/react 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.mts +55 -11
- package/dist/index.d.ts +55 -11
- package/dist/index.js +145 -42
- package/dist/index.mjs +141 -36
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import * as react from 'react';
|
2
|
-
import { FC, PropsWithChildren } from 'react';
|
2
|
+
import { FC, PropsWithChildren, ReactNode, ComponentType } from 'react';
|
3
3
|
import { TextareaAutosizeProps } from 'react-textarea-autosize';
|
4
|
-
import { UseChatHelpers } from 'ai/react';
|
4
|
+
import { UseChatHelpers, UseAssistantHelpers } from 'ai/react';
|
5
5
|
import { UseBoundStore, StoreApi } from 'zustand';
|
6
6
|
|
7
7
|
declare const ThreadRoot: react.ForwardRefExoticComponent<Pick<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
@@ -101,16 +101,26 @@ type ComposerStore = {
|
|
101
101
|
useComposer: UseBoundStore<StoreApi<ComposerState>>;
|
102
102
|
};
|
103
103
|
|
104
|
-
type
|
104
|
+
type ThreadMessageTextPart = {
|
105
105
|
type: "text";
|
106
106
|
text: string;
|
107
107
|
};
|
108
|
-
type
|
108
|
+
type ThreadMessageImagePart = {
|
109
109
|
type: "image";
|
110
110
|
image: string;
|
111
111
|
};
|
112
|
-
type
|
113
|
-
type
|
112
|
+
type ThreadMessageUIPart = {
|
113
|
+
type: "ui";
|
114
|
+
display: ReactNode;
|
115
|
+
};
|
116
|
+
type ThreadMessageToolCallPart = {
|
117
|
+
type: "tool-call";
|
118
|
+
name: string;
|
119
|
+
args: object;
|
120
|
+
result?: object;
|
121
|
+
};
|
122
|
+
type ThreadUserMessageContent = ThreadMessageTextPart | ThreadMessageImagePart | ThreadMessageUIPart;
|
123
|
+
type ThreadAssistantMessageContent = ThreadMessageTextPart | ThreadMessageImagePart | ThreadMessageUIPart | ThreadMessageToolCallPart;
|
114
124
|
type ThreadUserMessage = {
|
115
125
|
id: string;
|
116
126
|
role: "user";
|
@@ -122,6 +132,7 @@ type ThreadAssistantMessage = {
|
|
122
132
|
content: ThreadAssistantMessageContent[];
|
123
133
|
};
|
124
134
|
type ThreadMessage = ThreadUserMessage | ThreadAssistantMessage;
|
135
|
+
type CreateThreadMessage = Omit<ThreadUserMessage, "id">;
|
125
136
|
|
126
137
|
type MessageProviderProps = {
|
127
138
|
children?: React.ReactNode;
|
@@ -147,7 +158,28 @@ type MessageIfProps = RequireAtLeastOne<MessageIfFilters> & {
|
|
147
158
|
};
|
148
159
|
declare const MessageIf: FC<MessageIfProps>;
|
149
160
|
|
150
|
-
|
161
|
+
type MessageContentProps = {
|
162
|
+
components?: {
|
163
|
+
Text?: ComponentType<{
|
164
|
+
part: ThreadMessageTextPart;
|
165
|
+
}>;
|
166
|
+
Image?: ComponentType<{
|
167
|
+
part: ThreadMessageImagePart;
|
168
|
+
}>;
|
169
|
+
UI?: ComponentType<{
|
170
|
+
part: ThreadMessageUIPart;
|
171
|
+
}>;
|
172
|
+
tools?: {
|
173
|
+
by_name?: Record<string, ComponentType<{
|
174
|
+
part: ThreadMessageToolCallPart;
|
175
|
+
}>>;
|
176
|
+
Fallback?: ComponentType<{
|
177
|
+
part: ThreadMessageToolCallPart;
|
178
|
+
}>;
|
179
|
+
};
|
180
|
+
};
|
181
|
+
};
|
182
|
+
declare const MessageContent: FC<MessageContentProps>;
|
151
183
|
|
152
184
|
declare namespace index$2 {
|
153
185
|
export { MessageContent as Content, MessageIf as If, MessageProvider as Provider, MessageRoot as Root };
|
@@ -216,11 +248,23 @@ declare namespace index {
|
|
216
248
|
export { ActionBarCopy as Copy, ActionBarEdit as Edit, ActionBarReload as Reload, ActionBarRoot as Root };
|
217
249
|
}
|
218
250
|
|
219
|
-
type
|
251
|
+
type VercelAIAssistantProviderProps$1 = PropsWithChildren<{
|
220
252
|
chat: UseChatHelpers;
|
221
|
-
|
253
|
+
} | {
|
254
|
+
assistant: UseAssistantHelpers;
|
255
|
+
}>;
|
256
|
+
declare const VercelAIAssistantProvider: FC<VercelAIAssistantProviderProps$1>;
|
257
|
+
|
258
|
+
type RSCMessage = {
|
259
|
+
id: string;
|
260
|
+
role: "user" | "assistant";
|
261
|
+
display: ReactNode;
|
222
262
|
};
|
223
|
-
|
263
|
+
type VercelAIAssistantProviderProps = PropsWithChildren<{
|
264
|
+
messages: RSCMessage[];
|
265
|
+
append: (message: CreateThreadMessage) => Promise<void>;
|
266
|
+
}>;
|
267
|
+
declare const VercelRSCAssistantProvider: FC<VercelAIAssistantProviderProps>;
|
224
268
|
|
225
269
|
type MessageState = {
|
226
270
|
message: ThreadMessage;
|
@@ -248,4 +292,4 @@ declare const useGoToNextBranch: () => (() => void) | null;
|
|
248
292
|
|
249
293
|
declare const useGoToPreviousBranch: () => (() => void) | null;
|
250
294
|
|
251
|
-
export { index as ActionBarPrimitive, index$1 as BranchPickerPrimitive, index$3 as ComposerPrimitive, index$2 as MessagePrimitive, index$4 as ThreadPrimitive,
|
295
|
+
export { index as ActionBarPrimitive, index$1 as BranchPickerPrimitive, index$3 as ComposerPrimitive, index$2 as MessagePrimitive, index$4 as ThreadPrimitive, VercelAIAssistantProvider, VercelRSCAssistantProvider as unstable_VercelRSCAssistantProvider, useMessageContext as unstable_useMessageContext, useBeginMessageEdit, useCopyMessage, useGoToNextBranch, useGoToPreviousBranch, useReloadMessage };
|
package/dist/index.d.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import * as react from 'react';
|
2
|
-
import { FC, PropsWithChildren } from 'react';
|
2
|
+
import { FC, PropsWithChildren, ReactNode, ComponentType } from 'react';
|
3
3
|
import { TextareaAutosizeProps } from 'react-textarea-autosize';
|
4
|
-
import { UseChatHelpers } from 'ai/react';
|
4
|
+
import { UseChatHelpers, UseAssistantHelpers } from 'ai/react';
|
5
5
|
import { UseBoundStore, StoreApi } from 'zustand';
|
6
6
|
|
7
7
|
declare const ThreadRoot: react.ForwardRefExoticComponent<Pick<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
@@ -101,16 +101,26 @@ type ComposerStore = {
|
|
101
101
|
useComposer: UseBoundStore<StoreApi<ComposerState>>;
|
102
102
|
};
|
103
103
|
|
104
|
-
type
|
104
|
+
type ThreadMessageTextPart = {
|
105
105
|
type: "text";
|
106
106
|
text: string;
|
107
107
|
};
|
108
|
-
type
|
108
|
+
type ThreadMessageImagePart = {
|
109
109
|
type: "image";
|
110
110
|
image: string;
|
111
111
|
};
|
112
|
-
type
|
113
|
-
type
|
112
|
+
type ThreadMessageUIPart = {
|
113
|
+
type: "ui";
|
114
|
+
display: ReactNode;
|
115
|
+
};
|
116
|
+
type ThreadMessageToolCallPart = {
|
117
|
+
type: "tool-call";
|
118
|
+
name: string;
|
119
|
+
args: object;
|
120
|
+
result?: object;
|
121
|
+
};
|
122
|
+
type ThreadUserMessageContent = ThreadMessageTextPart | ThreadMessageImagePart | ThreadMessageUIPart;
|
123
|
+
type ThreadAssistantMessageContent = ThreadMessageTextPart | ThreadMessageImagePart | ThreadMessageUIPart | ThreadMessageToolCallPart;
|
114
124
|
type ThreadUserMessage = {
|
115
125
|
id: string;
|
116
126
|
role: "user";
|
@@ -122,6 +132,7 @@ type ThreadAssistantMessage = {
|
|
122
132
|
content: ThreadAssistantMessageContent[];
|
123
133
|
};
|
124
134
|
type ThreadMessage = ThreadUserMessage | ThreadAssistantMessage;
|
135
|
+
type CreateThreadMessage = Omit<ThreadUserMessage, "id">;
|
125
136
|
|
126
137
|
type MessageProviderProps = {
|
127
138
|
children?: React.ReactNode;
|
@@ -147,7 +158,28 @@ type MessageIfProps = RequireAtLeastOne<MessageIfFilters> & {
|
|
147
158
|
};
|
148
159
|
declare const MessageIf: FC<MessageIfProps>;
|
149
160
|
|
150
|
-
|
161
|
+
type MessageContentProps = {
|
162
|
+
components?: {
|
163
|
+
Text?: ComponentType<{
|
164
|
+
part: ThreadMessageTextPart;
|
165
|
+
}>;
|
166
|
+
Image?: ComponentType<{
|
167
|
+
part: ThreadMessageImagePart;
|
168
|
+
}>;
|
169
|
+
UI?: ComponentType<{
|
170
|
+
part: ThreadMessageUIPart;
|
171
|
+
}>;
|
172
|
+
tools?: {
|
173
|
+
by_name?: Record<string, ComponentType<{
|
174
|
+
part: ThreadMessageToolCallPart;
|
175
|
+
}>>;
|
176
|
+
Fallback?: ComponentType<{
|
177
|
+
part: ThreadMessageToolCallPart;
|
178
|
+
}>;
|
179
|
+
};
|
180
|
+
};
|
181
|
+
};
|
182
|
+
declare const MessageContent: FC<MessageContentProps>;
|
151
183
|
|
152
184
|
declare namespace index$2 {
|
153
185
|
export { MessageContent as Content, MessageIf as If, MessageProvider as Provider, MessageRoot as Root };
|
@@ -216,11 +248,23 @@ declare namespace index {
|
|
216
248
|
export { ActionBarCopy as Copy, ActionBarEdit as Edit, ActionBarReload as Reload, ActionBarRoot as Root };
|
217
249
|
}
|
218
250
|
|
219
|
-
type
|
251
|
+
type VercelAIAssistantProviderProps$1 = PropsWithChildren<{
|
220
252
|
chat: UseChatHelpers;
|
221
|
-
|
253
|
+
} | {
|
254
|
+
assistant: UseAssistantHelpers;
|
255
|
+
}>;
|
256
|
+
declare const VercelAIAssistantProvider: FC<VercelAIAssistantProviderProps$1>;
|
257
|
+
|
258
|
+
type RSCMessage = {
|
259
|
+
id: string;
|
260
|
+
role: "user" | "assistant";
|
261
|
+
display: ReactNode;
|
222
262
|
};
|
223
|
-
|
263
|
+
type VercelAIAssistantProviderProps = PropsWithChildren<{
|
264
|
+
messages: RSCMessage[];
|
265
|
+
append: (message: CreateThreadMessage) => Promise<void>;
|
266
|
+
}>;
|
267
|
+
declare const VercelRSCAssistantProvider: FC<VercelAIAssistantProviderProps>;
|
224
268
|
|
225
269
|
type MessageState = {
|
226
270
|
message: ThreadMessage;
|
@@ -248,4 +292,4 @@ declare const useGoToNextBranch: () => (() => void) | null;
|
|
248
292
|
|
249
293
|
declare const useGoToPreviousBranch: () => (() => void) | null;
|
250
294
|
|
251
|
-
export { index as ActionBarPrimitive, index$1 as BranchPickerPrimitive, index$3 as ComposerPrimitive, index$2 as MessagePrimitive, index$4 as ThreadPrimitive,
|
295
|
+
export { index as ActionBarPrimitive, index$1 as BranchPickerPrimitive, index$3 as ComposerPrimitive, index$2 as MessagePrimitive, index$4 as ThreadPrimitive, VercelAIAssistantProvider, VercelRSCAssistantProvider as unstable_VercelRSCAssistantProvider, useMessageContext as unstable_useMessageContext, useBeginMessageEdit, useCopyMessage, useGoToNextBranch, useGoToPreviousBranch, useReloadMessage };
|
package/dist/index.js
CHANGED
@@ -35,7 +35,8 @@ __export(src_exports, {
|
|
35
35
|
ComposerPrimitive: () => composer_exports,
|
36
36
|
MessagePrimitive: () => message_exports,
|
37
37
|
ThreadPrimitive: () => thread_exports,
|
38
|
-
VercelAIAssistantProvider: () =>
|
38
|
+
VercelAIAssistantProvider: () => VercelAIAssistantProvider,
|
39
|
+
unstable_VercelRSCAssistantProvider: () => VercelRSCAssistantProvider,
|
39
40
|
unstable_useMessageContext: () => useMessageContext,
|
40
41
|
useBeginMessageEdit: () => useBeginMessageEdit,
|
41
42
|
useCopyMessage: () => useCopyMessage,
|
@@ -102,10 +103,10 @@ var ThreadEmpty = ({ children }) => {
|
|
102
103
|
};
|
103
104
|
|
104
105
|
// src/primitives/thread/ThreadViewport.tsx
|
105
|
-
var import_react4 = require("react");
|
106
|
-
var import_react_primitive2 = require("@radix-ui/react-primitive");
|
107
|
-
var import_react_compose_refs = require("@radix-ui/react-compose-refs");
|
108
106
|
var import_primitive = require("@radix-ui/primitive");
|
107
|
+
var import_react_compose_refs = require("@radix-ui/react-compose-refs");
|
108
|
+
var import_react_primitive2 = require("@radix-ui/react-primitive");
|
109
|
+
var import_react4 = require("react");
|
109
110
|
|
110
111
|
// src/utils/hooks/useOnResizeContent.tsx
|
111
112
|
var import_react3 = require("react");
|
@@ -138,10 +139,8 @@ var useOnResizeContent = (ref, callback) => {
|
|
138
139
|
mutationObserver.observe(el, { childList: true });
|
139
140
|
for (const child of el.children) {
|
140
141
|
resizeObserver.observe(child);
|
141
|
-
console.log("observing child", child);
|
142
142
|
}
|
143
143
|
return () => {
|
144
|
-
console.log("disconnecting");
|
145
144
|
resizeObserver.disconnect();
|
146
145
|
mutationObserver.disconnect();
|
147
146
|
};
|
@@ -165,7 +164,6 @@ var ThreadViewport = (0, import_react4.forwardRef)(({ onScroll, children, ...res
|
|
165
164
|
return;
|
166
165
|
setIsAtBottom(div.scrollHeight - div.scrollTop <= div.clientHeight + 50);
|
167
166
|
};
|
168
|
-
console.log(isAtBottom);
|
169
167
|
return /* @__PURE__ */ React.createElement(
|
170
168
|
import_react_primitive2.Primitive.div,
|
171
169
|
{
|
@@ -270,13 +268,16 @@ var useVercelAIBranches = (chat) => {
|
|
270
268
|
},
|
271
269
|
[data, chat.messages, chat.setMessages]
|
272
270
|
);
|
271
|
+
const reloadMaybe = "reload" in chat ? chat.reload : void 0;
|
273
272
|
const reloadAt = (0, import_react5.useCallback)(
|
274
273
|
async (message) => {
|
274
|
+
if (!reloadMaybe)
|
275
|
+
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
275
276
|
const newMessages = sliceMessagesUntil(chat.messages, message);
|
276
277
|
chat.setMessages(newMessages);
|
277
|
-
await
|
278
|
+
await reloadMaybe();
|
278
279
|
},
|
279
|
-
[chat.messages, chat.setMessages,
|
280
|
+
[chat.messages, chat.setMessages, reloadMaybe]
|
280
281
|
);
|
281
282
|
const editAt = (0, import_react5.useCallback)(
|
282
283
|
async (message, newMessage) => {
|
@@ -495,12 +496,41 @@ var MessageIf = ({ children, ...query }) => {
|
|
495
496
|
};
|
496
497
|
|
497
498
|
// src/primitives/message/MessageContent.tsx
|
498
|
-
var
|
499
|
+
var defaultComponents = {
|
500
|
+
Text: ({ part }) => /* @__PURE__ */ React.createElement(React.Fragment, null, part.text),
|
501
|
+
Image: () => null,
|
502
|
+
UI: ({ part }) => part.display,
|
503
|
+
tools: {
|
504
|
+
Fallback: () => null
|
505
|
+
}
|
506
|
+
};
|
507
|
+
var MessageContent = ({
|
508
|
+
components: {
|
509
|
+
Text = defaultComponents.Text,
|
510
|
+
Image = defaultComponents.Image,
|
511
|
+
UI = defaultComponents.UI,
|
512
|
+
tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
|
513
|
+
} = {}
|
514
|
+
}) => {
|
499
515
|
const { useMessage } = useMessageContext();
|
500
516
|
const content = useMessage((s) => s.message.content);
|
501
|
-
|
502
|
-
|
503
|
-
|
517
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, content.map((part, i) => {
|
518
|
+
const key = i;
|
519
|
+
switch (part.type) {
|
520
|
+
case "text":
|
521
|
+
return /* @__PURE__ */ React.createElement(Text, { key, part });
|
522
|
+
case "image":
|
523
|
+
return /* @__PURE__ */ React.createElement(Image, { key, part });
|
524
|
+
case "ui":
|
525
|
+
return /* @__PURE__ */ React.createElement(UI, { key, part });
|
526
|
+
case "tool-call": {
|
527
|
+
const Tool = by_name[part.name] || Fallback;
|
528
|
+
return /* @__PURE__ */ React.createElement(Tool, { key, part });
|
529
|
+
}
|
530
|
+
default:
|
531
|
+
return null;
|
532
|
+
}
|
533
|
+
}));
|
504
534
|
};
|
505
535
|
|
506
536
|
// src/primitives/thread/ThreadMessages.tsx
|
@@ -872,25 +902,32 @@ var useBeginMessageEdit = () => {
|
|
872
902
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
873
903
|
|
874
904
|
// src/vercel/VercelAIAssistantProvider.tsx
|
905
|
+
var import_react18 = require("react");
|
906
|
+
|
907
|
+
// src/vercel/useDummyAIAssistantContext.tsx
|
875
908
|
var import_react17 = require("react");
|
876
909
|
var import_zustand2 = require("zustand");
|
877
|
-
var
|
910
|
+
var useDummyAIAssistantContext = () => {
|
878
911
|
const [context] = (0, import_react17.useState)(() => {
|
879
912
|
const useThread = (0, import_zustand2.create)()(() => ({
|
880
913
|
messages: [],
|
881
914
|
isLoading: false,
|
882
915
|
reload: async () => {
|
916
|
+
throw new Error("Not implemented");
|
883
917
|
},
|
884
918
|
append: async () => {
|
919
|
+
throw new Error("Not implemented");
|
885
920
|
},
|
886
921
|
stop: () => {
|
922
|
+
throw new Error("Not implemented");
|
887
923
|
}
|
888
924
|
}));
|
889
925
|
const useComposer = (0, import_zustand2.create)()(() => ({
|
890
926
|
isEditing: true,
|
891
927
|
canCancel: false,
|
892
928
|
value: "",
|
893
|
-
setValue: () => {
|
929
|
+
setValue: (value) => {
|
930
|
+
useComposer.setState({ value });
|
894
931
|
},
|
895
932
|
edit: () => {
|
896
933
|
throw new Error("Not implemented");
|
@@ -909,19 +946,24 @@ var useAIAssistantContext = () => {
|
|
909
946
|
const useBranchObserver = (0, import_zustand2.create)()(() => ({
|
910
947
|
getBranchState: () => ({
|
911
948
|
branchId: 0,
|
912
|
-
branchCount:
|
949
|
+
branchCount: 1
|
913
950
|
}),
|
914
951
|
switchToBranch: () => {
|
952
|
+
throw new Error("Not implemented");
|
915
953
|
},
|
916
954
|
editAt: async () => {
|
955
|
+
throw new Error("Not implemented");
|
917
956
|
},
|
918
957
|
reloadAt: async () => {
|
958
|
+
throw new Error("Not implemented");
|
919
959
|
}
|
920
960
|
}));
|
921
961
|
return { useThread, useComposer, useBranchObserver };
|
922
962
|
});
|
923
963
|
return context;
|
924
964
|
};
|
965
|
+
|
966
|
+
// src/vercel/VercelAIAssistantProvider.tsx
|
925
967
|
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
926
968
|
var vercelToThreadMessage = (message) => {
|
927
969
|
if (message.role !== "user" && message.role !== "assistant")
|
@@ -942,58 +984,118 @@ var vercelToCachedThreadMessages = (messages) => {
|
|
942
984
|
return newMessage;
|
943
985
|
});
|
944
986
|
};
|
945
|
-
var
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
const
|
951
|
-
|
952
|
-
|
953
|
-
|
987
|
+
var VercelAIAssistantProvider = ({
|
988
|
+
children,
|
989
|
+
...rest
|
990
|
+
}) => {
|
991
|
+
const context = useDummyAIAssistantContext();
|
992
|
+
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
993
|
+
const messages = (0, import_react18.useMemo)(() => {
|
994
|
+
return vercelToCachedThreadMessages(vercel.messages);
|
995
|
+
}, [vercel.messages]);
|
996
|
+
const maybeReload = "reload" in vercel ? vercel.reload : null;
|
997
|
+
const reload = (0, import_react18.useCallback)(async () => {
|
998
|
+
if (!maybeReload)
|
999
|
+
throw new Error("Reload not supported");
|
1000
|
+
await maybeReload();
|
1001
|
+
}, [maybeReload]);
|
1002
|
+
const append = (0, import_react18.useCallback)(
|
954
1003
|
async (message) => {
|
955
1004
|
if (message.content[0]?.type !== "text") {
|
956
1005
|
throw new Error("Only text content is currently supported");
|
957
1006
|
}
|
958
|
-
await
|
1007
|
+
await vercel.append({
|
959
1008
|
role: message.role,
|
960
1009
|
content: message.content[0].text
|
961
1010
|
});
|
962
1011
|
},
|
963
|
-
[
|
1012
|
+
[vercel.append]
|
964
1013
|
);
|
965
|
-
const stop = (0,
|
966
|
-
const lastMessage =
|
967
|
-
|
1014
|
+
const stop = (0, import_react18.useCallback)(() => {
|
1015
|
+
const lastMessage = vercel.messages.at(-1);
|
1016
|
+
vercel.stop();
|
968
1017
|
if (lastMessage?.role === "user") {
|
969
|
-
|
1018
|
+
vercel.setInput(lastMessage.content);
|
970
1019
|
}
|
971
|
-
}, [
|
972
|
-
|
1020
|
+
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1021
|
+
const isLoading = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
1022
|
+
(0, import_react18.useMemo)(() => {
|
973
1023
|
context.useThread.setState(
|
974
1024
|
{
|
975
1025
|
messages,
|
976
|
-
isLoading
|
1026
|
+
isLoading,
|
977
1027
|
reload,
|
978
1028
|
append,
|
979
1029
|
stop
|
980
1030
|
},
|
981
1031
|
true
|
982
1032
|
);
|
983
|
-
}, [context, messages, reload, append, stop,
|
984
|
-
(0,
|
1033
|
+
}, [context, messages, reload, append, stop, isLoading]);
|
1034
|
+
(0, import_react18.useMemo)(() => {
|
985
1035
|
context.useComposer.setState({
|
986
|
-
canCancel:
|
987
|
-
value:
|
988
|
-
setValue:
|
1036
|
+
canCancel: isLoading,
|
1037
|
+
value: vercel.input,
|
1038
|
+
setValue: vercel.setInput
|
989
1039
|
});
|
990
|
-
}, [context,
|
991
|
-
const branches = useVercelAIBranches(
|
992
|
-
(0,
|
1040
|
+
}, [context, isLoading, vercel.input, vercel.setInput]);
|
1041
|
+
const branches = useVercelAIBranches(vercel);
|
1042
|
+
(0, import_react18.useMemo)(() => {
|
993
1043
|
context.useBranchObserver.setState(branches, true);
|
994
1044
|
}, [context, branches]);
|
995
1045
|
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
996
1046
|
};
|
1047
|
+
|
1048
|
+
// src/vercel/VercelRSCAssistantProvider.tsx
|
1049
|
+
var import_react19 = require("react");
|
1050
|
+
var ThreadMessageCache2 = /* @__PURE__ */ new WeakMap();
|
1051
|
+
var vercelToThreadMessage2 = (message) => {
|
1052
|
+
if (message.role !== "user" && message.role !== "assistant")
|
1053
|
+
throw new Error("Unsupported role");
|
1054
|
+
return {
|
1055
|
+
id: message.id,
|
1056
|
+
role: message.role,
|
1057
|
+
content: [{ type: "ui", display: message.display }]
|
1058
|
+
};
|
1059
|
+
};
|
1060
|
+
var vercelToCachedThreadMessages2 = (messages) => {
|
1061
|
+
return messages.map((m) => {
|
1062
|
+
const cached = ThreadMessageCache2.get(m);
|
1063
|
+
if (cached)
|
1064
|
+
return cached;
|
1065
|
+
const newMessage = vercelToThreadMessage2(m);
|
1066
|
+
ThreadMessageCache2.set(m, newMessage);
|
1067
|
+
return newMessage;
|
1068
|
+
});
|
1069
|
+
};
|
1070
|
+
var VercelRSCAssistantProvider = ({
|
1071
|
+
children,
|
1072
|
+
messages: vercelMessages,
|
1073
|
+
append: vercelAppend
|
1074
|
+
}) => {
|
1075
|
+
const context = useDummyAIAssistantContext();
|
1076
|
+
const messages = (0, import_react19.useMemo)(() => {
|
1077
|
+
return vercelToCachedThreadMessages2(vercelMessages);
|
1078
|
+
}, [vercelMessages]);
|
1079
|
+
const append = (0, import_react19.useCallback)(
|
1080
|
+
async (message) => {
|
1081
|
+
if (message.content[0]?.type !== "text") {
|
1082
|
+
throw new Error("Only text content is currently supported");
|
1083
|
+
}
|
1084
|
+
await vercelAppend({
|
1085
|
+
role: message.role,
|
1086
|
+
content: [{ type: "text", text: message.content[0].text }]
|
1087
|
+
});
|
1088
|
+
},
|
1089
|
+
[vercelAppend]
|
1090
|
+
);
|
1091
|
+
(0, import_react19.useMemo)(() => {
|
1092
|
+
context.useThread.setState({
|
1093
|
+
messages,
|
1094
|
+
append
|
1095
|
+
});
|
1096
|
+
}, [context, messages, append]);
|
1097
|
+
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
1098
|
+
};
|
997
1099
|
// Annotate the CommonJS export names for ESM import in node:
|
998
1100
|
0 && (module.exports = {
|
999
1101
|
ActionBarPrimitive,
|
@@ -1002,6 +1104,7 @@ var VercelAIChatAssistantProvider = ({ chat, children }) => {
|
|
1002
1104
|
MessagePrimitive,
|
1003
1105
|
ThreadPrimitive,
|
1004
1106
|
VercelAIAssistantProvider,
|
1107
|
+
unstable_VercelRSCAssistantProvider,
|
1005
1108
|
unstable_useMessageContext,
|
1006
1109
|
useBeginMessageEdit,
|
1007
1110
|
useCopyMessage,
|
package/dist/index.mjs
CHANGED
@@ -63,12 +63,12 @@ var ThreadEmpty = ({ children }) => {
|
|
63
63
|
};
|
64
64
|
|
65
65
|
// src/primitives/thread/ThreadViewport.tsx
|
66
|
-
import {
|
66
|
+
import { composeEventHandlers } from "@radix-ui/primitive";
|
67
|
+
import { useComposedRefs } from "@radix-ui/react-compose-refs";
|
67
68
|
import {
|
68
69
|
Primitive as Primitive2
|
69
70
|
} from "@radix-ui/react-primitive";
|
70
|
-
import {
|
71
|
-
import { composeEventHandlers } from "@radix-ui/primitive";
|
71
|
+
import { forwardRef as forwardRef2, useRef as useRef2, useState } from "react";
|
72
72
|
|
73
73
|
// src/utils/hooks/useOnResizeContent.tsx
|
74
74
|
import { useLayoutEffect, useRef } from "react";
|
@@ -101,10 +101,8 @@ var useOnResizeContent = (ref, callback) => {
|
|
101
101
|
mutationObserver.observe(el, { childList: true });
|
102
102
|
for (const child of el.children) {
|
103
103
|
resizeObserver.observe(child);
|
104
|
-
console.log("observing child", child);
|
105
104
|
}
|
106
105
|
return () => {
|
107
|
-
console.log("disconnecting");
|
108
106
|
resizeObserver.disconnect();
|
109
107
|
mutationObserver.disconnect();
|
110
108
|
};
|
@@ -128,7 +126,6 @@ var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef)
|
|
128
126
|
return;
|
129
127
|
setIsAtBottom(div.scrollHeight - div.scrollTop <= div.clientHeight + 50);
|
130
128
|
};
|
131
|
-
console.log(isAtBottom);
|
132
129
|
return /* @__PURE__ */ React.createElement(
|
133
130
|
Primitive2.div,
|
134
131
|
{
|
@@ -233,13 +230,16 @@ var useVercelAIBranches = (chat) => {
|
|
233
230
|
},
|
234
231
|
[data, chat.messages, chat.setMessages]
|
235
232
|
);
|
233
|
+
const reloadMaybe = "reload" in chat ? chat.reload : void 0;
|
236
234
|
const reloadAt = useCallback(
|
237
235
|
async (message) => {
|
236
|
+
if (!reloadMaybe)
|
237
|
+
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
238
238
|
const newMessages = sliceMessagesUntil(chat.messages, message);
|
239
239
|
chat.setMessages(newMessages);
|
240
|
-
await
|
240
|
+
await reloadMaybe();
|
241
241
|
},
|
242
|
-
[chat.messages, chat.setMessages,
|
242
|
+
[chat.messages, chat.setMessages, reloadMaybe]
|
243
243
|
);
|
244
244
|
const editAt = useCallback(
|
245
245
|
async (message, newMessage) => {
|
@@ -460,12 +460,41 @@ var MessageIf = ({ children, ...query }) => {
|
|
460
460
|
};
|
461
461
|
|
462
462
|
// src/primitives/message/MessageContent.tsx
|
463
|
-
var
|
463
|
+
var defaultComponents = {
|
464
|
+
Text: ({ part }) => /* @__PURE__ */ React.createElement(React.Fragment, null, part.text),
|
465
|
+
Image: () => null,
|
466
|
+
UI: ({ part }) => part.display,
|
467
|
+
tools: {
|
468
|
+
Fallback: () => null
|
469
|
+
}
|
470
|
+
};
|
471
|
+
var MessageContent = ({
|
472
|
+
components: {
|
473
|
+
Text = defaultComponents.Text,
|
474
|
+
Image = defaultComponents.Image,
|
475
|
+
UI = defaultComponents.UI,
|
476
|
+
tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
|
477
|
+
} = {}
|
478
|
+
}) => {
|
464
479
|
const { useMessage } = useMessageContext();
|
465
480
|
const content = useMessage((s) => s.message.content);
|
466
|
-
|
467
|
-
|
468
|
-
|
481
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, content.map((part, i) => {
|
482
|
+
const key = i;
|
483
|
+
switch (part.type) {
|
484
|
+
case "text":
|
485
|
+
return /* @__PURE__ */ React.createElement(Text, { key, part });
|
486
|
+
case "image":
|
487
|
+
return /* @__PURE__ */ React.createElement(Image, { key, part });
|
488
|
+
case "ui":
|
489
|
+
return /* @__PURE__ */ React.createElement(UI, { key, part });
|
490
|
+
case "tool-call": {
|
491
|
+
const Tool = by_name[part.name] || Fallback;
|
492
|
+
return /* @__PURE__ */ React.createElement(Tool, { key, part });
|
493
|
+
}
|
494
|
+
default:
|
495
|
+
return null;
|
496
|
+
}
|
497
|
+
}));
|
469
498
|
};
|
470
499
|
|
471
500
|
// src/primitives/thread/ThreadMessages.tsx
|
@@ -855,25 +884,32 @@ var useBeginMessageEdit = () => {
|
|
855
884
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
856
885
|
|
857
886
|
// src/vercel/VercelAIAssistantProvider.tsx
|
858
|
-
import { useCallback as useCallback2, useMemo as useMemo4
|
887
|
+
import { useCallback as useCallback2, useMemo as useMemo4 } from "react";
|
888
|
+
|
889
|
+
// src/vercel/useDummyAIAssistantContext.tsx
|
890
|
+
import { useState as useState3 } from "react";
|
859
891
|
import { create as create2 } from "zustand";
|
860
|
-
var
|
892
|
+
var useDummyAIAssistantContext = () => {
|
861
893
|
const [context] = useState3(() => {
|
862
894
|
const useThread = create2()(() => ({
|
863
895
|
messages: [],
|
864
896
|
isLoading: false,
|
865
897
|
reload: async () => {
|
898
|
+
throw new Error("Not implemented");
|
866
899
|
},
|
867
900
|
append: async () => {
|
901
|
+
throw new Error("Not implemented");
|
868
902
|
},
|
869
903
|
stop: () => {
|
904
|
+
throw new Error("Not implemented");
|
870
905
|
}
|
871
906
|
}));
|
872
907
|
const useComposer = create2()(() => ({
|
873
908
|
isEditing: true,
|
874
909
|
canCancel: false,
|
875
910
|
value: "",
|
876
|
-
setValue: () => {
|
911
|
+
setValue: (value) => {
|
912
|
+
useComposer.setState({ value });
|
877
913
|
},
|
878
914
|
edit: () => {
|
879
915
|
throw new Error("Not implemented");
|
@@ -892,19 +928,24 @@ var useAIAssistantContext = () => {
|
|
892
928
|
const useBranchObserver = create2()(() => ({
|
893
929
|
getBranchState: () => ({
|
894
930
|
branchId: 0,
|
895
|
-
branchCount:
|
931
|
+
branchCount: 1
|
896
932
|
}),
|
897
933
|
switchToBranch: () => {
|
934
|
+
throw new Error("Not implemented");
|
898
935
|
},
|
899
936
|
editAt: async () => {
|
937
|
+
throw new Error("Not implemented");
|
900
938
|
},
|
901
939
|
reloadAt: async () => {
|
940
|
+
throw new Error("Not implemented");
|
902
941
|
}
|
903
942
|
}));
|
904
943
|
return { useThread, useComposer, useBranchObserver };
|
905
944
|
});
|
906
945
|
return context;
|
907
946
|
};
|
947
|
+
|
948
|
+
// src/vercel/VercelAIAssistantProvider.tsx
|
908
949
|
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
909
950
|
var vercelToThreadMessage = (message) => {
|
910
951
|
if (message.role !== "user" && message.role !== "assistant")
|
@@ -925,65 +966,129 @@ var vercelToCachedThreadMessages = (messages) => {
|
|
925
966
|
return newMessage;
|
926
967
|
});
|
927
968
|
};
|
928
|
-
var
|
929
|
-
|
969
|
+
var VercelAIAssistantProvider = ({
|
970
|
+
children,
|
971
|
+
...rest
|
972
|
+
}) => {
|
973
|
+
const context = useDummyAIAssistantContext();
|
974
|
+
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
930
975
|
const messages = useMemo4(() => {
|
931
|
-
return vercelToCachedThreadMessages(
|
932
|
-
}, [
|
976
|
+
return vercelToCachedThreadMessages(vercel.messages);
|
977
|
+
}, [vercel.messages]);
|
978
|
+
const maybeReload = "reload" in vercel ? vercel.reload : null;
|
933
979
|
const reload = useCallback2(async () => {
|
934
|
-
|
935
|
-
|
980
|
+
if (!maybeReload)
|
981
|
+
throw new Error("Reload not supported");
|
982
|
+
await maybeReload();
|
983
|
+
}, [maybeReload]);
|
936
984
|
const append = useCallback2(
|
937
985
|
async (message) => {
|
938
986
|
if (message.content[0]?.type !== "text") {
|
939
987
|
throw new Error("Only text content is currently supported");
|
940
988
|
}
|
941
|
-
await
|
989
|
+
await vercel.append({
|
942
990
|
role: message.role,
|
943
991
|
content: message.content[0].text
|
944
992
|
});
|
945
993
|
},
|
946
|
-
[
|
994
|
+
[vercel.append]
|
947
995
|
);
|
948
996
|
const stop = useCallback2(() => {
|
949
|
-
const lastMessage =
|
950
|
-
|
997
|
+
const lastMessage = vercel.messages.at(-1);
|
998
|
+
vercel.stop();
|
951
999
|
if (lastMessage?.role === "user") {
|
952
|
-
|
1000
|
+
vercel.setInput(lastMessage.content);
|
953
1001
|
}
|
954
|
-
}, [
|
1002
|
+
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1003
|
+
const isLoading = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
955
1004
|
useMemo4(() => {
|
956
1005
|
context.useThread.setState(
|
957
1006
|
{
|
958
1007
|
messages,
|
959
|
-
isLoading
|
1008
|
+
isLoading,
|
960
1009
|
reload,
|
961
1010
|
append,
|
962
1011
|
stop
|
963
1012
|
},
|
964
1013
|
true
|
965
1014
|
);
|
966
|
-
}, [context, messages, reload, append, stop,
|
1015
|
+
}, [context, messages, reload, append, stop, isLoading]);
|
967
1016
|
useMemo4(() => {
|
968
1017
|
context.useComposer.setState({
|
969
|
-
canCancel:
|
970
|
-
value:
|
971
|
-
setValue:
|
1018
|
+
canCancel: isLoading,
|
1019
|
+
value: vercel.input,
|
1020
|
+
setValue: vercel.setInput
|
972
1021
|
});
|
973
|
-
}, [context,
|
974
|
-
const branches = useVercelAIBranches(
|
1022
|
+
}, [context, isLoading, vercel.input, vercel.setInput]);
|
1023
|
+
const branches = useVercelAIBranches(vercel);
|
975
1024
|
useMemo4(() => {
|
976
1025
|
context.useBranchObserver.setState(branches, true);
|
977
1026
|
}, [context, branches]);
|
978
1027
|
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
979
1028
|
};
|
1029
|
+
|
1030
|
+
// src/vercel/VercelRSCAssistantProvider.tsx
|
1031
|
+
import {
|
1032
|
+
useCallback as useCallback3,
|
1033
|
+
useMemo as useMemo5
|
1034
|
+
} from "react";
|
1035
|
+
var ThreadMessageCache2 = /* @__PURE__ */ new WeakMap();
|
1036
|
+
var vercelToThreadMessage2 = (message) => {
|
1037
|
+
if (message.role !== "user" && message.role !== "assistant")
|
1038
|
+
throw new Error("Unsupported role");
|
1039
|
+
return {
|
1040
|
+
id: message.id,
|
1041
|
+
role: message.role,
|
1042
|
+
content: [{ type: "ui", display: message.display }]
|
1043
|
+
};
|
1044
|
+
};
|
1045
|
+
var vercelToCachedThreadMessages2 = (messages) => {
|
1046
|
+
return messages.map((m) => {
|
1047
|
+
const cached = ThreadMessageCache2.get(m);
|
1048
|
+
if (cached)
|
1049
|
+
return cached;
|
1050
|
+
const newMessage = vercelToThreadMessage2(m);
|
1051
|
+
ThreadMessageCache2.set(m, newMessage);
|
1052
|
+
return newMessage;
|
1053
|
+
});
|
1054
|
+
};
|
1055
|
+
var VercelRSCAssistantProvider = ({
|
1056
|
+
children,
|
1057
|
+
messages: vercelMessages,
|
1058
|
+
append: vercelAppend
|
1059
|
+
}) => {
|
1060
|
+
const context = useDummyAIAssistantContext();
|
1061
|
+
const messages = useMemo5(() => {
|
1062
|
+
return vercelToCachedThreadMessages2(vercelMessages);
|
1063
|
+
}, [vercelMessages]);
|
1064
|
+
const append = useCallback3(
|
1065
|
+
async (message) => {
|
1066
|
+
if (message.content[0]?.type !== "text") {
|
1067
|
+
throw new Error("Only text content is currently supported");
|
1068
|
+
}
|
1069
|
+
await vercelAppend({
|
1070
|
+
role: message.role,
|
1071
|
+
content: [{ type: "text", text: message.content[0].text }]
|
1072
|
+
});
|
1073
|
+
},
|
1074
|
+
[vercelAppend]
|
1075
|
+
);
|
1076
|
+
useMemo5(() => {
|
1077
|
+
context.useThread.setState({
|
1078
|
+
messages,
|
1079
|
+
append
|
1080
|
+
});
|
1081
|
+
}, [context, messages, append]);
|
1082
|
+
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
1083
|
+
};
|
980
1084
|
export {
|
981
1085
|
actionBar_exports as ActionBarPrimitive,
|
982
1086
|
branchPicker_exports as BranchPickerPrimitive,
|
983
1087
|
composer_exports as ComposerPrimitive,
|
984
1088
|
message_exports as MessagePrimitive,
|
985
1089
|
thread_exports as ThreadPrimitive,
|
986
|
-
|
1090
|
+
VercelAIAssistantProvider,
|
1091
|
+
VercelRSCAssistantProvider as unstable_VercelRSCAssistantProvider,
|
987
1092
|
useMessageContext as unstable_useMessageContext,
|
988
1093
|
useBeginMessageEdit,
|
989
1094
|
useCopyMessage,
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@assistant-ui/react",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.7",
|
4
4
|
"license": "MIT",
|
5
5
|
"exports": {
|
6
6
|
".": {
|
@@ -28,7 +28,7 @@
|
|
28
28
|
"@radix-ui/react-compose-refs": "^1.0.1",
|
29
29
|
"@radix-ui/react-primitive": "^1.0.3",
|
30
30
|
"@radix-ui/react-slot": "^1.0.2",
|
31
|
-
"ai": "^3.1.
|
31
|
+
"ai": "^3.1.12",
|
32
32
|
"react-textarea-autosize": "^8.5.3",
|
33
33
|
"zustand": "^4.5.2"
|
34
34
|
},
|