@assistant-ui/react 0.1.10 → 0.1.12

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.js CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
33
  ActionBarPrimitive: () => actionBar_exports,
34
+ AssistantModalPrimitive: () => assistantModal_exports,
34
35
  AssistantRuntimeProvider: () => AssistantRuntimeProvider,
35
36
  BranchPickerPrimitive: () => branchPicker_exports,
36
37
  ComposerPrimitive: () => composer_exports,
@@ -167,7 +168,7 @@ var useThreadContext = () => {
167
168
 
168
169
  // src/primitive-hooks/actionBar/useActionBarReload.tsx
169
170
  var useActionBarReload = () => {
170
- const { useThread, useThreadActions, useViewport } = useThreadContext();
171
+ const { useThread, useThreadActions, useComposer, useViewport } = useThreadContext();
171
172
  const { useMessage } = useMessageContext();
172
173
  const disabled = useCombinedStore(
173
174
  [useThread, useMessage],
@@ -177,7 +178,8 @@ var useActionBarReload = () => {
177
178
  const { parentId } = useMessage.getState();
178
179
  useThreadActions.getState().startRun(parentId);
179
180
  useViewport.getState().scrollToBottom();
180
- }, [useThreadActions, useMessage, useViewport]);
181
+ useComposer.getState().focus();
182
+ }, [useThreadActions, useComposer, useViewport, useMessage]);
181
183
  if (disabled) return null;
182
184
  return callback;
183
185
  };
@@ -300,12 +302,16 @@ var useComposerIf = (props) => {
300
302
  // src/primitive-hooks/composer/useComposerSend.tsx
301
303
  var import_react14 = require("react");
302
304
  var useComposerSend = () => {
305
+ const { useViewport, useComposer: useNewComposer } = useThreadContext();
303
306
  const { useComposer } = useComposerContext();
304
307
  const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
305
308
  const callback = (0, import_react14.useCallback)(() => {
306
- const { send } = useComposer.getState();
307
- send();
308
- }, [useComposer]);
309
+ const composerState = useComposer.getState();
310
+ if (!composerState.isEditing) return;
311
+ composerState.send();
312
+ useViewport.getState().scrollToBottom();
313
+ useNewComposer.getState().focus();
314
+ }, [useNewComposer, useComposer, useViewport]);
309
315
  if (disabled) return null;
310
316
  return callback;
311
317
  };
@@ -397,12 +403,12 @@ var useThreadEmpty = () => {
397
403
  // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
398
404
  var import_react15 = require("react");
399
405
  var useThreadScrollToBottom = () => {
400
- const { useViewport } = useThreadContext();
406
+ const { useComposer, useViewport } = useThreadContext();
401
407
  const isAtBottom = useViewport((s) => s.isAtBottom);
402
408
  const handleScrollToBottom = (0, import_react15.useCallback)(() => {
403
- const { scrollToBottom } = useViewport.getState();
404
- scrollToBottom();
405
- }, [useViewport]);
409
+ useViewport.getState().scrollToBottom();
410
+ useComposer.getState().focus();
411
+ }, [useViewport, useComposer]);
406
412
  if (isAtBottom) return null;
407
413
  return handleScrollToBottom;
408
414
  };
@@ -427,502 +433,242 @@ var useThreadSuggestion = ({
427
433
  return callback;
428
434
  };
429
435
 
430
- // src/primitives/thread/index.ts
431
- var thread_exports = {};
432
- __export(thread_exports, {
433
- Empty: () => ThreadEmpty,
434
- If: () => ThreadIf,
435
- Messages: () => ThreadMessages,
436
- Root: () => ThreadRoot,
437
- ScrollToBottom: () => ThreadScrollToBottom,
438
- Suggestion: () => ThreadSuggestion,
439
- Viewport: () => ThreadViewport
436
+ // src/primitives/actionBar/index.ts
437
+ var actionBar_exports = {};
438
+ __export(actionBar_exports, {
439
+ Copy: () => ActionBarCopy,
440
+ Edit: () => ActionBarEdit,
441
+ Reload: () => ActionBarReload,
442
+ Root: () => ActionBarRoot
440
443
  });
441
444
 
442
- // src/primitives/thread/ThreadRoot.tsx
445
+ // src/primitives/actionBar/ActionBarRoot.tsx
443
446
  var import_react_primitive = require("@radix-ui/react-primitive");
444
447
  var import_react17 = require("react");
445
448
  var import_jsx_runtime = require("react/jsx-runtime");
446
- var ThreadRoot = (0, import_react17.forwardRef)(
447
- (props, ref) => {
448
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { ...props, ref });
449
- }
450
- );
451
- ThreadRoot.displayName = "ThreadRoot";
452
-
453
- // src/primitives/thread/ThreadIf.tsx
454
- var ThreadIf = ({ children, ...query }) => {
455
- const result = useThreadIf(query);
456
- return result ? children : null;
457
- };
458
-
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 });
449
+ var useActionBarFloatStatus = ({
450
+ hideWhenRunning,
451
+ autohide,
452
+ autohideFloat
453
+ }) => {
454
+ const { useThread } = useThreadContext();
455
+ const { useMessage, useMessageUtils } = useMessageContext();
456
+ return useCombinedStore(
457
+ [useThread, useMessage, useMessageUtils],
458
+ (t, m, mu) => {
459
+ if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
460
+ const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
461
+ if (!autohideEnabled) return "normal" /* Normal */;
462
+ if (!mu.isHovering) return "hidden" /* Hidden */;
463
+ if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
464
+ return "floating" /* Floating */;
465
+ return "normal" /* Normal */;
466
+ }
467
+ );
463
468
  };
469
+ var ActionBarRoot = (0, import_react17.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
470
+ const hideAndfloatStatus = useActionBarFloatStatus({
471
+ hideWhenRunning,
472
+ autohide,
473
+ autohideFloat
474
+ });
475
+ if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
476
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
477
+ import_react_primitive.Primitive.div,
478
+ {
479
+ ...hideAndfloatStatus === "floating" /* Floating */ ? { "data-floating": "true" } : null,
480
+ ...rest,
481
+ ref
482
+ }
483
+ );
484
+ });
485
+ ActionBarRoot.displayName = "ActionBarRoot";
464
486
 
465
- // src/primitives/thread/ThreadViewport.tsx
487
+ // src/utils/createActionButton.tsx
466
488
  var import_primitive = require("@radix-ui/primitive");
467
- var import_react_compose_refs = require("@radix-ui/react-compose-refs");
468
489
  var import_react_primitive2 = require("@radix-ui/react-primitive");
469
- var import_react20 = require("react");
470
-
471
- // src/utils/hooks/useOnResizeContent.tsx
472
- var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
473
490
  var import_react18 = require("react");
474
- var useOnResizeContent = (ref, callback) => {
475
- 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);
487
- }
488
- }
489
- for (const node of mutation.removedNodes) {
490
- if (node instanceof Element) {
491
- resizeObserver.unobserve(node);
492
- }
493
- }
491
+ var import_jsx_runtime2 = require("react/jsx-runtime");
492
+ var createActionButton = (displayName, useActionButton) => {
493
+ const ActionButton = (0, import_react18.forwardRef)((props, forwardedRef) => {
494
+ const callback = useActionButton(props);
495
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
496
+ import_react_primitive2.Primitive.button,
497
+ {
498
+ type: "button",
499
+ disabled: !callback,
500
+ ...props,
501
+ ref: forwardedRef,
502
+ onClick: (0, import_primitive.composeEventHandlers)(props.onClick, () => {
503
+ callback?.();
504
+ })
494
505
  }
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]);
506
+ );
507
+ });
508
+ ActionButton.displayName = displayName;
509
+ return ActionButton;
507
510
  };
508
511
 
509
- // src/utils/hooks/useOnScrollToBottom.tsx
510
- var import_react_use_callback_ref2 = require("@radix-ui/react-use-callback-ref");
512
+ // src/primitives/actionBar/ActionBarCopy.tsx
513
+ var ActionBarCopy = createActionButton(
514
+ "ActionBarCopy",
515
+ useActionBarCopy
516
+ );
517
+
518
+ // src/primitives/actionBar/ActionBarReload.tsx
519
+ var ActionBarReload = createActionButton(
520
+ "ActionBarReload",
521
+ useActionBarReload
522
+ );
523
+
524
+ // src/primitives/actionBar/ActionBarEdit.tsx
525
+ var ActionBarEdit = createActionButton(
526
+ "ActionBarEdit",
527
+ useActionBarEdit
528
+ );
529
+
530
+ // src/primitives/assistantModal/index.ts
531
+ var assistantModal_exports = {};
532
+ __export(assistantModal_exports, {
533
+ Content: () => AssistantModalContent,
534
+ Root: () => AssistantModalRoot,
535
+ Trigger: () => AssistantModalTrigger
536
+ });
537
+
538
+ // src/primitives/assistantModal/AssistantModalRoot.tsx
539
+ var import_react20 = require("react");
540
+ var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"));
541
+ var import_primitive2 = require("@radix-ui/primitive");
542
+
543
+ // src/utils/hooks/useOnComposerFocus.tsx
544
+ var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
511
545
  var import_react19 = require("react");
512
- var useOnScrollToBottom = (callback) => {
513
- const callbackRef = (0, import_react_use_callback_ref2.useCallbackRef)(callback);
514
- const { useViewport } = useThreadContext();
546
+ var useOnComposerFocus = (callback) => {
547
+ const callbackRef = (0, import_react_use_callback_ref.useCallbackRef)(callback);
548
+ const { useComposer } = useThreadContext();
515
549
  (0, import_react19.useEffect)(() => {
516
- return useViewport.getState().onScrollToBottom(() => {
550
+ return useComposer.getState().onFocus(() => {
517
551
  callbackRef();
518
552
  });
519
- }, [useViewport, callbackRef]);
553
+ }, [useComposer, callbackRef]);
520
554
  };
521
555
 
522
- // src/primitives/thread/ThreadViewport.tsx
556
+ // src/primitives/assistantModal/AssistantModalRoot.tsx
523
557
  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);
528
- 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);
532
- const scrollToBottom = () => {
533
- const div = messagesEndRef.current;
534
- if (!div || !autoScroll) return;
535
- const behavior = firstRenderRef.current ? "instant" : "auto";
536
- firstRenderRef.current = false;
537
- isScrollingToBottomRef.current = true;
538
- div.scrollIntoView({ behavior });
539
- };
540
- useOnResizeContent(divRef, () => {
541
- if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom) {
542
- handleScroll();
543
- } else {
544
- scrollToBottom();
545
- }
546
- });
547
- useOnScrollToBottom(() => {
548
- scrollToBottom();
558
+ var usePopoverScope = PopoverPrimitive.createPopoverScope();
559
+ var useAssistantModalOpenState = (defaultOpen = false) => {
560
+ const state = (0, import_react20.useState)(defaultOpen);
561
+ const [, setOpen] = state;
562
+ useOnComposerFocus(() => {
563
+ setOpen(true);
549
564
  });
550
- const handleScroll = () => {
551
- const div = divRef.current;
552
- if (!div) return;
553
- const isAtBottom = useViewport.getState().isAtBottom;
554
- const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
555
- if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
556
- } else if (newIsAtBottom !== isAtBottom) {
557
- isScrollingToBottomRef.current = false;
558
- useViewport.setState({
559
- isAtBottom: newIsAtBottom
560
- });
561
- }
562
- lastScrollTop.current = div.scrollTop;
563
- };
564
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
565
- import_react_primitive2.Primitive.div,
565
+ return state;
566
+ };
567
+ var AssistantModalRoot = ({
568
+ __scopeAssistantModal,
569
+ defaultOpen,
570
+ open,
571
+ onOpenChange,
572
+ ...rest
573
+ }) => {
574
+ const scope = usePopoverScope(__scopeAssistantModal);
575
+ const [modalOpen, setOpen] = useAssistantModalOpenState(defaultOpen);
576
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
577
+ PopoverPrimitive.Root,
566
578
  {
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
- ]
579
+ ...scope,
580
+ open: open === void 0 ? modalOpen : open,
581
+ onOpenChange: (0, import_primitive2.composeEventHandlers)(onOpenChange, setOpen),
582
+ ...rest
574
583
  }
575
584
  );
576
- });
577
- ThreadViewport.displayName = "ThreadViewport";
578
-
579
- // src/primitives/thread/ThreadMessages.tsx
580
- var import_react22 = require("react");
585
+ };
586
+ AssistantModalRoot.displayName = "AssistantModalRoot";
581
587
 
582
- // src/context/providers/MessageProvider.tsx
588
+ // src/primitives/assistantModal/AssistantModalTrigger.tsx
583
589
  var import_react21 = require("react");
584
- var import_zustand3 = require("zustand");
585
-
586
- // src/context/stores/EditComposer.ts
587
- var import_zustand = require("zustand");
590
+ var PopoverPrimitive2 = __toESM(require("@radix-ui/react-popover"));
591
+ var import_jsx_runtime4 = require("react/jsx-runtime");
592
+ var AssistantModalTrigger = (0, import_react21.forwardRef)(
593
+ ({ __scopeAssistantModal, ...rest }, ref) => {
594
+ const scope = usePopoverScope(__scopeAssistantModal);
595
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PopoverPrimitive2.Trigger, { ...scope, ...rest, ref });
596
+ }
597
+ );
598
+ AssistantModalTrigger.displayName = "AssistantModalTrigger";
588
599
 
589
- // src/context/stores/BaseComposer.ts
590
- var makeBaseComposer = (set) => ({
591
- value: "",
592
- setValue: (value) => {
593
- set({ value });
600
+ // src/primitives/assistantModal/AssistantModalContent.tsx
601
+ var import_react22 = require("react");
602
+ var PopoverPrimitive3 = __toESM(require("@radix-ui/react-popover"));
603
+ var import_primitive3 = require("@radix-ui/primitive");
604
+ var import_jsx_runtime5 = require("react/jsx-runtime");
605
+ var AssistantModalContent = (0, import_react22.forwardRef)(
606
+ ({
607
+ __scopeAssistantModal,
608
+ side,
609
+ align,
610
+ onInteractOutside,
611
+ dissmissOnInteractOutside = false,
612
+ ...props
613
+ }, forwardedRef) => {
614
+ const scope = usePopoverScope(__scopeAssistantModal);
615
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PopoverPrimitive3.Portal, { ...scope, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
616
+ PopoverPrimitive3.Content,
617
+ {
618
+ ...scope,
619
+ ...props,
620
+ ref: forwardedRef,
621
+ side: side ?? "top",
622
+ align: align ?? "end",
623
+ onInteractOutside: (0, import_primitive3.composeEventHandlers)(
624
+ onInteractOutside,
625
+ dissmissOnInteractOutside ? void 0 : (e) => e.preventDefault()
626
+ )
627
+ }
628
+ ) });
594
629
  }
630
+ );
631
+ AssistantModalContent.displayName = "AssistantModalContent";
632
+
633
+ // src/primitives/branchPicker/index.ts
634
+ var branchPicker_exports = {};
635
+ __export(branchPicker_exports, {
636
+ Count: () => BranchPickerCount,
637
+ Next: () => BranchPickerNext,
638
+ Number: () => BranchPickerNumber,
639
+ Previous: () => BranchPickerPrevious,
640
+ Root: () => BranchPickerRoot
595
641
  });
596
642
 
597
- // src/context/stores/EditComposer.ts
598
- var makeEditComposerStore = ({
599
- onEdit,
600
- onSend
601
- }) => (0, import_zustand.create)()((set, get, store) => ({
602
- ...makeBaseComposer(set, get, store),
603
- isEditing: false,
604
- edit: () => {
605
- const value = onEdit();
606
- set({ isEditing: true, value });
607
- },
608
- send: () => {
609
- const value = get().value;
610
- set({ isEditing: false });
611
- onSend(value);
612
- },
613
- cancel: () => {
614
- if (!get().isEditing) return false;
615
- set({ isEditing: false });
616
- return true;
617
- }
618
- }));
643
+ // src/primitives/branchPicker/BranchPickerNext.tsx
644
+ var BranchPickerNext = createActionButton(
645
+ "BranchPickerNext",
646
+ useBranchPickerNext
647
+ );
619
648
 
620
- // src/context/stores/MessageUtils.ts
621
- var import_zustand2 = require("zustand");
622
- var makeMessageUtilsStore = () => (0, import_zustand2.create)((set) => ({
623
- inProgressIndicator: null,
624
- setInProgressIndicator: (value) => {
625
- set({ inProgressIndicator: value });
626
- },
627
- isCopied: false,
628
- setIsCopied: (value) => {
629
- set({ isCopied: value });
630
- },
631
- isHovering: false,
632
- setIsHovering: (value) => {
633
- set({ isHovering: value });
634
- }
635
- }));
649
+ // src/primitives/branchPicker/BranchPickerPrevious.tsx
650
+ var BranchPickerPrevious = createActionButton(
651
+ "BranchPickerPrevious",
652
+ useBranchPickerPrevious
653
+ );
636
654
 
637
- // src/context/providers/MessageProvider.tsx
638
- var import_jsx_runtime4 = require("react/jsx-runtime");
639
- var getIsLast = (thread, message) => {
640
- return thread.messages[thread.messages.length - 1]?.id === message.id;
655
+ // src/primitives/branchPicker/BranchPickerCount.tsx
656
+ var import_jsx_runtime6 = require("react/jsx-runtime");
657
+ var BranchPickerCount = () => {
658
+ const branchCount = useBranchPickerCount();
659
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: branchCount });
641
660
  };
642
- var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
643
- const parentId = thread.messages[messageIndex - 1]?.id ?? null;
644
- const message = thread.messages[messageIndex];
645
- if (!message) return;
646
- const isLast = getIsLast(thread, message);
647
- const branches = getBranches(message.id);
648
- const currentState = useMessage.getState();
649
- if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
650
- return;
651
- useMessage.setState({
652
- message,
653
- parentId,
654
- branches,
655
- isLast
656
- });
657
- };
658
- var useMessageContext2 = (messageIndex) => {
659
- const { useThread, useThreadActions } = useThreadContext();
660
- const [context] = (0, import_react21.useState)(() => {
661
- const useMessage = (0, import_zustand3.create)(() => ({}));
662
- const useMessageUtils = makeMessageUtilsStore();
663
- const useEditComposer = makeEditComposerStore({
664
- onEdit: () => {
665
- const message = useMessage.getState().message;
666
- if (message.role !== "user")
667
- throw new Error(
668
- "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
669
- );
670
- const text = getMessageText(message);
671
- return text;
672
- },
673
- onSend: (text) => {
674
- const { message, parentId } = useMessage.getState();
675
- if (message.role !== "user")
676
- throw new Error(
677
- "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
678
- );
679
- const nonTextParts = message.content.filter(
680
- (part) => part.type !== "text" && part.type !== "ui"
681
- );
682
- useThreadActions.getState().append({
683
- parentId,
684
- content: [{ type: "text", text }, ...nonTextParts]
685
- });
686
- }
687
- });
688
- syncMessage(
689
- useThread.getState(),
690
- useThreadActions.getState().getBranches,
691
- useMessage,
692
- messageIndex
693
- );
694
- return { useMessage, useMessageUtils, useEditComposer };
695
- });
696
- (0, import_react21.useEffect)(() => {
697
- return useThread.subscribe((thread) => {
698
- syncMessage(
699
- thread,
700
- useThreadActions.getState().getBranches,
701
- context.useMessage,
702
- messageIndex
703
- );
704
- });
705
- }, [useThread, useThreadActions, context, messageIndex]);
706
- return context;
707
- };
708
- var MessageProvider = ({
709
- messageIndex,
710
- children
711
- }) => {
712
- const context = useMessageContext2(messageIndex);
713
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MessageContext.Provider, { value: context, children });
714
- };
715
-
716
- // src/primitives/composer/ComposerIf.tsx
717
- var ComposerIf = ({ children, ...query }) => {
718
- const result = useComposerIf(query);
719
- return result ? children : null;
720
- };
721
-
722
- // src/primitives/message/MessageIf.tsx
723
- var MessageIf = ({ children, ...query }) => {
724
- const result = useMessageIf(query);
725
- return result ? children : null;
726
- };
727
-
728
- // src/primitives/thread/ThreadMessages.tsx
729
- var import_jsx_runtime5 = require("react/jsx-runtime");
730
- var getComponents = (components) => {
731
- return {
732
- EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
733
- UserMessage: components.UserMessage ?? components.Message,
734
- AssistantMessage: components.AssistantMessage ?? components.Message
735
- };
736
- };
737
- var ThreadMessageImpl = ({
738
- messageIndex,
739
- components
740
- }) => {
741
- 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, {}) })
746
- ] }),
747
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantMessage, {}) })
748
- ] });
749
- };
750
- var ThreadMessage = (0, import_react22.memo)(
751
- ThreadMessageImpl,
752
- (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
- );
754
- var ThreadMessages = ({ components }) => {
755
- const { useThread } = useThreadContext();
756
- const messagesLength = useThread((t) => t.messages.length);
757
- if (messagesLength === 0) return null;
758
- return new Array(messagesLength).fill(null).map((_, idx) => {
759
- const messageIndex = idx;
760
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
761
- ThreadMessage,
762
- {
763
- messageIndex,
764
- components
765
- },
766
- messageIndex
767
- );
768
- });
769
- };
770
-
771
- // src/utils/createActionButton.tsx
772
- var import_primitive2 = require("@radix-ui/primitive");
773
- var import_react_primitive3 = require("@radix-ui/react-primitive");
774
- var import_react23 = require("react");
775
- var import_jsx_runtime6 = require("react/jsx-runtime");
776
- var createActionButton = (displayName, useActionButton) => {
777
- const ActionButton = (0, import_react23.forwardRef)((props, forwardedRef) => {
778
- const callback = useActionButton(props);
779
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
780
- import_react_primitive3.Primitive.button,
781
- {
782
- type: "button",
783
- disabled: !callback,
784
- ...props,
785
- ref: forwardedRef,
786
- onClick: (0, import_primitive2.composeEventHandlers)(props.onClick, () => {
787
- callback?.();
788
- })
789
- }
790
- );
791
- });
792
- ActionButton.displayName = displayName;
793
- return ActionButton;
794
- };
795
-
796
- // src/primitives/thread/ThreadScrollToBottom.tsx
797
- var ThreadScrollToBottom = createActionButton(
798
- "ThreadScrollToBottom",
799
- useThreadScrollToBottom
800
- );
801
-
802
- // src/primitives/thread/ThreadSuggestion.tsx
803
- var ThreadSuggestion = createActionButton(
804
- "ThreadSuggestion",
805
- useThreadSuggestion
806
- );
807
-
808
- // src/primitives/composer/index.ts
809
- var composer_exports = {};
810
- __export(composer_exports, {
811
- Cancel: () => ComposerCancel,
812
- If: () => ComposerIf,
813
- Input: () => ComposerInput,
814
- Root: () => ComposerRoot,
815
- Send: () => ComposerSend
816
- });
817
661
 
818
- // 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");
821
- var import_react_primitive4 = require("@radix-ui/react-primitive");
822
- var import_react24 = require("react");
662
+ // src/primitives/branchPicker/BranchPickerNumber.tsx
823
663
  var import_jsx_runtime7 = require("react/jsx-runtime");
824
- var ComposerRoot = (0, import_react24.forwardRef)(
825
- ({ 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);
830
- const handleSubmit = (e) => {
831
- const composerState = useComposer.getState();
832
- if (!composerState.isEditing) return;
833
- e.preventDefault();
834
- composerState.send();
835
- useViewport.getState().scrollToBottom();
836
- };
837
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
838
- import_react_primitive4.Primitive.form,
839
- {
840
- ...rest,
841
- ref,
842
- onSubmit: (0, import_primitive3.composeEventHandlers)(onSubmit, handleSubmit)
843
- }
844
- );
845
- }
846
- );
847
- ComposerRoot.displayName = "ComposerRoot";
848
-
849
- // src/primitives/composer/ComposerInput.tsx
850
- var import_primitive4 = require("@radix-ui/primitive");
851
- var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
852
- var import_react_slot = require("@radix-ui/react-slot");
853
- var import_react25 = require("react");
854
- 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)(
857
- ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
858
- const { useThread } = useThreadContext();
859
- const { useComposer, type } = useComposerContext();
860
- const value = useComposer((c) => {
861
- if (!c.isEditing) return "";
862
- return c.value;
863
- });
864
- const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
865
- const textareaRef = (0, import_react25.useRef)(null);
866
- const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, textareaRef);
867
- const handleKeyPress = (e) => {
868
- 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) {
875
- const isRunning = useThread.getState().isRunning;
876
- if (!isRunning) {
877
- e.preventDefault();
878
- textareaRef.current?.closest("form")?.requestSubmit();
879
- }
880
- }
881
- };
882
- const autoFocusEnabled = autoFocus && !disabled;
883
- const focus = (0, import_react25.useCallback)(() => {
884
- const textarea = textareaRef.current;
885
- if (!textarea || !autoFocusEnabled) return;
886
- textarea.focus();
887
- textarea.setSelectionRange(
888
- textareaRef.current.value.length,
889
- textareaRef.current.value.length
890
- );
891
- }, [autoFocusEnabled]);
892
- (0, import_react25.useEffect)(() => focus(), [focus]);
893
- useOnScrollToBottom(() => {
894
- if (type === "new") {
895
- focus();
896
- }
897
- });
898
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
899
- Component,
900
- {
901
- value,
902
- ...rest,
903
- ref,
904
- autoFocus,
905
- disabled,
906
- onChange: (0, import_primitive4.composeEventHandlers)(onChange, (e) => {
907
- const composerState = useComposer.getState();
908
- if (!composerState.isEditing) return;
909
- return composerState.setValue(e.target.value);
910
- }),
911
- onKeyDown: (0, import_primitive4.composeEventHandlers)(onKeyDown, handleKeyPress)
912
- }
913
- );
914
- }
915
- );
916
- ComposerInput.displayName = "ComposerInput";
917
-
918
- // src/primitives/composer/ComposerSend.tsx
919
- var ComposerSend = createActionButton("ComposerSend", useComposerSend);
664
+ var BranchPickerNumber = () => {
665
+ const branchNumber = useBranchPickerNumber();
666
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: branchNumber });
667
+ };
920
668
 
921
- // src/primitives/composer/ComposerCancel.tsx
922
- var ComposerCancel = createActionButton(
923
- "ComposerCancel",
924
- useComposerCancel
925
- );
669
+ // src/primitives/branchPicker/BranchPickerRoot.tsx
670
+ var import_react_primitive6 = require("@radix-ui/react-primitive");
671
+ var import_react28 = require("react");
926
672
 
927
673
  // src/primitives/message/index.ts
928
674
  var message_exports = {};
@@ -934,11 +680,11 @@ __export(message_exports, {
934
680
  });
935
681
 
936
682
  // 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");
940
- var import_jsx_runtime9 = require("react/jsx-runtime");
941
- var MessageRoot = (0, import_react26.forwardRef)(
683
+ var import_primitive4 = require("@radix-ui/primitive");
684
+ var import_react_primitive3 = require("@radix-ui/react-primitive");
685
+ var import_react23 = require("react");
686
+ var import_jsx_runtime8 = require("react/jsx-runtime");
687
+ var MessageRoot = (0, import_react23.forwardRef)(
942
688
  ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
943
689
  const { useMessageUtils } = useMessageContext();
944
690
  const setIsHovering = useMessageUtils((s) => s.setIsHovering);
@@ -948,26 +694,32 @@ var MessageRoot = (0, import_react26.forwardRef)(
948
694
  const handleMouseLeave = () => {
949
695
  setIsHovering(false);
950
696
  };
951
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
952
- import_react_primitive5.Primitive.div,
697
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
698
+ import_react_primitive3.Primitive.div,
953
699
  {
954
700
  ...rest,
955
701
  ref,
956
- onMouseEnter: (0, import_primitive5.composeEventHandlers)(onMouseEnter, handleMouseEnter),
957
- onMouseLeave: (0, import_primitive5.composeEventHandlers)(onMouseLeave, handleMouseLeave)
702
+ onMouseEnter: (0, import_primitive4.composeEventHandlers)(onMouseEnter, handleMouseEnter),
703
+ onMouseLeave: (0, import_primitive4.composeEventHandlers)(onMouseLeave, handleMouseLeave)
958
704
  }
959
705
  );
960
706
  }
961
707
  );
962
708
  MessageRoot.displayName = "MessageRoot";
963
709
 
964
- // src/primitives/message/MessageContent.tsx
965
- var import_react29 = require("react");
710
+ // src/primitives/message/MessageIf.tsx
711
+ var MessageIf = ({ children, ...query }) => {
712
+ const result = useMessageIf(query);
713
+ return result ? children : null;
714
+ };
715
+
716
+ // src/primitives/message/MessageContent.tsx
717
+ var import_react26 = require("react");
966
718
 
967
719
  // src/context/providers/ContentPartProvider.tsx
968
- var import_react27 = require("react");
969
- var import_zustand4 = require("zustand");
970
- var import_jsx_runtime10 = require("react/jsx-runtime");
720
+ var import_react24 = require("react");
721
+ var import_zustand = require("zustand");
722
+ var import_jsx_runtime9 = require("react/jsx-runtime");
971
723
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
972
724
  const part = message.content[partIndex];
973
725
  if (!part) return;
@@ -984,14 +736,14 @@ var syncContentPart = ({ message }, useContentPart, partIndex) => {
984
736
  };
985
737
  var useContentPartContext2 = (partIndex) => {
986
738
  const { useMessage } = useMessageContext();
987
- const [context] = (0, import_react27.useState)(() => {
988
- const useContentPart = (0, import_zustand4.create)(
739
+ const [context] = (0, import_react24.useState)(() => {
740
+ const useContentPart = (0, import_zustand.create)(
989
741
  () => ({})
990
742
  );
991
743
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
992
744
  return { useContentPart };
993
745
  });
994
- (0, import_react27.useEffect)(() => {
746
+ (0, import_react24.useEffect)(() => {
995
747
  syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
996
748
  return useMessage.subscribe((message) => {
997
749
  syncContentPart(message, context.useContentPart, partIndex);
@@ -1004,7 +756,7 @@ var ContentPartProvider = ({
1004
756
  children
1005
757
  }) => {
1006
758
  const context = useContentPartContext2(partIndex);
1007
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ContentPartContext.Provider, { value: context, children });
759
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ContentPartContext.Provider, { value: context, children });
1008
760
  };
1009
761
 
1010
762
  // src/primitives/contentPart/ContentPartDisplay.tsx
@@ -1012,244 +764,649 @@ var ContentPartDisplay = () => {
1012
764
  const display = useContentPartDisplay();
1013
765
  return display ?? null;
1014
766
  };
1015
-
1016
- // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
1017
- var ContentPartInProgressIndicator = () => {
1018
- const indicator = useContentPartInProgressIndicator();
1019
- return indicator;
767
+
768
+ // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
769
+ var ContentPartInProgressIndicator = () => {
770
+ const indicator = useContentPartInProgressIndicator();
771
+ return indicator;
772
+ };
773
+
774
+ // src/primitives/contentPart/ContentPartText.tsx
775
+ var import_react_primitive4 = require("@radix-ui/react-primitive");
776
+ var import_react25 = require("react");
777
+ var import_jsx_runtime10 = require("react/jsx-runtime");
778
+ var ContentPartText = (0, import_react25.forwardRef)((props, forwardedRef) => {
779
+ const text = useContentPartText();
780
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_primitive4.Primitive.span, { ...props, ref: forwardedRef, children: text });
781
+ });
782
+ ContentPartText.displayName = "ContentPartText";
783
+
784
+ // src/primitives/message/MessageContent.tsx
785
+ var import_jsx_runtime11 = require("react/jsx-runtime");
786
+ var defaultComponents = {
787
+ Text: () => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
788
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ContentPartText, {}),
789
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ContentPartInProgressIndicator, {})
790
+ ] }),
791
+ Image: () => null,
792
+ UI: () => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ContentPartDisplay, {}),
793
+ tools: {
794
+ Fallback: (props) => {
795
+ const { useToolUIs } = useAssistantContext();
796
+ const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
797
+ if (!Render) return null;
798
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Render, { ...props });
799
+ }
800
+ }
801
+ };
802
+ var MessageContentPartComponent = ({
803
+ components: {
804
+ Text = defaultComponents.Text,
805
+ Image = defaultComponents.Image,
806
+ UI = defaultComponents.UI,
807
+ tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
808
+ } = {}
809
+ }) => {
810
+ const { useThreadActions } = useThreadContext();
811
+ const addToolResult = useThreadActions((t) => t.addToolResult);
812
+ const { useContentPart } = useContentPartContext();
813
+ const { part, status } = useContentPart();
814
+ const type = part.type;
815
+ switch (type) {
816
+ case "text":
817
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { part, status });
818
+ case "image":
819
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Image, { part, status });
820
+ case "ui":
821
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(UI, { part, status });
822
+ case "tool-call": {
823
+ const Tool = by_name[part.toolName] || Fallback;
824
+ const addResult = (result) => addToolResult(part.toolCallId, result);
825
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Tool, { part, status, addResult });
826
+ }
827
+ default:
828
+ throw new Error(`Unknown content part type: ${type}`);
829
+ }
830
+ };
831
+ var MessageContentPartImpl = ({
832
+ partIndex,
833
+ components
834
+ }) => {
835
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ContentPartProvider, { partIndex, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MessageContentPartComponent, { components }) });
836
+ };
837
+ var MessageContentPart = (0, import_react26.memo)(
838
+ MessageContentPartImpl,
839
+ (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
840
+ );
841
+ var MessageContent = ({ components }) => {
842
+ const { useMessage } = useMessageContext();
843
+ const contentLength = useMessage((s) => s.message.content.length);
844
+ return new Array(contentLength).fill(null).map((_, idx) => {
845
+ const partIndex = idx;
846
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
847
+ MessageContentPart,
848
+ {
849
+ partIndex,
850
+ components
851
+ },
852
+ partIndex
853
+ );
854
+ });
855
+ };
856
+
857
+ // src/primitives/message/MessageInProgress.tsx
858
+ var import_react_primitive5 = require("@radix-ui/react-primitive");
859
+ var import_react27 = require("react");
860
+ var import_jsx_runtime12 = require("react/jsx-runtime");
861
+ var MessageInProgress = (0, import_react27.forwardRef)((props, ref) => {
862
+ const { useMessageUtils } = useMessageContext();
863
+ (0, import_react27.useMemo)(() => {
864
+ useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_primitive5.Primitive.span, { ...props, ref }));
865
+ }, [useMessageUtils, props, ref]);
866
+ return null;
867
+ });
868
+ MessageInProgress.displayName = "MessageInProgress";
869
+
870
+ // src/primitives/branchPicker/BranchPickerRoot.tsx
871
+ var import_jsx_runtime13 = require("react/jsx-runtime");
872
+ var BranchPickerRoot = (0, import_react28.forwardRef)(({ hideWhenSingleBranch, ...rest }, ref) => {
873
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_primitive6.Primitive.div, { ...rest, ref }) });
874
+ });
875
+ BranchPickerRoot.displayName = "BranchPickerRoot";
876
+
877
+ // src/primitives/composer/index.ts
878
+ var composer_exports = {};
879
+ __export(composer_exports, {
880
+ Cancel: () => ComposerCancel,
881
+ If: () => ComposerIf,
882
+ Input: () => ComposerInput,
883
+ Root: () => ComposerRoot,
884
+ Send: () => ComposerSend
885
+ });
886
+
887
+ // src/primitives/composer/ComposerRoot.tsx
888
+ var import_primitive5 = require("@radix-ui/primitive");
889
+ var import_react_primitive7 = require("@radix-ui/react-primitive");
890
+ var import_react29 = require("react");
891
+ var import_jsx_runtime14 = require("react/jsx-runtime");
892
+ var ComposerRoot = (0, import_react29.forwardRef)(
893
+ ({ onSubmit, ...rest }, forwardedRef) => {
894
+ const send = useComposerSend();
895
+ const handleSubmit = (e) => {
896
+ if (!send) return;
897
+ e.preventDefault();
898
+ send();
899
+ };
900
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
901
+ import_react_primitive7.Primitive.form,
902
+ {
903
+ ...rest,
904
+ ref: forwardedRef,
905
+ onSubmit: (0, import_primitive5.composeEventHandlers)(onSubmit, handleSubmit)
906
+ }
907
+ );
908
+ }
909
+ );
910
+ ComposerRoot.displayName = "ComposerRoot";
911
+
912
+ // src/primitives/composer/ComposerInput.tsx
913
+ var import_primitive6 = require("@radix-ui/primitive");
914
+ var import_react_compose_refs = require("@radix-ui/react-compose-refs");
915
+ var import_react_slot = require("@radix-ui/react-slot");
916
+ var import_react30 = require("react");
917
+ var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"));
918
+ var import_react_use_escape_keydown = require("@radix-ui/react-use-escape-keydown");
919
+ var import_jsx_runtime15 = require("react/jsx-runtime");
920
+ var ComposerInput = (0, import_react30.forwardRef)(
921
+ ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
922
+ const { useThread } = useThreadContext();
923
+ const { useComposer, type } = useComposerContext();
924
+ const value = useComposer((c) => {
925
+ if (!c.isEditing) return "";
926
+ return c.value;
927
+ });
928
+ const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
929
+ const textareaRef = (0, import_react30.useRef)(null);
930
+ const ref = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, textareaRef);
931
+ (0, import_react_use_escape_keydown.useEscapeKeydown)((e) => {
932
+ const composer = useComposer.getState();
933
+ if (composer.cancel()) {
934
+ e.preventDefault();
935
+ }
936
+ });
937
+ const handleKeyPress = (e) => {
938
+ if (disabled) return;
939
+ if (e.key === "Enter" && e.shiftKey === false) {
940
+ const isRunning = useThread.getState().isRunning;
941
+ if (!isRunning) {
942
+ e.preventDefault();
943
+ textareaRef.current?.closest("form")?.requestSubmit();
944
+ }
945
+ }
946
+ };
947
+ const autoFocusEnabled = autoFocus && !disabled;
948
+ const focus = (0, import_react30.useCallback)(() => {
949
+ const textarea = textareaRef.current;
950
+ if (!textarea || !autoFocusEnabled) return;
951
+ textarea.focus({ preventScroll: true });
952
+ textarea.setSelectionRange(
953
+ textareaRef.current.value.length,
954
+ textareaRef.current.value.length
955
+ );
956
+ }, [autoFocusEnabled]);
957
+ (0, import_react30.useEffect)(() => focus(), [focus]);
958
+ useOnComposerFocus(() => {
959
+ if (type === "new") {
960
+ focus();
961
+ }
962
+ });
963
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
964
+ Component,
965
+ {
966
+ value,
967
+ ...rest,
968
+ ref,
969
+ disabled,
970
+ onChange: (0, import_primitive6.composeEventHandlers)(onChange, (e) => {
971
+ const composerState = useComposer.getState();
972
+ if (!composerState.isEditing) return;
973
+ return composerState.setValue(e.target.value);
974
+ }),
975
+ onKeyDown: (0, import_primitive6.composeEventHandlers)(onKeyDown, handleKeyPress)
976
+ }
977
+ );
978
+ }
979
+ );
980
+ ComposerInput.displayName = "ComposerInput";
981
+
982
+ // src/primitives/composer/ComposerSend.tsx
983
+ var import_react31 = require("react");
984
+ var import_react_primitive8 = require("@radix-ui/react-primitive");
985
+ var import_jsx_runtime16 = require("react/jsx-runtime");
986
+ var ComposerSend = (0, import_react31.forwardRef)(
987
+ ({ disabled, ...rest }, ref) => {
988
+ const { useComposer } = useComposerContext();
989
+ const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
990
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
991
+ import_react_primitive8.Primitive.button,
992
+ {
993
+ type: "submit",
994
+ ...rest,
995
+ ref,
996
+ disabled: disabled || !hasValue
997
+ }
998
+ );
999
+ }
1000
+ );
1001
+ ComposerSend.displayName = "ComposerSend";
1002
+
1003
+ // src/primitives/composer/ComposerCancel.tsx
1004
+ var ComposerCancel = createActionButton(
1005
+ "ComposerCancel",
1006
+ useComposerCancel
1007
+ );
1008
+
1009
+ // src/primitives/composer/ComposerIf.tsx
1010
+ var ComposerIf = ({ children, ...query }) => {
1011
+ const result = useComposerIf(query);
1012
+ return result ? children : null;
1013
+ };
1014
+
1015
+ // src/primitives/contentPart/index.ts
1016
+ var contentPart_exports = {};
1017
+ __export(contentPart_exports, {
1018
+ Display: () => ContentPartDisplay,
1019
+ Image: () => ContentPartImage,
1020
+ InProgressIndicator: () => ContentPartInProgressIndicator,
1021
+ Text: () => ContentPartText
1022
+ });
1023
+
1024
+ // src/primitives/contentPart/ContentPartImage.tsx
1025
+ var import_react_primitive9 = require("@radix-ui/react-primitive");
1026
+ var import_react32 = require("react");
1027
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1028
+ var ContentPartImage = (0, import_react32.forwardRef)((props, forwardedRef) => {
1029
+ const image = useContentPartImage();
1030
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_primitive9.Primitive.img, { src: image, ...props, ref: forwardedRef });
1031
+ });
1032
+ ContentPartImage.displayName = "ContentPartImage";
1033
+
1034
+ // src/primitives/thread/index.ts
1035
+ var thread_exports = {};
1036
+ __export(thread_exports, {
1037
+ Empty: () => ThreadEmpty,
1038
+ If: () => ThreadIf,
1039
+ Messages: () => ThreadMessages,
1040
+ Root: () => ThreadRoot,
1041
+ ScrollToBottom: () => ThreadScrollToBottom,
1042
+ Suggestion: () => ThreadSuggestion,
1043
+ Viewport: () => ThreadViewport
1044
+ });
1045
+
1046
+ // src/primitives/thread/ThreadRoot.tsx
1047
+ var import_react_primitive10 = require("@radix-ui/react-primitive");
1048
+ var import_react33 = require("react");
1049
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1050
+ var ThreadRoot = (0, import_react33.forwardRef)(
1051
+ (props, ref) => {
1052
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_primitive10.Primitive.div, { ...props, ref });
1053
+ }
1054
+ );
1055
+ ThreadRoot.displayName = "ThreadRoot";
1056
+
1057
+ // src/primitives/thread/ThreadEmpty.tsx
1058
+ var ThreadEmpty = ({ children }) => {
1059
+ const empty = useThreadEmpty();
1060
+ return empty ? children : null;
1061
+ };
1062
+
1063
+ // src/primitives/thread/ThreadIf.tsx
1064
+ var ThreadIf = ({ children, ...query }) => {
1065
+ const result = useThreadIf(query);
1066
+ return result ? children : null;
1067
+ };
1068
+
1069
+ // src/primitives/thread/ThreadViewport.tsx
1070
+ var import_react_compose_refs3 = require("@radix-ui/react-compose-refs");
1071
+ var import_react_primitive11 = require("@radix-ui/react-primitive");
1072
+ var import_react38 = require("react");
1073
+
1074
+ // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1075
+ var import_react_compose_refs2 = require("@radix-ui/react-compose-refs");
1076
+ var import_react37 = require("react");
1077
+
1078
+ // src/utils/hooks/useOnResizeContent.tsx
1079
+ var import_react_use_callback_ref2 = require("@radix-ui/react-use-callback-ref");
1080
+ var import_react35 = require("react");
1081
+
1082
+ // src/utils/hooks/useManagedRef.ts
1083
+ var import_react34 = require("react");
1084
+ var useManagedRef = (callback) => {
1085
+ const cleanupRef = (0, import_react34.useRef)();
1086
+ const ref = (0, import_react34.useCallback)(
1087
+ (el) => {
1088
+ if (cleanupRef.current) {
1089
+ cleanupRef.current();
1090
+ }
1091
+ if (el) {
1092
+ cleanupRef.current = callback(el);
1093
+ }
1094
+ },
1095
+ [callback]
1096
+ );
1097
+ return ref;
1098
+ };
1099
+
1100
+ // src/utils/hooks/useOnResizeContent.tsx
1101
+ var useOnResizeContent = (callback) => {
1102
+ const callbackRef = (0, import_react_use_callback_ref2.useCallbackRef)(callback);
1103
+ const refCallback = (0, import_react35.useCallback)(
1104
+ (el) => {
1105
+ const resizeObserver = new ResizeObserver(() => {
1106
+ callbackRef();
1107
+ });
1108
+ const mutationObserver = new MutationObserver((mutations) => {
1109
+ for (const mutation of mutations) {
1110
+ for (const node of mutation.addedNodes) {
1111
+ if (node instanceof Element) {
1112
+ resizeObserver.observe(node);
1113
+ }
1114
+ }
1115
+ for (const node of mutation.removedNodes) {
1116
+ if (node instanceof Element) {
1117
+ resizeObserver.unobserve(node);
1118
+ }
1119
+ }
1120
+ }
1121
+ callbackRef();
1122
+ });
1123
+ resizeObserver.observe(el);
1124
+ mutationObserver.observe(el, { childList: true });
1125
+ for (const child of el.children) {
1126
+ resizeObserver.observe(child);
1127
+ }
1128
+ return () => {
1129
+ resizeObserver.disconnect();
1130
+ mutationObserver.disconnect();
1131
+ };
1132
+ },
1133
+ [callbackRef]
1134
+ );
1135
+ return useManagedRef(refCallback);
1136
+ };
1137
+
1138
+ // src/utils/hooks/useOnScrollToBottom.tsx
1139
+ var import_react_use_callback_ref3 = require("@radix-ui/react-use-callback-ref");
1140
+ var import_react36 = require("react");
1141
+ var useOnScrollToBottom = (callback) => {
1142
+ const callbackRef = (0, import_react_use_callback_ref3.useCallbackRef)(callback);
1143
+ const { useViewport } = useThreadContext();
1144
+ (0, import_react36.useEffect)(() => {
1145
+ return useViewport.getState().onScrollToBottom(() => {
1146
+ callbackRef();
1147
+ });
1148
+ }, [useViewport, callbackRef]);
1149
+ };
1150
+
1151
+ // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1152
+ var useThreadViewportAutoScroll = ({
1153
+ autoScroll = true
1154
+ }) => {
1155
+ const divRef = (0, import_react37.useRef)(null);
1156
+ const { useViewport } = useThreadContext();
1157
+ const firstRenderRef = (0, import_react37.useRef)(true);
1158
+ const lastScrollTop = (0, import_react37.useRef)(0);
1159
+ const isScrollingToBottomRef = (0, import_react37.useRef)(false);
1160
+ const scrollToBottom = () => {
1161
+ const div = divRef.current;
1162
+ if (!div || !autoScroll) return;
1163
+ const behavior = firstRenderRef.current ? "instant" : "auto";
1164
+ firstRenderRef.current = false;
1165
+ isScrollingToBottomRef.current = true;
1166
+ div.scrollTo({ top: div.scrollHeight, behavior });
1167
+ };
1168
+ const handleScroll = () => {
1169
+ const div = divRef.current;
1170
+ if (!div) return;
1171
+ const isAtBottom = useViewport.getState().isAtBottom;
1172
+ const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
1173
+ if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
1174
+ } else {
1175
+ isScrollingToBottomRef.current = newIsAtBottom;
1176
+ if (newIsAtBottom !== isAtBottom) {
1177
+ useViewport.setState({
1178
+ isAtBottom: newIsAtBottom
1179
+ });
1180
+ }
1181
+ }
1182
+ lastScrollTop.current = div.scrollTop;
1183
+ };
1184
+ const resizeRef = useOnResizeContent(() => {
1185
+ if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom && !firstRenderRef.current) {
1186
+ handleScroll();
1187
+ } else {
1188
+ scrollToBottom();
1189
+ }
1190
+ });
1191
+ const scrollRef = useManagedRef((el) => {
1192
+ el.addEventListener("scroll", handleScroll);
1193
+ return () => {
1194
+ el.removeEventListener("scroll", handleScroll);
1195
+ };
1196
+ });
1197
+ const autoScrollRef = (0, import_react_compose_refs2.useComposedRefs)(resizeRef, scrollRef, divRef);
1198
+ useOnScrollToBottom(() => {
1199
+ scrollToBottom();
1200
+ });
1201
+ return autoScrollRef;
1202
+ };
1203
+
1204
+ // src/primitives/thread/ThreadViewport.tsx
1205
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1206
+ var ThreadViewport = (0, import_react38.forwardRef)(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
1207
+ const autoScrollRef = useThreadViewportAutoScroll({
1208
+ autoScroll
1209
+ });
1210
+ const ref = (0, import_react_compose_refs3.useComposedRefs)(forwardedRef, autoScrollRef);
1211
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_primitive11.Primitive.div, { ...rest, ref, children });
1212
+ });
1213
+ ThreadViewport.displayName = "ThreadViewport";
1214
+
1215
+ // src/primitives/thread/ThreadMessages.tsx
1216
+ var import_react40 = require("react");
1217
+
1218
+ // src/context/providers/MessageProvider.tsx
1219
+ var import_react39 = require("react");
1220
+ var import_zustand4 = require("zustand");
1221
+
1222
+ // src/context/stores/EditComposer.ts
1223
+ var import_zustand2 = require("zustand");
1224
+
1225
+ // src/context/stores/BaseComposer.ts
1226
+ var makeBaseComposer = (set) => ({
1227
+ value: "",
1228
+ setValue: (value) => {
1229
+ set({ value });
1230
+ }
1231
+ });
1232
+
1233
+ // src/context/stores/EditComposer.ts
1234
+ var makeEditComposerStore = ({
1235
+ onEdit,
1236
+ onSend
1237
+ }) => (0, import_zustand2.create)()((set, get, store) => ({
1238
+ ...makeBaseComposer(set, get, store),
1239
+ isEditing: false,
1240
+ edit: () => {
1241
+ const value = onEdit();
1242
+ set({ isEditing: true, value });
1243
+ },
1244
+ send: () => {
1245
+ const value = get().value;
1246
+ set({ isEditing: false });
1247
+ onSend(value);
1248
+ },
1249
+ cancel: () => {
1250
+ if (!get().isEditing) return false;
1251
+ set({ isEditing: false });
1252
+ return true;
1253
+ }
1254
+ }));
1255
+
1256
+ // src/context/stores/MessageUtils.ts
1257
+ var import_zustand3 = require("zustand");
1258
+ var makeMessageUtilsStore = () => (0, import_zustand3.create)((set) => ({
1259
+ inProgressIndicator: null,
1260
+ setInProgressIndicator: (value) => {
1261
+ set({ inProgressIndicator: value });
1262
+ },
1263
+ isCopied: false,
1264
+ setIsCopied: (value) => {
1265
+ set({ isCopied: value });
1266
+ },
1267
+ isHovering: false,
1268
+ setIsHovering: (value) => {
1269
+ set({ isHovering: value });
1270
+ }
1271
+ }));
1272
+
1273
+ // src/context/providers/MessageProvider.tsx
1274
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1275
+ var getIsLast = (thread, message) => {
1276
+ return thread.messages[thread.messages.length - 1]?.id === message.id;
1277
+ };
1278
+ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
1279
+ const parentId = thread.messages[messageIndex - 1]?.id ?? null;
1280
+ const message = thread.messages[messageIndex];
1281
+ if (!message) return;
1282
+ const isLast = getIsLast(thread, message);
1283
+ const branches = getBranches(message.id);
1284
+ const currentState = useMessage.getState();
1285
+ if (currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
1286
+ return;
1287
+ useMessage.setState({
1288
+ message,
1289
+ parentId,
1290
+ branches,
1291
+ isLast
1292
+ });
1293
+ };
1294
+ var useMessageContext2 = (messageIndex) => {
1295
+ const { useThread, useThreadActions } = useThreadContext();
1296
+ const [context] = (0, import_react39.useState)(() => {
1297
+ const useMessage = (0, import_zustand4.create)(() => ({}));
1298
+ const useMessageUtils = makeMessageUtilsStore();
1299
+ const useEditComposer = makeEditComposerStore({
1300
+ onEdit: () => {
1301
+ const message = useMessage.getState().message;
1302
+ if (message.role !== "user")
1303
+ throw new Error(
1304
+ "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
1305
+ );
1306
+ const text = getMessageText(message);
1307
+ return text;
1308
+ },
1309
+ onSend: (text) => {
1310
+ const { message, parentId } = useMessage.getState();
1311
+ if (message.role !== "user")
1312
+ throw new Error(
1313
+ "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
1314
+ );
1315
+ const nonTextParts = message.content.filter(
1316
+ (part) => part.type !== "text" && part.type !== "ui"
1317
+ );
1318
+ useThreadActions.getState().append({
1319
+ parentId,
1320
+ role: "user",
1321
+ content: [{ type: "text", text }, ...nonTextParts]
1322
+ });
1323
+ }
1324
+ });
1325
+ syncMessage(
1326
+ useThread.getState(),
1327
+ useThreadActions.getState().getBranches,
1328
+ useMessage,
1329
+ messageIndex
1330
+ );
1331
+ return { useMessage, useMessageUtils, useEditComposer };
1332
+ });
1333
+ (0, import_react39.useEffect)(() => {
1334
+ return useThread.subscribe((thread) => {
1335
+ syncMessage(
1336
+ thread,
1337
+ useThreadActions.getState().getBranches,
1338
+ context.useMessage,
1339
+ messageIndex
1340
+ );
1341
+ });
1342
+ }, [useThread, useThreadActions, context, messageIndex]);
1343
+ return context;
1344
+ };
1345
+ var MessageProvider = ({
1346
+ messageIndex,
1347
+ children
1348
+ }) => {
1349
+ const context = useMessageContext2(messageIndex);
1350
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(MessageContext.Provider, { value: context, children });
1020
1351
  };
1021
1352
 
1022
- // src/primitives/contentPart/ContentPartText.tsx
1023
- var import_react_primitive6 = require("@radix-ui/react-primitive");
1024
- var import_react28 = require("react");
1025
- var import_jsx_runtime11 = require("react/jsx-runtime");
1026
- var ContentPartText = (0, import_react28.forwardRef)((props, forwardedRef) => {
1027
- const text = useContentPartText();
1028
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_primitive6.Primitive.span, { ...props, ref: forwardedRef, children: text });
1029
- });
1030
- ContentPartText.displayName = "ContentPartText";
1031
-
1032
- // src/primitives/message/MessageContent.tsx
1033
- var import_jsx_runtime12 = require("react/jsx-runtime");
1034
- var defaultComponents = {
1035
- Text: () => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1036
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartText, {}),
1037
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartInProgressIndicator, {})
1038
- ] }),
1039
- Image: () => null,
1040
- UI: () => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartDisplay, {}),
1041
- tools: {
1042
- Fallback: (props) => {
1043
- const { useToolUIs } = useAssistantContext();
1044
- const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
1045
- if (!Render) return null;
1046
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Render, { ...props });
1047
- }
1048
- }
1049
- };
1050
- var MessageContentPartComponent = ({
1051
- components: {
1052
- Text = defaultComponents.Text,
1053
- Image = defaultComponents.Image,
1054
- UI = defaultComponents.UI,
1055
- tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
1056
- } = {}
1057
- }) => {
1058
- const { useThreadActions } = useThreadContext();
1059
- const addToolResult = useThreadActions((t) => t.addToolResult);
1060
- const { useContentPart } = useContentPartContext();
1061
- const { part, status } = useContentPart();
1062
- const type = part.type;
1063
- switch (type) {
1064
- case "text":
1065
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { part, status });
1066
- case "image":
1067
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Image, { part, status });
1068
- case "ui":
1069
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(UI, { part, status });
1070
- case "tool-call": {
1071
- const Tool = by_name[part.toolName] || Fallback;
1072
- const addResult = (result) => addToolResult(part.toolCallId, result);
1073
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tool, { part, status, addResult });
1074
- }
1075
- default:
1076
- throw new Error(`Unknown content part type: ${type}`);
1077
- }
1353
+ // src/primitives/thread/ThreadMessages.tsx
1354
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1355
+ var getComponents = (components) => {
1356
+ return {
1357
+ EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
1358
+ UserMessage: components.UserMessage ?? components.Message,
1359
+ AssistantMessage: components.AssistantMessage ?? components.Message
1360
+ };
1078
1361
  };
1079
- var MessageContentPartImpl = ({
1080
- partIndex,
1362
+ var ThreadMessageImpl = ({
1363
+ messageIndex,
1081
1364
  components
1082
1365
  }) => {
1083
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContentPartProvider, { partIndex, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MessageContentPartComponent, { components }) });
1366
+ const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
1367
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(MessageProvider, { messageIndex, children: [
1368
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(MessageIf, { user: true, children: [
1369
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ComposerIf, { editing: false, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(UserMessage, {}) }),
1370
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ComposerIf, { editing: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EditComposer, {}) })
1371
+ ] }),
1372
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MessageIf, { assistant: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantMessage, {}) })
1373
+ ] });
1084
1374
  };
1085
- var MessageContentPart = (0, import_react29.memo)(
1086
- MessageContentPartImpl,
1087
- (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
1375
+ var ThreadMessage = (0, import_react40.memo)(
1376
+ ThreadMessageImpl,
1377
+ (prev, next) => prev.messageIndex === next.messageIndex && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
1088
1378
  );
1089
- var MessageContent = ({ components }) => {
1090
- const { useMessage } = useMessageContext();
1091
- const contentLength = useMessage((s) => s.message.content.length);
1092
- return new Array(contentLength).fill(null).map((_, idx) => {
1093
- const partIndex = idx;
1094
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1095
- MessageContentPart,
1379
+ var ThreadMessages = ({ components }) => {
1380
+ const { useThread } = useThreadContext();
1381
+ const messagesLength = useThread((t) => t.messages.length);
1382
+ if (messagesLength === 0) return null;
1383
+ return new Array(messagesLength).fill(null).map((_, idx) => {
1384
+ const messageIndex = idx;
1385
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1386
+ ThreadMessage,
1096
1387
  {
1097
- partIndex,
1388
+ messageIndex,
1098
1389
  components
1099
1390
  },
1100
- partIndex
1391
+ messageIndex
1101
1392
  );
1102
1393
  });
1103
1394
  };
1104
1395
 
1105
- // src/primitives/message/MessageInProgress.tsx
1106
- var import_react_primitive7 = require("@radix-ui/react-primitive");
1107
- var import_react30 = require("react");
1108
- var import_jsx_runtime13 = require("react/jsx-runtime");
1109
- var MessageInProgress = (0, import_react30.forwardRef)((props, ref) => {
1110
- 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 }));
1113
- }, [useMessageUtils, props, ref]);
1114
- return null;
1115
- });
1116
- MessageInProgress.displayName = "MessageInProgress";
1117
-
1118
- // src/primitives/branchPicker/index.ts
1119
- var branchPicker_exports = {};
1120
- __export(branchPicker_exports, {
1121
- Count: () => BranchPickerCount,
1122
- Next: () => BranchPickerNext,
1123
- Number: () => BranchPickerNumber,
1124
- Previous: () => BranchPickerPrevious,
1125
- Root: () => BranchPickerRoot
1126
- });
1127
-
1128
- // src/primitives/branchPicker/BranchPickerNext.tsx
1129
- var BranchPickerNext = createActionButton(
1130
- "BranchPickerNext",
1131
- useBranchPickerNext
1132
- );
1133
-
1134
- // src/primitives/branchPicker/BranchPickerPrevious.tsx
1135
- var BranchPickerPrevious = createActionButton(
1136
- "BranchPickerPrevious",
1137
- useBranchPickerPrevious
1138
- );
1139
-
1140
- // src/primitives/branchPicker/BranchPickerCount.tsx
1141
- var import_jsx_runtime14 = require("react/jsx-runtime");
1142
- var BranchPickerCount = () => {
1143
- const branchCount = useBranchPickerCount();
1144
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: branchCount });
1145
- };
1146
-
1147
- // src/primitives/branchPicker/BranchPickerNumber.tsx
1148
- var import_jsx_runtime15 = require("react/jsx-runtime");
1149
- var BranchPickerNumber = () => {
1150
- const branchNumber = useBranchPickerNumber();
1151
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: branchNumber });
1152
- };
1153
-
1154
- // src/primitives/branchPicker/BranchPickerRoot.tsx
1155
- var import_react_primitive8 = require("@radix-ui/react-primitive");
1156
- var import_react31 = require("react");
1157
- 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 }) });
1160
- });
1161
- BranchPickerRoot.displayName = "BranchPickerRoot";
1162
-
1163
- // src/primitives/actionBar/index.ts
1164
- var actionBar_exports = {};
1165
- __export(actionBar_exports, {
1166
- Copy: () => ActionBarCopy,
1167
- Edit: () => ActionBarEdit,
1168
- Reload: () => ActionBarReload,
1169
- Root: () => ActionBarRoot
1170
- });
1171
-
1172
- // src/primitives/actionBar/ActionBarRoot.tsx
1173
- var import_react_primitive9 = require("@radix-ui/react-primitive");
1174
- var import_react32 = require("react");
1175
- var import_jsx_runtime17 = require("react/jsx-runtime");
1176
- var useActionBarFloatStatus = ({
1177
- hideWhenRunning,
1178
- autohide,
1179
- autohideFloat
1180
- }) => {
1181
- const { useThread } = useThreadContext();
1182
- const { useMessage, useMessageUtils } = useMessageContext();
1183
- return useCombinedStore(
1184
- [useThread, useMessage, useMessageUtils],
1185
- (t, m, mu) => {
1186
- if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
1187
- const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
1188
- if (!autohideEnabled) return "normal" /* Normal */;
1189
- if (!mu.isHovering) return "hidden" /* Hidden */;
1190
- if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
1191
- return "floating" /* Floating */;
1192
- return "normal" /* Normal */;
1193
- }
1194
- );
1195
- };
1196
- var ActionBarRoot = (0, import_react32.forwardRef)(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1197
- const hideAndfloatStatus = useActionBarFloatStatus({
1198
- hideWhenRunning,
1199
- autohide,
1200
- autohideFloat
1201
- });
1202
- if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
1203
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1204
- import_react_primitive9.Primitive.div,
1205
- {
1206
- ...hideAndfloatStatus === "floating" /* Floating */ ? { "data-floating": "true" } : null,
1207
- ...rest,
1208
- ref
1209
- }
1210
- );
1211
- });
1212
- ActionBarRoot.displayName = "ActionBarRoot";
1213
-
1214
- // src/primitives/actionBar/ActionBarCopy.tsx
1215
- var ActionBarCopy = createActionButton(
1216
- "ActionBarCopy",
1217
- useActionBarCopy
1218
- );
1219
-
1220
- // src/primitives/actionBar/ActionBarReload.tsx
1221
- var ActionBarReload = createActionButton(
1222
- "ActionBarReload",
1223
- useActionBarReload
1396
+ // src/primitives/thread/ThreadScrollToBottom.tsx
1397
+ var ThreadScrollToBottom = createActionButton(
1398
+ "ThreadScrollToBottom",
1399
+ useThreadScrollToBottom
1224
1400
  );
1225
1401
 
1226
- // src/primitives/actionBar/ActionBarEdit.tsx
1227
- var ActionBarEdit = createActionButton(
1228
- "ActionBarEdit",
1229
- useActionBarEdit
1402
+ // src/primitives/thread/ThreadSuggestion.tsx
1403
+ var ThreadSuggestion = createActionButton(
1404
+ "ThreadSuggestion",
1405
+ useThreadSuggestion
1230
1406
  );
1231
1407
 
1232
- // src/primitives/contentPart/index.ts
1233
- var contentPart_exports = {};
1234
- __export(contentPart_exports, {
1235
- Display: () => ContentPartDisplay,
1236
- Image: () => ContentPartImage,
1237
- InProgressIndicator: () => ContentPartInProgressIndicator,
1238
- Text: () => ContentPartText
1239
- });
1240
-
1241
- // src/primitives/contentPart/ContentPartImage.tsx
1242
- var import_react_primitive10 = require("@radix-ui/react-primitive");
1243
- var import_react33 = require("react");
1244
- var import_jsx_runtime18 = require("react/jsx-runtime");
1245
- var ContentPartImage = (0, import_react33.forwardRef)((props, forwardedRef) => {
1246
- const image = useContentPartImage();
1247
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_primitive10.Primitive.img, { src: image, ...props, ref: forwardedRef });
1248
- });
1249
- ContentPartImage.displayName = "ContentPartImage";
1250
-
1251
1408
  // src/runtime/local/useLocalRuntime.tsx
1252
- var import_react34 = require("react");
1409
+ var import_react41 = require("react");
1253
1410
 
1254
1411
  // src/utils/ModelConfigTypes.ts
1255
1412
  var mergeModelConfigs = (configSet) => {
@@ -1535,18 +1692,18 @@ var LocalRuntime = class {
1535
1692
 
1536
1693
  // src/runtime/local/useLocalRuntime.tsx
1537
1694
  var useLocalRuntime = (adapter) => {
1538
- const [runtime] = (0, import_react34.useState)(() => new LocalRuntime(adapter));
1539
- (0, import_react34.useInsertionEffect)(() => {
1695
+ const [runtime] = (0, import_react41.useState)(() => new LocalRuntime(adapter));
1696
+ (0, import_react41.useInsertionEffect)(() => {
1540
1697
  runtime.adapter = adapter;
1541
1698
  });
1542
1699
  return runtime;
1543
1700
  };
1544
1701
 
1545
1702
  // src/context/providers/AssistantRuntimeProvider.tsx
1546
- var import_react37 = require("react");
1703
+ var import_react44 = require("react");
1547
1704
 
1548
1705
  // src/context/providers/AssistantProvider.tsx
1549
- var import_react36 = require("react");
1706
+ var import_react43 = require("react");
1550
1707
 
1551
1708
  // src/context/stores/AssistantModelConfig.ts
1552
1709
  var import_zustand5 = require("zustand");
@@ -1611,30 +1768,45 @@ var makeAssistantToolUIsStore = () => (0, import_zustand6.create)((set) => {
1611
1768
  });
1612
1769
 
1613
1770
  // src/context/providers/ThreadProvider.tsx
1614
- var import_react35 = require("react");
1771
+ var import_react42 = require("react");
1615
1772
 
1616
1773
  // src/context/stores/Composer.ts
1617
1774
  var import_zustand7 = require("zustand");
1618
- var makeComposerStore = (useThread, useThreadActions) => (0, import_zustand7.create)()((set, get, store) => {
1619
- return {
1620
- ...makeBaseComposer(set, get, store),
1621
- isEditing: true,
1622
- send: () => {
1623
- const { setValue, value } = get();
1624
- setValue("");
1625
- useThreadActions.getState().append({
1626
- parentId: useThread.getState().messages.at(-1)?.id ?? null,
1627
- content: [{ type: "text", text: value }]
1628
- });
1629
- },
1630
- cancel: () => {
1631
- const thread = useThread.getState();
1632
- if (!thread.isRunning) return false;
1633
- useThreadActions.getState().cancelRun();
1634
- return true;
1635
- }
1636
- };
1637
- });
1775
+ var makeComposerStore = (useThread, useThreadActions) => {
1776
+ const focusListeners = /* @__PURE__ */ new Set();
1777
+ return (0, import_zustand7.create)()((set, get, store) => {
1778
+ return {
1779
+ ...makeBaseComposer(set, get, store),
1780
+ isEditing: true,
1781
+ send: () => {
1782
+ const { setValue, value } = get();
1783
+ setValue("");
1784
+ useThreadActions.getState().append({
1785
+ parentId: useThread.getState().messages.at(-1)?.id ?? null,
1786
+ role: "user",
1787
+ content: [{ type: "text", text: value }]
1788
+ });
1789
+ },
1790
+ cancel: () => {
1791
+ const thread = useThread.getState();
1792
+ if (!thread.isRunning) return false;
1793
+ useThreadActions.getState().cancelRun();
1794
+ return true;
1795
+ },
1796
+ focus: () => {
1797
+ for (const listener of focusListeners) {
1798
+ listener();
1799
+ }
1800
+ },
1801
+ onFocus: (listener) => {
1802
+ focusListeners.add(listener);
1803
+ return () => {
1804
+ focusListeners.delete(listener);
1805
+ };
1806
+ }
1807
+ };
1808
+ });
1809
+ };
1638
1810
 
1639
1811
  // src/context/stores/Thread.ts
1640
1812
  var import_zustand8 = require("zustand");
@@ -1681,16 +1853,16 @@ var makeThreadActionStore = (runtimeRef) => {
1681
1853
  };
1682
1854
 
1683
1855
  // src/context/providers/ThreadProvider.tsx
1684
- var import_jsx_runtime19 = require("react/jsx-runtime");
1856
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1685
1857
  var ThreadProvider = ({
1686
1858
  children,
1687
1859
  runtime
1688
1860
  }) => {
1689
- const runtimeRef = (0, import_react35.useRef)(runtime);
1690
- (0, import_react35.useInsertionEffect)(() => {
1861
+ const runtimeRef = (0, import_react42.useRef)(runtime);
1862
+ (0, import_react42.useInsertionEffect)(() => {
1691
1863
  runtimeRef.current = runtime;
1692
1864
  });
1693
- const [context] = (0, import_react35.useState)(() => {
1865
+ const [context] = (0, import_react42.useState)(() => {
1694
1866
  const useThread = makeThreadStore(runtimeRef);
1695
1867
  const useThreadActions = makeThreadActionStore(runtimeRef);
1696
1868
  const useViewport = makeThreadViewportStore();
@@ -1702,7 +1874,7 @@ var ThreadProvider = ({
1702
1874
  useViewport
1703
1875
  };
1704
1876
  });
1705
- (0, import_react35.useEffect)(() => {
1877
+ (0, import_react42.useEffect)(() => {
1706
1878
  const onRuntimeUpdate = () => {
1707
1879
  context.useThread.setState(
1708
1880
  Object.freeze({
@@ -1716,37 +1888,37 @@ var ThreadProvider = ({
1716
1888
  return runtime.subscribe(onRuntimeUpdate);
1717
1889
  }, [context, runtime]);
1718
1890
  const RuntimeSynchronizer = runtime.unstable_synchronizer;
1719
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(ThreadContext.Provider, { value: context, children: [
1720
- RuntimeSynchronizer && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(RuntimeSynchronizer, {}),
1891
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(ThreadContext.Provider, { value: context, children: [
1892
+ RuntimeSynchronizer && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RuntimeSynchronizer, {}),
1721
1893
  children
1722
1894
  ] });
1723
1895
  };
1724
1896
 
1725
1897
  // src/context/providers/AssistantProvider.tsx
1726
- var import_jsx_runtime20 = require("react/jsx-runtime");
1898
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1727
1899
  var AssistantProvider = ({ children, runtime }) => {
1728
- const runtimeRef = (0, import_react36.useRef)(runtime);
1729
- (0, import_react36.useInsertionEffect)(() => {
1900
+ const runtimeRef = (0, import_react43.useRef)(runtime);
1901
+ (0, import_react43.useInsertionEffect)(() => {
1730
1902
  runtimeRef.current = runtime;
1731
1903
  });
1732
- const [context] = (0, import_react36.useState)(() => {
1904
+ const [context] = (0, import_react43.useState)(() => {
1733
1905
  const useModelConfig = makeAssistantModelConfigStore();
1734
1906
  const useToolUIs = makeAssistantToolUIsStore();
1735
1907
  return { useModelConfig, useToolUIs };
1736
1908
  });
1737
1909
  const getModelCOnfig = context.useModelConfig((c) => c.getModelConfig);
1738
- (0, import_react36.useEffect)(() => {
1910
+ (0, import_react43.useEffect)(() => {
1739
1911
  return runtime.registerModelConfigProvider(getModelCOnfig);
1740
1912
  }, [runtime, getModelCOnfig]);
1741
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ThreadProvider, { runtime, children }) });
1913
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThreadProvider, { runtime, children }) });
1742
1914
  };
1743
1915
 
1744
1916
  // src/context/providers/AssistantRuntimeProvider.tsx
1745
- var import_jsx_runtime21 = require("react/jsx-runtime");
1917
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1746
1918
  var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
1747
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantProvider, { runtime, children });
1919
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AssistantProvider, { runtime, children });
1748
1920
  };
1749
- var AssistantRuntimeProvider = (0, import_react37.memo)(AssistantRuntimeProviderImpl);
1921
+ var AssistantRuntimeProvider = (0, import_react44.memo)(AssistantRuntimeProviderImpl);
1750
1922
 
1751
1923
  // src/internal.ts
1752
1924
  var internal_exports = {};
@@ -1757,6 +1929,7 @@ __export(internal_exports, {
1757
1929
  // Annotate the CommonJS export names for ESM import in node:
1758
1930
  0 && (module.exports = {
1759
1931
  ActionBarPrimitive,
1932
+ AssistantModalPrimitive,
1760
1933
  AssistantRuntimeProvider,
1761
1934
  BranchPickerPrimitive,
1762
1935
  ComposerPrimitive,