@assistant-ui/react 0.0.5 → 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 +93 -28
- package/dist/index.d.ts +93 -28
- package/dist/index.js +213 -76
- package/dist/index.mjs +212 -73
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
@@ -1,8 +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 {
|
5
|
-
import { UseChatHelpers } from 'ai/react';
|
4
|
+
import { UseChatHelpers, UseAssistantHelpers } from 'ai/react';
|
6
5
|
import { UseBoundStore, StoreApi } from 'zustand';
|
7
6
|
|
8
7
|
declare const ThreadRoot: react.ForwardRefExoticComponent<Pick<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
@@ -84,9 +83,60 @@ declare namespace index$3 {
|
|
84
83
|
export { ComposerCancel as Cancel, ComposerIf as If, ComposerInput as Input, ComposerRoot as Root, ComposerSend as Send };
|
85
84
|
}
|
86
85
|
|
86
|
+
type BranchState = {
|
87
|
+
branchId: number;
|
88
|
+
branchCount: number;
|
89
|
+
};
|
90
|
+
|
91
|
+
type ComposerState = {
|
92
|
+
isEditing: boolean;
|
93
|
+
canCancel: boolean;
|
94
|
+
edit: () => void;
|
95
|
+
send: () => void;
|
96
|
+
cancel: () => void;
|
97
|
+
value: string;
|
98
|
+
setValue: (value: string) => void;
|
99
|
+
};
|
100
|
+
type ComposerStore = {
|
101
|
+
useComposer: UseBoundStore<StoreApi<ComposerState>>;
|
102
|
+
};
|
103
|
+
|
104
|
+
type ThreadMessageTextPart = {
|
105
|
+
type: "text";
|
106
|
+
text: string;
|
107
|
+
};
|
108
|
+
type ThreadMessageImagePart = {
|
109
|
+
type: "image";
|
110
|
+
image: string;
|
111
|
+
};
|
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;
|
124
|
+
type ThreadUserMessage = {
|
125
|
+
id: string;
|
126
|
+
role: "user";
|
127
|
+
content: ThreadUserMessageContent[];
|
128
|
+
};
|
129
|
+
type ThreadAssistantMessage = {
|
130
|
+
id: string;
|
131
|
+
role: "assistant";
|
132
|
+
content: ThreadAssistantMessageContent[];
|
133
|
+
};
|
134
|
+
type ThreadMessage = ThreadUserMessage | ThreadAssistantMessage;
|
135
|
+
type CreateThreadMessage = Omit<ThreadUserMessage, "id">;
|
136
|
+
|
87
137
|
type MessageProviderProps = {
|
88
138
|
children?: React.ReactNode;
|
89
|
-
message:
|
139
|
+
message: ThreadMessage;
|
90
140
|
};
|
91
141
|
declare const MessageProvider: FC<MessageProviderProps>;
|
92
142
|
|
@@ -108,7 +158,28 @@ type MessageIfProps = RequireAtLeastOne<MessageIfFilters> & {
|
|
108
158
|
};
|
109
159
|
declare const MessageIf: FC<MessageIfProps>;
|
110
160
|
|
111
|
-
|
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>;
|
112
183
|
|
113
184
|
declare namespace index$2 {
|
114
185
|
export { MessageContent as Content, MessageIf as If, MessageProvider as Provider, MessageRoot as Root };
|
@@ -177,32 +248,26 @@ declare namespace index {
|
|
177
248
|
export { ActionBarCopy as Copy, ActionBarEdit as Edit, ActionBarReload as Reload, ActionBarRoot as Root };
|
178
249
|
}
|
179
250
|
|
180
|
-
type VercelAIAssistantProviderProps = {
|
251
|
+
type VercelAIAssistantProviderProps$1 = PropsWithChildren<{
|
181
252
|
chat: UseChatHelpers;
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
cancel: () => void;
|
192
|
-
value: string;
|
193
|
-
setValue: (value: string) => void;
|
194
|
-
};
|
195
|
-
type ComposerStore = {
|
196
|
-
useComposer: UseBoundStore<StoreApi<ComposerState>>;
|
197
|
-
};
|
198
|
-
|
199
|
-
type BranchState = {
|
200
|
-
branchId: number;
|
201
|
-
branchCount: number;
|
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;
|
202
262
|
};
|
263
|
+
type VercelAIAssistantProviderProps = PropsWithChildren<{
|
264
|
+
messages: RSCMessage[];
|
265
|
+
append: (message: CreateThreadMessage) => Promise<void>;
|
266
|
+
}>;
|
267
|
+
declare const VercelRSCAssistantProvider: FC<VercelAIAssistantProviderProps>;
|
203
268
|
|
204
269
|
type MessageState = {
|
205
|
-
message:
|
270
|
+
message: ThreadMessage;
|
206
271
|
branchState: BranchState;
|
207
272
|
isLast: boolean;
|
208
273
|
isCopied: boolean;
|
@@ -227,4 +292,4 @@ declare const useGoToNextBranch: () => (() => void) | null;
|
|
227
292
|
|
228
293
|
declare const useGoToPreviousBranch: () => (() => void) | null;
|
229
294
|
|
230
|
-
export { index as ActionBarPrimitive, index$1 as BranchPickerPrimitive, index$3 as ComposerPrimitive, index$2 as MessagePrimitive, index$4 as ThreadPrimitive, VercelAIAssistantProvider as
|
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,8 +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 {
|
5
|
-
import { UseChatHelpers } from 'ai/react';
|
4
|
+
import { UseChatHelpers, UseAssistantHelpers } from 'ai/react';
|
6
5
|
import { UseBoundStore, StoreApi } from 'zustand';
|
7
6
|
|
8
7
|
declare const ThreadRoot: react.ForwardRefExoticComponent<Pick<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
@@ -84,9 +83,60 @@ declare namespace index$3 {
|
|
84
83
|
export { ComposerCancel as Cancel, ComposerIf as If, ComposerInput as Input, ComposerRoot as Root, ComposerSend as Send };
|
85
84
|
}
|
86
85
|
|
86
|
+
type BranchState = {
|
87
|
+
branchId: number;
|
88
|
+
branchCount: number;
|
89
|
+
};
|
90
|
+
|
91
|
+
type ComposerState = {
|
92
|
+
isEditing: boolean;
|
93
|
+
canCancel: boolean;
|
94
|
+
edit: () => void;
|
95
|
+
send: () => void;
|
96
|
+
cancel: () => void;
|
97
|
+
value: string;
|
98
|
+
setValue: (value: string) => void;
|
99
|
+
};
|
100
|
+
type ComposerStore = {
|
101
|
+
useComposer: UseBoundStore<StoreApi<ComposerState>>;
|
102
|
+
};
|
103
|
+
|
104
|
+
type ThreadMessageTextPart = {
|
105
|
+
type: "text";
|
106
|
+
text: string;
|
107
|
+
};
|
108
|
+
type ThreadMessageImagePart = {
|
109
|
+
type: "image";
|
110
|
+
image: string;
|
111
|
+
};
|
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;
|
124
|
+
type ThreadUserMessage = {
|
125
|
+
id: string;
|
126
|
+
role: "user";
|
127
|
+
content: ThreadUserMessageContent[];
|
128
|
+
};
|
129
|
+
type ThreadAssistantMessage = {
|
130
|
+
id: string;
|
131
|
+
role: "assistant";
|
132
|
+
content: ThreadAssistantMessageContent[];
|
133
|
+
};
|
134
|
+
type ThreadMessage = ThreadUserMessage | ThreadAssistantMessage;
|
135
|
+
type CreateThreadMessage = Omit<ThreadUserMessage, "id">;
|
136
|
+
|
87
137
|
type MessageProviderProps = {
|
88
138
|
children?: React.ReactNode;
|
89
|
-
message:
|
139
|
+
message: ThreadMessage;
|
90
140
|
};
|
91
141
|
declare const MessageProvider: FC<MessageProviderProps>;
|
92
142
|
|
@@ -108,7 +158,28 @@ type MessageIfProps = RequireAtLeastOne<MessageIfFilters> & {
|
|
108
158
|
};
|
109
159
|
declare const MessageIf: FC<MessageIfProps>;
|
110
160
|
|
111
|
-
|
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>;
|
112
183
|
|
113
184
|
declare namespace index$2 {
|
114
185
|
export { MessageContent as Content, MessageIf as If, MessageProvider as Provider, MessageRoot as Root };
|
@@ -177,32 +248,26 @@ declare namespace index {
|
|
177
248
|
export { ActionBarCopy as Copy, ActionBarEdit as Edit, ActionBarReload as Reload, ActionBarRoot as Root };
|
178
249
|
}
|
179
250
|
|
180
|
-
type VercelAIAssistantProviderProps = {
|
251
|
+
type VercelAIAssistantProviderProps$1 = PropsWithChildren<{
|
181
252
|
chat: UseChatHelpers;
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
cancel: () => void;
|
192
|
-
value: string;
|
193
|
-
setValue: (value: string) => void;
|
194
|
-
};
|
195
|
-
type ComposerStore = {
|
196
|
-
useComposer: UseBoundStore<StoreApi<ComposerState>>;
|
197
|
-
};
|
198
|
-
|
199
|
-
type BranchState = {
|
200
|
-
branchId: number;
|
201
|
-
branchCount: number;
|
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;
|
202
262
|
};
|
263
|
+
type VercelAIAssistantProviderProps = PropsWithChildren<{
|
264
|
+
messages: RSCMessage[];
|
265
|
+
append: (message: CreateThreadMessage) => Promise<void>;
|
266
|
+
}>;
|
267
|
+
declare const VercelRSCAssistantProvider: FC<VercelAIAssistantProviderProps>;
|
203
268
|
|
204
269
|
type MessageState = {
|
205
|
-
message:
|
270
|
+
message: ThreadMessage;
|
206
271
|
branchState: BranchState;
|
207
272
|
isLast: boolean;
|
208
273
|
isCopied: boolean;
|
@@ -227,4 +292,4 @@ declare const useGoToNextBranch: () => (() => void) | null;
|
|
227
292
|
|
228
293
|
declare const useGoToPreviousBranch: () => (() => void) | null;
|
229
294
|
|
230
|
-
export { index as ActionBarPrimitive, index$1 as BranchPickerPrimitive, index$3 as ComposerPrimitive, index$2 as MessagePrimitive, index$4 as ThreadPrimitive, VercelAIAssistantProvider as
|
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
|
-
|
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
|
{
|
@@ -177,7 +175,7 @@ var ThreadViewport = (0, import_react4.forwardRef)(({ onScroll, children, ...res
|
|
177
175
|
);
|
178
176
|
});
|
179
177
|
|
180
|
-
// src/
|
178
|
+
// src/vercel/useVercelAIBranches.tsx
|
181
179
|
var import_react5 = require("react");
|
182
180
|
var ROOT_ID = "__ROOT_ID__";
|
183
181
|
var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
|
@@ -245,7 +243,7 @@ var sliceMessagesUntil = (messages, message) => {
|
|
245
243
|
throw new Error("Unexpected: Message not found");
|
246
244
|
return messages.slice(0, messageIdx);
|
247
245
|
};
|
248
|
-
var
|
246
|
+
var useVercelAIBranches = (chat) => {
|
249
247
|
const data = (0, import_react5.useRef)({
|
250
248
|
parentMap: /* @__PURE__ */ new Map(),
|
251
249
|
branchMap: /* @__PURE__ */ new Map(),
|
@@ -270,19 +268,27 @@ var useChatWithBranches = (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) => {
|
283
284
|
const newMessages = sliceMessagesUntil(chat.messages, message);
|
284
285
|
chat.setMessages(newMessages);
|
285
|
-
|
286
|
+
if (newMessage.content[0]?.type !== "text")
|
287
|
+
throw new Error("Only text content is currently supported");
|
288
|
+
await chat.append({
|
289
|
+
role: "user",
|
290
|
+
content: newMessage.content[0].text
|
291
|
+
});
|
286
292
|
},
|
287
293
|
[chat.messages, chat.setMessages, chat.append]
|
288
294
|
);
|
@@ -373,18 +379,25 @@ var useMessageContext2 = () => {
|
|
373
379
|
const useComposer = (0, import_zustand.create)((set, get) => ({
|
374
380
|
isEditing: false,
|
375
381
|
canCancel: true,
|
376
|
-
edit: () =>
|
377
|
-
|
378
|
-
|
379
|
-
|
382
|
+
edit: () => {
|
383
|
+
const message = useMessage.getState().message;
|
384
|
+
if (message.role !== "user")
|
385
|
+
throw new Error("Editing is only supported for user messages");
|
386
|
+
if (message.content[0]?.type !== "text")
|
387
|
+
throw new Error("Editing is only supported for text-only messages");
|
388
|
+
return set({
|
389
|
+
isEditing: true,
|
390
|
+
value: message.content[0].text
|
391
|
+
});
|
392
|
+
},
|
380
393
|
cancel: () => set({ isEditing: false }),
|
381
394
|
send: () => {
|
382
395
|
const message = useMessage.getState().message;
|
396
|
+
if (message.role !== "user")
|
397
|
+
throw new Error("Editing is only supported for user messages");
|
383
398
|
useBranchObserver.getState().editAt(message, {
|
384
|
-
|
385
|
-
|
386
|
-
// remove id to create a new message
|
387
|
-
content: get().value
|
399
|
+
role: "user",
|
400
|
+
content: [{ type: "text", text: get().value }]
|
388
401
|
});
|
389
402
|
set({ isEditing: false });
|
390
403
|
},
|
@@ -483,10 +496,41 @@ var MessageIf = ({ children, ...query }) => {
|
|
483
496
|
};
|
484
497
|
|
485
498
|
// src/primitives/message/MessageContent.tsx
|
486
|
-
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
|
+
}) => {
|
487
515
|
const { useMessage } = useMessageContext();
|
488
516
|
const content = useMessage((s) => s.message.content);
|
489
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, content)
|
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
|
+
}));
|
490
534
|
};
|
491
535
|
|
492
536
|
// src/primitives/thread/ThreadMessages.tsx
|
@@ -515,7 +559,7 @@ var ThreadMessages = ({ components }) => {
|
|
515
559
|
message: {
|
516
560
|
id: UPCOMING_MESSAGE_ID,
|
517
561
|
role: "assistant",
|
518
|
-
content: "..."
|
562
|
+
content: [{ type: "text", text: "..." }]
|
519
563
|
}
|
520
564
|
},
|
521
565
|
/* @__PURE__ */ React.createElement(AssistantMessage, null)
|
@@ -810,11 +854,10 @@ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
|
810
854
|
if (isEditing)
|
811
855
|
return null;
|
812
856
|
return () => {
|
813
|
-
const {
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
navigator.clipboard.writeText(content);
|
857
|
+
const { message, setIsCopied } = useMessage.getState();
|
858
|
+
if (message.content[0]?.type !== "text")
|
859
|
+
throw new Error("Copying is only supported for text-only messages");
|
860
|
+
navigator.clipboard.writeText(message.content[0].text);
|
818
861
|
setIsCopied(true);
|
819
862
|
setTimeout(() => setIsCopied(false), copiedDuration);
|
820
863
|
};
|
@@ -832,7 +875,10 @@ var useReloadMessage = () => {
|
|
832
875
|
if (isLoading || !isAssistant)
|
833
876
|
return null;
|
834
877
|
return () => {
|
835
|
-
|
878
|
+
const message = useMessage.getState().message;
|
879
|
+
if (message.role !== "assistant")
|
880
|
+
throw new Error("Reloading is only supported on assistant messages");
|
881
|
+
useBranchObserver.getState().reloadAt(message);
|
836
882
|
};
|
837
883
|
};
|
838
884
|
|
@@ -856,36 +902,40 @@ var useBeginMessageEdit = () => {
|
|
856
902
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
857
903
|
|
858
904
|
// src/vercel/VercelAIAssistantProvider.tsx
|
905
|
+
var import_react18 = require("react");
|
906
|
+
|
907
|
+
// src/vercel/useDummyAIAssistantContext.tsx
|
859
908
|
var import_react17 = require("react");
|
860
909
|
var import_zustand2 = require("zustand");
|
861
|
-
var
|
910
|
+
var useDummyAIAssistantContext = () => {
|
862
911
|
const [context] = (0, import_react17.useState)(() => {
|
863
912
|
const useThread = (0, import_zustand2.create)()(() => ({
|
864
913
|
messages: [],
|
865
|
-
setMessages: () => {
|
866
|
-
},
|
867
914
|
isLoading: false,
|
868
915
|
reload: async () => {
|
916
|
+
throw new Error("Not implemented");
|
869
917
|
},
|
870
918
|
append: async () => {
|
919
|
+
throw new Error("Not implemented");
|
871
920
|
},
|
872
921
|
stop: () => {
|
922
|
+
throw new Error("Not implemented");
|
873
923
|
}
|
874
924
|
}));
|
875
925
|
const useComposer = (0, import_zustand2.create)()(() => ({
|
876
926
|
isEditing: true,
|
877
927
|
canCancel: false,
|
878
928
|
value: "",
|
879
|
-
setValue: () => {
|
929
|
+
setValue: (value) => {
|
930
|
+
useComposer.setState({ value });
|
880
931
|
},
|
881
932
|
edit: () => {
|
882
933
|
throw new Error("Not implemented");
|
883
934
|
},
|
884
935
|
send: () => {
|
885
936
|
useThread.getState().append({
|
886
|
-
content: useComposer.getState().value,
|
887
937
|
role: "user",
|
888
|
-
|
938
|
+
content: [{ type: "text", text: useComposer.getState().value }]
|
889
939
|
});
|
890
940
|
useComposer.getState().setValue("");
|
891
941
|
},
|
@@ -896,70 +946,156 @@ var useAIAssistantContext = () => {
|
|
896
946
|
const useBranchObserver = (0, import_zustand2.create)()(() => ({
|
897
947
|
getBranchState: () => ({
|
898
948
|
branchId: 0,
|
899
|
-
branchCount:
|
949
|
+
branchCount: 1
|
900
950
|
}),
|
901
951
|
switchToBranch: () => {
|
952
|
+
throw new Error("Not implemented");
|
902
953
|
},
|
903
954
|
editAt: async () => {
|
955
|
+
throw new Error("Not implemented");
|
904
956
|
},
|
905
957
|
reloadAt: async () => {
|
958
|
+
throw new Error("Not implemented");
|
906
959
|
}
|
907
960
|
}));
|
908
961
|
return { useThread, useComposer, useBranchObserver };
|
909
962
|
});
|
910
963
|
return context;
|
911
964
|
};
|
965
|
+
|
966
|
+
// src/vercel/VercelAIAssistantProvider.tsx
|
967
|
+
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
968
|
+
var vercelToThreadMessage = (message) => {
|
969
|
+
if (message.role !== "user" && message.role !== "assistant")
|
970
|
+
throw new Error("Unsupported role");
|
971
|
+
return {
|
972
|
+
id: message.id,
|
973
|
+
role: message.role,
|
974
|
+
content: [{ type: "text", text: message.content }]
|
975
|
+
};
|
976
|
+
};
|
977
|
+
var vercelToCachedThreadMessages = (messages) => {
|
978
|
+
return messages.map((m) => {
|
979
|
+
const cached = ThreadMessageCache.get(m);
|
980
|
+
if (cached)
|
981
|
+
return cached;
|
982
|
+
const newMessage = vercelToThreadMessage(m);
|
983
|
+
ThreadMessageCache.set(m, newMessage);
|
984
|
+
return newMessage;
|
985
|
+
});
|
986
|
+
};
|
912
987
|
var VercelAIAssistantProvider = ({
|
913
|
-
|
914
|
-
|
988
|
+
children,
|
989
|
+
...rest
|
915
990
|
}) => {
|
916
|
-
const context =
|
917
|
-
|
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)(
|
1003
|
+
async (message) => {
|
1004
|
+
if (message.content[0]?.type !== "text") {
|
1005
|
+
throw new Error("Only text content is currently supported");
|
1006
|
+
}
|
1007
|
+
await vercel.append({
|
1008
|
+
role: message.role,
|
1009
|
+
content: message.content[0].text
|
1010
|
+
});
|
1011
|
+
},
|
1012
|
+
[vercel.append]
|
1013
|
+
);
|
1014
|
+
const stop = (0, import_react18.useCallback)(() => {
|
1015
|
+
const lastMessage = vercel.messages.at(-1);
|
1016
|
+
vercel.stop();
|
1017
|
+
if (lastMessage?.role === "user") {
|
1018
|
+
vercel.setInput(lastMessage.content);
|
1019
|
+
}
|
1020
|
+
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1021
|
+
const isLoading = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
1022
|
+
(0, import_react18.useMemo)(() => {
|
918
1023
|
context.useThread.setState(
|
919
1024
|
{
|
920
|
-
messages
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
reload: async () => {
|
926
|
-
await chat.reload();
|
927
|
-
},
|
928
|
-
append: async (message) => {
|
929
|
-
await chat.append(message);
|
930
|
-
},
|
931
|
-
stop: () => {
|
932
|
-
const lastMessage = chat.messages.at(-1);
|
933
|
-
chat.stop();
|
934
|
-
if (lastMessage?.role === "user") {
|
935
|
-
chat.setInput(lastMessage.content);
|
936
|
-
}
|
937
|
-
}
|
1025
|
+
messages,
|
1026
|
+
isLoading,
|
1027
|
+
reload,
|
1028
|
+
append,
|
1029
|
+
stop
|
938
1030
|
},
|
939
1031
|
true
|
940
1032
|
);
|
941
|
-
}, [context,
|
942
|
-
(0,
|
1033
|
+
}, [context, messages, reload, append, stop, isLoading]);
|
1034
|
+
(0, import_react18.useMemo)(() => {
|
943
1035
|
context.useComposer.setState({
|
944
|
-
canCancel:
|
945
|
-
value:
|
946
|
-
setValue:
|
1036
|
+
canCancel: isLoading,
|
1037
|
+
value: vercel.input,
|
1038
|
+
setValue: vercel.setInput
|
947
1039
|
});
|
948
|
-
}, [context,
|
949
|
-
const branches =
|
950
|
-
(0,
|
951
|
-
context.useBranchObserver.setState(
|
952
|
-
{
|
953
|
-
getBranchState: (message) => branches.getBranchState(message),
|
954
|
-
switchToBranch: (message, branchId) => branches.switchToBranch(message, branchId),
|
955
|
-
editAt: async (message, newMessage) => branches.editAt(message, newMessage),
|
956
|
-
reloadAt: async (message) => branches.reloadAt(message)
|
957
|
-
},
|
958
|
-
true
|
959
|
-
);
|
1040
|
+
}, [context, isLoading, vercel.input, vercel.setInput]);
|
1041
|
+
const branches = useVercelAIBranches(vercel);
|
1042
|
+
(0, import_react18.useMemo)(() => {
|
1043
|
+
context.useBranchObserver.setState(branches, true);
|
960
1044
|
}, [context, branches]);
|
961
1045
|
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
962
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
|
+
};
|
963
1099
|
// Annotate the CommonJS export names for ESM import in node:
|
964
1100
|
0 && (module.exports = {
|
965
1101
|
ActionBarPrimitive,
|
@@ -967,7 +1103,8 @@ var VercelAIAssistantProvider = ({
|
|
967
1103
|
ComposerPrimitive,
|
968
1104
|
MessagePrimitive,
|
969
1105
|
ThreadPrimitive,
|
970
|
-
|
1106
|
+
VercelAIAssistantProvider,
|
1107
|
+
unstable_VercelRSCAssistantProvider,
|
971
1108
|
unstable_useMessageContext,
|
972
1109
|
useBeginMessageEdit,
|
973
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
|
{
|
@@ -140,7 +137,7 @@ var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef)
|
|
140
137
|
);
|
141
138
|
});
|
142
139
|
|
143
|
-
// src/
|
140
|
+
// src/vercel/useVercelAIBranches.tsx
|
144
141
|
import { useCallback, useMemo, useRef as useRef3 } from "react";
|
145
142
|
var ROOT_ID = "__ROOT_ID__";
|
146
143
|
var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
|
@@ -208,7 +205,7 @@ var sliceMessagesUntil = (messages, message) => {
|
|
208
205
|
throw new Error("Unexpected: Message not found");
|
209
206
|
return messages.slice(0, messageIdx);
|
210
207
|
};
|
211
|
-
var
|
208
|
+
var useVercelAIBranches = (chat) => {
|
212
209
|
const data = useRef3({
|
213
210
|
parentMap: /* @__PURE__ */ new Map(),
|
214
211
|
branchMap: /* @__PURE__ */ new Map(),
|
@@ -233,19 +230,27 @@ var useChatWithBranches = (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) => {
|
246
246
|
const newMessages = sliceMessagesUntil(chat.messages, message);
|
247
247
|
chat.setMessages(newMessages);
|
248
|
-
|
248
|
+
if (newMessage.content[0]?.type !== "text")
|
249
|
+
throw new Error("Only text content is currently supported");
|
250
|
+
await chat.append({
|
251
|
+
role: "user",
|
252
|
+
content: newMessage.content[0].text
|
253
|
+
});
|
249
254
|
},
|
250
255
|
[chat.messages, chat.setMessages, chat.append]
|
251
256
|
);
|
@@ -336,18 +341,25 @@ var useMessageContext2 = () => {
|
|
336
341
|
const useComposer = create((set, get) => ({
|
337
342
|
isEditing: false,
|
338
343
|
canCancel: true,
|
339
|
-
edit: () =>
|
340
|
-
|
341
|
-
|
342
|
-
|
344
|
+
edit: () => {
|
345
|
+
const message = useMessage.getState().message;
|
346
|
+
if (message.role !== "user")
|
347
|
+
throw new Error("Editing is only supported for user messages");
|
348
|
+
if (message.content[0]?.type !== "text")
|
349
|
+
throw new Error("Editing is only supported for text-only messages");
|
350
|
+
return set({
|
351
|
+
isEditing: true,
|
352
|
+
value: message.content[0].text
|
353
|
+
});
|
354
|
+
},
|
343
355
|
cancel: () => set({ isEditing: false }),
|
344
356
|
send: () => {
|
345
357
|
const message = useMessage.getState().message;
|
358
|
+
if (message.role !== "user")
|
359
|
+
throw new Error("Editing is only supported for user messages");
|
346
360
|
useBranchObserver.getState().editAt(message, {
|
347
|
-
|
348
|
-
|
349
|
-
// remove id to create a new message
|
350
|
-
content: get().value
|
361
|
+
role: "user",
|
362
|
+
content: [{ type: "text", text: get().value }]
|
351
363
|
});
|
352
364
|
set({ isEditing: false });
|
353
365
|
},
|
@@ -448,10 +460,41 @@ var MessageIf = ({ children, ...query }) => {
|
|
448
460
|
};
|
449
461
|
|
450
462
|
// src/primitives/message/MessageContent.tsx
|
451
|
-
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
|
+
}) => {
|
452
479
|
const { useMessage } = useMessageContext();
|
453
480
|
const content = useMessage((s) => s.message.content);
|
454
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, null, content)
|
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
|
+
}));
|
455
498
|
};
|
456
499
|
|
457
500
|
// src/primitives/thread/ThreadMessages.tsx
|
@@ -480,7 +523,7 @@ var ThreadMessages = ({ components }) => {
|
|
480
523
|
message: {
|
481
524
|
id: UPCOMING_MESSAGE_ID,
|
482
525
|
role: "assistant",
|
483
|
-
content: "..."
|
526
|
+
content: [{ type: "text", text: "..." }]
|
484
527
|
}
|
485
528
|
},
|
486
529
|
/* @__PURE__ */ React.createElement(AssistantMessage, null)
|
@@ -793,11 +836,10 @@ var useCopyMessage = ({ copiedDuration = 3e3 }) => {
|
|
793
836
|
if (isEditing)
|
794
837
|
return null;
|
795
838
|
return () => {
|
796
|
-
const {
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
navigator.clipboard.writeText(content);
|
839
|
+
const { message, setIsCopied } = useMessage.getState();
|
840
|
+
if (message.content[0]?.type !== "text")
|
841
|
+
throw new Error("Copying is only supported for text-only messages");
|
842
|
+
navigator.clipboard.writeText(message.content[0].text);
|
801
843
|
setIsCopied(true);
|
802
844
|
setTimeout(() => setIsCopied(false), copiedDuration);
|
803
845
|
};
|
@@ -815,7 +857,10 @@ var useReloadMessage = () => {
|
|
815
857
|
if (isLoading || !isAssistant)
|
816
858
|
return null;
|
817
859
|
return () => {
|
818
|
-
|
860
|
+
const message = useMessage.getState().message;
|
861
|
+
if (message.role !== "assistant")
|
862
|
+
throw new Error("Reloading is only supported on assistant messages");
|
863
|
+
useBranchObserver.getState().reloadAt(message);
|
819
864
|
};
|
820
865
|
};
|
821
866
|
|
@@ -839,36 +884,40 @@ var useBeginMessageEdit = () => {
|
|
839
884
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
840
885
|
|
841
886
|
// src/vercel/VercelAIAssistantProvider.tsx
|
842
|
-
import {
|
887
|
+
import { useCallback as useCallback2, useMemo as useMemo4 } from "react";
|
888
|
+
|
889
|
+
// src/vercel/useDummyAIAssistantContext.tsx
|
890
|
+
import { useState as useState3 } from "react";
|
843
891
|
import { create as create2 } from "zustand";
|
844
|
-
var
|
892
|
+
var useDummyAIAssistantContext = () => {
|
845
893
|
const [context] = useState3(() => {
|
846
894
|
const useThread = create2()(() => ({
|
847
895
|
messages: [],
|
848
|
-
setMessages: () => {
|
849
|
-
},
|
850
896
|
isLoading: false,
|
851
897
|
reload: async () => {
|
898
|
+
throw new Error("Not implemented");
|
852
899
|
},
|
853
900
|
append: async () => {
|
901
|
+
throw new Error("Not implemented");
|
854
902
|
},
|
855
903
|
stop: () => {
|
904
|
+
throw new Error("Not implemented");
|
856
905
|
}
|
857
906
|
}));
|
858
907
|
const useComposer = create2()(() => ({
|
859
908
|
isEditing: true,
|
860
909
|
canCancel: false,
|
861
910
|
value: "",
|
862
|
-
setValue: () => {
|
911
|
+
setValue: (value) => {
|
912
|
+
useComposer.setState({ value });
|
863
913
|
},
|
864
914
|
edit: () => {
|
865
915
|
throw new Error("Not implemented");
|
866
916
|
},
|
867
917
|
send: () => {
|
868
918
|
useThread.getState().append({
|
869
|
-
content: useComposer.getState().value,
|
870
919
|
role: "user",
|
871
|
-
|
920
|
+
content: [{ type: "text", text: useComposer.getState().value }]
|
872
921
|
});
|
873
922
|
useComposer.getState().setValue("");
|
874
923
|
},
|
@@ -879,77 +928,167 @@ var useAIAssistantContext = () => {
|
|
879
928
|
const useBranchObserver = create2()(() => ({
|
880
929
|
getBranchState: () => ({
|
881
930
|
branchId: 0,
|
882
|
-
branchCount:
|
931
|
+
branchCount: 1
|
883
932
|
}),
|
884
933
|
switchToBranch: () => {
|
934
|
+
throw new Error("Not implemented");
|
885
935
|
},
|
886
936
|
editAt: async () => {
|
937
|
+
throw new Error("Not implemented");
|
887
938
|
},
|
888
939
|
reloadAt: async () => {
|
940
|
+
throw new Error("Not implemented");
|
889
941
|
}
|
890
942
|
}));
|
891
943
|
return { useThread, useComposer, useBranchObserver };
|
892
944
|
});
|
893
945
|
return context;
|
894
946
|
};
|
947
|
+
|
948
|
+
// src/vercel/VercelAIAssistantProvider.tsx
|
949
|
+
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
950
|
+
var vercelToThreadMessage = (message) => {
|
951
|
+
if (message.role !== "user" && message.role !== "assistant")
|
952
|
+
throw new Error("Unsupported role");
|
953
|
+
return {
|
954
|
+
id: message.id,
|
955
|
+
role: message.role,
|
956
|
+
content: [{ type: "text", text: message.content }]
|
957
|
+
};
|
958
|
+
};
|
959
|
+
var vercelToCachedThreadMessages = (messages) => {
|
960
|
+
return messages.map((m) => {
|
961
|
+
const cached = ThreadMessageCache.get(m);
|
962
|
+
if (cached)
|
963
|
+
return cached;
|
964
|
+
const newMessage = vercelToThreadMessage(m);
|
965
|
+
ThreadMessageCache.set(m, newMessage);
|
966
|
+
return newMessage;
|
967
|
+
});
|
968
|
+
};
|
895
969
|
var VercelAIAssistantProvider = ({
|
896
|
-
|
897
|
-
|
970
|
+
children,
|
971
|
+
...rest
|
898
972
|
}) => {
|
899
|
-
const context =
|
973
|
+
const context = useDummyAIAssistantContext();
|
974
|
+
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
975
|
+
const messages = useMemo4(() => {
|
976
|
+
return vercelToCachedThreadMessages(vercel.messages);
|
977
|
+
}, [vercel.messages]);
|
978
|
+
const maybeReload = "reload" in vercel ? vercel.reload : null;
|
979
|
+
const reload = useCallback2(async () => {
|
980
|
+
if (!maybeReload)
|
981
|
+
throw new Error("Reload not supported");
|
982
|
+
await maybeReload();
|
983
|
+
}, [maybeReload]);
|
984
|
+
const append = useCallback2(
|
985
|
+
async (message) => {
|
986
|
+
if (message.content[0]?.type !== "text") {
|
987
|
+
throw new Error("Only text content is currently supported");
|
988
|
+
}
|
989
|
+
await vercel.append({
|
990
|
+
role: message.role,
|
991
|
+
content: message.content[0].text
|
992
|
+
});
|
993
|
+
},
|
994
|
+
[vercel.append]
|
995
|
+
);
|
996
|
+
const stop = useCallback2(() => {
|
997
|
+
const lastMessage = vercel.messages.at(-1);
|
998
|
+
vercel.stop();
|
999
|
+
if (lastMessage?.role === "user") {
|
1000
|
+
vercel.setInput(lastMessage.content);
|
1001
|
+
}
|
1002
|
+
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1003
|
+
const isLoading = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
900
1004
|
useMemo4(() => {
|
901
1005
|
context.useThread.setState(
|
902
1006
|
{
|
903
|
-
messages
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
reload: async () => {
|
909
|
-
await chat.reload();
|
910
|
-
},
|
911
|
-
append: async (message) => {
|
912
|
-
await chat.append(message);
|
913
|
-
},
|
914
|
-
stop: () => {
|
915
|
-
const lastMessage = chat.messages.at(-1);
|
916
|
-
chat.stop();
|
917
|
-
if (lastMessage?.role === "user") {
|
918
|
-
chat.setInput(lastMessage.content);
|
919
|
-
}
|
920
|
-
}
|
1007
|
+
messages,
|
1008
|
+
isLoading,
|
1009
|
+
reload,
|
1010
|
+
append,
|
1011
|
+
stop
|
921
1012
|
},
|
922
1013
|
true
|
923
1014
|
);
|
924
|
-
}, [context,
|
1015
|
+
}, [context, messages, reload, append, stop, isLoading]);
|
925
1016
|
useMemo4(() => {
|
926
1017
|
context.useComposer.setState({
|
927
|
-
canCancel:
|
928
|
-
value:
|
929
|
-
setValue:
|
1018
|
+
canCancel: isLoading,
|
1019
|
+
value: vercel.input,
|
1020
|
+
setValue: vercel.setInput
|
930
1021
|
});
|
931
|
-
}, [context,
|
932
|
-
const branches =
|
1022
|
+
}, [context, isLoading, vercel.input, vercel.setInput]);
|
1023
|
+
const branches = useVercelAIBranches(vercel);
|
933
1024
|
useMemo4(() => {
|
934
|
-
context.useBranchObserver.setState(
|
935
|
-
{
|
936
|
-
getBranchState: (message) => branches.getBranchState(message),
|
937
|
-
switchToBranch: (message, branchId) => branches.switchToBranch(message, branchId),
|
938
|
-
editAt: async (message, newMessage) => branches.editAt(message, newMessage),
|
939
|
-
reloadAt: async (message) => branches.reloadAt(message)
|
940
|
-
},
|
941
|
-
true
|
942
|
-
);
|
1025
|
+
context.useBranchObserver.setState(branches, true);
|
943
1026
|
}, [context, branches]);
|
944
1027
|
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
945
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
|
+
};
|
946
1084
|
export {
|
947
1085
|
actionBar_exports as ActionBarPrimitive,
|
948
1086
|
branchPicker_exports as BranchPickerPrimitive,
|
949
1087
|
composer_exports as ComposerPrimitive,
|
950
1088
|
message_exports as MessagePrimitive,
|
951
1089
|
thread_exports as ThreadPrimitive,
|
952
|
-
VercelAIAssistantProvider
|
1090
|
+
VercelAIAssistantProvider,
|
1091
|
+
VercelRSCAssistantProvider as unstable_VercelRSCAssistantProvider,
|
953
1092
|
useMessageContext as unstable_useMessageContext,
|
954
1093
|
useBeginMessageEdit,
|
955
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
|
},
|