@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.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__ */ React.createElement(Primitive.div, { ...props, ref });
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__ */ React.createElement(ThreadIf, { empty: true }, children);
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__ */ React.createElement(
166
+ return /* @__PURE__ */ jsxs(
164
167
  Primitive2.div,
165
168
  {
166
169
  ...rest,
167
170
  onScroll: composeEventHandlers(onScroll, handleScroll),
168
- ref
169
- },
170
- children,
171
- /* @__PURE__ */ React.createElement("div", { ref: messagesEndRef })
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
- return useMemo(
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 as useMemo2, useState } from "react";
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
- return onSend(value);
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
- onSend,
398
- onCancel
399
- }) => create()((set, get, store) => ({
400
- ...makeBaseComposer(set, get, store),
401
- isEditing: true,
402
- canCancel: false,
403
- send: () => {
404
- const value = get().value;
405
- set({ value: "", canCancel: true });
406
- onSend(value).then(() => {
407
- set({ canCancel: false });
408
- });
409
- },
410
- cancel: onCancel
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
- const hasUpcoming = hasUpcomingMessage(thread);
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
- return useThread.getState().append({
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
- useMemo2(() => {
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__ */ React.createElement(MessageContext.Provider, { value: context }, children);
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__ */ React.createElement(
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 && message.branchCount < 2)
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__ */ React.createElement(React.Fragment, null, part.text),
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__ */ React.createElement(React.Fragment, null, content.map((part, i) => {
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__ */ React.createElement(Text, { key, part });
430
+ return /* @__PURE__ */ jsx6(Text, { part }, key);
553
431
  case "image":
554
- return /* @__PURE__ */ React.createElement(Image, { key, part });
432
+ return /* @__PURE__ */ jsx6(Image, { part }, key);
555
433
  case "ui":
556
- return /* @__PURE__ */ React.createElement(UI, { key, part });
434
+ return /* @__PURE__ */ jsx6(UI, { part }, key);
557
435
  case "tool-call": {
558
436
  const Tool = by_name[part.name] || Fallback;
559
- return /* @__PURE__ */ React.createElement(Tool, { key, part });
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__ */ React.createElement(React.Fragment, null, messages.map((message, idx) => {
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__ */ React.createElement(MessageProvider, { key: idx, message }, /* @__PURE__ */ React.createElement(MessageIf, { user: true }, /* @__PURE__ */ React.createElement(ComposerIf, { editing: false }, /* @__PURE__ */ React.createElement(UserMessage, null)), /* @__PURE__ */ React.createElement(ComposerIf, { editing: true }, /* @__PURE__ */ React.createElement(EditComposer, null))), /* @__PURE__ */ React.createElement(MessageIf, { assistant: true }, /* @__PURE__ */ React.createElement(AssistantMessage, null)))
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
- }), hasUpcomingMessage(thread) && /* @__PURE__ */ React.createElement(
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__ */ React.createElement(
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 useRef5 } from "react";
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 = useRef5(null);
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__ */ React.createElement(
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 as useCallback2,
548
+ useCallback,
675
549
  useEffect as useEffect2,
676
- useRef as useRef6
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" && composer.canCancel) {
694
- e.preventDefault();
695
- useComposer.getState().cancel();
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 = useRef6(null);
581
+ const textareaRef = useRef5(null);
706
582
  const ref = useComposedRefs3(forwardedRef, textareaRef);
707
583
  const autoFocusEnabled = autoFocus !== false && !disabled;
708
- const focus = useCallback2(() => {
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__ */ React.createElement(
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__ */ React.createElement(
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
- var ComposerCancel = forwardRef8(({ disabled, onClick, ...rest }, ref) => {
647
+ import { jsx as jsx12 } from "react/jsx-runtime";
648
+ var ComposerCancel = forwardRef8(({ onClick, ...rest }, ref) => {
771
649
  const { useComposer } = useComposerContext();
772
- const hasValue = useComposer((c) => c.canCancel);
773
- const handleClose = () => {
650
+ const handleCancel = () => {
774
651
  useComposer.getState().cancel();
775
652
  };
776
- return /* @__PURE__ */ React.createElement(
653
+ return /* @__PURE__ */ jsx12(
777
654
  Primitive7.button,
778
655
  {
779
656
  type: "button",
780
657
  ...rest,
781
658
  ref,
782
- onClick: composeEventHandlers6(onClick, handleClose),
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 useMemo3 } from "react";
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 = useMemo3(() => createCombinedStore(stores), stores);
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 { useComposer, useMessage } = useMessageContext();
703
+ const { useMessage, useComposer } = useMessageContext();
828
704
  const disabled = useCombinedStore(
829
- [useThread, useComposer, useMessage],
830
- (t, c, m) => t.isRunning || c.isEditing || m.message.branchId + 1 >= m.message.branchCount
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, message.branchId + 1);
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 { forwardRef as forwardRef9 } from "react";
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 { composeEventHandlers as composeEventHandlers7 } from "@radix-ui/primitive";
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__ */ React.createElement(
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 { useComposer, useMessage } = useMessageContext();
747
+ const { useMessage, useComposer } = useMessageContext();
871
748
  const disabled = useCombinedStore(
872
- [useThread, useComposer, useMessage],
873
- (t, c, m) => t.isRunning || c.isEditing || m.message.branchId <= 0
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(message.id, message.branchId - 1);
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.message.branchCount);
890
- return /* @__PURE__ */ React.createElement(React.Fragment, null, branchCount);
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 branchId = useMessage((s) => s.message.branchId);
897
- return /* @__PURE__ */ React.createElement(React.Fragment, null, branchId + 1);
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__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(Primitive9.div, { ...rest, ref }));
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.message.branchCount <= 1)
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__ */ React.createElement(
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 = create4()(() => ({
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, branchId, branchCount) => {
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
- branchId,
1086
- branchCount,
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, getBranchState) => {
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 ?? ROOT_PARENT_ID;
1094
- const { branchId, branchCount } = getBranchState(m.id);
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
- vercel.messages,
1117
- branches.getBranchState
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
- messages,
1131
- isRunning,
1132
- cancelRun,
1133
- switchToBranch: branches.switchToBranch,
1134
- append: branches.append,
1135
- startRun: branches.startRun
1136
- });
1137
- }, [context, messages, isRunning, cancelRun, branches]);
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, isRunning, vercel.input, vercel.setInput]);
1145
- return /* @__PURE__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
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 ?? ROOT_PARENT_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 ?? ROOT_PARENT_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__ */ React.createElement(AssistantContext.Provider, { value: context }, children);
1321
+ return /* @__PURE__ */ jsx19(AssistantContext.Provider, { value: context, children });
1206
1322
  };
1207
1323
  export {
1208
1324
  actionBar_exports as ActionBarPrimitive,