@assistant-ui/react 0.0.15 → 0.0.17

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
@@ -68,18 +68,18 @@ import { useComposedRefs } from "@radix-ui/react-compose-refs";
68
68
  import {
69
69
  Primitive as Primitive2
70
70
  } from "@radix-ui/react-primitive";
71
- import { forwardRef as forwardRef2, useRef as useRef3 } from "react";
71
+ import { forwardRef as forwardRef2, useRef } from "react";
72
72
 
73
73
  // src/utils/hooks/useOnResizeContent.tsx
74
- import { useLayoutEffect, useRef } from "react";
74
+ import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
75
+ import { useEffect } from "react";
75
76
  var useOnResizeContent = (ref, callback) => {
76
- const callbackRef = useRef(callback);
77
- callbackRef.current = callback;
78
- useLayoutEffect(() => {
77
+ const callbackRef = useCallbackRef(callback);
78
+ useEffect(() => {
79
79
  const el = ref.current;
80
80
  if (!el) return;
81
81
  const resizeObserver = new ResizeObserver(() => {
82
- callbackRef.current();
82
+ callbackRef();
83
83
  });
84
84
  const mutationObserver = new MutationObserver((mutations) => {
85
85
  for (const mutation of mutations) {
@@ -94,7 +94,7 @@ var useOnResizeContent = (ref, callback) => {
94
94
  }
95
95
  }
96
96
  }
97
- callbackRef.current();
97
+ callbackRef();
98
98
  });
99
99
  resizeObserver.observe(el);
100
100
  mutationObserver.observe(el, { childList: true });
@@ -105,31 +105,31 @@ var useOnResizeContent = (ref, callback) => {
105
105
  resizeObserver.disconnect();
106
106
  mutationObserver.disconnect();
107
107
  };
108
- }, [ref.current]);
108
+ }, [ref.current, callbackRef]);
109
109
  };
110
110
 
111
111
  // src/utils/hooks/useOnScrollToBottom.tsx
112
- import { useEffect, useRef as useRef2 } from "react";
112
+ import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
113
+ import { useEffect as useEffect2 } from "react";
113
114
  var useOnScrollToBottom = (callback) => {
114
- const callbackRef = useRef2(callback);
115
- callbackRef.current = callback;
115
+ const callbackRef = useCallbackRef2(callback);
116
116
  const { useViewport } = useAssistantContext();
117
- useEffect(() => {
117
+ useEffect2(() => {
118
118
  return useViewport.getState().onScrollToBottom(() => {
119
- callbackRef.current();
119
+ callbackRef();
120
120
  });
121
- }, [useViewport]);
121
+ }, [useViewport, callbackRef]);
122
122
  };
123
123
 
124
124
  // src/primitives/thread/ThreadViewport.tsx
125
125
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
126
126
  var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
127
- const messagesEndRef = useRef3(null);
128
- const divRef = useRef3(null);
127
+ const messagesEndRef = useRef(null);
128
+ const divRef = useRef(null);
129
129
  const ref = useComposedRefs(forwardedRef, divRef);
130
130
  const { useViewport } = useAssistantContext();
131
- const firstRenderRef = useRef3(true);
132
- const lastScrollTop = useRef3(0);
131
+ const firstRenderRef = useRef(true);
132
+ const lastScrollTop = useRef(0);
133
133
  const scrollToBottom = () => {
134
134
  const div = messagesEndRef.current;
135
135
  if (!div || !autoScroll) return;
@@ -179,7 +179,9 @@ var MessageContext = createContext2(null);
179
179
  var useMessageContext = () => {
180
180
  const context = useContext2(MessageContext);
181
181
  if (!context)
182
- throw new Error("This component must be used within a MessageProvider.");
182
+ throw new Error(
183
+ "This component must be used within a MessagePrimitive.Provider."
184
+ );
183
185
  return context;
184
186
  };
185
187
 
@@ -212,6 +214,7 @@ var message_exports = {};
212
214
  __export(message_exports, {
213
215
  Content: () => MessageContent,
214
216
  If: () => MessageIf,
217
+ InProgress: () => MessageInProgress,
215
218
  Provider: () => MessageProvider,
216
219
  Root: () => MessageRoot
217
220
  });
@@ -293,8 +296,12 @@ var useMessageContext2 = () => {
293
296
  parentId: null,
294
297
  branches: [],
295
298
  isLast: false,
299
+ inProgressIndicator: null,
296
300
  isCopied: false,
297
301
  isHovering: false,
302
+ setInProgressIndicator: (value) => {
303
+ set({ inProgressIndicator: value });
304
+ },
298
305
  setIsCopied: (value) => {
299
306
  set({ isCopied: value });
300
307
  },
@@ -398,10 +405,94 @@ var MessageIf = ({ children, ...query }) => {
398
405
  return result ? children : null;
399
406
  };
400
407
 
408
+ // src/utils/context/combined/useCombinedStore.ts
409
+ import { useMemo as useMemo2 } from "react";
410
+
411
+ // src/utils/context/combined/createCombinedStore.ts
412
+ import { useSyncExternalStore } from "react";
413
+ var createCombinedStore = (stores) => {
414
+ const subscribe = (callback) => {
415
+ const unsubscribes = stores.map((store) => store.subscribe(callback));
416
+ return () => {
417
+ for (const unsub of unsubscribes) {
418
+ unsub();
419
+ }
420
+ };
421
+ };
422
+ return (selector) => {
423
+ const getSnapshot = () => selector(...stores.map((store) => store.getState()));
424
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
425
+ };
426
+ };
427
+
428
+ // src/utils/context/combined/useCombinedStore.ts
429
+ var useCombinedStore = (stores, selector) => {
430
+ const useCombined = useMemo2(() => createCombinedStore(stores), stores);
431
+ return useCombined(selector);
432
+ };
433
+
434
+ // src/utils/context/useContentPartContext.ts
435
+ import { createContext as createContext3, useContext as useContext4 } from "react";
436
+ var ContentPartContext = createContext3(null);
437
+ var useContentPartContext = () => {
438
+ const context = useContext4(ContentPartContext);
439
+ if (!context)
440
+ throw new Error(
441
+ "This component must be used within a ContentPartPrimitive.Provider."
442
+ );
443
+ return context;
444
+ };
445
+
446
+ // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
447
+ var ContentPartInProgressIndicator = () => {
448
+ const { useMessage } = useMessageContext();
449
+ const { useContentPart } = useContentPartContext();
450
+ const indicator = useCombinedStore(
451
+ [useMessage, useContentPart],
452
+ (m, c) => c.status === "in_progress" ? m.inProgressIndicator : null
453
+ );
454
+ return indicator;
455
+ };
456
+
457
+ // src/primitives/contentPart/ContentPartProvider.tsx
458
+ import { useMemo as useMemo3, useState as useState2 } from "react";
459
+ import { create as create3 } from "zustand";
460
+ import { jsx as jsx6 } from "react/jsx-runtime";
461
+ var useContentPartContext2 = () => {
462
+ const [context] = useState2(() => {
463
+ const useContentPart = create3(() => ({
464
+ part: null,
465
+ status: "done"
466
+ }));
467
+ return { useContentPart };
468
+ });
469
+ return context;
470
+ };
471
+ var ContentPartProvider = ({
472
+ part,
473
+ status,
474
+ children
475
+ }) => {
476
+ const context = useContentPartContext2();
477
+ useMemo3(() => {
478
+ context.useContentPart.setState(
479
+ {
480
+ part,
481
+ status
482
+ },
483
+ true
484
+ );
485
+ }, [context, part, status]);
486
+ return /* @__PURE__ */ jsx6(ContentPartContext.Provider, { value: context, children });
487
+ };
488
+
401
489
  // src/primitives/message/MessageContent.tsx
402
- import { Fragment, jsx as jsx6 } from "react/jsx-runtime";
490
+ import { Fragment, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
403
491
  var defaultComponents = {
404
- Text: ({ part }) => /* @__PURE__ */ jsx6(Fragment, { children: part.text }),
492
+ Text: ({ part }) => /* @__PURE__ */ jsxs2(Fragment, { children: [
493
+ part.text,
494
+ /* @__PURE__ */ jsx7(ContentPartInProgressIndicator, {})
495
+ ] }),
405
496
  Image: () => null,
406
497
  UI: ({ part }) => part.display,
407
498
  tools: {
@@ -417,28 +508,59 @@ var MessageContent = ({
417
508
  } = {}
418
509
  }) => {
419
510
  const { useMessage } = useMessageContext();
420
- const content = useMessage((s) => s.message.content);
421
- return /* @__PURE__ */ jsx6(Fragment, { children: content.map((part, i) => {
511
+ const message = useMessage((s) => s.message);
512
+ const content = message.content;
513
+ const status = message.role === "assistant" ? message.status : "done";
514
+ return /* @__PURE__ */ jsx7(Fragment, { children: content.map((part, i) => {
422
515
  const key = i;
423
- switch (part.type) {
516
+ const type = part.type;
517
+ let component = null;
518
+ switch (type) {
424
519
  case "text":
425
- return /* @__PURE__ */ jsx6(Text, { part }, key);
520
+ component = /* @__PURE__ */ jsx7(Text, { part });
521
+ break;
426
522
  case "image":
427
- return /* @__PURE__ */ jsx6(Image, { part }, key);
523
+ component = /* @__PURE__ */ jsx7(Image, { part });
524
+ break;
428
525
  case "ui":
429
- return /* @__PURE__ */ jsx6(UI, { part }, key);
526
+ component = /* @__PURE__ */ jsx7(UI, { part });
527
+ break;
430
528
  case "tool-call": {
431
529
  const Tool = by_name[part.name] || Fallback;
432
- return /* @__PURE__ */ jsx6(Tool, { part }, key);
530
+ component = /* @__PURE__ */ jsx7(Tool, { part });
531
+ break;
433
532
  }
434
533
  default:
435
- return null;
534
+ throw new Error(`Unknown content part type: ${type}`);
436
535
  }
536
+ return /* @__PURE__ */ jsx7(
537
+ ContentPartProvider,
538
+ {
539
+ part,
540
+ status: i === content.length - 1 ? status : "done",
541
+ children: component
542
+ },
543
+ key
544
+ );
437
545
  }) });
438
546
  };
439
547
 
548
+ // src/primitives/message/MessageInProgress.tsx
549
+ import {
550
+ Primitive as Primitive4
551
+ } from "@radix-ui/react-primitive";
552
+ import { forwardRef as forwardRef4, useMemo as useMemo4 } from "react";
553
+ import { jsx as jsx8 } from "react/jsx-runtime";
554
+ var MessageInProgress = forwardRef4((props, ref) => {
555
+ const { useMessage } = useMessageContext();
556
+ useMemo4(() => {
557
+ useMessage.getState().setInProgressIndicator(/* @__PURE__ */ jsx8(Primitive4.div, { ...props, ref }));
558
+ }, [useMessage, props, ref]);
559
+ return null;
560
+ });
561
+
440
562
  // src/primitives/thread/ThreadMessages.tsx
441
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
563
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
442
564
  var getComponents = (components) => {
443
565
  return {
444
566
  EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
@@ -452,19 +574,19 @@ var ThreadMessages = ({ components }) => {
452
574
  const messages = thread.messages;
453
575
  const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
454
576
  if (messages.length === 0) return null;
455
- return /* @__PURE__ */ jsx7(Fragment2, { children: messages.map((message, idx) => {
577
+ return /* @__PURE__ */ jsx9(Fragment2, { children: messages.map((message, idx) => {
456
578
  const parentId = messages[idx - 1]?.id ?? null;
457
- return /* @__PURE__ */ jsxs2(
579
+ return /* @__PURE__ */ jsxs3(
458
580
  MessageProvider,
459
581
  {
460
582
  message,
461
583
  parentId,
462
584
  children: [
463
- /* @__PURE__ */ jsxs2(MessageIf, { user: true, children: [
464
- /* @__PURE__ */ jsx7(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx7(UserMessage, {}) }),
465
- /* @__PURE__ */ jsx7(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx7(EditComposer, {}) })
585
+ /* @__PURE__ */ jsxs3(MessageIf, { user: true, children: [
586
+ /* @__PURE__ */ jsx9(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx9(UserMessage, {}) }),
587
+ /* @__PURE__ */ jsx9(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx9(EditComposer, {}) })
466
588
  ] }),
467
- /* @__PURE__ */ jsx7(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx7(AssistantMessage, {}) })
589
+ /* @__PURE__ */ jsx9(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx9(AssistantMessage, {}) })
468
590
  ]
469
591
  },
470
592
  parentId ?? "__ROOT__"
@@ -475,18 +597,18 @@ var ThreadMessages = ({ components }) => {
475
597
  // src/primitives/thread/ThreadScrollToBottom.tsx
476
598
  import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
477
599
  import {
478
- Primitive as Primitive4
600
+ Primitive as Primitive5
479
601
  } from "@radix-ui/react-primitive";
480
- import { forwardRef as forwardRef4 } from "react";
481
- import { jsx as jsx8 } from "react/jsx-runtime";
482
- var ThreadScrollToBottom = forwardRef4(({ onClick, ...rest }, ref) => {
602
+ import { forwardRef as forwardRef5 } from "react";
603
+ import { jsx as jsx10 } from "react/jsx-runtime";
604
+ var ThreadScrollToBottom = forwardRef5(({ onClick, ...rest }, ref) => {
483
605
  const { useViewport } = useAssistantContext();
484
606
  const isAtBottom = useViewport((s) => s.isAtBottom);
485
607
  const handleScrollToBottom = () => {
486
608
  useViewport.getState().scrollToBottom();
487
609
  };
488
- return /* @__PURE__ */ jsx8(
489
- Primitive4.button,
610
+ return /* @__PURE__ */ jsx10(
611
+ Primitive5.button,
490
612
  {
491
613
  ...rest,
492
614
  disabled: isAtBottom,
@@ -499,11 +621,11 @@ var ThreadScrollToBottom = forwardRef4(({ onClick, ...rest }, ref) => {
499
621
  // src/primitives/thread/ThreadSuggestion.tsx
500
622
  import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
501
623
  import {
502
- Primitive as Primitive5
624
+ Primitive as Primitive6
503
625
  } from "@radix-ui/react-primitive";
504
- import { forwardRef as forwardRef5 } from "react";
505
- import { jsx as jsx9 } from "react/jsx-runtime";
506
- var ThreadSuggestion = forwardRef5(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
626
+ import { forwardRef as forwardRef6 } from "react";
627
+ import { jsx as jsx11 } from "react/jsx-runtime";
628
+ var ThreadSuggestion = forwardRef6(({ onClick, prompt, method, autoSend: send, ...rest }, ref) => {
507
629
  const { useThread, useComposer } = useAssistantContext();
508
630
  const isDisabled = useThread((t) => t.isRunning);
509
631
  const handleApplySuggestion = () => {
@@ -514,8 +636,8 @@ var ThreadSuggestion = forwardRef5(({ onClick, prompt, method, autoSend: send, .
514
636
  composer.send();
515
637
  }
516
638
  };
517
- return /* @__PURE__ */ jsx9(
518
- Primitive5.button,
639
+ return /* @__PURE__ */ jsx11(
640
+ Primitive6.button,
519
641
  {
520
642
  ...rest,
521
643
  disabled: isDisabled,
@@ -539,15 +661,15 @@ __export(composer_exports, {
539
661
  import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
540
662
  import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
541
663
  import {
542
- Primitive as Primitive6
664
+ Primitive as Primitive7
543
665
  } from "@radix-ui/react-primitive";
544
- import { forwardRef as forwardRef6, useRef as useRef4 } from "react";
545
- import { jsx as jsx10 } from "react/jsx-runtime";
546
- var ComposerRoot = forwardRef6(
666
+ import { forwardRef as forwardRef7, useRef as useRef2 } from "react";
667
+ import { jsx as jsx12 } from "react/jsx-runtime";
668
+ var ComposerRoot = forwardRef7(
547
669
  ({ onSubmit, ...rest }, forwardedRef) => {
548
670
  const { useViewport } = useAssistantContext();
549
671
  const { useComposer } = useComposerContext();
550
- const formRef = useRef4(null);
672
+ const formRef = useRef2(null);
551
673
  const ref = useComposedRefs2(forwardedRef, formRef);
552
674
  const handleSubmit = (e) => {
553
675
  const composerState = useComposer.getState();
@@ -556,8 +678,8 @@ var ComposerRoot = forwardRef6(
556
678
  composerState.send();
557
679
  useViewport.getState().scrollToBottom();
558
680
  };
559
- return /* @__PURE__ */ jsx10(
560
- Primitive6.form,
681
+ return /* @__PURE__ */ jsx12(
682
+ Primitive7.form,
561
683
  {
562
684
  ...rest,
563
685
  ref,
@@ -572,14 +694,14 @@ import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primiti
572
694
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
573
695
  import { Slot } from "@radix-ui/react-slot";
574
696
  import {
575
- forwardRef as forwardRef7,
697
+ forwardRef as forwardRef8,
576
698
  useCallback,
577
- useEffect as useEffect2,
578
- useRef as useRef5
699
+ useEffect as useEffect3,
700
+ useRef as useRef3
579
701
  } from "react";
580
702
  import TextareaAutosize from "react-textarea-autosize";
581
- import { jsx as jsx11 } from "react/jsx-runtime";
582
- var ComposerInput = forwardRef7(
703
+ import { jsx as jsx13 } from "react/jsx-runtime";
704
+ var ComposerInput = forwardRef8(
583
705
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
584
706
  const { useThread, useViewport } = useAssistantContext();
585
707
  const { useComposer, type } = useComposerContext();
@@ -604,7 +726,7 @@ var ComposerInput = forwardRef7(
604
726
  }
605
727
  }
606
728
  };
607
- const textareaRef = useRef5(null);
729
+ const textareaRef = useRef3(null);
608
730
  const ref = useComposedRefs3(forwardedRef, textareaRef);
609
731
  const autoFocusEnabled = autoFocus && !disabled;
610
732
  const focus = useCallback(() => {
@@ -616,13 +738,13 @@ var ComposerInput = forwardRef7(
616
738
  textareaRef.current.value.length
617
739
  );
618
740
  }, [autoFocusEnabled]);
619
- useEffect2(() => focus(), [focus]);
741
+ useEffect3(() => focus(), [focus]);
620
742
  useOnScrollToBottom(() => {
621
743
  if (type === "assistant") {
622
744
  focus();
623
745
  }
624
746
  });
625
- return /* @__PURE__ */ jsx11(
747
+ return /* @__PURE__ */ jsx13(
626
748
  Component,
627
749
  {
628
750
  value,
@@ -642,16 +764,16 @@ var ComposerInput = forwardRef7(
642
764
 
643
765
  // src/primitives/composer/ComposerSend.tsx
644
766
  import {
645
- Primitive as Primitive7
767
+ Primitive as Primitive8
646
768
  } from "@radix-ui/react-primitive";
647
- import { forwardRef as forwardRef8 } from "react";
648
- import { jsx as jsx12 } from "react/jsx-runtime";
649
- var ComposerSend = forwardRef8(
769
+ import { forwardRef as forwardRef9 } from "react";
770
+ import { jsx as jsx14 } from "react/jsx-runtime";
771
+ var ComposerSend = forwardRef9(
650
772
  ({ disabled, ...rest }, ref) => {
651
773
  const { useComposer } = useComposerContext();
652
774
  const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
653
- return /* @__PURE__ */ jsx12(
654
- Primitive7.button,
775
+ return /* @__PURE__ */ jsx14(
776
+ Primitive8.button,
655
777
  {
656
778
  type: "submit",
657
779
  ...rest,
@@ -665,17 +787,17 @@ var ComposerSend = forwardRef8(
665
787
  // src/primitives/composer/ComposerCancel.tsx
666
788
  import { composeEventHandlers as composeEventHandlers7 } from "@radix-ui/primitive";
667
789
  import {
668
- Primitive as Primitive8
790
+ Primitive as Primitive9
669
791
  } from "@radix-ui/react-primitive";
670
- import { forwardRef as forwardRef9 } from "react";
671
- import { jsx as jsx13 } from "react/jsx-runtime";
672
- var ComposerCancel = forwardRef9(({ onClick, ...rest }, ref) => {
792
+ import { forwardRef as forwardRef10 } from "react";
793
+ import { jsx as jsx15 } from "react/jsx-runtime";
794
+ var ComposerCancel = forwardRef10(({ onClick, ...rest }, ref) => {
673
795
  const { useComposer } = useComposerContext();
674
796
  const handleCancel = () => {
675
797
  useComposer.getState().cancel();
676
798
  };
677
- return /* @__PURE__ */ jsx13(
678
- Primitive8.button,
799
+ return /* @__PURE__ */ jsx15(
800
+ Primitive9.button,
679
801
  {
680
802
  type: "button",
681
803
  ...rest,
@@ -695,32 +817,6 @@ __export(branchPicker_exports, {
695
817
  Root: () => BranchPickerRoot
696
818
  });
697
819
 
698
- // src/utils/context/combined/useCombinedStore.ts
699
- import { useMemo as useMemo2 } from "react";
700
-
701
- // src/utils/context/combined/createCombinedStore.ts
702
- import { useSyncExternalStore } from "react";
703
- var createCombinedStore = (stores) => {
704
- const subscribe = (callback) => {
705
- const unsubscribes = stores.map((store) => store.subscribe(callback));
706
- return () => {
707
- for (const unsub of unsubscribes) {
708
- unsub();
709
- }
710
- };
711
- };
712
- return (selector) => {
713
- const getSnapshot = () => selector(...stores.map((store) => store.getState()));
714
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
715
- };
716
- };
717
-
718
- // src/utils/context/combined/useCombinedStore.ts
719
- var useCombinedStore = (stores, selector) => {
720
- const useCombined = useMemo2(() => createCombinedStore(stores), stores);
721
- return useCombined(selector);
722
- };
723
-
724
820
  // src/actions/useGoToNextBranch.tsx
725
821
  var useGoToNextBranch = () => {
726
822
  const { useThread } = useAssistantContext();
@@ -739,16 +835,16 @@ var useGoToNextBranch = () => {
739
835
  // src/utils/createActionButton.tsx
740
836
  import { composeEventHandlers as composeEventHandlers8 } from "@radix-ui/primitive";
741
837
  import {
742
- Primitive as Primitive9
838
+ Primitive as Primitive10
743
839
  } from "@radix-ui/react-primitive";
744
- import { forwardRef as forwardRef10 } from "react";
745
- import { jsx as jsx14 } from "react/jsx-runtime";
840
+ import { forwardRef as forwardRef11 } from "react";
841
+ import { jsx as jsx16 } from "react/jsx-runtime";
746
842
  var createActionButton = (useActionButton) => {
747
- return forwardRef10(
843
+ return forwardRef11(
748
844
  (props, forwardedRef) => {
749
845
  const onClick = useActionButton(props);
750
- return /* @__PURE__ */ jsx14(
751
- Primitive9.button,
846
+ return /* @__PURE__ */ jsx16(
847
+ Primitive10.button,
752
848
  {
753
849
  type: "button",
754
850
  disabled: !onClick,
@@ -777,7 +873,6 @@ var useGoToPreviousBranch = () => {
777
873
  const { message, branches } = useMessage.getState();
778
874
  useThread.getState().switchToBranch(
779
875
  branches[branches.indexOf(message.id) - 1]
780
- // TODO probably there's a more elegant way to do this
781
876
  );
782
877
  };
783
878
  };
@@ -786,29 +881,29 @@ var useGoToPreviousBranch = () => {
786
881
  var BranchPickerPrevious = createActionButton(useGoToPreviousBranch);
787
882
 
788
883
  // src/primitives/branchPicker/BranchPickerCount.tsx
789
- import { Fragment as Fragment3, jsx as jsx15 } from "react/jsx-runtime";
884
+ import { Fragment as Fragment3, jsx as jsx17 } from "react/jsx-runtime";
790
885
  var BranchPickerCount = () => {
791
886
  const { useMessage } = useMessageContext();
792
887
  const branchCount = useMessage((s) => s.branches.length);
793
- return /* @__PURE__ */ jsx15(Fragment3, { children: branchCount });
888
+ return /* @__PURE__ */ jsx17(Fragment3, { children: branchCount });
794
889
  };
795
890
 
796
891
  // src/primitives/branchPicker/BranchPickerNumber.tsx
797
- import { Fragment as Fragment4, jsx as jsx16 } from "react/jsx-runtime";
892
+ import { Fragment as Fragment4, jsx as jsx18 } from "react/jsx-runtime";
798
893
  var BranchPickerNumber = () => {
799
894
  const { useMessage } = useMessageContext();
800
895
  const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
801
- return /* @__PURE__ */ jsx16(Fragment4, { children: branchIdx + 1 });
896
+ return /* @__PURE__ */ jsx18(Fragment4, { children: branchIdx + 1 });
802
897
  };
803
898
 
804
899
  // src/primitives/branchPicker/BranchPickerRoot.tsx
805
900
  import {
806
- Primitive as Primitive10
901
+ Primitive as Primitive11
807
902
  } from "@radix-ui/react-primitive";
808
- import { forwardRef as forwardRef11 } from "react";
809
- import { jsx as jsx17 } from "react/jsx-runtime";
810
- var BranchPickerRoot = forwardRef11(({ hideWhenSingleBranch, ...rest }, ref) => {
811
- return /* @__PURE__ */ jsx17(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx17(Primitive10.div, { ...rest, ref }) });
903
+ import { forwardRef as forwardRef12 } from "react";
904
+ import { jsx as jsx19 } from "react/jsx-runtime";
905
+ var BranchPickerRoot = forwardRef12(({ hideWhenSingleBranch, ...rest }, ref) => {
906
+ return /* @__PURE__ */ jsx19(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx19(Primitive11.div, { ...rest, ref }) });
812
907
  });
813
908
 
814
909
  // src/primitives/actionBar/index.ts
@@ -822,11 +917,11 @@ __export(actionBar_exports, {
822
917
 
823
918
  // src/primitives/actionBar/ActionBarRoot.tsx
824
919
  import {
825
- Primitive as Primitive11
920
+ Primitive as Primitive12
826
921
  } from "@radix-ui/react-primitive";
827
- import { forwardRef as forwardRef12 } from "react";
828
- import { jsx as jsx18 } from "react/jsx-runtime";
829
- var ActionBarRoot = forwardRef12(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
922
+ import { forwardRef as forwardRef13 } from "react";
923
+ import { jsx as jsx20 } from "react/jsx-runtime";
924
+ var ActionBarRoot = forwardRef13(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
830
925
  const { useThread } = useAssistantContext();
831
926
  const { useMessage } = useMessageContext();
832
927
  const hideAndfloatStatus = useCombinedStore(
@@ -842,8 +937,8 @@ var ActionBarRoot = forwardRef12(({ hideWhenRunning, autohide, autohideFloat, ..
842
937
  }
843
938
  );
844
939
  if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
845
- return /* @__PURE__ */ jsx18(
846
- Primitive11.div,
940
+ return /* @__PURE__ */ jsx20(
941
+ Primitive12.div,
847
942
  {
848
943
  "data-floating": hideAndfloatStatus === "floating" /* Floating */,
849
944
  ...rest,
@@ -911,18 +1006,25 @@ var useBeginMessageEdit = () => {
911
1006
  // src/primitives/actionBar/ActionBarEdit.tsx
912
1007
  var ActionBarEdit = createActionButton(useBeginMessageEdit);
913
1008
 
1009
+ // src/primitives/contentPart/index.ts
1010
+ var contentPart_exports = {};
1011
+ __export(contentPart_exports, {
1012
+ InProgressIndicator: () => ContentPartInProgressIndicator,
1013
+ Provider: () => ContentPartProvider
1014
+ });
1015
+
914
1016
  // src/adapters/vercel/VercelAIAssistantProvider.tsx
915
- import { useMemo as useMemo4 } from "react";
1017
+ import { useMemo as useMemo6 } from "react";
916
1018
 
917
1019
  // src/adapters/vercel/useDummyAIAssistantContext.tsx
918
- import { useState as useState2 } from "react";
919
- import { create as create4 } from "zustand";
1020
+ import { useState as useState3 } from "react";
1021
+ import { create as create5 } from "zustand";
920
1022
 
921
1023
  // src/utils/context/stores/ViewportStore.tsx
922
- import { create as create3 } from "zustand";
1024
+ import { create as create4 } from "zustand";
923
1025
  var makeViewportStore = () => {
924
1026
  const scrollToBottomListeners = /* @__PURE__ */ new Set();
925
- return create3(() => ({
1027
+ return create4(() => ({
926
1028
  isAtBottom: true,
927
1029
  scrollToBottom: () => {
928
1030
  for (const listener of scrollToBottomListeners) {
@@ -940,7 +1042,7 @@ var makeViewportStore = () => {
940
1042
 
941
1043
  // src/adapters/vercel/useDummyAIAssistantContext.tsx
942
1044
  var makeDummyThreadStore = () => {
943
- return create4(() => ({
1045
+ return create5(() => ({
944
1046
  messages: [],
945
1047
  isRunning: false,
946
1048
  getBranches: () => {
@@ -961,7 +1063,7 @@ var makeDummyThreadStore = () => {
961
1063
  }));
962
1064
  };
963
1065
  var useDummyAIAssistantContext = () => {
964
- const [context] = useState2(() => {
1066
+ const [context] = useState3(() => {
965
1067
  const useThread = makeDummyThreadStore();
966
1068
  const useViewport = makeViewportStore();
967
1069
  const useComposer = makeThreadComposerStore(useThread);
@@ -971,7 +1073,8 @@ var useDummyAIAssistantContext = () => {
971
1073
  };
972
1074
 
973
1075
  // src/adapters/vercel/useVercelAIThreadState.tsx
974
- import { useCallback as useCallback2, useMemo as useMemo3, useRef as useRef6, useState as useState3 } from "react";
1076
+ import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
1077
+ import { useCallback as useCallback2, useMemo as useMemo5, useRef as useRef4, useState as useState4 } from "react";
975
1078
 
976
1079
  // src/adapters/MessageRepository.tsx
977
1080
  import { customAlphabet } from "nanoid/non-secure";
@@ -981,7 +1084,6 @@ var generateId = customAlphabet(
981
1084
  );
982
1085
  var optimisticPrefix = "__optimistic__";
983
1086
  var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
984
- var isOptimisticId = (id) => id.startsWith(optimisticPrefix);
985
1087
  var findHead = (message) => {
986
1088
  if (message.next) return findHead(message.next);
987
1089
  return message;
@@ -990,7 +1092,41 @@ var MessageRepository = class {
990
1092
  messages = /* @__PURE__ */ new Map();
991
1093
  // message_id -> item
992
1094
  head = null;
993
- rootChildren = [];
1095
+ root = {
1096
+ children: []
1097
+ };
1098
+ getFallbackChild(p) {
1099
+ const childId = p.children.at(-1);
1100
+ const child = childId ? this.messages.get(childId) : null;
1101
+ if (child === void 0)
1102
+ throw new Error(
1103
+ "MessageRepository(getFallbackChild): Child message not found. This is likely an internal bug in assistant-ui."
1104
+ );
1105
+ return child;
1106
+ }
1107
+ performOp(newParent, child, operation) {
1108
+ const parentOrRoot = child.prev ?? this.root;
1109
+ const newParentOrRoot = newParent ?? this.root;
1110
+ if (operation === "relink" && parentOrRoot === newParentOrRoot) return;
1111
+ if (operation !== "link") {
1112
+ parentOrRoot.children = parentOrRoot.children.filter(
1113
+ (m) => m !== child.current.id
1114
+ );
1115
+ if (child.prev?.next === child) {
1116
+ child.prev.next = this.getFallbackChild(child.prev);
1117
+ }
1118
+ }
1119
+ if (operation !== "cut") {
1120
+ newParentOrRoot.children = [
1121
+ ...newParentOrRoot.children,
1122
+ child.current.id
1123
+ ];
1124
+ if (newParent && (findHead(child) === this.head || newParent.next === null)) {
1125
+ newParent.next = child;
1126
+ }
1127
+ child.prev = newParent;
1128
+ }
1129
+ }
994
1130
  getMessages() {
995
1131
  const messages = new Array(this.head?.level ?? 0);
996
1132
  for (let current = this.head; current; current = current.prev) {
@@ -999,20 +1135,17 @@ var MessageRepository = class {
999
1135
  return messages;
1000
1136
  }
1001
1137
  addOrUpdateMessage(parentId, message) {
1002
- const item = this.messages.get(message.id);
1003
- if (item) {
1004
- if ((item.prev?.current.id ?? null) !== parentId) {
1005
- this.deleteMessage(message.id);
1006
- } else {
1007
- item.current = message;
1008
- return;
1009
- }
1010
- }
1138
+ const existingItem = this.messages.get(message.id);
1011
1139
  const prev = parentId ? this.messages.get(parentId) : null;
1012
1140
  if (prev === void 0)
1013
1141
  throw new Error(
1014
1142
  "MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui."
1015
1143
  );
1144
+ if (existingItem) {
1145
+ existingItem.current = message;
1146
+ this.performOp(prev, existingItem, "relink");
1147
+ return;
1148
+ }
1016
1149
  const newItem = {
1017
1150
  prev,
1018
1151
  current: message,
@@ -1021,80 +1154,57 @@ var MessageRepository = class {
1021
1154
  level: prev ? prev.level + 1 : 0
1022
1155
  };
1023
1156
  this.messages.set(message.id, newItem);
1024
- if (prev) {
1025
- prev.children = [...prev.children, message.id];
1026
- prev.next = newItem;
1027
- } else {
1028
- this.rootChildren = [...this.rootChildren, message.id];
1029
- }
1030
1157
  if (this.head === prev) {
1031
1158
  this.head = newItem;
1032
1159
  }
1160
+ this.performOp(prev, newItem, "link");
1033
1161
  }
1034
- deleteMessage(messageId) {
1035
- const message = this.messages.get(messageId);
1036
- if (!message)
1037
- throw new Error(
1038
- "MessageRepository(deleteMessage): Message not found. This is likely an internal bug in assistant-ui."
1039
- );
1040
- if (message.children.length > 0) {
1041
- for (const child of message.children) {
1042
- this.deleteMessage(child);
1043
- }
1044
- }
1045
- this.messages.delete(messageId);
1046
- if (message.prev) {
1047
- message.prev.children = message.prev.children.filter(
1048
- (m) => m !== messageId
1049
- );
1050
- if (message.prev.next === message) {
1051
- const childId = message.prev.children.at(-1);
1052
- const child = childId ? this.messages.get(childId) : null;
1053
- if (child === void 0)
1054
- throw new Error(
1055
- "MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
1056
- );
1057
- message.prev.next = child;
1058
- }
1059
- } else {
1060
- this.rootChildren = this.rootChildren.filter((m) => m !== messageId);
1061
- }
1062
- if (this.head === message) {
1063
- this.head = message.prev ? findHead(message.prev) : null;
1064
- }
1065
- }
1066
- getOptimisticId() {
1162
+ appendOptimisticMessage(parentId, message) {
1067
1163
  let optimisticId;
1068
1164
  do {
1069
1165
  optimisticId = generateOptimisticId();
1070
1166
  } while (this.messages.has(optimisticId));
1071
- return optimisticId;
1072
- }
1073
- commitOptimisticRun(parentId) {
1074
- const optimisticId = this.getOptimisticId();
1075
1167
  this.addOrUpdateMessage(parentId, {
1168
+ ...message,
1076
1169
  id: optimisticId,
1077
- role: "assistant",
1078
- content: [
1079
- {
1080
- type: "text",
1081
- text: ""
1082
- }
1083
- ],
1084
- createdAt: /* @__PURE__ */ new Date()
1170
+ createdAt: /* @__PURE__ */ new Date(),
1171
+ ...message.role === "assistant" ? { status: "in_progress" } : void 0
1085
1172
  });
1086
1173
  return optimisticId;
1087
1174
  }
1175
+ deleteMessage(messageId, newParentId) {
1176
+ const message = this.messages.get(messageId);
1177
+ const newParent = newParentId ? this.messages.get(newParentId) : null;
1178
+ if (!message)
1179
+ throw new Error(
1180
+ "MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
1181
+ );
1182
+ if (newParent === void 0)
1183
+ throw new Error(
1184
+ "MessageRepository(deleteMessage): New message not found. This is likely an internal bug in assistant-ui."
1185
+ );
1186
+ for (const child of message.children) {
1187
+ const childMessage = this.messages.get(child);
1188
+ if (!childMessage)
1189
+ throw new Error(
1190
+ "MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
1191
+ );
1192
+ this.performOp(newParent, childMessage, "relink");
1193
+ }
1194
+ this.messages.delete(messageId);
1195
+ if (this.head === message) {
1196
+ this.head = this.getFallbackChild(message.prev ?? this.root);
1197
+ }
1198
+ this.performOp(null, message, "cut");
1199
+ }
1088
1200
  getBranches(messageId) {
1089
1201
  const message = this.messages.get(messageId);
1090
1202
  if (!message)
1091
1203
  throw new Error(
1092
1204
  "MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui."
1093
1205
  );
1094
- if (message.prev) {
1095
- return message.prev.children;
1096
- }
1097
- return this.rootChildren;
1206
+ const { children } = message.prev ?? this.root;
1207
+ return children;
1098
1208
  }
1099
1209
  switchToBranch(messageId) {
1100
1210
  const message = this.messages.get(messageId);
@@ -1108,28 +1218,28 @@ var MessageRepository = class {
1108
1218
  this.head = findHead(message);
1109
1219
  }
1110
1220
  resetHead(messageId) {
1111
- if (messageId) {
1112
- const message = this.messages.get(messageId);
1113
- if (!message)
1114
- throw new Error(
1115
- "MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui."
1116
- );
1117
- this.head = message;
1118
- for (let current = message; current; current = current.prev) {
1119
- if (current.prev) {
1120
- current.prev.next = current;
1121
- }
1122
- }
1123
- } else {
1221
+ if (messageId === null) {
1124
1222
  this.head = null;
1223
+ return;
1224
+ }
1225
+ const message = this.messages.get(messageId);
1226
+ if (!message)
1227
+ throw new Error(
1228
+ "MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui."
1229
+ );
1230
+ this.head = message;
1231
+ for (let current = message; current; current = current.prev) {
1232
+ if (current.prev) {
1233
+ current.prev.next = current;
1234
+ }
1125
1235
  }
1126
1236
  }
1127
1237
  };
1128
1238
 
1129
1239
  // src/adapters/ThreadMessageConverter.tsx
1130
1240
  var ThreadMessageConverter = class {
1131
- constructor(converter2) {
1132
- this.converter = converter2;
1241
+ constructor(converter) {
1242
+ this.converter = converter;
1133
1243
  }
1134
1244
  cache = /* @__PURE__ */ new WeakMap();
1135
1245
  convertMessages(messages) {
@@ -1143,33 +1253,55 @@ var ThreadMessageConverter = class {
1143
1253
  }
1144
1254
  };
1145
1255
 
1256
+ // src/adapters/vercel/VercelThreadMessage.tsx
1257
+ var symbolInnerMessage = Symbol("innerMessage");
1258
+ var symbolInnerRSCMessage = Symbol("innerRSCMessage");
1259
+ var getVercelMessage = (message) => {
1260
+ return message[symbolInnerMessage];
1261
+ };
1262
+ var getVercelRSCMessage = (message) => {
1263
+ return message[symbolInnerRSCMessage];
1264
+ };
1265
+
1146
1266
  // src/adapters/vercel/useVercelAIThreadState.tsx
1147
- var vercelToThreadMessage = (message) => {
1148
- if (message.role !== "user" && message.role !== "assistant")
1149
- throw new Error(
1150
- `You have a message with an unsupported role. The role ${message.role} is not supported.`
1151
- );
1152
- return {
1267
+ var vercelToThreadMessage = (message, status) => {
1268
+ const common = {
1153
1269
  id: message.id,
1154
- role: message.role,
1155
- content: [
1156
- ...message.content ? [{ type: "text", text: message.content }] : [],
1157
- ...message.toolInvocations?.map((t) => ({
1158
- type: "tool-call",
1159
- name: t.toolName,
1160
- args: t.args,
1161
- result: "result" in t ? t.result : void 0
1162
- })) ?? []
1163
- ],
1164
- // ignore type mismatch for now
1165
1270
  createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1166
- innerMessage: message
1271
+ [symbolInnerMessage]: message
1167
1272
  };
1273
+ switch (message.role) {
1274
+ case "user":
1275
+ return {
1276
+ ...common,
1277
+ role: "user",
1278
+ content: [{ type: "text", text: message.content }]
1279
+ };
1280
+ case "assistant":
1281
+ return {
1282
+ ...common,
1283
+ role: "assistant",
1284
+ content: [
1285
+ ...message.content ? [{ type: "text", text: message.content }] : [],
1286
+ ...message.toolInvocations?.map(
1287
+ (t) => ({
1288
+ type: "tool-call",
1289
+ name: t.toolName,
1290
+ args: t.args,
1291
+ result: "result" in t ? t.result : void 0
1292
+ })
1293
+ ) ?? []
1294
+ ],
1295
+ status
1296
+ };
1297
+ default:
1298
+ throw new Error(
1299
+ `You have a message with an unsupported role. The role ${message.role} is not supported.`
1300
+ );
1301
+ }
1168
1302
  };
1169
- var converter = new ThreadMessageConverter(vercelToThreadMessage);
1170
1303
  var sliceMessagesUntil = (messages, messageId) => {
1171
1304
  if (messageId == null) return [];
1172
- if (isOptimisticId(messageId)) return messages;
1173
1305
  const messageIdx = messages.findIndex((m) => m.id === messageId);
1174
1306
  if (messageIdx === -1)
1175
1307
  throw new Error(
@@ -1185,12 +1317,17 @@ var getIsRunning = (vercel) => {
1185
1317
  return vercel.status === "in_progress";
1186
1318
  };
1187
1319
  var useVercelAIThreadState = (vercel) => {
1188
- const [data] = useState3(() => new MessageRepository());
1189
- const vercelRef = useRef6(vercel);
1190
- vercelRef.current = vercel;
1191
- const isRunning = getIsRunning(vercelRef.current);
1192
- const assistantOptimisticIdRef = useRef6(null);
1193
- const messages = useMemo3(() => {
1320
+ const [data] = useState4(() => new MessageRepository());
1321
+ const isRunning = getIsRunning(vercel);
1322
+ const convertCallback = useCallbackRef3((message) => {
1323
+ return vercelToThreadMessage(
1324
+ message,
1325
+ vercel.messages.at(-1) === message && isRunning ? "in_progress" : "done"
1326
+ );
1327
+ });
1328
+ const converter = new ThreadMessageConverter(convertCallback);
1329
+ const assistantOptimisticIdRef = useRef4(null);
1330
+ const messages = useMemo5(() => {
1194
1331
  const vm = converter.convertMessages(vercel.messages);
1195
1332
  for (let i = 0; i < vm.length; i++) {
1196
1333
  const message = vm[i];
@@ -1198,66 +1335,61 @@ var useVercelAIThreadState = (vercel) => {
1198
1335
  data.addOrUpdateMessage(parent?.id ?? null, message);
1199
1336
  }
1200
1337
  if (assistantOptimisticIdRef.current) {
1201
- data.deleteMessage(assistantOptimisticIdRef.current);
1338
+ data.deleteMessage(assistantOptimisticIdRef.current, null);
1202
1339
  assistantOptimisticIdRef.current = null;
1203
1340
  }
1204
1341
  if (hasUpcomingMessage(isRunning, vm)) {
1205
- assistantOptimisticIdRef.current = data.commitOptimisticRun(
1206
- vm.at(-1)?.id ?? null
1342
+ assistantOptimisticIdRef.current = data.appendOptimisticMessage(
1343
+ vm.at(-1)?.id ?? null,
1344
+ {
1345
+ role: "assistant",
1346
+ content: [{ type: "text", text: "" }]
1347
+ }
1207
1348
  );
1208
1349
  }
1209
1350
  data.resetHead(assistantOptimisticIdRef.current ?? vm.at(-1)?.id ?? null);
1210
1351
  return data.getMessages();
1211
- }, [data, isRunning, vercel.messages]);
1352
+ }, [converter, data, isRunning, vercel.messages]);
1212
1353
  const getBranches2 = useCallback2(
1213
1354
  (messageId) => {
1214
1355
  return data.getBranches(messageId);
1215
1356
  },
1216
1357
  [data]
1217
1358
  );
1218
- const switchToBranch2 = useCallback2(
1219
- (messageId) => {
1220
- data.switchToBranch(messageId);
1221
- vercelRef.current.setMessages(
1222
- data.getMessages().filter((m) => !isOptimisticId(m.id)).map((m) => m.innerMessage)
1223
- );
1224
- },
1225
- [data]
1226
- );
1227
- const startRun = useCallback2(async (parentId) => {
1228
- const reloadMaybe = "reload" in vercelRef.current ? vercelRef.current.reload : void 0;
1359
+ const switchToBranch2 = useCallbackRef3((messageId) => {
1360
+ data.switchToBranch(messageId);
1361
+ vercel.setMessages(
1362
+ data.getMessages().map(getVercelMessage).filter((m) => m != null)
1363
+ );
1364
+ });
1365
+ const startRun = useCallbackRef3(async (parentId) => {
1366
+ const reloadMaybe = "reload" in vercel ? vercel.reload : void 0;
1229
1367
  if (!reloadMaybe)
1230
1368
  throw new Error(
1231
1369
  "Reload is not supported by Vercel AI SDK's useAssistant."
1232
1370
  );
1233
- const newMessages = sliceMessagesUntil(
1234
- vercelRef.current.messages,
1235
- parentId
1236
- );
1237
- vercelRef.current.setMessages(newMessages);
1371
+ const newMessages = sliceMessagesUntil(vercel.messages, parentId);
1372
+ vercel.setMessages(newMessages);
1238
1373
  await reloadMaybe();
1239
- }, []);
1240
- const append = useCallback2(async (message) => {
1374
+ });
1375
+ const append = useCallbackRef3(async (message) => {
1241
1376
  if (message.content.length !== 1 || message.content[0]?.type !== "text")
1242
1377
  throw new Error("Only text content is supported by Vercel AI SDK.");
1243
- const newMessages = sliceMessagesUntil(
1244
- vercelRef.current.messages,
1245
- message.parentId
1246
- );
1247
- vercelRef.current.setMessages(newMessages);
1248
- await vercelRef.current.append({
1378
+ const newMessages = sliceMessagesUntil(vercel.messages, message.parentId);
1379
+ vercel.setMessages(newMessages);
1380
+ await vercel.append({
1249
1381
  role: "user",
1250
1382
  content: message.content[0].text
1251
1383
  });
1252
- }, []);
1253
- const cancelRun2 = useCallback2(() => {
1254
- const lastMessage = vercelRef.current.messages.at(-1);
1255
- vercelRef.current.stop();
1384
+ });
1385
+ const cancelRun2 = useCallbackRef3(() => {
1386
+ const lastMessage = vercel.messages.at(-1);
1387
+ vercel.stop();
1256
1388
  if (lastMessage?.role === "user") {
1257
- vercelRef.current.setInput(lastMessage.content);
1389
+ vercel.setInput(lastMessage.content);
1258
1390
  }
1259
- }, []);
1260
- return useMemo3(
1391
+ });
1392
+ return useMemo5(
1261
1393
  () => ({
1262
1394
  isRunning,
1263
1395
  messages,
@@ -1280,7 +1412,7 @@ var useVercelAIThreadState = (vercel) => {
1280
1412
  };
1281
1413
 
1282
1414
  // src/adapters/vercel/VercelAIAssistantProvider.tsx
1283
- import { jsx as jsx19 } from "react/jsx-runtime";
1415
+ import { jsx as jsx21 } from "react/jsx-runtime";
1284
1416
  var VercelAIAssistantProvider = ({
1285
1417
  children,
1286
1418
  ...rest
@@ -1288,31 +1420,34 @@ var VercelAIAssistantProvider = ({
1288
1420
  const context = useDummyAIAssistantContext();
1289
1421
  const vercel = "chat" in rest ? rest.chat : rest.assistant;
1290
1422
  const threadState = useVercelAIThreadState(vercel);
1291
- useMemo4(() => {
1423
+ useMemo6(() => {
1292
1424
  context.useThread.setState(threadState, true);
1293
1425
  }, [context, threadState]);
1294
- useMemo4(() => {
1426
+ useMemo6(() => {
1295
1427
  context.useComposer.setState({
1296
1428
  value: vercel.input,
1297
1429
  setValue: vercel.setInput
1298
1430
  });
1299
1431
  }, [context, vercel.input, vercel.setInput]);
1300
- return /* @__PURE__ */ jsx19(AssistantContext.Provider, { value: context, children });
1432
+ return /* @__PURE__ */ jsx21(AssistantContext.Provider, { value: context, children });
1301
1433
  };
1302
1434
 
1303
1435
  // src/adapters/vercel/VercelRSCAssistantProvider.tsx
1304
1436
  import {
1305
1437
  useCallback as useCallback3,
1306
- useMemo as useMemo5,
1307
- useState as useState4
1438
+ useMemo as useMemo7,
1439
+ useState as useState5
1308
1440
  } from "react";
1309
- import { jsx as jsx20 } from "react/jsx-runtime";
1310
- var vercelToThreadMessage2 = (message) => {
1441
+ import { jsx as jsx22 } from "react/jsx-runtime";
1442
+ var vercelToThreadMessage2 = (converter, rawMessage) => {
1443
+ const message = converter(rawMessage);
1311
1444
  return {
1312
1445
  id: message.id,
1313
1446
  role: message.role,
1314
1447
  content: [{ type: "ui", display: message.display }],
1315
- createdAt: message.createdAt ?? /* @__PURE__ */ new Date()
1448
+ createdAt: message.createdAt ?? /* @__PURE__ */ new Date(),
1449
+ ...{ status: "done" },
1450
+ [symbolInnerRSCMessage]: rawMessage
1316
1451
  };
1317
1452
  };
1318
1453
  var EMPTY_BRANCHES = [];
@@ -1340,20 +1475,20 @@ var VercelRSCAssistantProvider = ({
1340
1475
  reload
1341
1476
  }) => {
1342
1477
  const context = useDummyAIAssistantContext();
1343
- const [isRunning, setIsRunning] = useState4(false);
1478
+ const [isRunning, setIsRunning] = useState5(false);
1344
1479
  const withRunning = useCallback3((callback) => {
1345
1480
  setIsRunning(true);
1346
1481
  return callback.finally(() => setIsRunning(false));
1347
1482
  }, []);
1348
- const converter2 = useMemo5(() => {
1483
+ const converter = useMemo7(() => {
1349
1484
  const rscConverter = convertMessage ?? ((m) => m);
1350
1485
  return new ThreadMessageConverter((m) => {
1351
- return vercelToThreadMessage2(rscConverter(m));
1486
+ return vercelToThreadMessage2(rscConverter, m);
1352
1487
  });
1353
1488
  }, [convertMessage]);
1354
- const messages = useMemo5(() => {
1355
- return converter2.convertMessages(vercelMessages);
1356
- }, [converter2, vercelMessages]);
1489
+ const messages = useMemo7(() => {
1490
+ return converter.convertMessages(vercelMessages);
1491
+ }, [converter, vercelMessages]);
1357
1492
  const append = useCallback3(
1358
1493
  async (message) => {
1359
1494
  if (message.parentId !== (context.useThread.getState().messages.at(-1)?.id ?? null)) {
@@ -1378,7 +1513,7 @@ var VercelRSCAssistantProvider = ({
1378
1513
  },
1379
1514
  [withRunning, reload]
1380
1515
  );
1381
- useMemo5(() => {
1516
+ useMemo7(() => {
1382
1517
  context.useThread.setState(
1383
1518
  {
1384
1519
  messages,
@@ -1392,16 +1527,19 @@ var VercelRSCAssistantProvider = ({
1392
1527
  true
1393
1528
  );
1394
1529
  }, [context, messages, isRunning, append, startRun]);
1395
- return /* @__PURE__ */ jsx20(AssistantContext.Provider, { value: context, children });
1530
+ return /* @__PURE__ */ jsx22(AssistantContext.Provider, { value: context, children });
1396
1531
  };
1397
1532
  export {
1398
1533
  actionBar_exports as ActionBarPrimitive,
1399
1534
  branchPicker_exports as BranchPickerPrimitive,
1400
1535
  composer_exports as ComposerPrimitive,
1536
+ contentPart_exports as ContentPartPrimitive,
1401
1537
  message_exports as MessagePrimitive,
1402
1538
  thread_exports as ThreadPrimitive,
1403
1539
  VercelAIAssistantProvider,
1404
1540
  VercelRSCAssistantProvider,
1541
+ getVercelMessage as unstable_getVercelMessage,
1542
+ getVercelRSCMessage as unstable_getVercelRSCMessage,
1405
1543
  useMessageContext as unstable_useMessageContext,
1406
1544
  useBeginMessageEdit,
1407
1545
  useCopyMessage,