@assistant-ui/react 0.0.6 → 0.0.7
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.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
|
},
|