@assistant-ui/react 0.0.7 → 0.0.9
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 +21 -12
- package/dist/index.d.ts +21 -12
- package/dist/index.js +412 -328
- package/dist/index.mjs +403 -318
- package/package.json +2 -2
package/dist/index.js
CHANGED
@@ -53,6 +53,7 @@ __export(thread_exports, {
|
|
53
53
|
If: () => ThreadIf,
|
54
54
|
Messages: () => ThreadMessages,
|
55
55
|
Root: () => ThreadRoot,
|
56
|
+
ScrollToBottom: () => ThreadScrollToBottom,
|
56
57
|
Viewport: () => ThreadViewport
|
57
58
|
});
|
58
59
|
|
@@ -106,7 +107,7 @@ var ThreadEmpty = ({ children }) => {
|
|
106
107
|
var import_primitive = require("@radix-ui/primitive");
|
107
108
|
var import_react_compose_refs = require("@radix-ui/react-compose-refs");
|
108
109
|
var import_react_primitive2 = require("@radix-ui/react-primitive");
|
109
|
-
var
|
110
|
+
var import_react5 = require("react");
|
110
111
|
|
111
112
|
// src/utils/hooks/useOnResizeContent.tsx
|
112
113
|
var import_react3 = require("react");
|
@@ -147,22 +148,55 @@ var useOnResizeContent = (ref, callback) => {
|
|
147
148
|
}, [ref.current]);
|
148
149
|
};
|
149
150
|
|
151
|
+
// src/utils/hooks/useOnScrollToBottom.tsx
|
152
|
+
var import_react4 = require("react");
|
153
|
+
var useOnScrollToBottom = (callback) => {
|
154
|
+
const callbackRef = (0, import_react4.useRef)(callback);
|
155
|
+
callbackRef.current = callback;
|
156
|
+
const { useThread } = useAssistantContext();
|
157
|
+
(0, import_react4.useEffect)(() => {
|
158
|
+
return useThread.getState().onScrollToBottom(() => {
|
159
|
+
callbackRef.current();
|
160
|
+
});
|
161
|
+
}, [useThread]);
|
162
|
+
};
|
163
|
+
|
150
164
|
// src/primitives/thread/ThreadViewport.tsx
|
151
|
-
var ThreadViewport = (0,
|
152
|
-
const
|
165
|
+
var ThreadViewport = (0, import_react5.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
|
166
|
+
const messagesEndRef = (0, import_react5.useRef)(null);
|
167
|
+
const divRef = (0, import_react5.useRef)(null);
|
153
168
|
const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
|
154
|
-
const
|
169
|
+
const { useThread } = useAssistantContext();
|
170
|
+
const firstRenderRef = (0, import_react5.useRef)(true);
|
171
|
+
const lastScrollTop = (0, import_react5.useRef)(0);
|
172
|
+
const scrollToBottom = () => {
|
173
|
+
const div = messagesEndRef.current;
|
174
|
+
if (!div || !autoScroll)
|
175
|
+
return;
|
176
|
+
const behavior = firstRenderRef.current ? "instant" : "auto";
|
177
|
+
firstRenderRef.current = false;
|
178
|
+
useThread.setState({ isAtBottom: true });
|
179
|
+
div.scrollIntoView({ behavior });
|
180
|
+
};
|
155
181
|
useOnResizeContent(divRef, () => {
|
156
|
-
|
157
|
-
if (!div || !isAtBottom)
|
182
|
+
if (!useThread.getState().isAtBottom)
|
158
183
|
return;
|
159
|
-
|
184
|
+
scrollToBottom();
|
185
|
+
});
|
186
|
+
useOnScrollToBottom(() => {
|
187
|
+
scrollToBottom();
|
160
188
|
});
|
161
189
|
const handleScroll = () => {
|
162
190
|
const div = divRef.current;
|
163
191
|
if (!div)
|
164
192
|
return;
|
165
|
-
|
193
|
+
const isAtBottom = useThread.getState().isAtBottom;
|
194
|
+
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
|
195
|
+
if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
|
196
|
+
} else if (newIsAtBottom !== isAtBottom) {
|
197
|
+
useThread.setState({ isAtBottom: newIsAtBottom });
|
198
|
+
}
|
199
|
+
lastScrollTop.current = div.scrollTop;
|
166
200
|
};
|
167
201
|
return /* @__PURE__ */ React.createElement(
|
168
202
|
import_react_primitive2.Primitive.div,
|
@@ -171,19 +205,24 @@ var ThreadViewport = (0, import_react4.forwardRef)(({ onScroll, children, ...res
|
|
171
205
|
onScroll: (0, import_primitive.composeEventHandlers)(onScroll, handleScroll),
|
172
206
|
ref
|
173
207
|
},
|
174
|
-
children
|
208
|
+
children,
|
209
|
+
/* @__PURE__ */ React.createElement("div", { ref: messagesEndRef })
|
175
210
|
);
|
176
211
|
});
|
177
212
|
|
178
|
-
// src/vercel/useVercelAIBranches.tsx
|
179
|
-
var
|
180
|
-
|
213
|
+
// src/adapters/vercel/useVercelAIBranches.tsx
|
214
|
+
var import_react6 = require("react");
|
215
|
+
|
216
|
+
// src/utils/context/stores/AssistantTypes.ts
|
217
|
+
var ROOT_PARENT_ID = "__ROOT_ID__";
|
218
|
+
|
219
|
+
// src/adapters/vercel/useVercelAIBranches.tsx
|
181
220
|
var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
|
182
221
|
var updateBranchData = (data, messages) => {
|
183
222
|
for (let i = 0; i < messages.length; i++) {
|
184
223
|
const child = messages[i];
|
185
224
|
const childId = child.id;
|
186
|
-
const parentId = messages[i - 1]?.id ??
|
225
|
+
const parentId = messages[i - 1]?.id ?? ROOT_PARENT_ID;
|
187
226
|
data.parentMap.set(childId, parentId);
|
188
227
|
const parentArray = data.branchMap.get(parentId);
|
189
228
|
if (!parentArray) {
|
@@ -194,32 +233,32 @@ var updateBranchData = (data, messages) => {
|
|
194
233
|
data.snapshots.set(childId, messages);
|
195
234
|
}
|
196
235
|
};
|
197
|
-
var getParentId = (data, messages,
|
198
|
-
if (
|
236
|
+
var getParentId = (data, messages, messageId) => {
|
237
|
+
if (messageId === UPCOMING_MESSAGE_ID) {
|
199
238
|
const parent = messages.at(-1);
|
200
239
|
if (!parent)
|
201
|
-
return
|
240
|
+
return ROOT_PARENT_ID;
|
202
241
|
return parent.id;
|
203
242
|
}
|
204
|
-
const parentId = data.parentMap.get(
|
243
|
+
const parentId = data.parentMap.get(messageId);
|
205
244
|
if (!parentId)
|
206
245
|
throw new Error("Unexpected: Message parent not found");
|
207
246
|
return parentId;
|
208
247
|
};
|
209
|
-
var getBranchStateImpl = (data, messages,
|
210
|
-
const parentId = getParentId(data, messages,
|
248
|
+
var getBranchStateImpl = (data, messages, messageId) => {
|
249
|
+
const parentId = getParentId(data, messages, messageId);
|
211
250
|
const branches = data.branchMap.get(parentId) ?? [];
|
212
|
-
const branchId =
|
251
|
+
const branchId = messageId === UPCOMING_MESSAGE_ID ? branches.length : branches.indexOf(messageId);
|
213
252
|
if (branchId === -1)
|
214
253
|
throw new Error("Unexpected: Message not found in parent children");
|
215
|
-
const upcomingOffset =
|
254
|
+
const upcomingOffset = messageId === UPCOMING_MESSAGE_ID ? 1 : 0;
|
216
255
|
return {
|
217
256
|
branchId,
|
218
257
|
branchCount: branches.length + upcomingOffset
|
219
258
|
};
|
220
259
|
};
|
221
|
-
var switchToBranchImpl = (data, messages,
|
222
|
-
const parentId = getParentId(data, messages,
|
260
|
+
var switchToBranchImpl = (data, messages, messageId, branchId) => {
|
261
|
+
const parentId = getParentId(data, messages, messageId);
|
223
262
|
const branches = data.branchMap.get(parentId);
|
224
263
|
if (!branches)
|
225
264
|
throw new Error("Unexpected: Parent children not found");
|
@@ -228,40 +267,42 @@ var switchToBranchImpl = (data, messages, message, branchId) => {
|
|
228
267
|
throw new Error("Unexpected: Requested branch not found");
|
229
268
|
if (branchId < 0 || branchId >= branches.length)
|
230
269
|
throw new Error("Switch to branch called with a branch index out of range");
|
231
|
-
if (newMessageId ===
|
270
|
+
if (newMessageId === messageId)
|
232
271
|
return messages;
|
233
272
|
const snapshot = data.snapshots.get(newMessageId);
|
234
273
|
if (!snapshot)
|
235
274
|
throw new Error("Unexpected: Branch snapshot not found");
|
236
275
|
return snapshot;
|
237
276
|
};
|
238
|
-
var sliceMessagesUntil = (messages,
|
239
|
-
if (
|
277
|
+
var sliceMessagesUntil = (messages, messageId) => {
|
278
|
+
if (messageId === ROOT_PARENT_ID)
|
279
|
+
return [];
|
280
|
+
if (messageId === UPCOMING_MESSAGE_ID)
|
240
281
|
return messages;
|
241
|
-
const messageIdx = messages.findIndex((m) => m.id ===
|
282
|
+
const messageIdx = messages.findIndex((m) => m.id === messageId);
|
242
283
|
if (messageIdx === -1)
|
243
284
|
throw new Error("Unexpected: Message not found");
|
244
|
-
return messages.slice(0, messageIdx);
|
285
|
+
return messages.slice(0, messageIdx + 1);
|
245
286
|
};
|
246
|
-
var useVercelAIBranches = (chat) => {
|
247
|
-
const data = (0,
|
287
|
+
var useVercelAIBranches = (chat, context) => {
|
288
|
+
const data = (0, import_react6.useRef)({
|
248
289
|
parentMap: /* @__PURE__ */ new Map(),
|
249
290
|
branchMap: /* @__PURE__ */ new Map(),
|
250
291
|
snapshots: /* @__PURE__ */ new Map()
|
251
292
|
}).current;
|
252
293
|
updateBranchData(data, chat.messages);
|
253
|
-
const getBranchState = (0,
|
254
|
-
(
|
255
|
-
return getBranchStateImpl(data, chat.messages,
|
294
|
+
const getBranchState = (0, import_react6.useCallback)(
|
295
|
+
(messageId) => {
|
296
|
+
return getBranchStateImpl(data, chat.messages, messageId);
|
256
297
|
},
|
257
298
|
[data, chat.messages]
|
258
299
|
);
|
259
|
-
const switchToBranch = (0,
|
260
|
-
(
|
300
|
+
const switchToBranch = (0, import_react6.useCallback)(
|
301
|
+
(messageId, branchId) => {
|
261
302
|
const newMessages = switchToBranchImpl(
|
262
303
|
data,
|
263
304
|
chat.messages,
|
264
|
-
|
305
|
+
messageId,
|
265
306
|
branchId
|
266
307
|
);
|
267
308
|
chat.setMessages(newMessages);
|
@@ -269,61 +310,66 @@ var useVercelAIBranches = (chat) => {
|
|
269
310
|
[data, chat.messages, chat.setMessages]
|
270
311
|
);
|
271
312
|
const reloadMaybe = "reload" in chat ? chat.reload : void 0;
|
272
|
-
const
|
273
|
-
async (
|
313
|
+
const reload = (0, import_react6.useCallback)(
|
314
|
+
async (messageId) => {
|
274
315
|
if (!reloadMaybe)
|
275
316
|
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
276
|
-
const newMessages = sliceMessagesUntil(chat.messages,
|
317
|
+
const newMessages = sliceMessagesUntil(chat.messages, messageId);
|
277
318
|
chat.setMessages(newMessages);
|
319
|
+
context.useThread.getState().scrollToBottom();
|
278
320
|
await reloadMaybe();
|
279
321
|
},
|
280
|
-
[chat.messages, chat.setMessages, reloadMaybe]
|
322
|
+
[context, chat.messages, chat.setMessages, reloadMaybe]
|
281
323
|
);
|
282
|
-
const
|
283
|
-
async (message
|
284
|
-
const newMessages = sliceMessagesUntil(chat.messages, message);
|
324
|
+
const append = (0, import_react6.useCallback)(
|
325
|
+
async (message) => {
|
326
|
+
const newMessages = sliceMessagesUntil(chat.messages, message.parentId);
|
285
327
|
chat.setMessages(newMessages);
|
286
|
-
if (
|
328
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
287
329
|
throw new Error("Only text content is currently supported");
|
330
|
+
context.useThread.getState().scrollToBottom();
|
288
331
|
await chat.append({
|
289
332
|
role: "user",
|
290
|
-
content:
|
333
|
+
content: message.content[0].text
|
291
334
|
});
|
292
335
|
},
|
293
|
-
[chat.messages, chat.setMessages, chat.append]
|
336
|
+
[context, chat.messages, chat.setMessages, chat.append]
|
294
337
|
);
|
295
|
-
return (0,
|
338
|
+
return (0, import_react6.useMemo)(
|
296
339
|
() => ({
|
297
340
|
getBranchState,
|
298
341
|
switchToBranch,
|
299
|
-
|
300
|
-
|
342
|
+
append,
|
343
|
+
reload
|
301
344
|
}),
|
302
|
-
[getBranchState, switchToBranch,
|
345
|
+
[getBranchState, switchToBranch, append, reload]
|
303
346
|
);
|
304
347
|
};
|
305
348
|
var hasUpcomingMessage = (thread) => {
|
306
349
|
return thread.isLoading && thread.messages[thread.messages.length - 1]?.role !== "assistant";
|
307
350
|
};
|
308
351
|
|
309
|
-
// src/utils/context/
|
310
|
-
var
|
352
|
+
// src/utils/context/useComposerContext.ts
|
353
|
+
var import_react8 = require("react");
|
311
354
|
|
312
|
-
// src/utils/context/
|
313
|
-
var
|
314
|
-
var MessageContext = (0,
|
355
|
+
// src/utils/context/useMessageContext.ts
|
356
|
+
var import_react7 = require("react");
|
357
|
+
var MessageContext = (0, import_react7.createContext)(null);
|
315
358
|
var useMessageContext = () => {
|
316
|
-
const context = (0,
|
359
|
+
const context = (0, import_react7.useContext)(MessageContext);
|
317
360
|
if (!context)
|
318
361
|
throw new Error("useMessageContext must be used within a MessageProvider");
|
319
362
|
return context;
|
320
363
|
};
|
321
364
|
|
322
|
-
// src/utils/context/
|
365
|
+
// src/utils/context/useComposerContext.ts
|
323
366
|
var useComposerContext = () => {
|
324
367
|
const { useComposer: useAssisstantComposer } = useAssistantContext();
|
325
|
-
const { useComposer: useMessageComposer } = (0,
|
326
|
-
return {
|
368
|
+
const { useComposer: useMessageComposer } = (0, import_react8.useContext)(MessageContext) ?? {};
|
369
|
+
return {
|
370
|
+
useComposer: useMessageComposer ?? useAssisstantComposer,
|
371
|
+
type: useMessageComposer ? "message" : "assistant"
|
372
|
+
};
|
327
373
|
};
|
328
374
|
|
329
375
|
// src/primitives/composer/ComposerIf.tsx
|
@@ -352,16 +398,15 @@ __export(message_exports, {
|
|
352
398
|
});
|
353
399
|
|
354
400
|
// src/primitives/message/MessageProvider.tsx
|
355
|
-
var
|
401
|
+
var import_react9 = require("react");
|
356
402
|
var import_zustand = require("zustand");
|
357
|
-
var import_shallow = require("zustand/react/shallow");
|
358
403
|
var getIsLast = (thread, message) => {
|
359
404
|
const hasUpcoming = hasUpcomingMessage(thread);
|
360
405
|
return hasUpcoming ? message.id === UPCOMING_MESSAGE_ID : thread.messages[thread.messages.length - 1]?.id === message.id;
|
361
406
|
};
|
362
407
|
var useMessageContext2 = () => {
|
363
|
-
const
|
364
|
-
|
408
|
+
const [context] = (0, import_react9.useState)(() => {
|
409
|
+
const { useThread } = useAssistantContext();
|
365
410
|
const useMessage = (0, import_zustand.create)(() => ({
|
366
411
|
message: null,
|
367
412
|
isLast: false,
|
@@ -370,10 +415,6 @@ var useMessageContext2 = () => {
|
|
370
415
|
setIsCopied: () => {
|
371
416
|
},
|
372
417
|
setIsHovering: () => {
|
373
|
-
},
|
374
|
-
branchState: {
|
375
|
-
branchId: 0,
|
376
|
-
branchCount: 0
|
377
418
|
}
|
378
419
|
}));
|
379
420
|
const useComposer = (0, import_zustand.create)((set, get) => ({
|
@@ -395,8 +436,8 @@ var useMessageContext2 = () => {
|
|
395
436
|
const message = useMessage.getState().message;
|
396
437
|
if (message.role !== "user")
|
397
438
|
throw new Error("Editing is only supported for user messages");
|
398
|
-
|
399
|
-
|
439
|
+
useThread.getState().append({
|
440
|
+
parentId: message.parentId,
|
400
441
|
content: [{ type: "text", text: get().value }]
|
401
442
|
});
|
402
443
|
set({ isEditing: false });
|
@@ -412,15 +453,12 @@ var MessageProvider = ({
|
|
412
453
|
message,
|
413
454
|
children
|
414
455
|
}) => {
|
415
|
-
const { useThread
|
456
|
+
const { useThread } = useAssistantContext();
|
416
457
|
const context = useMessageContext2();
|
417
|
-
const branchState = useBranchObserver(
|
418
|
-
(0, import_shallow.useShallow)((b) => b.getBranchState(message))
|
419
|
-
);
|
420
458
|
const isLast = useThread((thread) => getIsLast(thread, message));
|
421
|
-
const [isCopied, setIsCopied] = (0,
|
422
|
-
const [isHovering, setIsHovering] = (0,
|
423
|
-
(0,
|
459
|
+
const [isCopied, setIsCopied] = (0, import_react9.useState)(false);
|
460
|
+
const [isHovering, setIsHovering] = (0, import_react9.useState)(false);
|
461
|
+
(0, import_react9.useMemo)(() => {
|
424
462
|
context.useMessage.setState(
|
425
463
|
{
|
426
464
|
message,
|
@@ -428,20 +466,19 @@ var MessageProvider = ({
|
|
428
466
|
isCopied,
|
429
467
|
isHovering,
|
430
468
|
setIsCopied,
|
431
|
-
setIsHovering
|
432
|
-
branchState
|
469
|
+
setIsHovering
|
433
470
|
},
|
434
471
|
true
|
435
472
|
);
|
436
|
-
}, [context, message, isLast, isCopied, isHovering
|
473
|
+
}, [context, message, isLast, isCopied, isHovering]);
|
437
474
|
return /* @__PURE__ */ React.createElement(MessageContext.Provider, { value: context }, children);
|
438
475
|
};
|
439
476
|
|
440
477
|
// src/primitives/message/MessageRoot.tsx
|
441
478
|
var import_primitive2 = require("@radix-ui/primitive");
|
442
479
|
var import_react_primitive3 = require("@radix-ui/react-primitive");
|
443
|
-
var
|
444
|
-
var MessageRoot = (0,
|
480
|
+
var import_react10 = require("react");
|
481
|
+
var MessageRoot = (0, import_react10.forwardRef)(
|
445
482
|
({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
|
446
483
|
const { useMessage } = useMessageContext();
|
447
484
|
const setIsHovering = useMessage((s) => s.setIsHovering);
|
@@ -466,29 +503,21 @@ var MessageRoot = (0, import_react9.forwardRef)(
|
|
466
503
|
// src/primitives/message/MessageIf.tsx
|
467
504
|
var useMessageIf = (props) => {
|
468
505
|
const { useMessage } = useMessageContext();
|
469
|
-
return useMessage(
|
470
|
-
(
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
return false;
|
485
|
-
if (props.copied === true && !isCopied)
|
486
|
-
return false;
|
487
|
-
if (props.copied === false && isCopied)
|
488
|
-
return false;
|
489
|
-
return true;
|
490
|
-
}
|
491
|
-
);
|
506
|
+
return useMessage(({ message, isLast, isCopied, isHovering }) => {
|
507
|
+
if (props.hasBranches === true && message.branchCount < 2)
|
508
|
+
return false;
|
509
|
+
if (props.user && message.role !== "user")
|
510
|
+
return false;
|
511
|
+
if (props.assistant && message.role !== "assistant")
|
512
|
+
return false;
|
513
|
+
if (props.lastOrHover === true && !isHovering && !isLast)
|
514
|
+
return false;
|
515
|
+
if (props.copied === true && !isCopied)
|
516
|
+
return false;
|
517
|
+
if (props.copied === false && isCopied)
|
518
|
+
return false;
|
519
|
+
return true;
|
520
|
+
});
|
492
521
|
};
|
493
522
|
var MessageIf = ({ children, ...query }) => {
|
494
523
|
const result = useMessageIf(query);
|
@@ -559,13 +588,40 @@ var ThreadMessages = ({ components }) => {
|
|
559
588
|
message: {
|
560
589
|
id: UPCOMING_MESSAGE_ID,
|
561
590
|
role: "assistant",
|
562
|
-
content: [{ type: "text", text: "..." }]
|
591
|
+
content: [{ type: "text", text: "..." }],
|
592
|
+
parentId: messages.at(-1)?.id ?? ROOT_PARENT_ID,
|
593
|
+
// TODO fix these (move upcoming message to AssistantContext)
|
594
|
+
branchId: 0,
|
595
|
+
branchCount: 1,
|
596
|
+
createdAt: /* @__PURE__ */ new Date()
|
563
597
|
}
|
564
598
|
},
|
565
599
|
/* @__PURE__ */ React.createElement(AssistantMessage, null)
|
566
600
|
));
|
567
601
|
};
|
568
602
|
|
603
|
+
// src/primitives/thread/ThreadScrollToBottom.tsx
|
604
|
+
var import_primitive3 = require("@radix-ui/primitive");
|
605
|
+
var import_react_primitive4 = require("@radix-ui/react-primitive");
|
606
|
+
var import_react11 = require("react");
|
607
|
+
var ThreadScrollToBottom = (0, import_react11.forwardRef)(({ onClick, ...rest }, ref) => {
|
608
|
+
const { useThread } = useAssistantContext();
|
609
|
+
const isAtBottom = useThread((s) => s.isAtBottom);
|
610
|
+
const handleScrollToBottom = () => {
|
611
|
+
const thread = useThread.getState();
|
612
|
+
thread.scrollToBottom();
|
613
|
+
};
|
614
|
+
return /* @__PURE__ */ React.createElement(
|
615
|
+
import_react_primitive4.Primitive.button,
|
616
|
+
{
|
617
|
+
...rest,
|
618
|
+
disabled: isAtBottom,
|
619
|
+
ref,
|
620
|
+
onClick: (0, import_primitive3.composeEventHandlers)(onClick, handleScrollToBottom)
|
621
|
+
}
|
622
|
+
);
|
623
|
+
});
|
624
|
+
|
569
625
|
// src/primitives/composer/index.ts
|
570
626
|
var composer_exports = {};
|
571
627
|
__export(composer_exports, {
|
@@ -577,33 +633,15 @@ __export(composer_exports, {
|
|
577
633
|
});
|
578
634
|
|
579
635
|
// src/primitives/composer/ComposerRoot.tsx
|
580
|
-
var
|
636
|
+
var import_primitive4 = require("@radix-ui/primitive");
|
581
637
|
var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
|
582
|
-
var
|
583
|
-
var
|
584
|
-
var
|
585
|
-
var useComposerFormContext = () => {
|
586
|
-
const context = (0, import_react10.useContext)(ComposerFormContext);
|
587
|
-
if (!context) {
|
588
|
-
throw new Error(
|
589
|
-
"Composer compound components cannot be rendered outside the Composer component"
|
590
|
-
);
|
591
|
-
}
|
592
|
-
return context;
|
593
|
-
};
|
594
|
-
var ComposerRoot = (0, import_react10.forwardRef)(
|
638
|
+
var import_react_primitive5 = require("@radix-ui/react-primitive");
|
639
|
+
var import_react12 = require("react");
|
640
|
+
var ComposerRoot = (0, import_react12.forwardRef)(
|
595
641
|
({ onSubmit, ...rest }, forwardedRef) => {
|
596
642
|
const { useComposer } = useComposerContext();
|
597
|
-
const formRef = (0,
|
643
|
+
const formRef = (0, import_react12.useRef)(null);
|
598
644
|
const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
|
599
|
-
const composerContextValue = (0, import_react10.useMemo)(
|
600
|
-
() => ({
|
601
|
-
submit: () => formRef.current?.dispatchEvent(
|
602
|
-
new Event("submit", { cancelable: true, bubbles: true })
|
603
|
-
)
|
604
|
-
}),
|
605
|
-
[]
|
606
|
-
);
|
607
645
|
const handleSubmit = (e) => {
|
608
646
|
const composerState = useComposer.getState();
|
609
647
|
if (!composerState.isEditing)
|
@@ -611,73 +649,96 @@ var ComposerRoot = (0, import_react10.forwardRef)(
|
|
611
649
|
e.preventDefault();
|
612
650
|
composerState.send();
|
613
651
|
};
|
614
|
-
return /* @__PURE__ */ React.createElement(
|
615
|
-
|
652
|
+
return /* @__PURE__ */ React.createElement(
|
653
|
+
import_react_primitive5.Primitive.form,
|
616
654
|
{
|
617
655
|
...rest,
|
618
656
|
ref,
|
619
|
-
onSubmit: (0,
|
657
|
+
onSubmit: (0, import_primitive4.composeEventHandlers)(onSubmit, handleSubmit)
|
620
658
|
}
|
621
|
-
)
|
659
|
+
);
|
622
660
|
}
|
623
661
|
);
|
624
662
|
|
625
663
|
// src/primitives/composer/ComposerInput.tsx
|
626
|
-
var
|
664
|
+
var import_primitive5 = require("@radix-ui/primitive");
|
665
|
+
var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
|
627
666
|
var import_react_slot = require("@radix-ui/react-slot");
|
628
|
-
var
|
667
|
+
var import_react13 = require("react");
|
629
668
|
var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
|
630
|
-
var ComposerInput = (0,
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
}
|
669
|
-
|
670
|
-
|
669
|
+
var ComposerInput = (0, import_react13.forwardRef)(
|
670
|
+
({ autoFocus, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
671
|
+
const { useThread } = useAssistantContext();
|
672
|
+
const { useComposer, type } = useComposerContext();
|
673
|
+
const value = useComposer((c) => {
|
674
|
+
if (!c.isEditing)
|
675
|
+
return "";
|
676
|
+
return c.value;
|
677
|
+
});
|
678
|
+
const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
|
679
|
+
const handleKeyPress = (e) => {
|
680
|
+
if (disabled)
|
681
|
+
return;
|
682
|
+
const composer = useComposer.getState();
|
683
|
+
if (e.key === "Escape" && composer.canCancel) {
|
684
|
+
e.preventDefault();
|
685
|
+
useComposer.getState().cancel();
|
686
|
+
}
|
687
|
+
if (e.key === "Enter" && e.shiftKey === false) {
|
688
|
+
const isLoading = useThread.getState().isLoading;
|
689
|
+
if (!isLoading) {
|
690
|
+
e.preventDefault();
|
691
|
+
composer.send();
|
692
|
+
}
|
693
|
+
}
|
694
|
+
};
|
695
|
+
const textareaRef = (0, import_react13.useRef)(null);
|
696
|
+
const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
|
697
|
+
const autoFocusEnabled = autoFocus !== false && !disabled;
|
698
|
+
const focus = (0, import_react13.useCallback)(() => {
|
699
|
+
const textarea = textareaRef.current;
|
700
|
+
if (!textarea || !autoFocusEnabled)
|
701
|
+
return;
|
702
|
+
textarea.focus();
|
703
|
+
textarea.setSelectionRange(
|
704
|
+
textareaRef.current.value.length,
|
705
|
+
textareaRef.current.value.length
|
706
|
+
);
|
707
|
+
}, [autoFocusEnabled]);
|
708
|
+
(0, import_react13.useEffect)(() => focus(), [focus]);
|
709
|
+
useOnScrollToBottom(() => {
|
710
|
+
if (type === "assistant") {
|
711
|
+
focus();
|
712
|
+
}
|
713
|
+
});
|
714
|
+
return /* @__PURE__ */ React.createElement(
|
715
|
+
Component,
|
716
|
+
{
|
717
|
+
value,
|
718
|
+
...rest,
|
719
|
+
ref,
|
720
|
+
disabled,
|
721
|
+
onChange: (0, import_primitive5.composeEventHandlers)(onChange, (e) => {
|
722
|
+
const composerState = useComposer.getState();
|
723
|
+
if (!composerState.isEditing)
|
724
|
+
return;
|
725
|
+
return composerState.setValue(e.target.value);
|
726
|
+
}),
|
727
|
+
onKeyDown: (0, import_primitive5.composeEventHandlers)(onKeyDown, handleKeyPress)
|
728
|
+
}
|
729
|
+
);
|
730
|
+
}
|
731
|
+
);
|
671
732
|
|
672
733
|
// src/primitives/composer/ComposerSend.tsx
|
673
|
-
var
|
674
|
-
var
|
675
|
-
var ComposerSend = (0,
|
734
|
+
var import_react_primitive6 = require("@radix-ui/react-primitive");
|
735
|
+
var import_react14 = require("react");
|
736
|
+
var ComposerSend = (0, import_react14.forwardRef)(
|
676
737
|
({ disabled, ...rest }, ref) => {
|
677
738
|
const { useComposer } = useComposerContext();
|
678
739
|
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
679
740
|
return /* @__PURE__ */ React.createElement(
|
680
|
-
|
741
|
+
import_react_primitive6.Primitive.button,
|
681
742
|
{
|
682
743
|
type: "submit",
|
683
744
|
...rest,
|
@@ -689,22 +750,22 @@ var ComposerSend = (0, import_react12.forwardRef)(
|
|
689
750
|
);
|
690
751
|
|
691
752
|
// src/primitives/composer/ComposerCancel.tsx
|
692
|
-
var
|
693
|
-
var
|
694
|
-
var
|
695
|
-
var ComposerCancel = (0,
|
753
|
+
var import_primitive6 = require("@radix-ui/primitive");
|
754
|
+
var import_react_primitive7 = require("@radix-ui/react-primitive");
|
755
|
+
var import_react15 = require("react");
|
756
|
+
var ComposerCancel = (0, import_react15.forwardRef)(({ disabled, onClick, ...rest }, ref) => {
|
696
757
|
const { useComposer } = useComposerContext();
|
697
758
|
const hasValue = useComposer((c) => c.canCancel);
|
698
759
|
const handleClose = () => {
|
699
760
|
useComposer.getState().cancel();
|
700
761
|
};
|
701
762
|
return /* @__PURE__ */ React.createElement(
|
702
|
-
|
763
|
+
import_react_primitive7.Primitive.button,
|
703
764
|
{
|
704
765
|
type: "button",
|
705
766
|
...rest,
|
706
767
|
ref,
|
707
|
-
onClick: (0,
|
768
|
+
onClick: (0, import_primitive6.composeEventHandlers)(onClick, handleClose),
|
708
769
|
disabled: disabled || !hasValue
|
709
770
|
}
|
710
771
|
);
|
@@ -720,42 +781,64 @@ __export(branchPicker_exports, {
|
|
720
781
|
Root: () => BranchPickerRoot
|
721
782
|
});
|
722
783
|
|
784
|
+
// src/utils/context/combined/useCombinedStore.ts
|
785
|
+
var import_react17 = require("react");
|
786
|
+
|
787
|
+
// src/utils/context/combined/createCombinedStore.ts
|
788
|
+
var import_react16 = require("react");
|
789
|
+
var createCombinedStore = (stores) => {
|
790
|
+
const subscribe = (callback) => {
|
791
|
+
const unsubscribes = stores.map((store) => store.subscribe(callback));
|
792
|
+
return () => {
|
793
|
+
for (const unsub of unsubscribes) {
|
794
|
+
unsub();
|
795
|
+
}
|
796
|
+
};
|
797
|
+
};
|
798
|
+
return (selector) => {
|
799
|
+
const getSnapshot = () => selector(...stores.map((store) => store.getState()));
|
800
|
+
return (0, import_react16.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
801
|
+
};
|
802
|
+
};
|
803
|
+
|
804
|
+
// src/utils/context/combined/useCombinedStore.ts
|
805
|
+
var useCombinedStore = (stores, selector) => {
|
806
|
+
const useCombined = (0, import_react17.useMemo)(() => createCombinedStore(stores), stores);
|
807
|
+
return useCombined(selector);
|
808
|
+
};
|
809
|
+
|
723
810
|
// src/actions/useGoToNextBranch.tsx
|
724
811
|
var useGoToNextBranch = () => {
|
725
|
-
const { useThread
|
812
|
+
const { useThread } = useAssistantContext();
|
726
813
|
const { useComposer, useMessage } = useMessageContext();
|
727
|
-
const
|
728
|
-
|
729
|
-
|
730
|
-
({ branchState: { branchId, branchCount } }) => branchId + 1 < branchCount
|
814
|
+
const disabled = useCombinedStore(
|
815
|
+
[useThread, useComposer, useMessage],
|
816
|
+
(t, c, m) => t.isLoading || c.isEditing || m.message.branchId + 1 >= m.message.branchCount
|
731
817
|
);
|
732
|
-
if (
|
818
|
+
if (disabled)
|
733
819
|
return null;
|
734
820
|
return () => {
|
735
|
-
const {
|
736
|
-
|
737
|
-
branchState: { branchId }
|
738
|
-
} = useMessage.getState();
|
739
|
-
useBranchObserver.getState().switchToBranch(message, branchId + 1);
|
821
|
+
const { message } = useMessage.getState();
|
822
|
+
useThread.getState().switchToBranch(message.id, message.branchId + 1);
|
740
823
|
};
|
741
824
|
};
|
742
825
|
|
743
826
|
// src/utils/createActionButton.tsx
|
744
|
-
var
|
745
|
-
var
|
746
|
-
var
|
827
|
+
var import_react18 = require("react");
|
828
|
+
var import_react_primitive8 = require("@radix-ui/react-primitive");
|
829
|
+
var import_primitive7 = require("@radix-ui/primitive");
|
747
830
|
var createActionButton = (useActionButton) => {
|
748
|
-
return (0,
|
831
|
+
return (0, import_react18.forwardRef)(
|
749
832
|
(props, forwardedRef) => {
|
750
833
|
const onClick = useActionButton(props);
|
751
834
|
return /* @__PURE__ */ React.createElement(
|
752
|
-
|
835
|
+
import_react_primitive8.Primitive.button,
|
753
836
|
{
|
754
837
|
type: "button",
|
755
838
|
disabled: !onClick,
|
756
839
|
...props,
|
757
840
|
ref: forwardedRef,
|
758
|
-
onClick: (0,
|
841
|
+
onClick: (0, import_primitive7.composeEventHandlers)(props.onClick, onClick ?? void 0)
|
759
842
|
}
|
760
843
|
);
|
761
844
|
}
|
@@ -767,19 +850,17 @@ var BranchPickerNext = createActionButton(useGoToNextBranch);
|
|
767
850
|
|
768
851
|
// src/actions/useGoToPreviousBranch.tsx
|
769
852
|
var useGoToPreviousBranch = () => {
|
770
|
-
const { useThread
|
853
|
+
const { useThread } = useAssistantContext();
|
771
854
|
const { useComposer, useMessage } = useMessageContext();
|
772
|
-
const
|
773
|
-
|
774
|
-
|
775
|
-
|
855
|
+
const disabled = useCombinedStore(
|
856
|
+
[useThread, useComposer, useMessage],
|
857
|
+
(t, c, m) => t.isLoading || c.isEditing || m.message.branchId <= 0
|
858
|
+
);
|
859
|
+
if (disabled)
|
776
860
|
return null;
|
777
861
|
return () => {
|
778
|
-
const {
|
779
|
-
|
780
|
-
branchState: { branchId }
|
781
|
-
} = useMessage.getState();
|
782
|
-
useBranchObserver.getState().switchToBranch(message, branchId - 1);
|
862
|
+
const { message } = useMessage.getState();
|
863
|
+
useThread.getState().switchToBranch(message.id, message.branchId - 1);
|
783
864
|
};
|
784
865
|
};
|
785
866
|
|
@@ -789,22 +870,22 @@ var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
|
|
789
870
|
// src/primitives/branchPicker/BranchPickerCount.tsx
|
790
871
|
var BranchPickerCount = () => {
|
791
872
|
const { useMessage } = useMessageContext();
|
792
|
-
const branchCount = useMessage((s) => s.
|
873
|
+
const branchCount = useMessage((s) => s.message.branchCount);
|
793
874
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, branchCount);
|
794
875
|
};
|
795
876
|
|
796
877
|
// src/primitives/branchPicker/BranchPickerNumber.tsx
|
797
878
|
var BranchPickerNumber = () => {
|
798
879
|
const { useMessage } = useMessageContext();
|
799
|
-
const branchId = useMessage((s) => s.
|
880
|
+
const branchId = useMessage((s) => s.message.branchId);
|
800
881
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, branchId + 1);
|
801
882
|
};
|
802
883
|
|
803
884
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
804
|
-
var
|
805
|
-
var
|
806
|
-
var BranchPickerRoot = (0,
|
807
|
-
return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(
|
885
|
+
var import_react_primitive9 = require("@radix-ui/react-primitive");
|
886
|
+
var import_react19 = require("react");
|
887
|
+
var BranchPickerRoot = (0, import_react19.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
|
888
|
+
return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(import_react_primitive9.Primitive.div, { ...rest, ref }));
|
808
889
|
});
|
809
890
|
|
810
891
|
// src/primitives/actionBar/index.ts
|
@@ -817,28 +898,30 @@ __export(actionBar_exports, {
|
|
817
898
|
});
|
818
899
|
|
819
900
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
820
|
-
var
|
821
|
-
var
|
822
|
-
var ActionBarRoot = (0,
|
901
|
+
var import_react_primitive10 = require("@radix-ui/react-primitive");
|
902
|
+
var import_react20 = require("react");
|
903
|
+
var ActionBarRoot = (0, import_react20.forwardRef)(({ hideWhenBusy, autohide, autohideFloat, ...rest }, ref) => {
|
823
904
|
const { useThread } = useAssistantContext();
|
824
905
|
const { useMessage } = useMessageContext();
|
825
|
-
const hideAndfloatStatus =
|
826
|
-
|
827
|
-
|
906
|
+
const hideAndfloatStatus = useCombinedStore(
|
907
|
+
[useThread, useMessage],
|
908
|
+
(t, m) => {
|
909
|
+
if (hideWhenBusy && t.isLoading)
|
910
|
+
return "hidden" /* Hidden */;
|
911
|
+
const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
|
912
|
+
if (!autohideEnabled)
|
913
|
+
return "normal" /* Normal */;
|
914
|
+
if (!m.isHovering)
|
915
|
+
return "hidden" /* Hidden */;
|
916
|
+
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.message.branchCount <= 1)
|
917
|
+
return "floating" /* Floating */;
|
828
918
|
return "normal" /* Normal */;
|
829
|
-
|
830
|
-
|
831
|
-
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branchState.branchCount <= 1)
|
832
|
-
return "floating" /* Floating */;
|
833
|
-
return "normal" /* Normal */;
|
834
|
-
});
|
835
|
-
const busy = useThread((t) => t.isLoading);
|
836
|
-
if (hideWhenBusy && busy)
|
837
|
-
return null;
|
919
|
+
}
|
920
|
+
);
|
838
921
|
if (hideAndfloatStatus === "hidden" /* Hidden */)
|
839
922
|
return null;
|
840
923
|
return /* @__PURE__ */ React.createElement(
|
841
|
-
|
924
|
+
import_react_primitive10.Primitive.div,
|
842
925
|
{
|
843
926
|
"data-floating": hideAndfloatStatus === "floating" /* Floating */,
|
844
927
|
...rest,
|
@@ -868,17 +951,19 @@ var ActionBarCopy = createActionButton(useCopyMessage);
|
|
868
951
|
|
869
952
|
// src/actions/useReloadMessage.tsx
|
870
953
|
var useReloadMessage = () => {
|
871
|
-
const { useThread
|
954
|
+
const { useThread } = useAssistantContext();
|
872
955
|
const { useMessage } = useMessageContext();
|
873
|
-
const
|
874
|
-
|
875
|
-
|
956
|
+
const disabled = useCombinedStore(
|
957
|
+
[useThread, useMessage],
|
958
|
+
(t, m) => t.isLoading || m.message.role !== "assistant"
|
959
|
+
);
|
960
|
+
if (disabled)
|
876
961
|
return null;
|
877
962
|
return () => {
|
878
963
|
const message = useMessage.getState().message;
|
879
964
|
if (message.role !== "assistant")
|
880
965
|
throw new Error("Reloading is only supported on assistant messages");
|
881
|
-
|
966
|
+
useThread.getState().reload(message.id);
|
882
967
|
};
|
883
968
|
};
|
884
969
|
|
@@ -888,9 +973,11 @@ var ActionBarReload = createActionButton(useReloadMessage);
|
|
888
973
|
// src/actions/useBeginMessageEdit.tsx
|
889
974
|
var useBeginMessageEdit = () => {
|
890
975
|
const { useMessage, useComposer } = useMessageContext();
|
891
|
-
const
|
892
|
-
|
893
|
-
|
976
|
+
const disabled = useCombinedStore(
|
977
|
+
[useMessage, useComposer],
|
978
|
+
(m, c) => m.message.role !== "user" || c.isEditing
|
979
|
+
);
|
980
|
+
if (disabled)
|
894
981
|
return null;
|
895
982
|
return () => {
|
896
983
|
const { edit } = useComposer.getState();
|
@@ -901,25 +988,41 @@ var useBeginMessageEdit = () => {
|
|
901
988
|
// src/primitives/actionBar/ActionBarEdit.tsx
|
902
989
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
903
990
|
|
904
|
-
// src/vercel/VercelAIAssistantProvider.tsx
|
905
|
-
var
|
991
|
+
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
992
|
+
var import_react22 = require("react");
|
906
993
|
|
907
|
-
// src/vercel/useDummyAIAssistantContext.tsx
|
908
|
-
var
|
994
|
+
// src/adapters/vercel/useDummyAIAssistantContext.tsx
|
995
|
+
var import_react21 = require("react");
|
909
996
|
var import_zustand2 = require("zustand");
|
910
997
|
var useDummyAIAssistantContext = () => {
|
911
|
-
const [context] = (0,
|
998
|
+
const [context] = (0, import_react21.useState)(() => {
|
999
|
+
const scrollToBottomListeners = /* @__PURE__ */ new Set();
|
912
1000
|
const useThread = (0, import_zustand2.create)()(() => ({
|
913
1001
|
messages: [],
|
914
1002
|
isLoading: false,
|
915
|
-
reload: async () => {
|
916
|
-
throw new Error("Not implemented");
|
917
|
-
},
|
918
1003
|
append: async () => {
|
919
1004
|
throw new Error("Not implemented");
|
920
1005
|
},
|
921
1006
|
stop: () => {
|
922
1007
|
throw new Error("Not implemented");
|
1008
|
+
},
|
1009
|
+
switchToBranch: () => {
|
1010
|
+
throw new Error("Not implemented");
|
1011
|
+
},
|
1012
|
+
reload: async () => {
|
1013
|
+
throw new Error("Not implemented");
|
1014
|
+
},
|
1015
|
+
isAtBottom: true,
|
1016
|
+
scrollToBottom: () => {
|
1017
|
+
for (const listener of scrollToBottomListeners) {
|
1018
|
+
listener();
|
1019
|
+
}
|
1020
|
+
},
|
1021
|
+
onScrollToBottom: (callback) => {
|
1022
|
+
scrollToBottomListeners.add(callback);
|
1023
|
+
return () => {
|
1024
|
+
scrollToBottomListeners.delete(callback);
|
1025
|
+
};
|
923
1026
|
}
|
924
1027
|
}));
|
925
1028
|
const useComposer = (0, import_zustand2.create)()(() => ({
|
@@ -934,7 +1037,7 @@ var useDummyAIAssistantContext = () => {
|
|
934
1037
|
},
|
935
1038
|
send: () => {
|
936
1039
|
useThread.getState().append({
|
937
|
-
|
1040
|
+
parentId: useThread.getState().messages.at(-1)?.id ?? ROOT_PARENT_ID,
|
938
1041
|
content: [{ type: "text", text: useComposer.getState().value }]
|
939
1042
|
});
|
940
1043
|
useComposer.getState().setValue("");
|
@@ -943,43 +1046,39 @@ var useDummyAIAssistantContext = () => {
|
|
943
1046
|
useThread.getState().stop();
|
944
1047
|
}
|
945
1048
|
}));
|
946
|
-
|
947
|
-
getBranchState: () => ({
|
948
|
-
branchId: 0,
|
949
|
-
branchCount: 1
|
950
|
-
}),
|
951
|
-
switchToBranch: () => {
|
952
|
-
throw new Error("Not implemented");
|
953
|
-
},
|
954
|
-
editAt: async () => {
|
955
|
-
throw new Error("Not implemented");
|
956
|
-
},
|
957
|
-
reloadAt: async () => {
|
958
|
-
throw new Error("Not implemented");
|
959
|
-
}
|
960
|
-
}));
|
961
|
-
return { useThread, useComposer, useBranchObserver };
|
1049
|
+
return { useThread, useComposer };
|
962
1050
|
});
|
963
1051
|
return context;
|
964
1052
|
};
|
965
1053
|
|
966
|
-
// src/vercel/VercelAIAssistantProvider.tsx
|
1054
|
+
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
967
1055
|
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
968
|
-
var vercelToThreadMessage = (message) => {
|
1056
|
+
var vercelToThreadMessage = (message, parentId, branchId, branchCount) => {
|
969
1057
|
if (message.role !== "user" && message.role !== "assistant")
|
970
1058
|
throw new Error("Unsupported role");
|
971
1059
|
return {
|
1060
|
+
parentId,
|
972
1061
|
id: message.id,
|
973
1062
|
role: message.role,
|
974
|
-
content: [{ type: "text", text: message.content }]
|
1063
|
+
content: [{ type: "text", text: message.content }],
|
1064
|
+
branchId,
|
1065
|
+
branchCount,
|
1066
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
|
975
1067
|
};
|
976
1068
|
};
|
977
|
-
var vercelToCachedThreadMessages = (messages) => {
|
978
|
-
return messages.map((m) => {
|
1069
|
+
var vercelToCachedThreadMessages = (messages, getBranchState) => {
|
1070
|
+
return messages.map((m, idx) => {
|
979
1071
|
const cached = ThreadMessageCache.get(m);
|
980
|
-
|
1072
|
+
const parentId = messages[idx - 1]?.id ?? ROOT_PARENT_ID;
|
1073
|
+
const { branchId, branchCount } = getBranchState(m.id);
|
1074
|
+
if (cached && cached.parentId === parentId && cached.branchId === branchId && cached.branchCount === branchCount)
|
981
1075
|
return cached;
|
982
|
-
const newMessage = vercelToThreadMessage(
|
1076
|
+
const newMessage = vercelToThreadMessage(
|
1077
|
+
m,
|
1078
|
+
parentId,
|
1079
|
+
branchId,
|
1080
|
+
branchCount
|
1081
|
+
);
|
983
1082
|
ThreadMessageCache.set(m, newMessage);
|
984
1083
|
return newMessage;
|
985
1084
|
});
|
@@ -990,28 +1089,14 @@ var VercelAIAssistantProvider = ({
|
|
990
1089
|
}) => {
|
991
1090
|
const context = useDummyAIAssistantContext();
|
992
1091
|
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
993
|
-
const
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
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)(() => {
|
1092
|
+
const branches = useVercelAIBranches(vercel, context);
|
1093
|
+
const messages = (0, import_react22.useMemo)(() => {
|
1094
|
+
return vercelToCachedThreadMessages(
|
1095
|
+
vercel.messages,
|
1096
|
+
branches.getBranchState
|
1097
|
+
);
|
1098
|
+
}, [vercel.messages, branches.getBranchState]);
|
1099
|
+
const stop = (0, import_react22.useCallback)(() => {
|
1015
1100
|
const lastMessage = vercel.messages.at(-1);
|
1016
1101
|
vercel.stop();
|
1017
1102
|
if (lastMessage?.role === "user") {
|
@@ -1019,50 +1104,49 @@ var VercelAIAssistantProvider = ({
|
|
1019
1104
|
}
|
1020
1105
|
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1021
1106
|
const isLoading = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
1022
|
-
(0,
|
1023
|
-
context.useThread.setState(
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
}, [context, messages, reload, append, stop, isLoading]);
|
1034
|
-
(0, import_react18.useMemo)(() => {
|
1107
|
+
(0, import_react22.useMemo)(() => {
|
1108
|
+
context.useThread.setState({
|
1109
|
+
messages,
|
1110
|
+
isLoading,
|
1111
|
+
stop,
|
1112
|
+
switchToBranch: branches.switchToBranch,
|
1113
|
+
append: branches.append,
|
1114
|
+
reload: branches.reload
|
1115
|
+
});
|
1116
|
+
}, [context, messages, isLoading, stop, branches]);
|
1117
|
+
(0, import_react22.useMemo)(() => {
|
1035
1118
|
context.useComposer.setState({
|
1036
1119
|
canCancel: isLoading,
|
1037
1120
|
value: vercel.input,
|
1038
1121
|
setValue: vercel.setInput
|
1039
1122
|
});
|
1040
1123
|
}, [context, isLoading, vercel.input, vercel.setInput]);
|
1041
|
-
const branches = useVercelAIBranches(vercel);
|
1042
|
-
(0, import_react18.useMemo)(() => {
|
1043
|
-
context.useBranchObserver.setState(branches, true);
|
1044
|
-
}, [context, branches]);
|
1045
1124
|
return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
|
1046
1125
|
};
|
1047
1126
|
|
1048
|
-
// src/vercel/VercelRSCAssistantProvider.tsx
|
1049
|
-
var
|
1127
|
+
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
1128
|
+
var import_react23 = require("react");
|
1050
1129
|
var ThreadMessageCache2 = /* @__PURE__ */ new WeakMap();
|
1051
|
-
var vercelToThreadMessage2 = (message) => {
|
1130
|
+
var vercelToThreadMessage2 = (parentId, message) => {
|
1052
1131
|
if (message.role !== "user" && message.role !== "assistant")
|
1053
1132
|
throw new Error("Unsupported role");
|
1054
1133
|
return {
|
1134
|
+
parentId,
|
1055
1135
|
id: message.id,
|
1056
1136
|
role: message.role,
|
1057
|
-
content: [{ type: "ui", display: message.display }]
|
1137
|
+
content: [{ type: "ui", display: message.display }],
|
1138
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1139
|
+
branchId: 0,
|
1140
|
+
branchCount: 1
|
1058
1141
|
};
|
1059
1142
|
};
|
1060
1143
|
var vercelToCachedThreadMessages2 = (messages) => {
|
1061
|
-
return messages.map((m) => {
|
1144
|
+
return messages.map((m, idx) => {
|
1062
1145
|
const cached = ThreadMessageCache2.get(m);
|
1063
|
-
|
1146
|
+
const parentId = messages[idx - 1]?.id ?? ROOT_PARENT_ID;
|
1147
|
+
if (cached && cached.parentId === parentId)
|
1064
1148
|
return cached;
|
1065
|
-
const newMessage = vercelToThreadMessage2(m);
|
1149
|
+
const newMessage = vercelToThreadMessage2(parentId, m);
|
1066
1150
|
ThreadMessageCache2.set(m, newMessage);
|
1067
1151
|
return newMessage;
|
1068
1152
|
});
|
@@ -1073,22 +1157,22 @@ var VercelRSCAssistantProvider = ({
|
|
1073
1157
|
append: vercelAppend
|
1074
1158
|
}) => {
|
1075
1159
|
const context = useDummyAIAssistantContext();
|
1076
|
-
const messages = (0,
|
1160
|
+
const messages = (0, import_react23.useMemo)(() => {
|
1077
1161
|
return vercelToCachedThreadMessages2(vercelMessages);
|
1078
1162
|
}, [vercelMessages]);
|
1079
|
-
const append = (0,
|
1163
|
+
const append = (0, import_react23.useCallback)(
|
1080
1164
|
async (message) => {
|
1165
|
+
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? ROOT_PARENT_ID))
|
1166
|
+
throw new Error("Unexpected: Message editing is not supported");
|
1081
1167
|
if (message.content[0]?.type !== "text") {
|
1082
1168
|
throw new Error("Only text content is currently supported");
|
1083
1169
|
}
|
1084
|
-
|
1085
|
-
|
1086
|
-
content: [{ type: "text", text: message.content[0].text }]
|
1087
|
-
});
|
1170
|
+
context.useThread.getState().scrollToBottom();
|
1171
|
+
await vercelAppend(message);
|
1088
1172
|
},
|
1089
|
-
[vercelAppend]
|
1173
|
+
[context, vercelAppend]
|
1090
1174
|
);
|
1091
|
-
(0,
|
1175
|
+
(0, import_react23.useMemo)(() => {
|
1092
1176
|
context.useThread.setState({
|
1093
1177
|
messages,
|
1094
1178
|
append
|