@assistant-ui/react 0.0.15 → 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
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,