@assistant-ui/react 0.0.10 → 0.0.11
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 +20 -18
- package/dist/index.d.ts +20 -18
- package/dist/index.js +455 -339
- package/dist/index.mjs +429 -313
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
@@ -16,13 +16,14 @@ __export(thread_exports, {
|
|
16
16
|
});
|
17
17
|
|
18
18
|
// src/primitives/thread/ThreadRoot.tsx
|
19
|
-
import { forwardRef } from "react";
|
20
19
|
import {
|
21
20
|
Primitive
|
22
21
|
} from "@radix-ui/react-primitive";
|
22
|
+
import { forwardRef } from "react";
|
23
|
+
import { jsx } from "react/jsx-runtime";
|
23
24
|
var ThreadRoot = forwardRef(
|
24
25
|
(props, ref) => {
|
25
|
-
return /* @__PURE__ */
|
26
|
+
return /* @__PURE__ */ jsx(Primitive.div, { ...props, ref });
|
26
27
|
}
|
27
28
|
);
|
28
29
|
|
@@ -59,8 +60,9 @@ var ThreadIf = ({ children, ...query }) => {
|
|
59
60
|
};
|
60
61
|
|
61
62
|
// src/primitives/thread/ThreadEmpty.tsx
|
63
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
62
64
|
var ThreadEmpty = ({ children }) => {
|
63
|
-
return /* @__PURE__ */
|
65
|
+
return /* @__PURE__ */ jsx2(ThreadIf, { empty: true, children });
|
64
66
|
};
|
65
67
|
|
66
68
|
// src/primitives/thread/ThreadViewport.tsx
|
@@ -124,6 +126,7 @@ var useOnScrollToBottom = (callback) => {
|
|
124
126
|
};
|
125
127
|
|
126
128
|
// src/primitives/thread/ThreadViewport.tsx
|
129
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
127
130
|
var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
|
128
131
|
const messagesEndRef = useRef3(null);
|
129
132
|
const divRef = useRef3(null);
|
@@ -160,156 +163,19 @@ var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...re
|
|
160
163
|
}
|
161
164
|
lastScrollTop.current = div.scrollTop;
|
162
165
|
};
|
163
|
-
return /* @__PURE__ */
|
166
|
+
return /* @__PURE__ */ jsxs(
|
164
167
|
Primitive2.div,
|
165
168
|
{
|
166
169
|
...rest,
|
167
170
|
onScroll: composeEventHandlers(onScroll, handleScroll),
|
168
|
-
ref
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
});
|
174
|
-
|
175
|
-
// src/adapters/vercel/useVercelAIBranches.tsx
|
176
|
-
import { useCallback, useMemo, useRef as useRef4 } from "react";
|
177
|
-
|
178
|
-
// src/utils/context/stores/AssistantTypes.ts
|
179
|
-
var ROOT_PARENT_ID = "__ROOT_ID__";
|
180
|
-
|
181
|
-
// src/adapters/vercel/useVercelAIBranches.tsx
|
182
|
-
var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
|
183
|
-
var updateBranchData = (data, messages) => {
|
184
|
-
for (let i = 0; i < messages.length; i++) {
|
185
|
-
const child = messages[i];
|
186
|
-
const childId = child.id;
|
187
|
-
const parentId = messages[i - 1]?.id ?? ROOT_PARENT_ID;
|
188
|
-
data.parentMap.set(childId, parentId);
|
189
|
-
const parentArray = data.branchMap.get(parentId);
|
190
|
-
if (!parentArray) {
|
191
|
-
data.branchMap.set(parentId, [childId]);
|
192
|
-
} else if (!parentArray.includes(childId)) {
|
193
|
-
parentArray.push(childId);
|
171
|
+
ref,
|
172
|
+
children: [
|
173
|
+
children,
|
174
|
+
/* @__PURE__ */ jsx3("div", { ref: messagesEndRef })
|
175
|
+
]
|
194
176
|
}
|
195
|
-
data.snapshots.set(childId, messages);
|
196
|
-
}
|
197
|
-
};
|
198
|
-
var getParentId = (data, messages, messageId) => {
|
199
|
-
if (messageId === UPCOMING_MESSAGE_ID) {
|
200
|
-
const parent = messages.at(-1);
|
201
|
-
if (!parent)
|
202
|
-
return ROOT_PARENT_ID;
|
203
|
-
return parent.id;
|
204
|
-
}
|
205
|
-
const parentId = data.parentMap.get(messageId);
|
206
|
-
if (!parentId)
|
207
|
-
throw new Error("Unexpected: Message parent not found");
|
208
|
-
return parentId;
|
209
|
-
};
|
210
|
-
var getBranchStateImpl = (data, messages, messageId) => {
|
211
|
-
const parentId = getParentId(data, messages, messageId);
|
212
|
-
const branches = data.branchMap.get(parentId) ?? [];
|
213
|
-
const branchId = messageId === UPCOMING_MESSAGE_ID ? branches.length : branches.indexOf(messageId);
|
214
|
-
if (branchId === -1)
|
215
|
-
throw new Error("Unexpected: Message not found in parent children");
|
216
|
-
const upcomingOffset = messageId === UPCOMING_MESSAGE_ID ? 1 : 0;
|
217
|
-
return {
|
218
|
-
branchId,
|
219
|
-
branchCount: branches.length + upcomingOffset
|
220
|
-
};
|
221
|
-
};
|
222
|
-
var switchToBranchImpl = (data, messages, messageId, branchId) => {
|
223
|
-
const parentId = getParentId(data, messages, messageId);
|
224
|
-
const branches = data.branchMap.get(parentId);
|
225
|
-
if (!branches)
|
226
|
-
throw new Error("Unexpected: Parent children not found");
|
227
|
-
const newMessageId = branches[branchId];
|
228
|
-
if (!newMessageId)
|
229
|
-
throw new Error("Unexpected: Requested branch not found");
|
230
|
-
if (branchId < 0 || branchId >= branches.length)
|
231
|
-
throw new Error("Switch to branch called with a branch index out of range");
|
232
|
-
if (newMessageId === messageId)
|
233
|
-
return messages;
|
234
|
-
const snapshot = data.snapshots.get(newMessageId);
|
235
|
-
if (!snapshot)
|
236
|
-
throw new Error("Unexpected: Branch snapshot not found");
|
237
|
-
return snapshot;
|
238
|
-
};
|
239
|
-
var sliceMessagesUntil = (messages, messageId) => {
|
240
|
-
if (messageId === ROOT_PARENT_ID)
|
241
|
-
return [];
|
242
|
-
if (messageId === UPCOMING_MESSAGE_ID)
|
243
|
-
return messages;
|
244
|
-
const messageIdx = messages.findIndex((m) => m.id === messageId);
|
245
|
-
if (messageIdx === -1)
|
246
|
-
throw new Error("Unexpected: Message not found");
|
247
|
-
return messages.slice(0, messageIdx + 1);
|
248
|
-
};
|
249
|
-
var useVercelAIBranches = (chat, context) => {
|
250
|
-
const data = useRef4({
|
251
|
-
parentMap: /* @__PURE__ */ new Map(),
|
252
|
-
branchMap: /* @__PURE__ */ new Map(),
|
253
|
-
snapshots: /* @__PURE__ */ new Map()
|
254
|
-
}).current;
|
255
|
-
updateBranchData(data, chat.messages);
|
256
|
-
const getBranchState = useCallback(
|
257
|
-
(messageId) => {
|
258
|
-
return getBranchStateImpl(data, chat.messages, messageId);
|
259
|
-
},
|
260
|
-
[data, chat.messages]
|
261
|
-
);
|
262
|
-
const switchToBranch = useCallback(
|
263
|
-
(messageId, branchId) => {
|
264
|
-
const newMessages = switchToBranchImpl(
|
265
|
-
data,
|
266
|
-
chat.messages,
|
267
|
-
messageId,
|
268
|
-
branchId
|
269
|
-
);
|
270
|
-
chat.setMessages(newMessages);
|
271
|
-
},
|
272
|
-
[data, chat.messages, chat.setMessages]
|
273
|
-
);
|
274
|
-
const reloadMaybe = "reload" in chat ? chat.reload : void 0;
|
275
|
-
const startRun = useCallback(
|
276
|
-
async (parentId) => {
|
277
|
-
if (!reloadMaybe)
|
278
|
-
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
279
|
-
const newMessages = sliceMessagesUntil(chat.messages, parentId);
|
280
|
-
chat.setMessages(newMessages);
|
281
|
-
context.useViewport.getState().scrollToBottom();
|
282
|
-
await reloadMaybe();
|
283
|
-
},
|
284
|
-
[context, chat.messages, chat.setMessages, reloadMaybe]
|
285
|
-
);
|
286
|
-
const append = useCallback(
|
287
|
-
async (message) => {
|
288
|
-
const newMessages = sliceMessagesUntil(chat.messages, message.parentId);
|
289
|
-
chat.setMessages(newMessages);
|
290
|
-
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
291
|
-
throw new Error("Only text content is currently supported");
|
292
|
-
context.useViewport.getState().scrollToBottom();
|
293
|
-
await chat.append({
|
294
|
-
role: "user",
|
295
|
-
content: message.content[0].text
|
296
|
-
});
|
297
|
-
},
|
298
|
-
[context, chat.messages, chat.setMessages, chat.append]
|
299
177
|
);
|
300
|
-
|
301
|
-
() => ({
|
302
|
-
getBranchState,
|
303
|
-
switchToBranch,
|
304
|
-
append,
|
305
|
-
startRun
|
306
|
-
}),
|
307
|
-
[getBranchState, switchToBranch, append, startRun]
|
308
|
-
);
|
309
|
-
};
|
310
|
-
var hasUpcomingMessage = (thread) => {
|
311
|
-
return thread.isRunning && thread.messages[thread.messages.length - 1]?.role !== "assistant";
|
312
|
-
};
|
178
|
+
});
|
313
179
|
|
314
180
|
// src/utils/context/useComposerContext.ts
|
315
181
|
import { useContext as useContext3 } from "react";
|
@@ -360,7 +226,7 @@ __export(message_exports, {
|
|
360
226
|
});
|
361
227
|
|
362
228
|
// src/primitives/message/MessageProvider.tsx
|
363
|
-
import { useMemo
|
229
|
+
import { useMemo, useState } from "react";
|
364
230
|
import { create as create2 } from "zustand";
|
365
231
|
|
366
232
|
// src/utils/context/stores/ComposerStore.ts
|
@@ -378,7 +244,6 @@ var makeMessageComposerStore = ({
|
|
378
244
|
onSend
|
379
245
|
}) => create()((set, get, store) => ({
|
380
246
|
...makeBaseComposer(set, get, store),
|
381
|
-
canCancel: true,
|
382
247
|
isEditing: false,
|
383
248
|
edit: () => {
|
384
249
|
const value = onEdit();
|
@@ -387,39 +252,48 @@ var makeMessageComposerStore = ({
|
|
387
252
|
send: () => {
|
388
253
|
const value = get().value;
|
389
254
|
set({ isEditing: false });
|
390
|
-
|
255
|
+
onSend(value);
|
391
256
|
},
|
392
257
|
cancel: () => {
|
258
|
+
if (!get().isEditing)
|
259
|
+
return false;
|
393
260
|
set({ isEditing: false });
|
261
|
+
return true;
|
394
262
|
}
|
395
263
|
}));
|
396
|
-
var makeThreadComposerStore = ({
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
264
|
+
var makeThreadComposerStore = (useThread) => create()((set, get, store) => {
|
265
|
+
return {
|
266
|
+
...makeBaseComposer(set, get, store),
|
267
|
+
isEditing: true,
|
268
|
+
send: () => {
|
269
|
+
const { value } = get();
|
270
|
+
set({ value: "" });
|
271
|
+
useThread.getState().append({
|
272
|
+
parentId: useThread.getState().messages.at(-1)?.id ?? null,
|
273
|
+
content: [{ type: "text", text: value }]
|
274
|
+
});
|
275
|
+
},
|
276
|
+
cancel: () => {
|
277
|
+
const thread = useThread.getState();
|
278
|
+
if (!thread.isRunning)
|
279
|
+
return false;
|
280
|
+
useThread.getState().cancelRun();
|
281
|
+
return true;
|
282
|
+
}
|
283
|
+
};
|
284
|
+
});
|
412
285
|
|
413
286
|
// src/primitives/message/MessageProvider.tsx
|
287
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
414
288
|
var getIsLast = (thread, message) => {
|
415
|
-
|
416
|
-
return hasUpcoming ? message.id === UPCOMING_MESSAGE_ID : thread.messages[thread.messages.length - 1]?.id === message.id;
|
289
|
+
return thread.messages[thread.messages.length - 1]?.id === message.id;
|
417
290
|
};
|
418
291
|
var useMessageContext2 = () => {
|
292
|
+
const { useThread } = useAssistantContext();
|
419
293
|
const [context] = useState(() => {
|
420
|
-
const { useThread } = useAssistantContext();
|
421
294
|
const useMessage = create2(() => ({
|
422
295
|
message: null,
|
296
|
+
branches: [],
|
423
297
|
isLast: false,
|
424
298
|
isCopied: false,
|
425
299
|
isHovering: false,
|
@@ -439,7 +313,7 @@ var useMessageContext2 = () => {
|
|
439
313
|
},
|
440
314
|
onSend: (text) => {
|
441
315
|
const message = useMessage.getState().message;
|
442
|
-
|
316
|
+
useThread.getState().append({
|
443
317
|
parentId: message.parentId,
|
444
318
|
content: [{ type: "text", text }]
|
445
319
|
});
|
@@ -456,12 +330,14 @@ var MessageProvider = ({
|
|
456
330
|
const { useThread } = useAssistantContext();
|
457
331
|
const context = useMessageContext2();
|
458
332
|
const isLast = useThread((thread) => getIsLast(thread, message));
|
333
|
+
const branches = useThread((thread) => thread.getBranches(message.id));
|
459
334
|
const [isCopied, setIsCopied] = useState(false);
|
460
335
|
const [isHovering, setIsHovering] = useState(false);
|
461
|
-
|
336
|
+
useMemo(() => {
|
462
337
|
context.useMessage.setState(
|
463
338
|
{
|
464
339
|
message,
|
340
|
+
branches,
|
465
341
|
isLast,
|
466
342
|
isCopied,
|
467
343
|
isHovering,
|
@@ -470,8 +346,8 @@ var MessageProvider = ({
|
|
470
346
|
},
|
471
347
|
true
|
472
348
|
);
|
473
|
-
}, [context, message, isLast, isCopied, isHovering]);
|
474
|
-
return /* @__PURE__ */
|
349
|
+
}, [context, message, branches, isLast, isCopied, isHovering]);
|
350
|
+
return /* @__PURE__ */ jsx4(MessageContext.Provider, { value: context, children });
|
475
351
|
};
|
476
352
|
|
477
353
|
// src/primitives/message/MessageRoot.tsx
|
@@ -480,6 +356,7 @@ import {
|
|
480
356
|
Primitive as Primitive3
|
481
357
|
} from "@radix-ui/react-primitive";
|
482
358
|
import { forwardRef as forwardRef3 } from "react";
|
359
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
483
360
|
var MessageRoot = forwardRef3(
|
484
361
|
({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
|
485
362
|
const { useMessage } = useMessageContext();
|
@@ -490,7 +367,7 @@ var MessageRoot = forwardRef3(
|
|
490
367
|
const handleMouseLeave = () => {
|
491
368
|
setIsHovering(false);
|
492
369
|
};
|
493
|
-
return /* @__PURE__ */
|
370
|
+
return /* @__PURE__ */ jsx5(
|
494
371
|
Primitive3.div,
|
495
372
|
{
|
496
373
|
...rest,
|
@@ -505,8 +382,8 @@ var MessageRoot = forwardRef3(
|
|
505
382
|
// src/primitives/message/MessageIf.tsx
|
506
383
|
var useMessageIf = (props) => {
|
507
384
|
const { useMessage } = useMessageContext();
|
508
|
-
return useMessage(({ message, isLast, isCopied, isHovering }) => {
|
509
|
-
if (props.hasBranches === true &&
|
385
|
+
return useMessage(({ message, branches, isLast, isCopied, isHovering }) => {
|
386
|
+
if (props.hasBranches === true && branches.length < 2)
|
510
387
|
return false;
|
511
388
|
if (props.user && message.role !== "user")
|
512
389
|
return false;
|
@@ -527,8 +404,9 @@ var MessageIf = ({ children, ...query }) => {
|
|
527
404
|
};
|
528
405
|
|
529
406
|
// src/primitives/message/MessageContent.tsx
|
407
|
+
import { Fragment, jsx as jsx6 } from "react/jsx-runtime";
|
530
408
|
var defaultComponents = {
|
531
|
-
Text: ({ part }) => /* @__PURE__ */
|
409
|
+
Text: ({ part }) => /* @__PURE__ */ jsx6(Fragment, { children: part.text }),
|
532
410
|
Image: () => null,
|
533
411
|
UI: ({ part }) => part.display,
|
534
412
|
tools: {
|
@@ -545,26 +423,27 @@ var MessageContent = ({
|
|
545
423
|
}) => {
|
546
424
|
const { useMessage } = useMessageContext();
|
547
425
|
const content = useMessage((s) => s.message.content);
|
548
|
-
return /* @__PURE__ */
|
426
|
+
return /* @__PURE__ */ jsx6(Fragment, { children: content.map((part, i) => {
|
549
427
|
const key = i;
|
550
428
|
switch (part.type) {
|
551
429
|
case "text":
|
552
|
-
return /* @__PURE__ */
|
430
|
+
return /* @__PURE__ */ jsx6(Text, { part }, key);
|
553
431
|
case "image":
|
554
|
-
return /* @__PURE__ */
|
432
|
+
return /* @__PURE__ */ jsx6(Image, { part }, key);
|
555
433
|
case "ui":
|
556
|
-
return /* @__PURE__ */
|
434
|
+
return /* @__PURE__ */ jsx6(UI, { part }, key);
|
557
435
|
case "tool-call": {
|
558
436
|
const Tool = by_name[part.name] || Fallback;
|
559
|
-
return /* @__PURE__ */
|
437
|
+
return /* @__PURE__ */ jsx6(Tool, { part }, key);
|
560
438
|
}
|
561
439
|
default:
|
562
440
|
return null;
|
563
441
|
}
|
564
|
-
}));
|
442
|
+
}) });
|
565
443
|
};
|
566
444
|
|
567
445
|
// src/primitives/thread/ThreadMessages.tsx
|
446
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
568
447
|
var getComponents = (components) => {
|
569
448
|
return {
|
570
449
|
EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
|
@@ -579,27 +458,18 @@ var ThreadMessages = ({ components }) => {
|
|
579
458
|
const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
|
580
459
|
if (messages.length === 0)
|
581
460
|
return null;
|
582
|
-
return /* @__PURE__ */
|
461
|
+
return /* @__PURE__ */ jsx7(Fragment2, { children: messages.map((message, idx) => {
|
583
462
|
return (
|
584
463
|
// biome-ignore lint/suspicious/noArrayIndexKey: fixes a11y issues with branch navigation
|
585
|
-
/* @__PURE__ */
|
464
|
+
/* @__PURE__ */ jsxs2(MessageProvider, { message, children: [
|
465
|
+
/* @__PURE__ */ jsxs2(MessageIf, { user: true, children: [
|
466
|
+
/* @__PURE__ */ jsx7(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx7(UserMessage, {}) }),
|
467
|
+
/* @__PURE__ */ jsx7(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx7(EditComposer, {}) })
|
468
|
+
] }),
|
469
|
+
/* @__PURE__ */ jsx7(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx7(AssistantMessage, {}) })
|
470
|
+
] }, idx)
|
586
471
|
);
|
587
|
-
})
|
588
|
-
MessageProvider,
|
589
|
-
{
|
590
|
-
message: {
|
591
|
-
id: UPCOMING_MESSAGE_ID,
|
592
|
-
role: "assistant",
|
593
|
-
content: [{ type: "text", text: "..." }],
|
594
|
-
parentId: messages.at(-1)?.id ?? ROOT_PARENT_ID,
|
595
|
-
// TODO fix these (move upcoming message to AssistantContext)
|
596
|
-
branchId: 0,
|
597
|
-
branchCount: 1,
|
598
|
-
createdAt: /* @__PURE__ */ new Date()
|
599
|
-
}
|
600
|
-
},
|
601
|
-
/* @__PURE__ */ React.createElement(AssistantMessage, null)
|
602
|
-
));
|
472
|
+
}) });
|
603
473
|
};
|
604
474
|
|
605
475
|
// src/primitives/thread/ThreadScrollToBottom.tsx
|
@@ -608,13 +478,14 @@ import {
|
|
608
478
|
Primitive as Primitive4
|
609
479
|
} from "@radix-ui/react-primitive";
|
610
480
|
import { forwardRef as forwardRef4 } from "react";
|
481
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
611
482
|
var ThreadScrollToBottom = forwardRef4(({ onClick, ...rest }, ref) => {
|
612
483
|
const { useViewport } = useAssistantContext();
|
613
484
|
const isAtBottom = useViewport((s) => s.isAtBottom);
|
614
485
|
const handleScrollToBottom = () => {
|
615
486
|
useViewport.getState().scrollToBottom();
|
616
487
|
};
|
617
|
-
return /* @__PURE__ */
|
488
|
+
return /* @__PURE__ */ jsx8(
|
618
489
|
Primitive4.button,
|
619
490
|
{
|
620
491
|
...rest,
|
@@ -641,11 +512,13 @@ import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-ref
|
|
641
512
|
import {
|
642
513
|
Primitive as Primitive5
|
643
514
|
} from "@radix-ui/react-primitive";
|
644
|
-
import { forwardRef as forwardRef5, useRef as
|
515
|
+
import { forwardRef as forwardRef5, useRef as useRef4 } from "react";
|
516
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
645
517
|
var ComposerRoot = forwardRef5(
|
646
518
|
({ onSubmit, ...rest }, forwardedRef) => {
|
519
|
+
const { useViewport } = useAssistantContext();
|
647
520
|
const { useComposer } = useComposerContext();
|
648
|
-
const formRef =
|
521
|
+
const formRef = useRef4(null);
|
649
522
|
const ref = useComposedRefs2(forwardedRef, formRef);
|
650
523
|
const handleSubmit = (e) => {
|
651
524
|
const composerState = useComposer.getState();
|
@@ -653,8 +526,9 @@ var ComposerRoot = forwardRef5(
|
|
653
526
|
return;
|
654
527
|
e.preventDefault();
|
655
528
|
composerState.send();
|
529
|
+
useViewport.getState().scrollToBottom();
|
656
530
|
};
|
657
|
-
return /* @__PURE__ */
|
531
|
+
return /* @__PURE__ */ jsx9(
|
658
532
|
Primitive5.form,
|
659
533
|
{
|
660
534
|
...rest,
|
@@ -671,14 +545,15 @@ import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-ref
|
|
671
545
|
import { Slot } from "@radix-ui/react-slot";
|
672
546
|
import {
|
673
547
|
forwardRef as forwardRef6,
|
674
|
-
useCallback
|
548
|
+
useCallback,
|
675
549
|
useEffect as useEffect2,
|
676
|
-
useRef as
|
550
|
+
useRef as useRef5
|
677
551
|
} from "react";
|
678
552
|
import TextareaAutosize from "react-textarea-autosize";
|
553
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
679
554
|
var ComposerInput = forwardRef6(
|
680
555
|
({ autoFocus, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
681
|
-
const { useThread } = useAssistantContext();
|
556
|
+
const { useThread, useViewport } = useAssistantContext();
|
682
557
|
const { useComposer, type } = useComposerContext();
|
683
558
|
const value = useComposer((c) => {
|
684
559
|
if (!c.isEditing)
|
@@ -690,22 +565,23 @@ var ComposerInput = forwardRef6(
|
|
690
565
|
if (disabled)
|
691
566
|
return;
|
692
567
|
const composer = useComposer.getState();
|
693
|
-
if (e.key === "Escape"
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
if (e.key === "Enter" && e.shiftKey === false) {
|
568
|
+
if (e.key === "Escape") {
|
569
|
+
if (useComposer.getState().cancel()) {
|
570
|
+
e.preventDefault();
|
571
|
+
}
|
572
|
+
} else if (e.key === "Enter" && e.shiftKey === false) {
|
698
573
|
const isRunning = useThread.getState().isRunning;
|
699
574
|
if (!isRunning) {
|
700
575
|
e.preventDefault();
|
701
576
|
composer.send();
|
577
|
+
useViewport.getState().scrollToBottom();
|
702
578
|
}
|
703
579
|
}
|
704
580
|
};
|
705
|
-
const textareaRef =
|
581
|
+
const textareaRef = useRef5(null);
|
706
582
|
const ref = useComposedRefs3(forwardedRef, textareaRef);
|
707
583
|
const autoFocusEnabled = autoFocus !== false && !disabled;
|
708
|
-
const focus =
|
584
|
+
const focus = useCallback(() => {
|
709
585
|
const textarea = textareaRef.current;
|
710
586
|
if (!textarea || !autoFocusEnabled)
|
711
587
|
return;
|
@@ -721,7 +597,7 @@ var ComposerInput = forwardRef6(
|
|
721
597
|
focus();
|
722
598
|
}
|
723
599
|
});
|
724
|
-
return /* @__PURE__ */
|
600
|
+
return /* @__PURE__ */ jsx10(
|
725
601
|
Component,
|
726
602
|
{
|
727
603
|
value,
|
@@ -745,11 +621,12 @@ import {
|
|
745
621
|
Primitive as Primitive6
|
746
622
|
} from "@radix-ui/react-primitive";
|
747
623
|
import { forwardRef as forwardRef7 } from "react";
|
624
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
748
625
|
var ComposerSend = forwardRef7(
|
749
626
|
({ disabled, ...rest }, ref) => {
|
750
627
|
const { useComposer } = useComposerContext();
|
751
628
|
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
752
|
-
return /* @__PURE__ */
|
629
|
+
return /* @__PURE__ */ jsx11(
|
753
630
|
Primitive6.button,
|
754
631
|
{
|
755
632
|
type: "submit",
|
@@ -767,20 +644,19 @@ import {
|
|
767
644
|
Primitive as Primitive7
|
768
645
|
} from "@radix-ui/react-primitive";
|
769
646
|
import { forwardRef as forwardRef8 } from "react";
|
770
|
-
|
647
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
648
|
+
var ComposerCancel = forwardRef8(({ onClick, ...rest }, ref) => {
|
771
649
|
const { useComposer } = useComposerContext();
|
772
|
-
const
|
773
|
-
const handleClose = () => {
|
650
|
+
const handleCancel = () => {
|
774
651
|
useComposer.getState().cancel();
|
775
652
|
};
|
776
|
-
return /* @__PURE__ */
|
653
|
+
return /* @__PURE__ */ jsx12(
|
777
654
|
Primitive7.button,
|
778
655
|
{
|
779
656
|
type: "button",
|
780
657
|
...rest,
|
781
658
|
ref,
|
782
|
-
onClick: composeEventHandlers6(onClick,
|
783
|
-
disabled: disabled || !hasValue
|
659
|
+
onClick: composeEventHandlers6(onClick, handleCancel)
|
784
660
|
}
|
785
661
|
);
|
786
662
|
});
|
@@ -796,7 +672,7 @@ __export(branchPicker_exports, {
|
|
796
672
|
});
|
797
673
|
|
798
674
|
// src/utils/context/combined/useCombinedStore.ts
|
799
|
-
import { useMemo as
|
675
|
+
import { useMemo as useMemo2 } from "react";
|
800
676
|
|
801
677
|
// src/utils/context/combined/createCombinedStore.ts
|
802
678
|
import { useSyncExternalStore } from "react";
|
@@ -817,37 +693,38 @@ var createCombinedStore = (stores) => {
|
|
817
693
|
|
818
694
|
// src/utils/context/combined/useCombinedStore.ts
|
819
695
|
var useCombinedStore = (stores, selector) => {
|
820
|
-
const useCombined =
|
696
|
+
const useCombined = useMemo2(() => createCombinedStore(stores), stores);
|
821
697
|
return useCombined(selector);
|
822
698
|
};
|
823
699
|
|
824
700
|
// src/actions/useGoToNextBranch.tsx
|
825
701
|
var useGoToNextBranch = () => {
|
826
702
|
const { useThread } = useAssistantContext();
|
827
|
-
const {
|
703
|
+
const { useMessage, useComposer } = useMessageContext();
|
828
704
|
const disabled = useCombinedStore(
|
829
|
-
[
|
830
|
-
(
|
705
|
+
[useMessage, useComposer],
|
706
|
+
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
|
831
707
|
);
|
832
708
|
if (disabled)
|
833
709
|
return null;
|
834
710
|
return () => {
|
835
|
-
const { message } = useMessage.getState();
|
836
|
-
useThread.getState().switchToBranch(message.id
|
711
|
+
const { message, branches } = useMessage.getState();
|
712
|
+
useThread.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
|
837
713
|
};
|
838
714
|
};
|
839
715
|
|
840
716
|
// src/utils/createActionButton.tsx
|
841
|
-
import {
|
717
|
+
import { composeEventHandlers as composeEventHandlers7 } from "@radix-ui/primitive";
|
842
718
|
import {
|
843
719
|
Primitive as Primitive8
|
844
720
|
} from "@radix-ui/react-primitive";
|
845
|
-
import {
|
721
|
+
import { forwardRef as forwardRef9 } from "react";
|
722
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
846
723
|
var createActionButton = (useActionButton) => {
|
847
724
|
return forwardRef9(
|
848
725
|
(props, forwardedRef) => {
|
849
726
|
const onClick = useActionButton(props);
|
850
|
-
return /* @__PURE__ */
|
727
|
+
return /* @__PURE__ */ jsx13(
|
851
728
|
Primitive8.button,
|
852
729
|
{
|
853
730
|
type: "button",
|
@@ -867,16 +744,19 @@ var BranchPickerNext = createActionButton(useGoToNextBranch);
|
|
867
744
|
// src/actions/useGoToPreviousBranch.tsx
|
868
745
|
var useGoToPreviousBranch = () => {
|
869
746
|
const { useThread } = useAssistantContext();
|
870
|
-
const {
|
747
|
+
const { useMessage, useComposer } = useMessageContext();
|
871
748
|
const disabled = useCombinedStore(
|
872
|
-
[
|
873
|
-
(
|
749
|
+
[useMessage, useComposer],
|
750
|
+
(m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
|
874
751
|
);
|
875
752
|
if (disabled)
|
876
753
|
return null;
|
877
754
|
return () => {
|
878
|
-
const { message } = useMessage.getState();
|
879
|
-
useThread.getState().switchToBranch(
|
755
|
+
const { message, branches } = useMessage.getState();
|
756
|
+
useThread.getState().switchToBranch(
|
757
|
+
branches[branches.indexOf(message.id) - 1]
|
758
|
+
// TODO probably there's a more elegant way to do this
|
759
|
+
);
|
880
760
|
};
|
881
761
|
};
|
882
762
|
|
@@ -884,17 +764,19 @@ var useGoToPreviousBranch = () => {
|
|
884
764
|
var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
|
885
765
|
|
886
766
|
// src/primitives/branchPicker/BranchPickerCount.tsx
|
767
|
+
import { Fragment as Fragment3, jsx as jsx14 } from "react/jsx-runtime";
|
887
768
|
var BranchPickerCount = () => {
|
888
769
|
const { useMessage } = useMessageContext();
|
889
|
-
const branchCount = useMessage((s) => s.
|
890
|
-
return /* @__PURE__ */
|
770
|
+
const branchCount = useMessage((s) => s.branches.length);
|
771
|
+
return /* @__PURE__ */ jsx14(Fragment3, { children: branchCount });
|
891
772
|
};
|
892
773
|
|
893
774
|
// src/primitives/branchPicker/BranchPickerNumber.tsx
|
775
|
+
import { Fragment as Fragment4, jsx as jsx15 } from "react/jsx-runtime";
|
894
776
|
var BranchPickerNumber = () => {
|
895
777
|
const { useMessage } = useMessageContext();
|
896
|
-
const
|
897
|
-
return /* @__PURE__ */
|
778
|
+
const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
|
779
|
+
return /* @__PURE__ */ jsx15(Fragment4, { children: branchIdx + 1 });
|
898
780
|
};
|
899
781
|
|
900
782
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
@@ -902,8 +784,9 @@ import {
|
|
902
784
|
Primitive as Primitive9
|
903
785
|
} from "@radix-ui/react-primitive";
|
904
786
|
import { forwardRef as forwardRef10 } from "react";
|
787
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
905
788
|
var BranchPickerRoot = forwardRef10(({ hideWhenSingleBranch, ...rest }, ref) => {
|
906
|
-
return /* @__PURE__ */
|
789
|
+
return /* @__PURE__ */ jsx16(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx16(Primitive9.div, { ...rest, ref }) });
|
907
790
|
});
|
908
791
|
|
909
792
|
// src/primitives/actionBar/index.ts
|
@@ -920,6 +803,7 @@ import {
|
|
920
803
|
Primitive as Primitive10
|
921
804
|
} from "@radix-ui/react-primitive";
|
922
805
|
import { forwardRef as forwardRef11 } from "react";
|
806
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
923
807
|
var ActionBarRoot = forwardRef11(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
|
924
808
|
const { useThread } = useAssistantContext();
|
925
809
|
const { useMessage } = useMessageContext();
|
@@ -933,14 +817,14 @@ var ActionBarRoot = forwardRef11(({ hideWhenRunning, autohide, autohideFloat, ..
|
|
933
817
|
return "normal" /* Normal */;
|
934
818
|
if (!m.isHovering)
|
935
819
|
return "hidden" /* Hidden */;
|
936
|
-
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.
|
820
|
+
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
|
937
821
|
return "floating" /* Floating */;
|
938
822
|
return "normal" /* Normal */;
|
939
823
|
}
|
940
824
|
);
|
941
825
|
if (hideAndfloatStatus === "hidden" /* Hidden */)
|
942
826
|
return null;
|
943
|
-
return /* @__PURE__ */
|
827
|
+
return /* @__PURE__ */ jsx17(
|
944
828
|
Primitive10.div,
|
945
829
|
{
|
946
830
|
"data-floating": hideAndfloatStatus === "floating" /* Floating */,
|
@@ -971,7 +855,7 @@ var ActionBarCopy = createActionButton(useCopyMessage);
|
|
971
855
|
|
972
856
|
// src/actions/useReloadMessage.tsx
|
973
857
|
var useReloadMessage = () => {
|
974
|
-
const { useThread } = useAssistantContext();
|
858
|
+
const { useThread, useViewport } = useAssistantContext();
|
975
859
|
const { useMessage } = useMessageContext();
|
976
860
|
const disabled = useCombinedStore(
|
977
861
|
[useThread, useMessage],
|
@@ -984,6 +868,7 @@ var useReloadMessage = () => {
|
|
984
868
|
if (message.role !== "assistant")
|
985
869
|
throw new Error("Reloading is only supported on assistant messages");
|
986
870
|
useThread.getState().startRun(message.parentId);
|
871
|
+
useViewport.getState().scrollToBottom();
|
987
872
|
};
|
988
873
|
};
|
989
874
|
|
@@ -1036,45 +921,285 @@ var makeViewportStore = () => {
|
|
1036
921
|
};
|
1037
922
|
|
1038
923
|
// src/adapters/vercel/useDummyAIAssistantContext.tsx
|
924
|
+
var makeDummyThreadStore = () => {
|
925
|
+
return create4(() => ({
|
926
|
+
messages: [],
|
927
|
+
isRunning: false,
|
928
|
+
getBranches: () => {
|
929
|
+
return [];
|
930
|
+
},
|
931
|
+
switchToBranch: () => {
|
932
|
+
throw new Error("Not implemented");
|
933
|
+
},
|
934
|
+
append: async () => {
|
935
|
+
throw new Error("Not implemented");
|
936
|
+
},
|
937
|
+
cancelRun: () => {
|
938
|
+
throw new Error("Not implemented");
|
939
|
+
},
|
940
|
+
startRun: async () => {
|
941
|
+
throw new Error("Not implemented");
|
942
|
+
}
|
943
|
+
}));
|
944
|
+
};
|
1039
945
|
var useDummyAIAssistantContext = () => {
|
1040
946
|
const [context] = useState2(() => {
|
1041
|
-
const useThread =
|
1042
|
-
id: "",
|
1043
|
-
messages: [],
|
1044
|
-
isRunning: false,
|
1045
|
-
append: async () => {
|
1046
|
-
throw new Error("Not implemented");
|
1047
|
-
},
|
1048
|
-
cancelRun: () => {
|
1049
|
-
throw new Error("Not implemented");
|
1050
|
-
},
|
1051
|
-
switchToBranch: () => {
|
1052
|
-
throw new Error("Not implemented");
|
1053
|
-
},
|
1054
|
-
startRun: async () => {
|
1055
|
-
throw new Error("Not implemented");
|
1056
|
-
}
|
1057
|
-
}));
|
947
|
+
const useThread = makeDummyThreadStore();
|
1058
948
|
const useViewport = makeViewportStore();
|
1059
|
-
const useComposer = makeThreadComposerStore(
|
1060
|
-
onSend: async (text) => {
|
1061
|
-
await useThread.getState().append({
|
1062
|
-
parentId: useThread.getState().messages.at(-1)?.id ?? ROOT_PARENT_ID,
|
1063
|
-
content: [{ type: "text", text }]
|
1064
|
-
});
|
1065
|
-
},
|
1066
|
-
onCancel: () => {
|
1067
|
-
useThread.getState().cancelRun();
|
1068
|
-
}
|
1069
|
-
});
|
949
|
+
const useComposer = makeThreadComposerStore(useThread);
|
1070
950
|
return { useThread, useViewport, useComposer };
|
1071
951
|
});
|
1072
952
|
return context;
|
1073
953
|
};
|
1074
954
|
|
955
|
+
// src/adapters/vercel/useVercelAIBranches.tsx
|
956
|
+
import { useCallback as useCallback2, useMemo as useMemo3, useRef as useRef6, useState as useState3 } from "react";
|
957
|
+
|
958
|
+
// ../../node_modules/nanoid/non-secure/index.js
|
959
|
+
var customAlphabet = (alphabet, defaultSize = 21) => {
|
960
|
+
return (size = defaultSize) => {
|
961
|
+
let id = "";
|
962
|
+
let i = size;
|
963
|
+
while (i--) {
|
964
|
+
id += alphabet[Math.random() * alphabet.length | 0];
|
965
|
+
}
|
966
|
+
return id;
|
967
|
+
};
|
968
|
+
};
|
969
|
+
|
970
|
+
// src/adapters/MessageRepository.tsx
|
971
|
+
var generateId = customAlphabet(
|
972
|
+
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
973
|
+
7
|
974
|
+
);
|
975
|
+
var optimisticPrefix = "__optimistic__";
|
976
|
+
var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
|
977
|
+
var isOptimisticId = (id) => id.startsWith(optimisticPrefix);
|
978
|
+
var findHead = (message) => {
|
979
|
+
if (message.next)
|
980
|
+
return findHead(message.next);
|
981
|
+
return message;
|
982
|
+
};
|
983
|
+
var MessageRepository = class {
|
984
|
+
messages = /* @__PURE__ */ new Map();
|
985
|
+
// message_id -> item
|
986
|
+
head = null;
|
987
|
+
rootChildren = [];
|
988
|
+
getMessages() {
|
989
|
+
const messages = new Array(this.head?.level ?? 0);
|
990
|
+
for (let current = this.head; current; current = current.prev) {
|
991
|
+
messages[current.level] = current.current;
|
992
|
+
}
|
993
|
+
return messages;
|
994
|
+
}
|
995
|
+
addOrUpdateMessage(message) {
|
996
|
+
const item = this.messages.get(message.id);
|
997
|
+
if (item) {
|
998
|
+
if (item.current.parentId !== message.parentId) {
|
999
|
+
this.deleteMessage(message.id);
|
1000
|
+
} else {
|
1001
|
+
item.current = message;
|
1002
|
+
return;
|
1003
|
+
}
|
1004
|
+
}
|
1005
|
+
const prev = message.parentId ? this.messages.get(message.parentId) : null;
|
1006
|
+
if (prev === void 0)
|
1007
|
+
throw new Error("Unexpected: Parent message not found");
|
1008
|
+
const newItem = {
|
1009
|
+
prev,
|
1010
|
+
current: message,
|
1011
|
+
next: null,
|
1012
|
+
children: [],
|
1013
|
+
level: prev ? prev.level + 1 : 0
|
1014
|
+
};
|
1015
|
+
this.messages.set(message.id, newItem);
|
1016
|
+
if (prev) {
|
1017
|
+
prev.children = [...prev.children, message.id];
|
1018
|
+
prev.next = newItem;
|
1019
|
+
} else {
|
1020
|
+
this.rootChildren = [...this.rootChildren, message.id];
|
1021
|
+
}
|
1022
|
+
if (this.head === prev) {
|
1023
|
+
this.head = newItem;
|
1024
|
+
}
|
1025
|
+
}
|
1026
|
+
deleteMessage(messageId) {
|
1027
|
+
const message = this.messages.get(messageId);
|
1028
|
+
if (!message)
|
1029
|
+
throw new Error("Unexpected: Message not found");
|
1030
|
+
if (message.children.length > 0) {
|
1031
|
+
for (const child of message.children) {
|
1032
|
+
this.deleteMessage(child);
|
1033
|
+
}
|
1034
|
+
}
|
1035
|
+
this.messages.delete(messageId);
|
1036
|
+
if (message.prev) {
|
1037
|
+
message.prev.children = message.prev.children.filter(
|
1038
|
+
(m) => m !== messageId
|
1039
|
+
);
|
1040
|
+
if (message.prev.next === message) {
|
1041
|
+
const childId = message.prev.children.at(-1);
|
1042
|
+
const child = childId ? this.messages.get(childId) : null;
|
1043
|
+
if (child === void 0)
|
1044
|
+
throw new Error("Unexpected: Child message not found");
|
1045
|
+
message.prev.next = child;
|
1046
|
+
}
|
1047
|
+
} else {
|
1048
|
+
this.rootChildren = this.rootChildren.filter((m) => m !== messageId);
|
1049
|
+
}
|
1050
|
+
if (this.head === message) {
|
1051
|
+
this.head = message.prev ? findHead(message.prev) : null;
|
1052
|
+
}
|
1053
|
+
}
|
1054
|
+
getOptimisticId = () => {
|
1055
|
+
let optimisticId;
|
1056
|
+
do {
|
1057
|
+
optimisticId = generateOptimisticId();
|
1058
|
+
} while (this.messages.has(optimisticId));
|
1059
|
+
return optimisticId;
|
1060
|
+
};
|
1061
|
+
commitOptimisticRun(parentId) {
|
1062
|
+
const optimisticId = this.getOptimisticId();
|
1063
|
+
this.addOrUpdateMessage({
|
1064
|
+
id: optimisticId,
|
1065
|
+
role: "assistant",
|
1066
|
+
content: [
|
1067
|
+
{
|
1068
|
+
type: "text",
|
1069
|
+
text: ""
|
1070
|
+
}
|
1071
|
+
],
|
1072
|
+
parentId,
|
1073
|
+
createdAt: /* @__PURE__ */ new Date()
|
1074
|
+
});
|
1075
|
+
return optimisticId;
|
1076
|
+
}
|
1077
|
+
getBranches(messageId) {
|
1078
|
+
const message = this.messages.get(messageId);
|
1079
|
+
if (!message)
|
1080
|
+
throw new Error("Unexpected: Message not found");
|
1081
|
+
if (message.prev) {
|
1082
|
+
return message.prev.children;
|
1083
|
+
}
|
1084
|
+
return this.rootChildren;
|
1085
|
+
}
|
1086
|
+
switchToBranch(messageId) {
|
1087
|
+
const message = this.messages.get(messageId);
|
1088
|
+
if (!message)
|
1089
|
+
throw new Error("Unexpected: Branch not found");
|
1090
|
+
if (message.prev) {
|
1091
|
+
message.prev.next = message;
|
1092
|
+
}
|
1093
|
+
this.head = findHead(message);
|
1094
|
+
}
|
1095
|
+
resetHead(messageId) {
|
1096
|
+
if (messageId) {
|
1097
|
+
const message = this.messages.get(messageId);
|
1098
|
+
if (!message)
|
1099
|
+
throw new Error("Unexpected: Branch not found");
|
1100
|
+
this.head = message;
|
1101
|
+
for (let current = message; current; current = current.prev) {
|
1102
|
+
if (current.prev) {
|
1103
|
+
current.prev.next = current;
|
1104
|
+
}
|
1105
|
+
}
|
1106
|
+
} else {
|
1107
|
+
this.head = null;
|
1108
|
+
}
|
1109
|
+
}
|
1110
|
+
};
|
1111
|
+
|
1112
|
+
// src/adapters/vercel/useVercelAIBranches.tsx
|
1113
|
+
var sliceMessagesUntil = (messages, messageId) => {
|
1114
|
+
if (messageId == null)
|
1115
|
+
return [];
|
1116
|
+
if (isOptimisticId(messageId))
|
1117
|
+
return messages;
|
1118
|
+
const messageIdx = messages.findIndex((m) => m.id === messageId);
|
1119
|
+
if (messageIdx === -1)
|
1120
|
+
throw new Error("Unexpected: Message not found");
|
1121
|
+
return messages.slice(0, messageIdx + 1);
|
1122
|
+
};
|
1123
|
+
var hasUpcomingMessage = (isRunning, messages) => {
|
1124
|
+
return isRunning && messages[messages.length - 1]?.role !== "assistant";
|
1125
|
+
};
|
1126
|
+
var useVercelAIBranches = (chat, messages) => {
|
1127
|
+
const [data] = useState3(() => new MessageRepository());
|
1128
|
+
const isRunning = "isLoading" in chat ? chat.isLoading : chat.status === "in_progress";
|
1129
|
+
const assistantOptimisticIdRef = useRef6(null);
|
1130
|
+
const messagesEx = useMemo3(() => {
|
1131
|
+
for (const message of messages) {
|
1132
|
+
data.addOrUpdateMessage(message);
|
1133
|
+
}
|
1134
|
+
if (assistantOptimisticIdRef.current) {
|
1135
|
+
data.deleteMessage(assistantOptimisticIdRef.current);
|
1136
|
+
assistantOptimisticIdRef.current = null;
|
1137
|
+
}
|
1138
|
+
if (hasUpcomingMessage(isRunning, messages)) {
|
1139
|
+
assistantOptimisticIdRef.current = data.commitOptimisticRun(
|
1140
|
+
messages.at(-1)?.id ?? null
|
1141
|
+
);
|
1142
|
+
}
|
1143
|
+
data.resetHead(
|
1144
|
+
assistantOptimisticIdRef.current ?? messages.at(-1)?.id ?? null
|
1145
|
+
);
|
1146
|
+
return data.getMessages();
|
1147
|
+
}, [data, isRunning, messages]);
|
1148
|
+
const getBranches = useCallback2(
|
1149
|
+
(messageId) => {
|
1150
|
+
return data.getBranches(messageId);
|
1151
|
+
},
|
1152
|
+
[data]
|
1153
|
+
);
|
1154
|
+
const switchToBranch = useCallback2(
|
1155
|
+
(messageId) => {
|
1156
|
+
data.switchToBranch(messageId);
|
1157
|
+
chat.setMessages(
|
1158
|
+
data.getMessages().filter((m) => !isOptimisticId(m.id)).map((m) => m.innerMessage)
|
1159
|
+
);
|
1160
|
+
},
|
1161
|
+
[data, chat.setMessages]
|
1162
|
+
);
|
1163
|
+
const reloadMaybe = "reload" in chat ? chat.reload : void 0;
|
1164
|
+
const startRun = useCallback2(
|
1165
|
+
async (parentId) => {
|
1166
|
+
if (!reloadMaybe)
|
1167
|
+
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
1168
|
+
const newMessages = sliceMessagesUntil(chat.messages, parentId);
|
1169
|
+
chat.setMessages(newMessages);
|
1170
|
+
await reloadMaybe();
|
1171
|
+
},
|
1172
|
+
[chat.messages, chat.setMessages, reloadMaybe]
|
1173
|
+
);
|
1174
|
+
const append = useCallback2(
|
1175
|
+
async (message) => {
|
1176
|
+
if (message.content.length !== 1 || message.content[0]?.type !== "text")
|
1177
|
+
throw new Error("Only text content is supported by Vercel AI SDK");
|
1178
|
+
const newMessages = sliceMessagesUntil(chat.messages, message.parentId);
|
1179
|
+
chat.setMessages(newMessages);
|
1180
|
+
await chat.append({
|
1181
|
+
role: "user",
|
1182
|
+
content: message.content[0].text
|
1183
|
+
});
|
1184
|
+
},
|
1185
|
+
[chat.messages, chat.setMessages, chat.append]
|
1186
|
+
);
|
1187
|
+
return useMemo3(
|
1188
|
+
() => ({
|
1189
|
+
messages: messagesEx,
|
1190
|
+
getBranches,
|
1191
|
+
switchToBranch,
|
1192
|
+
append,
|
1193
|
+
startRun
|
1194
|
+
}),
|
1195
|
+
[messagesEx, getBranches, switchToBranch, append, startRun]
|
1196
|
+
);
|
1197
|
+
};
|
1198
|
+
|
1075
1199
|
// src/adapters/vercel/VercelAIAssistantProvider.tsx
|
1200
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
1076
1201
|
var ThreadMessageCache = /* @__PURE__ */ new WeakMap();
|
1077
|
-
var vercelToThreadMessage = (message, parentId
|
1202
|
+
var vercelToThreadMessage = (message, parentId) => {
|
1078
1203
|
if (message.role !== "user" && message.role !== "assistant")
|
1079
1204
|
throw new Error("Unsupported role");
|
1080
1205
|
return {
|
@@ -1082,24 +1207,17 @@ var vercelToThreadMessage = (message, parentId, branchId, branchCount) => {
|
|
1082
1207
|
id: message.id,
|
1083
1208
|
role: message.role,
|
1084
1209
|
content: [{ type: "text", text: message.content }],
|
1085
|
-
|
1086
|
-
|
1087
|
-
createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
|
1210
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
|
1211
|
+
innerMessage: message
|
1088
1212
|
};
|
1089
1213
|
};
|
1090
|
-
var vercelToCachedThreadMessages = (messages
|
1214
|
+
var vercelToCachedThreadMessages = (messages) => {
|
1091
1215
|
return messages.map((m, idx) => {
|
1092
1216
|
const cached = ThreadMessageCache.get(m);
|
1093
|
-
const parentId = messages[idx - 1]?.id ??
|
1094
|
-
|
1095
|
-
if (cached && cached.parentId === parentId && cached.branchId === branchId && cached.branchCount === branchCount)
|
1217
|
+
const parentId = messages[idx - 1]?.id ?? null;
|
1218
|
+
if (cached && cached.parentId === parentId)
|
1096
1219
|
return cached;
|
1097
|
-
const newMessage = vercelToThreadMessage(
|
1098
|
-
m,
|
1099
|
-
parentId,
|
1100
|
-
branchId,
|
1101
|
-
branchCount
|
1102
|
-
);
|
1220
|
+
const newMessage = vercelToThreadMessage(m, parentId);
|
1103
1221
|
ThreadMessageCache.set(m, newMessage);
|
1104
1222
|
return newMessage;
|
1105
1223
|
});
|
@@ -1110,13 +1228,10 @@ var VercelAIAssistantProvider = ({
|
|
1110
1228
|
}) => {
|
1111
1229
|
const context = useDummyAIAssistantContext();
|
1112
1230
|
const vercel = "chat" in rest ? rest.chat : rest.assistant;
|
1113
|
-
const branches = useVercelAIBranches(vercel, context);
|
1114
1231
|
const messages = useMemo4(() => {
|
1115
|
-
return vercelToCachedThreadMessages(
|
1116
|
-
|
1117
|
-
|
1118
|
-
);
|
1119
|
-
}, [vercel.messages, branches.getBranchState]);
|
1232
|
+
return vercelToCachedThreadMessages(vercel.messages);
|
1233
|
+
}, [vercel.messages]);
|
1234
|
+
const branches = useVercelAIBranches(vercel, messages);
|
1120
1235
|
const cancelRun = useCallback3(() => {
|
1121
1236
|
const lastMessage = vercel.messages.at(-1);
|
1122
1237
|
vercel.stop();
|
@@ -1126,23 +1241,26 @@ var VercelAIAssistantProvider = ({
|
|
1126
1241
|
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1127
1242
|
const isRunning = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
1128
1243
|
useMemo4(() => {
|
1129
|
-
context.useThread.setState(
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1244
|
+
context.useThread.setState(
|
1245
|
+
{
|
1246
|
+
messages: branches.messages,
|
1247
|
+
isRunning,
|
1248
|
+
getBranches: branches.getBranches,
|
1249
|
+
switchToBranch: branches.switchToBranch,
|
1250
|
+
append: branches.append,
|
1251
|
+
startRun: branches.startRun,
|
1252
|
+
cancelRun
|
1253
|
+
},
|
1254
|
+
true
|
1255
|
+
);
|
1256
|
+
}, [context, isRunning, cancelRun, branches]);
|
1138
1257
|
useMemo4(() => {
|
1139
1258
|
context.useComposer.setState({
|
1140
|
-
canCancel: isRunning,
|
1141
1259
|
value: vercel.input,
|
1142
1260
|
setValue: vercel.setInput
|
1143
1261
|
});
|
1144
|
-
}, [context,
|
1145
|
-
return /* @__PURE__ */
|
1262
|
+
}, [context, vercel.input, vercel.setInput]);
|
1263
|
+
return /* @__PURE__ */ jsx18(AssistantContext.Provider, { value: context, children });
|
1146
1264
|
};
|
1147
1265
|
|
1148
1266
|
// src/adapters/vercel/VercelRSCAssistantProvider.tsx
|
@@ -1150,6 +1268,7 @@ import {
|
|
1150
1268
|
useCallback as useCallback4,
|
1151
1269
|
useMemo as useMemo5
|
1152
1270
|
} from "react";
|
1271
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
1153
1272
|
var ThreadMessageCache2 = /* @__PURE__ */ new WeakMap();
|
1154
1273
|
var vercelToThreadMessage2 = (parentId, message) => {
|
1155
1274
|
if (message.role !== "user" && message.role !== "assistant")
|
@@ -1159,15 +1278,13 @@ var vercelToThreadMessage2 = (parentId, message) => {
|
|
1159
1278
|
id: message.id,
|
1160
1279
|
role: message.role,
|
1161
1280
|
content: [{ type: "ui", display: message.display }],
|
1162
|
-
createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
|
1163
|
-
branchId: 0,
|
1164
|
-
branchCount: 1
|
1281
|
+
createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
|
1165
1282
|
};
|
1166
1283
|
};
|
1167
1284
|
var vercelToCachedThreadMessages2 = (messages) => {
|
1168
1285
|
return messages.map((m, idx) => {
|
1169
1286
|
const cached = ThreadMessageCache2.get(m);
|
1170
|
-
const parentId = messages[idx - 1]?.id ??
|
1287
|
+
const parentId = messages[idx - 1]?.id ?? null;
|
1171
1288
|
if (cached && cached.parentId === parentId)
|
1172
1289
|
return cached;
|
1173
1290
|
const newMessage = vercelToThreadMessage2(parentId, m);
|
@@ -1186,12 +1303,11 @@ var VercelRSCAssistantProvider = ({
|
|
1186
1303
|
}, [vercelMessages]);
|
1187
1304
|
const append = useCallback4(
|
1188
1305
|
async (message) => {
|
1189
|
-
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ??
|
1306
|
+
if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null))
|
1190
1307
|
throw new Error("Unexpected: Message editing is not supported");
|
1191
1308
|
if (message.content[0]?.type !== "text") {
|
1192
1309
|
throw new Error("Only text content is currently supported");
|
1193
1310
|
}
|
1194
|
-
context.useViewport.getState().scrollToBottom();
|
1195
1311
|
await vercelAppend(message);
|
1196
1312
|
},
|
1197
1313
|
[context, vercelAppend]
|
@@ -1202,7 +1318,7 @@ var VercelRSCAssistantProvider = ({
|
|
1202
1318
|
append
|
1203
1319
|
});
|
1204
1320
|
}, [context, messages, append]);
|
1205
|
-
return /* @__PURE__ */
|
1321
|
+
return /* @__PURE__ */ jsx19(AssistantContext.Provider, { value: context, children });
|
1206
1322
|
};
|
1207
1323
|
export {
|
1208
1324
|
actionBar_exports as ActionBarPrimitive,
|