@assistant-ui/react 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -300,12 +300,15 @@ var useComposerIf = (props) => {
300
300
  // src/primitive-hooks/composer/useComposerSend.tsx
301
301
  var import_react14 = require("react");
302
302
  var useComposerSend = () => {
303
+ const { useViewport } = useThreadContext();
303
304
  const { useComposer } = useComposerContext();
304
305
  const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
305
306
  const callback = (0, import_react14.useCallback)(() => {
306
- const { send } = useComposer.getState();
307
- send();
308
- }, [useComposer]);
307
+ const composerState = useComposer.getState();
308
+ if (!composerState.isEditing) return;
309
+ composerState.send();
310
+ useViewport.getState().scrollToBottom();
311
+ }, [useComposer, useViewport]);
309
312
  if (disabled) return null;
310
313
  return callback;
311
314
  };
@@ -450,137 +453,169 @@ var ThreadRoot = (0, import_react17.forwardRef)(
450
453
  );
451
454
  ThreadRoot.displayName = "ThreadRoot";
452
455
 
456
+ // src/primitives/thread/ThreadEmpty.tsx
457
+ var ThreadEmpty = ({ children }) => {
458
+ const empty = useThreadEmpty();
459
+ return empty ? children : null;
460
+ };
461
+
453
462
  // src/primitives/thread/ThreadIf.tsx
454
463
  var ThreadIf = ({ children, ...query }) => {
455
464
  const result = useThreadIf(query);
456
465
  return result ? children : null;
457
466
  };
458
467
 
459
- // src/primitives/thread/ThreadEmpty.tsx
460
- var import_jsx_runtime2 = require("react/jsx-runtime");
461
- var ThreadEmpty = ({ children }) => {
462
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThreadIf, { empty: true, children });
463
- };
464
-
465
468
  // src/primitives/thread/ThreadViewport.tsx
466
- var import_primitive = require("@radix-ui/primitive");
467
- var import_react_compose_refs = require("@radix-ui/react-compose-refs");
469
+ var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
468
470
  var import_react_primitive2 = require("@radix-ui/react-primitive");
469
- var import_react20 = require("react");
471
+ var import_react22 = require("react");
472
+
473
+ // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
474
+ var import_react_compose_refs = require("@radix-ui/react-compose-refs");
475
+ var import_react21 = require("react");
470
476
 
471
477
  // src/utils/hooks/useOnResizeContent.tsx
472
478
  var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
479
+ var import_react19 = require("react");
480
+
481
+ // src/utils/hooks/useManagedRef.ts
473
482
  var import_react18 = require("react");
474
- var useOnResizeContent = (ref, callback) => {
483
+ var useManagedRef = (callback) => {
484
+ const cleanupRef = (0, import_react18.useRef)();
485
+ const ref = (0, import_react18.useCallback)(
486
+ (el) => {
487
+ if (cleanupRef.current) {
488
+ cleanupRef.current();
489
+ }
490
+ if (el) {
491
+ cleanupRef.current = callback(el);
492
+ }
493
+ },
494
+ [callback]
495
+ );
496
+ return ref;
497
+ };
498
+
499
+ // src/utils/hooks/useOnResizeContent.tsx
500
+ var useOnResizeContent = (callback) => {
475
501
  const callbackRef = (0, import_react_use_callback_ref.useCallbackRef)(callback);
476
- (0, import_react18.useEffect)(() => {
477
- const el = ref.current;
478
- if (!el) return;
479
- const resizeObserver = new ResizeObserver(() => {
480
- callbackRef();
481
- });
482
- const mutationObserver = new MutationObserver((mutations) => {
483
- for (const mutation of mutations) {
484
- for (const node of mutation.addedNodes) {
485
- if (node instanceof Element) {
486
- resizeObserver.observe(node);
502
+ const refCallback = (0, import_react19.useCallback)(
503
+ (el) => {
504
+ const resizeObserver = new ResizeObserver(() => {
505
+ callbackRef();
506
+ });
507
+ const mutationObserver = new MutationObserver((mutations) => {
508
+ for (const mutation of mutations) {
509
+ for (const node of mutation.addedNodes) {
510
+ if (node instanceof Element) {
511
+ resizeObserver.observe(node);
512
+ }
487
513
  }
488
- }
489
- for (const node of mutation.removedNodes) {
490
- if (node instanceof Element) {
491
- resizeObserver.unobserve(node);
514
+ for (const node of mutation.removedNodes) {
515
+ if (node instanceof Element) {
516
+ resizeObserver.unobserve(node);
517
+ }
492
518
  }
493
519
  }
520
+ callbackRef();
521
+ });
522
+ resizeObserver.observe(el);
523
+ mutationObserver.observe(el, { childList: true });
524
+ for (const child of el.children) {
525
+ resizeObserver.observe(child);
494
526
  }
495
- callbackRef();
496
- });
497
- resizeObserver.observe(el);
498
- mutationObserver.observe(el, { childList: true });
499
- for (const child of el.children) {
500
- resizeObserver.observe(child);
501
- }
502
- return () => {
503
- resizeObserver.disconnect();
504
- mutationObserver.disconnect();
505
- };
506
- }, [ref, callbackRef]);
527
+ return () => {
528
+ resizeObserver.disconnect();
529
+ mutationObserver.disconnect();
530
+ };
531
+ },
532
+ [callbackRef]
533
+ );
534
+ return useManagedRef(refCallback);
507
535
  };
508
536
 
509
537
  // src/utils/hooks/useOnScrollToBottom.tsx
510
538
  var import_react_use_callback_ref2 = require("@radix-ui/react-use-callback-ref");
511
- var import_react19 = require("react");
539
+ var import_react20 = require("react");
512
540
  var useOnScrollToBottom = (callback) => {
513
541
  const callbackRef = (0, import_react_use_callback_ref2.useCallbackRef)(callback);
514
542
  const { useViewport } = useThreadContext();
515
- (0, import_react19.useEffect)(() => {
543
+ (0, import_react20.useEffect)(() => {
516
544
  return useViewport.getState().onScrollToBottom(() => {
517
545
  callbackRef();
518
546
  });
519
547
  }, [useViewport, callbackRef]);
520
548
  };
521
549
 
522
- // src/primitives/thread/ThreadViewport.tsx
523
- var import_jsx_runtime3 = require("react/jsx-runtime");
524
- var ThreadViewport = (0, import_react20.forwardRef)(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
525
- const messagesEndRef = (0, import_react20.useRef)(null);
526
- const divRef = (0, import_react20.useRef)(null);
527
- const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, divRef);
550
+ // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
551
+ var useThreadViewportAutoScroll = ({
552
+ autoScroll = true
553
+ }) => {
554
+ const divRef = (0, import_react21.useRef)(null);
528
555
  const { useViewport } = useThreadContext();
529
- const firstRenderRef = (0, import_react20.useRef)(true);
530
- const isScrollingToBottomRef = (0, import_react20.useRef)(false);
531
- const lastScrollTop = (0, import_react20.useRef)(0);
556
+ const firstRenderRef = (0, import_react21.useRef)(true);
557
+ const lastScrollTop = (0, import_react21.useRef)(0);
558
+ const isScrollingToBottomRef = (0, import_react21.useRef)(false);
532
559
  const scrollToBottom = () => {
533
- const div = messagesEndRef.current;
560
+ const div = divRef.current;
534
561
  if (!div || !autoScroll) return;
535
562
  const behavior = firstRenderRef.current ? "instant" : "auto";
536
563
  firstRenderRef.current = false;
537
564
  isScrollingToBottomRef.current = true;
538
- div.scrollIntoView({ behavior });
565
+ div.scrollTo({ top: div.scrollHeight, behavior });
539
566
  };
540
- useOnResizeContent(divRef, () => {
541
- if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom) {
542
- handleScroll();
543
- } else {
544
- scrollToBottom();
545
- }
546
- });
547
- useOnScrollToBottom(() => {
548
- scrollToBottom();
549
- });
550
567
  const handleScroll = () => {
551
568
  const div = divRef.current;
552
569
  if (!div) return;
553
570
  const isAtBottom = useViewport.getState().isAtBottom;
554
571
  const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
555
572
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
556
- } else if (newIsAtBottom !== isAtBottom) {
557
- isScrollingToBottomRef.current = false;
558
- useViewport.setState({
559
- isAtBottom: newIsAtBottom
560
- });
573
+ } else {
574
+ isScrollingToBottomRef.current = newIsAtBottom;
575
+ if (newIsAtBottom !== isAtBottom) {
576
+ useViewport.setState({
577
+ isAtBottom: newIsAtBottom
578
+ });
579
+ }
561
580
  }
562
581
  lastScrollTop.current = div.scrollTop;
563
582
  };
564
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
565
- import_react_primitive2.Primitive.div,
566
- {
567
- ...rest,
568
- onScroll: (0, import_primitive.composeEventHandlers)(onScroll, handleScroll),
569
- ref,
570
- children: [
571
- children,
572
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: messagesEndRef })
573
- ]
583
+ const resizeRef = useOnResizeContent(() => {
584
+ if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom && !firstRenderRef.current) {
585
+ handleScroll();
586
+ } else {
587
+ scrollToBottom();
574
588
  }
575
- );
589
+ });
590
+ const scrollRef = useManagedRef((el) => {
591
+ el.addEventListener("scroll", handleScroll);
592
+ return () => {
593
+ el.removeEventListener("scroll", handleScroll);
594
+ };
595
+ });
596
+ const autoScrollRef = (0, import_react_compose_refs.useComposedRefs)(resizeRef, scrollRef, divRef);
597
+ useOnScrollToBottom(() => {
598
+ scrollToBottom();
599
+ });
600
+ return autoScrollRef;
601
+ };
602
+
603
+ // src/primitives/thread/ThreadViewport.tsx
604
+ var import_jsx_runtime2 = require("react/jsx-runtime");
605
+ var ThreadViewport = (0, import_react22.forwardRef)(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
606
+ const autoScrollRef = useThreadViewportAutoScroll({
607
+ autoScroll
608
+ });
609
+ const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, autoScrollRef);
610
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_primitive2.Primitive.div, { ...rest, ref, children });
576
611
  });
577
612
  ThreadViewport.displayName = "ThreadViewport";
578
613
 
579
614
  // src/primitives/thread/ThreadMessages.tsx
580
- var import_react22 = require("react");
615
+ var import_react24 = require("react");
581
616
 
582
617
  // src/context/providers/MessageProvider.tsx
583
- var import_react21 = require("react");
618
+ var import_react23 = require("react");
584
619
  var import_zustand3 = require("zustand");
585
620
 
586
621
  // src/context/stores/EditComposer.ts
@@ -635,7 +670,7 @@ var makeMessageUtilsStore = () => (0, import_zustand2.create)((set) => ({
635
670
  }));
636
671
 
637
672
  // src/context/providers/MessageProvider.tsx
638
- var import_jsx_runtime4 = require("react/jsx-runtime");
673
+ var import_jsx_runtime3 = require("react/jsx-runtime");
639
674
  var getIsLast = (thread, message) => {
640
675
  return thread.messages[thread.messages.length - 1]?.id === message.id;
641
676
  };
@@ -657,7 +692,7 @@ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
657
692
  };
658
693
  var useMessageContext2 = (messageIndex) => {
659
694
  const { useThread, useThreadActions } = useThreadContext();
660
- const [context] = (0, import_react21.useState)(() => {
695
+ const [context] = (0, import_react23.useState)(() => {
661
696
  const useMessage = (0, import_zustand3.create)(() => ({}));
662
697
  const useMessageUtils = makeMessageUtilsStore();
663
698
  const useEditComposer = makeEditComposerStore({
@@ -681,6 +716,7 @@ var useMessageContext2 = (messageIndex) => {
681
716
  );
682
717
  useThreadActions.getState().append({
683
718
  parentId,
719
+ role: "user",
684
720
  content: [{ type: "text", text }, ...nonTextParts]
685
721
  });
686
722
  }
@@ -693,7 +729,7 @@ var useMessageContext2 = (messageIndex) => {
693
729
  );
694
730
  return { useMessage, useMessageUtils, useEditComposer };
695
731
  });
696
- (0, import_react21.useEffect)(() => {
732
+ (0, import_react23.useEffect)(() => {
697
733
  return useThread.subscribe((thread) => {
698
734
  syncMessage(
699
735
  thread,
@@ -710,7 +746,7 @@ var MessageProvider = ({
710
746
  children
711
747
  }) => {
712
748
  const context = useMessageContext2(messageIndex);
713
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContext.Provider, { value: context, children });
749
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MessageContext.Provider, { value: context, children });
714
750
  };
715
751
 
716
752
  // src/primitives/composer/ComposerIf.tsx
@@ -726,7 +762,7 @@ var MessageIf = ({ children, ...query }) => {
726
762
  };
727
763
 
728
764
  // src/primitives/thread/ThreadMessages.tsx
729
- var import_jsx_runtime5 = require("react/jsx-runtime");
765
+ var import_jsx_runtime4 = require("react/jsx-runtime");
730
766
  var getComponents = (components) => {
731
767
  return {
732
768
  EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
@@ -739,15 +775,15 @@ var ThreadMessageImpl = ({
739
775
  components
740
776
  }) => {
741
777
  const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
742
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MessageProvider, { messageIndex, children: [
743
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MessageIf, { user: true, children: [
744
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(UserMessage, {}) }),
745
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EditComposer, {}) })
778
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MessageProvider, { messageIndex, children: [
779
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MessageIf, { user: true, children: [
780
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UserMessage, {}) }),
781
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EditComposer, {}) })
746
782
  ] }),
747
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantMessage, {}) })
783
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AssistantMessage, {}) })
748
784
  ] });
749
785
  };
750
- var ThreadMessage = (0, import_react22.memo)(
786
+ var ThreadMessage = (0, import_react24.memo)(
751
787
  ThreadMessageImpl,
752
788
  (prev, next) => prev.messageIndex === next.messageIndex && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
753
789
  );
@@ -757,7 +793,7 @@ var ThreadMessages = ({ components }) => {
757
793
  if (messagesLength === 0) return null;
758
794
  return new Array(messagesLength).fill(null).map((_, idx) => {
759
795
  const messageIndex = idx;
760
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
796
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
761
797
  ThreadMessage,
762
798
  {
763
799
  messageIndex,
@@ -769,21 +805,21 @@ var ThreadMessages = ({ components }) => {
769
805
  };
770
806
 
771
807
  // src/utils/createActionButton.tsx
772
- var import_primitive2 = require("@radix-ui/primitive");
808
+ var import_primitive = require("@radix-ui/primitive");
773
809
  var import_react_primitive3 = require("@radix-ui/react-primitive");
774
- var import_react23 = require("react");
775
- var import_jsx_runtime6 = require("react/jsx-runtime");
810
+ var import_react25 = require("react");
811
+ var import_jsx_runtime5 = require("react/jsx-runtime");
776
812
  var createActionButton = (displayName, useActionButton) => {
777
- const ActionButton = (0, import_react23.forwardRef)((props, forwardedRef) => {
813
+ const ActionButton = (0, import_react25.forwardRef)((props, forwardedRef) => {
778
814
  const callback = useActionButton(props);
779
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
815
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
780
816
  import_react_primitive3.Primitive.button,
781
817
  {
782
818
  type: "button",
783
819
  disabled: !callback,
784
820
  ...props,
785
821
  ref: forwardedRef,
786
- onClick: (0, import_primitive2.composeEventHandlers)(props.onClick, () => {
822
+ onClick: (0, import_primitive.composeEventHandlers)(props.onClick, () => {
787
823
  callback?.();
788
824
  })
789
825
  }
@@ -816,30 +852,24 @@ __export(composer_exports, {
816
852
  });
817
853
 
818
854
  // src/primitives/composer/ComposerRoot.tsx
819
- var import_primitive3 = require("@radix-ui/primitive");
820
- var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
855
+ var import_primitive2 = require("@radix-ui/primitive");
821
856
  var import_react_primitive4 = require("@radix-ui/react-primitive");
822
- var import_react24 = require("react");
823
- var import_jsx_runtime7 = require("react/jsx-runtime");
824
- var ComposerRoot = (0, import_react24.forwardRef)(
857
+ var import_react26 = require("react");
858
+ var import_jsx_runtime6 = require("react/jsx-runtime");
859
+ var ComposerRoot = (0, import_react26.forwardRef)(
825
860
  ({ onSubmit, ...rest }, forwardedRef) => {
826
- const { useViewport } = useThreadContext();
827
- const { useComposer } = useComposerContext();
828
- const formRef = (0, import_react24.useRef)(null);
829
- const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, formRef);
861
+ const send = useComposerSend();
830
862
  const handleSubmit = (e) => {
831
- const composerState = useComposer.getState();
832
- if (!composerState.isEditing) return;
863
+ if (!send) return;
833
864
  e.preventDefault();
834
- composerState.send();
835
- useViewport.getState().scrollToBottom();
865
+ send();
836
866
  };
837
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
867
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
838
868
  import_react_primitive4.Primitive.form,
839
869
  {
840
870
  ...rest,
841
- ref,
842
- onSubmit: (0, import_primitive3.composeEventHandlers)(onSubmit, handleSubmit)
871
+ ref: forwardedRef,
872
+ onSubmit: (0, import_primitive2.composeEventHandlers)(onSubmit, handleSubmit)
843
873
  }
844
874
  );
845
875
  }
@@ -847,13 +877,14 @@ var ComposerRoot = (0, import_react24.forwardRef)(
847
877
  ComposerRoot.displayName = "ComposerRoot";
848
878
 
849
879
  // src/primitives/composer/ComposerInput.tsx
850
- var import_primitive4 = require("@radix-ui/primitive");
880
+ var import_primitive3 = require("@radix-ui/primitive");
851
881
  var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
852
882
  var import_react_slot = require("@radix-ui/react-slot");
853
- var import_react25 = require("react");
883
+ var import_react27 = require("react");
854
884
  var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
855
- var import_jsx_runtime8 = require("react/jsx-runtime");
856
- var ComposerInput = (0, import_react25.forwardRef)(
885
+ var import_react_use_escape_keydown = require("@radix-ui/react-use-escape-keydown");
886
+ var import_jsx_runtime7 = require("react/jsx-runtime");
887
+ var ComposerInput = (0, import_react27.forwardRef)(
857
888
  ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
858
889
  const { useThread } = useThreadContext();
859
890
  const { useComposer, type } = useComposerContext();
@@ -862,16 +893,17 @@ var ComposerInput = (0, import_react25.forwardRef)(
862
893
  return c.value;
863
894
  });
864
895
  const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
865
- const textareaRef = (0, import_react25.useRef)(null);
896
+ const textareaRef = (0, import_react27.useRef)(null);
866
897
  const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
898
+ (0, import_react_use_escape_keydown.useEscapeKeydown)((e) => {
899
+ const composer = useComposer.getState();
900
+ if (composer.cancel()) {
901
+ e.preventDefault();
902
+ }
903
+ });
867
904
  const handleKeyPress = (e) => {
868
905
  if (disabled) return;
869
- if (e.key === "Escape") {
870
- const composer = useComposer.getState();
871
- if (composer.cancel()) {
872
- e.preventDefault();
873
- }
874
- } else if (e.key === "Enter" && e.shiftKey === false) {
906
+ if (e.key === "Enter" && e.shiftKey === false) {
875
907
  const isRunning = useThread.getState().isRunning;
876
908
  if (!isRunning) {
877
909
  e.preventDefault();
@@ -880,7 +912,7 @@ var ComposerInput = (0, import_react25.forwardRef)(
880
912
  }
881
913
  };
882
914
  const autoFocusEnabled = autoFocus && !disabled;
883
- const focus = (0, import_react25.useCallback)(() => {
915
+ const focus = (0, import_react27.useCallback)(() => {
884
916
  const textarea = textareaRef.current;
885
917
  if (!textarea || !autoFocusEnabled) return;
886
918
  textarea.focus();
@@ -889,13 +921,13 @@ var ComposerInput = (0, import_react25.forwardRef)(
889
921
  textareaRef.current.value.length
890
922
  );
891
923
  }, [autoFocusEnabled]);
892
- (0, import_react25.useEffect)(() => focus(), [focus]);
924
+ (0, import_react27.useEffect)(() => focus(), [focus]);
893
925
  useOnScrollToBottom(() => {
894
926
  if (type === "new") {
895
927
  focus();
896
928
  }
897
929
  });
898
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
930
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
899
931
  Component,
900
932
  {
901
933
  value,
@@ -903,12 +935,12 @@ var ComposerInput = (0, import_react25.forwardRef)(
903
935
  ref,
904
936
  autoFocus,
905
937
  disabled,
906
- onChange: (0, import_primitive4.composeEventHandlers)(onChange, (e) => {
938
+ onChange: (0, import_primitive3.composeEventHandlers)(onChange, (e) => {
907
939
  const composerState = useComposer.getState();
908
940
  if (!composerState.isEditing) return;
909
941
  return composerState.setValue(e.target.value);
910
942
  }),
911
- onKeyDown: (0, import_primitive4.composeEventHandlers)(onKeyDown, handleKeyPress)
943
+ onKeyDown: (0, import_primitive3.composeEventHandlers)(onKeyDown, handleKeyPress)
912
944
  }
913
945
  );
914
946
  }
@@ -916,7 +948,25 @@ var ComposerInput = (0, import_react25.forwardRef)(
916
948
  ComposerInput.displayName = "ComposerInput";
917
949
 
918
950
  // src/primitives/composer/ComposerSend.tsx
919
- var ComposerSend = createActionButton("ComposerSend", useComposerSend);
951
+ var import_react28 = require("react");
952
+ var import_react_primitive5 = require("@radix-ui/react-primitive");
953
+ var import_jsx_runtime8 = require("react/jsx-runtime");
954
+ var ComposerSend = (0, import_react28.forwardRef)(
955
+ ({ disabled, ...rest }, ref) => {
956
+ const { useComposer } = useComposerContext();
957
+ const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
958
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
959
+ import_react_primitive5.Primitive.button,
960
+ {
961
+ type: "submit",
962
+ ...rest,
963
+ ref,
964
+ disabled: disabled || !hasValue
965
+ }
966
+ );
967
+ }
968
+ );
969
+ ComposerSend.displayName = "ComposerSend";
920
970
 
921
971
  // src/primitives/composer/ComposerCancel.tsx
922
972
  var ComposerCancel = createActionButton(
@@ -934,11 +984,11 @@ __export(message_exports, {
934
984
  });
935
985
 
936
986
  // src/primitives/message/MessageRoot.tsx
937
- var import_primitive5 = require("@radix-ui/primitive");
938
- var import_react_primitive5 = require("@radix-ui/react-primitive");
939
- var import_react26 = require("react");
987
+ var import_primitive4 = require("@radix-ui/primitive");
988
+ var import_react_primitive6 = require("@radix-ui/react-primitive");
989
+ var import_react29 = require("react");
940
990
  var import_jsx_runtime9 = require("react/jsx-runtime");
941
- var MessageRoot = (0, import_react26.forwardRef)(
991
+ var MessageRoot = (0, import_react29.forwardRef)(
942
992
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
943
993
  const { useMessageUtils } = useMessageContext();
944
994
  const setIsHovering = useMessageUtils((s) => s.setIsHovering);
@@ -949,12 +999,12 @@ var MessageRoot = (0, import_react26.forwardRef)(
949
999
  setIsHovering(false);
950
1000
  };
951
1001
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
952
- import_react_primitive5.Primitive.div,
1002
+ import_react_primitive6.Primitive.div,
953
1003
  {
954
1004
  ...rest,
955
1005
  ref,
956
- onMouseEnter: (0, import_primitive5.composeEventHandlers)(onMouseEnter, handleMouseEnter),
957
- onMouseLeave: (0, import_primitive5.composeEventHandlers)(onMouseLeave, handleMouseLeave)
1006
+ onMouseEnter: (0, import_primitive4.composeEventHandlers)(onMouseEnter, handleMouseEnter),
1007
+ onMouseLeave: (0, import_primitive4.composeEventHandlers)(onMouseLeave, handleMouseLeave)
958
1008
  }
959
1009
  );
960
1010
  }
@@ -962,10 +1012,10 @@ var MessageRoot = (0, import_react26.forwardRef)(
962
1012
  MessageRoot.displayName = "MessageRoot";
963
1013
 
964
1014
  // src/primitives/message/MessageContent.tsx
965
- var import_react29 = require("react");
1015
+ var import_react32 = require("react");
966
1016
 
967
1017
  // src/context/providers/ContentPartProvider.tsx
968
- var import_react27 = require("react");
1018
+ var import_react30 = require("react");
969
1019
  var import_zustand4 = require("zustand");
970
1020
  var import_jsx_runtime10 = require("react/jsx-runtime");
971
1021
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
@@ -984,14 +1034,14 @@ var syncContentPart = ({ message }, useContentPart, partIndex) => {
984
1034
  };
985
1035
  var useContentPartContext2 = (partIndex) => {
986
1036
  const { useMessage } = useMessageContext();
987
- const [context] = (0, import_react27.useState)(() => {
1037
+ const [context] = (0, import_react30.useState)(() => {
988
1038
  const useContentPart = (0, import_zustand4.create)(
989
1039
  () => ({})
990
1040
  );
991
1041
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
992
1042
  return { useContentPart };
993
1043
  });
994
- (0, import_react27.useEffect)(() => {
1044
+ (0, import_react30.useEffect)(() => {
995
1045
  syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
996
1046
  return useMessage.subscribe((message) => {
997
1047
  syncContentPart(message, context.useContentPart, partIndex);
@@ -1020,12 +1070,12 @@ var ContentPartInProgressIndicator = () => {
1020
1070
  };
1021
1071
 
1022
1072
  // src/primitives/contentPart/ContentPartText.tsx
1023
- var import_react_primitive6 = require("@radix-ui/react-primitive");
1024
- var import_react28 = require("react");
1073
+ var import_react_primitive7 = require("@radix-ui/react-primitive");
1074
+ var import_react31 = require("react");
1025
1075
  var import_jsx_runtime11 = require("react/jsx-runtime");
1026
- var ContentPartText = (0, import_react28.forwardRef)((props, forwardedRef) => {
1076
+ var ContentPartText = (0, import_react31.forwardRef)((props, forwardedRef) => {
1027
1077
  const text = useContentPartText();
1028
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_primitive6.Primitive.span, { ...props, ref: forwardedRef, children: text });
1078
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_primitive7.Primitive.span, { ...props, ref: forwardedRef, children: text });
1029
1079
  });
1030
1080
  ContentPartText.displayName = "ContentPartText";
1031
1081
 
@@ -1082,7 +1132,7 @@ var MessageContentPartImpl = ({
1082
1132
  }) => {
1083
1133
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartProvider, { partIndex, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MessageContentPartComponent, { components }) });
1084
1134
  };
1085
- var MessageContentPart = (0, import_react29.memo)(
1135
+ var MessageContentPart = (0, import_react32.memo)(
1086
1136
  MessageContentPartImpl,
1087
1137
  (prev, next) => prev.partIndex === next.partIndex && prev.components?.Text === next.components?.Text && prev.components?.Image === next.components?.Image && prev.components?.UI === next.components?.UI && prev.components?.tools === next.components?.tools
1088
1138
  );
@@ -1103,13 +1153,13 @@ var MessageContent = ({ components }) => {
1103
1153
  };
1104
1154
 
1105
1155
  // src/primitives/message/MessageInProgress.tsx
1106
- var import_react_primitive7 = require("@radix-ui/react-primitive");
1107
- var import_react30 = require("react");
1156
+ var import_react_primitive8 = require("@radix-ui/react-primitive");
1157
+ var import_react33 = require("react");
1108
1158
  var import_jsx_runtime13 = require("react/jsx-runtime");
1109
- var MessageInProgress = (0, import_react30.forwardRef)((props, ref) => {
1159
+ var MessageInProgress = (0, import_react33.forwardRef)((props, ref) => {
1110
1160
  const { useMessageUtils } = useMessageContext();
1111
- (0, import_react30.useMemo)(() => {
1112
- useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_primitive7.Primitive.span, { ...props, ref }));
1161
+ (0, import_react33.useMemo)(() => {
1162
+ useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_primitive8.Primitive.span, { ...props, ref }));
1113
1163
  }, [useMessageUtils, props, ref]);
1114
1164
  return null;
1115
1165
  });
@@ -1152,11 +1202,11 @@ var BranchPickerNumber = () => {
1152
1202
  };
1153
1203
 
1154
1204
  // src/primitives/branchPicker/BranchPickerRoot.tsx
1155
- var import_react_primitive8 = require("@radix-ui/react-primitive");
1156
- var import_react31 = require("react");
1205
+ var import_react_primitive9 = require("@radix-ui/react-primitive");
1206
+ var import_react34 = require("react");
1157
1207
  var import_jsx_runtime16 = require("react/jsx-runtime");
1158
- var BranchPickerRoot = (0, import_react31.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
1159
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_primitive8.Primitive.div, { ...rest, ref }) });
1208
+ var BranchPickerRoot = (0, import_react34.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
1209
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_primitive9.Primitive.div, { ...rest, ref }) });
1160
1210
  });
1161
1211
  BranchPickerRoot.displayName = "BranchPickerRoot";
1162
1212
 
@@ -1170,8 +1220,8 @@ __export(actionBar_exports, {
1170
1220
  });
1171
1221
 
1172
1222
  // src/primitives/actionBar/ActionBarRoot.tsx
1173
- var import_react_primitive9 = require("@radix-ui/react-primitive");
1174
- var import_react32 = require("react");
1223
+ var import_react_primitive10 = require("@radix-ui/react-primitive");
1224
+ var import_react35 = require("react");
1175
1225
  var import_jsx_runtime17 = require("react/jsx-runtime");
1176
1226
  var useActionBarFloatStatus = ({
1177
1227
  hideWhenRunning,
@@ -1193,7 +1243,7 @@ var useActionBarFloatStatus = ({
1193
1243
  }
1194
1244
  );
1195
1245
  };
1196
- var ActionBarRoot = (0, import_react32.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1246
+ var ActionBarRoot = (0, import_react35.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1197
1247
  const hideAndfloatStatus = useActionBarFloatStatus({
1198
1248
  hideWhenRunning,
1199
1249
  autohide,
@@ -1201,7 +1251,7 @@ var ActionBarRoot = (0, import_react32.forwardRef)(({ hideWhenRunning, autohide,
1201
1251
  });
1202
1252
  if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
1203
1253
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1204
- import_react_primitive9.Primitive.div,
1254
+ import_react_primitive10.Primitive.div,
1205
1255
  {
1206
1256
  ...hideAndfloatStatus === "floating" /* Floating */ ? { "data-floating": "true" } : null,
1207
1257
  ...rest,
@@ -1239,17 +1289,17 @@ __export(contentPart_exports, {
1239
1289
  });
1240
1290
 
1241
1291
  // src/primitives/contentPart/ContentPartImage.tsx
1242
- var import_react_primitive10 = require("@radix-ui/react-primitive");
1243
- var import_react33 = require("react");
1292
+ var import_react_primitive11 = require("@radix-ui/react-primitive");
1293
+ var import_react36 = require("react");
1244
1294
  var import_jsx_runtime18 = require("react/jsx-runtime");
1245
- var ContentPartImage = (0, import_react33.forwardRef)((props, forwardedRef) => {
1295
+ var ContentPartImage = (0, import_react36.forwardRef)((props, forwardedRef) => {
1246
1296
  const image = useContentPartImage();
1247
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_primitive10.Primitive.img, { src: image, ...props, ref: forwardedRef });
1297
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_primitive11.Primitive.img, { src: image, ...props, ref: forwardedRef });
1248
1298
  });
1249
1299
  ContentPartImage.displayName = "ContentPartImage";
1250
1300
 
1251
1301
  // src/runtime/local/useLocalRuntime.tsx
1252
- var import_react34 = require("react");
1302
+ var import_react37 = require("react");
1253
1303
 
1254
1304
  // src/utils/ModelConfigTypes.ts
1255
1305
  var mergeModelConfigs = (configSet) => {
@@ -1535,18 +1585,18 @@ var LocalRuntime = class {
1535
1585
 
1536
1586
  // src/runtime/local/useLocalRuntime.tsx
1537
1587
  var useLocalRuntime = (adapter) => {
1538
- const [runtime] = (0, import_react34.useState)(() => new LocalRuntime(adapter));
1539
- (0, import_react34.useInsertionEffect)(() => {
1588
+ const [runtime] = (0, import_react37.useState)(() => new LocalRuntime(adapter));
1589
+ (0, import_react37.useInsertionEffect)(() => {
1540
1590
  runtime.adapter = adapter;
1541
1591
  });
1542
1592
  return runtime;
1543
1593
  };
1544
1594
 
1545
1595
  // src/context/providers/AssistantRuntimeProvider.tsx
1546
- var import_react37 = require("react");
1596
+ var import_react40 = require("react");
1547
1597
 
1548
1598
  // src/context/providers/AssistantProvider.tsx
1549
- var import_react36 = require("react");
1599
+ var import_react39 = require("react");
1550
1600
 
1551
1601
  // src/context/stores/AssistantModelConfig.ts
1552
1602
  var import_zustand5 = require("zustand");
@@ -1611,7 +1661,7 @@ var makeAssistantToolUIsStore = () => (0, import_zustand6.create)((set) => {
1611
1661
  });
1612
1662
 
1613
1663
  // src/context/providers/ThreadProvider.tsx
1614
- var import_react35 = require("react");
1664
+ var import_react38 = require("react");
1615
1665
 
1616
1666
  // src/context/stores/Composer.ts
1617
1667
  var import_zustand7 = require("zustand");
@@ -1624,6 +1674,7 @@ var makeComposerStore = (useThread, useThreadActions) => (0, import_zustand7.cre
1624
1674
  setValue("");
1625
1675
  useThreadActions.getState().append({
1626
1676
  parentId: useThread.getState().messages.at(-1)?.id ?? null,
1677
+ role: "user",
1627
1678
  content: [{ type: "text", text: value }]
1628
1679
  });
1629
1680
  },
@@ -1686,11 +1737,11 @@ var ThreadProvider = ({
1686
1737
  children,
1687
1738
  runtime
1688
1739
  }) => {
1689
- const runtimeRef = (0, import_react35.useRef)(runtime);
1690
- (0, import_react35.useInsertionEffect)(() => {
1740
+ const runtimeRef = (0, import_react38.useRef)(runtime);
1741
+ (0, import_react38.useInsertionEffect)(() => {
1691
1742
  runtimeRef.current = runtime;
1692
1743
  });
1693
- const [context] = (0, import_react35.useState)(() => {
1744
+ const [context] = (0, import_react38.useState)(() => {
1694
1745
  const useThread = makeThreadStore(runtimeRef);
1695
1746
  const useThreadActions = makeThreadActionStore(runtimeRef);
1696
1747
  const useViewport = makeThreadViewportStore();
@@ -1702,7 +1753,7 @@ var ThreadProvider = ({
1702
1753
  useViewport
1703
1754
  };
1704
1755
  });
1705
- (0, import_react35.useEffect)(() => {
1756
+ (0, import_react38.useEffect)(() => {
1706
1757
  const onRuntimeUpdate = () => {
1707
1758
  context.useThread.setState(
1708
1759
  Object.freeze({
@@ -1725,17 +1776,17 @@ var ThreadProvider = ({
1725
1776
  // src/context/providers/AssistantProvider.tsx
1726
1777
  var import_jsx_runtime20 = require("react/jsx-runtime");
1727
1778
  var AssistantProvider = ({ children, runtime }) => {
1728
- const runtimeRef = (0, import_react36.useRef)(runtime);
1729
- (0, import_react36.useInsertionEffect)(() => {
1779
+ const runtimeRef = (0, import_react39.useRef)(runtime);
1780
+ (0, import_react39.useInsertionEffect)(() => {
1730
1781
  runtimeRef.current = runtime;
1731
1782
  });
1732
- const [context] = (0, import_react36.useState)(() => {
1783
+ const [context] = (0, import_react39.useState)(() => {
1733
1784
  const useModelConfig = makeAssistantModelConfigStore();
1734
1785
  const useToolUIs = makeAssistantToolUIsStore();
1735
1786
  return { useModelConfig, useToolUIs };
1736
1787
  });
1737
1788
  const getModelCOnfig = context.useModelConfig((c) => c.getModelConfig);
1738
- (0, import_react36.useEffect)(() => {
1789
+ (0, import_react39.useEffect)(() => {
1739
1790
  return runtime.registerModelConfigProvider(getModelCOnfig);
1740
1791
  }, [runtime, getModelCOnfig]);
1741
1792
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ThreadProvider, { runtime, children }) });
@@ -1746,7 +1797,7 @@ var import_jsx_runtime21 = require("react/jsx-runtime");
1746
1797
  var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
1747
1798
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantProvider, { runtime, children });
1748
1799
  };
1749
- var AssistantRuntimeProvider = (0, import_react37.memo)(AssistantRuntimeProviderImpl);
1800
+ var AssistantRuntimeProvider = (0, import_react40.memo)(AssistantRuntimeProviderImpl);
1750
1801
 
1751
1802
  // src/internal.ts
1752
1803
  var internal_exports = {};