@assistant-ui/react 0.1.10 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -91,7 +91,7 @@ var useActionBarEdit = () => {
91
91
  // src/primitive-hooks/actionBar/useActionBarReload.tsx
92
92
  import { useCallback as useCallback3 } from "react";
93
93
  var useActionBarReload = () => {
94
- const { useThread, useThreadActions, useViewport } = useThreadContext();
94
+ const { useThread, useThreadActions, useComposer, useViewport } = useThreadContext();
95
95
  const { useMessage } = useMessageContext();
96
96
  const disabled = useCombinedStore(
97
97
  [useThread, useMessage],
@@ -101,7 +101,8 @@ var useActionBarReload = () => {
101
101
  const { parentId } = useMessage.getState();
102
102
  useThreadActions.getState().startRun(parentId);
103
103
  useViewport.getState().scrollToBottom();
104
- }, [useThreadActions, useMessage, useViewport]);
104
+ useComposer.getState().focus();
105
+ }, [useThreadActions, useComposer, useViewport, useMessage]);
105
106
  if (disabled) return null;
106
107
  return callback;
107
108
  };
@@ -180,12 +181,16 @@ var useComposerIf = (props) => {
180
181
  // src/primitive-hooks/composer/useComposerSend.tsx
181
182
  import { useCallback as useCallback7 } from "react";
182
183
  var useComposerSend = () => {
184
+ const { useViewport, useComposer: useNewComposer } = useThreadContext();
183
185
  const { useComposer } = useComposerContext();
184
186
  const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
185
187
  const callback = useCallback7(() => {
186
- const { send } = useComposer.getState();
187
- send();
188
- }, [useComposer]);
188
+ const composerState = useComposer.getState();
189
+ if (!composerState.isEditing) return;
190
+ composerState.send();
191
+ useViewport.getState().scrollToBottom();
192
+ useNewComposer.getState().focus();
193
+ }, [useNewComposer, useComposer, useViewport]);
189
194
  if (disabled) return null;
190
195
  return callback;
191
196
  };
@@ -277,12 +282,12 @@ var useThreadEmpty = () => {
277
282
  // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
278
283
  import { useCallback as useCallback8 } from "react";
279
284
  var useThreadScrollToBottom = () => {
280
- const { useViewport } = useThreadContext();
285
+ const { useComposer, useViewport } = useThreadContext();
281
286
  const isAtBottom = useViewport((s) => s.isAtBottom);
282
287
  const handleScrollToBottom = useCallback8(() => {
283
- const { scrollToBottom } = useViewport.getState();
284
- scrollToBottom();
285
- }, [useViewport]);
288
+ useViewport.getState().scrollToBottom();
289
+ useComposer.getState().focus();
290
+ }, [useViewport, useComposer]);
286
291
  if (isAtBottom) return null;
287
292
  return handleScrollToBottom;
288
293
  };
@@ -307,225 +312,862 @@ var useThreadSuggestion = ({
307
312
  return callback;
308
313
  };
309
314
 
310
- // src/primitives/thread/index.ts
311
- var thread_exports = {};
312
- __export(thread_exports, {
313
- Empty: () => ThreadEmpty,
314
- If: () => ThreadIf,
315
- Messages: () => ThreadMessages,
316
- Root: () => ThreadRoot,
317
- ScrollToBottom: () => ThreadScrollToBottom,
318
- Suggestion: () => ThreadSuggestion,
319
- Viewport: () => ThreadViewport
315
+ // src/primitives/actionBar/index.ts
316
+ var actionBar_exports = {};
317
+ __export(actionBar_exports, {
318
+ Copy: () => ActionBarCopy,
319
+ Edit: () => ActionBarEdit,
320
+ Reload: () => ActionBarReload,
321
+ Root: () => ActionBarRoot
320
322
  });
321
323
 
322
- // src/primitives/thread/ThreadRoot.tsx
324
+ // src/primitives/actionBar/ActionBarRoot.tsx
323
325
  import { Primitive } from "@radix-ui/react-primitive";
324
326
  import { forwardRef } from "react";
325
327
  import { jsx } from "react/jsx-runtime";
326
- var ThreadRoot = forwardRef(
327
- (props, ref) => {
328
- return /* @__PURE__ */ jsx(Primitive.div, { ...props, ref });
329
- }
330
- );
331
- ThreadRoot.displayName = "ThreadRoot";
332
-
333
- // src/primitives/thread/ThreadIf.tsx
334
- var ThreadIf = ({ children, ...query }) => {
335
- const result = useThreadIf(query);
336
- return result ? children : null;
328
+ var useActionBarFloatStatus = ({
329
+ hideWhenRunning,
330
+ autohide,
331
+ autohideFloat
332
+ }) => {
333
+ const { useThread } = useThreadContext();
334
+ const { useMessage, useMessageUtils } = useMessageContext();
335
+ return useCombinedStore(
336
+ [useThread, useMessage, useMessageUtils],
337
+ (t, m, mu) => {
338
+ if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
339
+ const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
340
+ if (!autohideEnabled) return "normal" /* Normal */;
341
+ if (!mu.isHovering) return "hidden" /* Hidden */;
342
+ if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
343
+ return "floating" /* Floating */;
344
+ return "normal" /* Normal */;
345
+ }
346
+ );
337
347
  };
348
+ var ActionBarRoot = forwardRef(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
349
+ const hideAndfloatStatus = useActionBarFloatStatus({
350
+ hideWhenRunning,
351
+ autohide,
352
+ autohideFloat
353
+ });
354
+ if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
355
+ return /* @__PURE__ */ jsx(
356
+ Primitive.div,
357
+ {
358
+ ...hideAndfloatStatus === "floating" /* Floating */ ? { "data-floating": "true" } : null,
359
+ ...rest,
360
+ ref
361
+ }
362
+ );
363
+ });
364
+ ActionBarRoot.displayName = "ActionBarRoot";
338
365
 
339
- // src/primitives/thread/ThreadEmpty.tsx
366
+ // src/utils/createActionButton.tsx
367
+ import { composeEventHandlers } from "@radix-ui/primitive";
368
+ import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
369
+ import { forwardRef as forwardRef2 } from "react";
340
370
  import { jsx as jsx2 } from "react/jsx-runtime";
341
- var ThreadEmpty = ({ children }) => {
342
- return /* @__PURE__ */ jsx2(ThreadIf, { empty: true, children });
371
+ var createActionButton = (displayName, useActionButton) => {
372
+ const ActionButton = forwardRef2((props, forwardedRef) => {
373
+ const callback = useActionButton(props);
374
+ return /* @__PURE__ */ jsx2(
375
+ Primitive2.button,
376
+ {
377
+ type: "button",
378
+ disabled: !callback,
379
+ ...props,
380
+ ref: forwardedRef,
381
+ onClick: composeEventHandlers(props.onClick, () => {
382
+ callback?.();
383
+ })
384
+ }
385
+ );
386
+ });
387
+ ActionButton.displayName = displayName;
388
+ return ActionButton;
343
389
  };
344
390
 
345
- // src/primitives/thread/ThreadViewport.tsx
346
- import { composeEventHandlers } from "@radix-ui/primitive";
347
- import { useComposedRefs } from "@radix-ui/react-compose-refs";
348
- import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
349
- import {
350
- forwardRef as forwardRef2,
351
- useRef
352
- } from "react";
391
+ // src/primitives/actionBar/ActionBarCopy.tsx
392
+ var ActionBarCopy = createActionButton(
393
+ "ActionBarCopy",
394
+ useActionBarCopy
395
+ );
353
396
 
354
- // src/utils/hooks/useOnResizeContent.tsx
397
+ // src/primitives/actionBar/ActionBarReload.tsx
398
+ var ActionBarReload = createActionButton(
399
+ "ActionBarReload",
400
+ useActionBarReload
401
+ );
402
+
403
+ // src/primitives/actionBar/ActionBarEdit.tsx
404
+ var ActionBarEdit = createActionButton(
405
+ "ActionBarEdit",
406
+ useActionBarEdit
407
+ );
408
+
409
+ // src/primitives/assistantModal/index.ts
410
+ var assistantModal_exports = {};
411
+ __export(assistantModal_exports, {
412
+ Content: () => AssistantModalContent,
413
+ Root: () => AssistantModalRoot,
414
+ Trigger: () => AssistantModalTrigger
415
+ });
416
+
417
+ // src/primitives/assistantModal/AssistantModalRoot.tsx
418
+ import { useState } from "react";
419
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
420
+ import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
421
+
422
+ // src/utils/hooks/useOnComposerFocus.tsx
355
423
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
356
424
  import { useEffect } from "react";
357
- var useOnResizeContent = (ref, callback) => {
425
+ var useOnComposerFocus = (callback) => {
358
426
  const callbackRef = useCallbackRef(callback);
427
+ const { useComposer } = useThreadContext();
359
428
  useEffect(() => {
360
- const el = ref.current;
361
- if (!el) return;
362
- const resizeObserver = new ResizeObserver(() => {
363
- callbackRef();
364
- });
365
- const mutationObserver = new MutationObserver((mutations) => {
366
- for (const mutation of mutations) {
367
- for (const node of mutation.addedNodes) {
368
- if (node instanceof Element) {
369
- resizeObserver.observe(node);
370
- }
371
- }
372
- for (const node of mutation.removedNodes) {
373
- if (node instanceof Element) {
374
- resizeObserver.unobserve(node);
375
- }
376
- }
377
- }
378
- callbackRef();
379
- });
380
- resizeObserver.observe(el);
381
- mutationObserver.observe(el, { childList: true });
382
- for (const child of el.children) {
383
- resizeObserver.observe(child);
384
- }
385
- return () => {
386
- resizeObserver.disconnect();
387
- mutationObserver.disconnect();
388
- };
389
- }, [ref, callbackRef]);
390
- };
391
-
392
- // src/utils/hooks/useOnScrollToBottom.tsx
393
- import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
394
- import { useEffect as useEffect2 } from "react";
395
- var useOnScrollToBottom = (callback) => {
396
- const callbackRef = useCallbackRef2(callback);
397
- const { useViewport } = useThreadContext();
398
- useEffect2(() => {
399
- return useViewport.getState().onScrollToBottom(() => {
429
+ return useComposer.getState().onFocus(() => {
400
430
  callbackRef();
401
431
  });
402
- }, [useViewport, callbackRef]);
432
+ }, [useComposer, callbackRef]);
403
433
  };
404
434
 
405
- // src/primitives/thread/ThreadViewport.tsx
406
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
407
- var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
408
- const messagesEndRef = useRef(null);
409
- const divRef = useRef(null);
410
- const ref = useComposedRefs(forwardedRef, divRef);
411
- const { useViewport } = useThreadContext();
412
- const firstRenderRef = useRef(true);
413
- const isScrollingToBottomRef = useRef(false);
414
- const lastScrollTop = useRef(0);
415
- const scrollToBottom = () => {
416
- const div = messagesEndRef.current;
417
- if (!div || !autoScroll) return;
418
- const behavior = firstRenderRef.current ? "instant" : "auto";
419
- firstRenderRef.current = false;
420
- isScrollingToBottomRef.current = true;
421
- div.scrollIntoView({ behavior });
422
- };
423
- useOnResizeContent(divRef, () => {
424
- if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom) {
425
- handleScroll();
426
- } else {
427
- scrollToBottom();
428
- }
435
+ // src/primitives/assistantModal/AssistantModalRoot.tsx
436
+ import { jsx as jsx3 } from "react/jsx-runtime";
437
+ var usePopoverScope = PopoverPrimitive.createPopoverScope();
438
+ var useAssistantModalOpenState = (defaultOpen = false) => {
439
+ const state = useState(defaultOpen);
440
+ const [, setOpen] = state;
441
+ useOnComposerFocus(() => {
442
+ setOpen(true);
429
443
  });
430
- useOnScrollToBottom(() => {
431
- scrollToBottom();
432
- });
433
- const handleScroll = () => {
434
- const div = divRef.current;
435
- if (!div) return;
436
- const isAtBottom = useViewport.getState().isAtBottom;
437
- const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
438
- if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
439
- } else if (newIsAtBottom !== isAtBottom) {
440
- isScrollingToBottomRef.current = false;
441
- useViewport.setState({
442
- isAtBottom: newIsAtBottom
443
- });
444
- }
445
- lastScrollTop.current = div.scrollTop;
446
- };
447
- return /* @__PURE__ */ jsxs(
448
- Primitive2.div,
444
+ return state;
445
+ };
446
+ var AssistantModalRoot = ({
447
+ __scopeAssistantModal,
448
+ defaultOpen,
449
+ open,
450
+ onOpenChange,
451
+ ...rest
452
+ }) => {
453
+ const scope = usePopoverScope(__scopeAssistantModal);
454
+ const [modalOpen, setOpen] = useAssistantModalOpenState(defaultOpen);
455
+ return /* @__PURE__ */ jsx3(
456
+ PopoverPrimitive.Root,
449
457
  {
450
- ...rest,
451
- onScroll: composeEventHandlers(onScroll, handleScroll),
452
- ref,
453
- children: [
454
- children,
455
- /* @__PURE__ */ jsx3("div", { ref: messagesEndRef })
456
- ]
458
+ ...scope,
459
+ open: open === void 0 ? modalOpen : open,
460
+ onOpenChange: composeEventHandlers2(onOpenChange, setOpen),
461
+ ...rest
457
462
  }
458
463
  );
459
- });
460
- ThreadViewport.displayName = "ThreadViewport";
461
-
462
- // src/primitives/thread/ThreadMessages.tsx
463
- import { memo } from "react";
464
-
465
- // src/context/providers/MessageProvider.tsx
466
- import { useEffect as useEffect3, useState } from "react";
467
- import { create as create3 } from "zustand";
464
+ };
465
+ AssistantModalRoot.displayName = "AssistantModalRoot";
468
466
 
469
- // src/context/stores/EditComposer.ts
470
- import { create } from "zustand";
467
+ // src/primitives/assistantModal/AssistantModalTrigger.tsx
468
+ import { forwardRef as forwardRef3 } from "react";
469
+ import * as PopoverPrimitive2 from "@radix-ui/react-popover";
470
+ import { jsx as jsx4 } from "react/jsx-runtime";
471
+ var AssistantModalTrigger = forwardRef3(
472
+ ({ __scopeAssistantModal, ...rest }, ref) => {
473
+ const scope = usePopoverScope(__scopeAssistantModal);
474
+ return /* @__PURE__ */ jsx4(PopoverPrimitive2.Trigger, { ...scope, ...rest, ref });
475
+ }
476
+ );
477
+ AssistantModalTrigger.displayName = "AssistantModalTrigger";
471
478
 
472
- // src/context/stores/BaseComposer.ts
473
- var makeBaseComposer = (set) => ({
474
- value: "",
475
- setValue: (value) => {
476
- set({ value });
479
+ // src/primitives/assistantModal/AssistantModalContent.tsx
480
+ import { forwardRef as forwardRef4 } from "react";
481
+ import * as PopoverPrimitive3 from "@radix-ui/react-popover";
482
+ import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
483
+ import { jsx as jsx5 } from "react/jsx-runtime";
484
+ var AssistantModalContent = forwardRef4(
485
+ ({
486
+ __scopeAssistantModal,
487
+ side,
488
+ align,
489
+ onInteractOutside,
490
+ dissmissOnInteractOutside = false,
491
+ ...props
492
+ }, forwardedRef) => {
493
+ const scope = usePopoverScope(__scopeAssistantModal);
494
+ return /* @__PURE__ */ jsx5(PopoverPrimitive3.Portal, { ...scope, children: /* @__PURE__ */ jsx5(
495
+ PopoverPrimitive3.Content,
496
+ {
497
+ ...scope,
498
+ ...props,
499
+ ref: forwardedRef,
500
+ side: side ?? "top",
501
+ align: align ?? "end",
502
+ onInteractOutside: composeEventHandlers3(
503
+ onInteractOutside,
504
+ dissmissOnInteractOutside ? void 0 : (e) => e.preventDefault()
505
+ )
506
+ }
507
+ ) });
477
508
  }
509
+ );
510
+ AssistantModalContent.displayName = "AssistantModalContent";
511
+
512
+ // src/primitives/branchPicker/index.ts
513
+ var branchPicker_exports = {};
514
+ __export(branchPicker_exports, {
515
+ Count: () => BranchPickerCount,
516
+ Next: () => BranchPickerNext,
517
+ Number: () => BranchPickerNumber,
518
+ Previous: () => BranchPickerPrevious,
519
+ Root: () => BranchPickerRoot
478
520
  });
479
521
 
480
- // src/context/stores/EditComposer.ts
481
- var makeEditComposerStore = ({
482
- onEdit,
483
- onSend
484
- }) => create()((set, get, store) => ({
485
- ...makeBaseComposer(set, get, store),
486
- isEditing: false,
487
- edit: () => {
488
- const value = onEdit();
489
- set({ isEditing: true, value });
490
- },
491
- send: () => {
492
- const value = get().value;
493
- set({ isEditing: false });
494
- onSend(value);
495
- },
496
- cancel: () => {
497
- if (!get().isEditing) return false;
498
- set({ isEditing: false });
499
- return true;
500
- }
501
- }));
522
+ // src/primitives/branchPicker/BranchPickerNext.tsx
523
+ var BranchPickerNext = createActionButton(
524
+ "BranchPickerNext",
525
+ useBranchPickerNext
526
+ );
502
527
 
503
- // src/context/stores/MessageUtils.ts
504
- import { create as create2 } from "zustand";
505
- var makeMessageUtilsStore = () => create2((set) => ({
506
- inProgressIndicator: null,
507
- setInProgressIndicator: (value) => {
508
- set({ inProgressIndicator: value });
509
- },
510
- isCopied: false,
511
- setIsCopied: (value) => {
512
- set({ isCopied: value });
513
- },
514
- isHovering: false,
515
- setIsHovering: (value) => {
516
- set({ isHovering: value });
517
- }
518
- }));
528
+ // src/primitives/branchPicker/BranchPickerPrevious.tsx
529
+ var BranchPickerPrevious = createActionButton(
530
+ "BranchPickerPrevious",
531
+ useBranchPickerPrevious
532
+ );
519
533
 
520
- // src/context/providers/MessageProvider.tsx
521
- import { jsx as jsx4 } from "react/jsx-runtime";
522
- var getIsLast = (thread, message) => {
523
- return thread.messages[thread.messages.length - 1]?.id === message.id;
534
+ // src/primitives/branchPicker/BranchPickerCount.tsx
535
+ import { Fragment, jsx as jsx6 } from "react/jsx-runtime";
536
+ var BranchPickerCount = () => {
537
+ const branchCount = useBranchPickerCount();
538
+ return /* @__PURE__ */ jsx6(Fragment, { children: branchCount });
524
539
  };
525
- var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
526
- const parentId = thread.messages[messageIndex - 1]?.id ?? null;
527
- const message = thread.messages[messageIndex];
528
- if (!message) return;
540
+
541
+ // src/primitives/branchPicker/BranchPickerNumber.tsx
542
+ import { Fragment as Fragment2, jsx as jsx7 } from "react/jsx-runtime";
543
+ var BranchPickerNumber = () => {
544
+ const branchNumber = useBranchPickerNumber();
545
+ return /* @__PURE__ */ jsx7(Fragment2, { children: branchNumber });
546
+ };
547
+
548
+ // src/primitives/branchPicker/BranchPickerRoot.tsx
549
+ import { Primitive as Primitive6 } from "@radix-ui/react-primitive";
550
+ import { forwardRef as forwardRef8 } from "react";
551
+
552
+ // src/primitives/message/index.ts
553
+ var message_exports = {};
554
+ __export(message_exports, {
555
+ Content: () => MessageContent,
556
+ If: () => MessageIf,
557
+ InProgress: () => MessageInProgress,
558
+ Root: () => MessageRoot
559
+ });
560
+
561
+ // src/primitives/message/MessageRoot.tsx
562
+ import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
563
+ import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
564
+ import { forwardRef as forwardRef5 } from "react";
565
+ import { jsx as jsx8 } from "react/jsx-runtime";
566
+ var MessageRoot = forwardRef5(
567
+ ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
568
+ const { useMessageUtils } = useMessageContext();
569
+ const setIsHovering = useMessageUtils((s) => s.setIsHovering);
570
+ const handleMouseEnter = () => {
571
+ setIsHovering(true);
572
+ };
573
+ const handleMouseLeave = () => {
574
+ setIsHovering(false);
575
+ };
576
+ return /* @__PURE__ */ jsx8(
577
+ Primitive3.div,
578
+ {
579
+ ...rest,
580
+ ref,
581
+ onMouseEnter: composeEventHandlers4(onMouseEnter, handleMouseEnter),
582
+ onMouseLeave: composeEventHandlers4(onMouseLeave, handleMouseLeave)
583
+ }
584
+ );
585
+ }
586
+ );
587
+ MessageRoot.displayName = "MessageRoot";
588
+
589
+ // src/primitives/message/MessageIf.tsx
590
+ var MessageIf = ({ children, ...query }) => {
591
+ const result = useMessageIf(query);
592
+ return result ? children : null;
593
+ };
594
+
595
+ // src/primitives/message/MessageContent.tsx
596
+ import { memo } from "react";
597
+
598
+ // src/context/providers/ContentPartProvider.tsx
599
+ import { useEffect as useEffect2, useState as useState2 } from "react";
600
+ import { create } from "zustand";
601
+ import { jsx as jsx9 } from "react/jsx-runtime";
602
+ var syncContentPart = ({ message }, useContentPart, partIndex) => {
603
+ const part = message.content[partIndex];
604
+ if (!part) return;
605
+ const messageStatus = message.role === "assistant" ? message.status : "done";
606
+ const status = partIndex === message.content.length - 1 ? messageStatus : "done";
607
+ const currentState = useContentPart.getState();
608
+ if (currentState.part === part && currentState.status === status) return;
609
+ useContentPart.setState(
610
+ Object.freeze({
611
+ part,
612
+ status
613
+ })
614
+ );
615
+ };
616
+ var useContentPartContext2 = (partIndex) => {
617
+ const { useMessage } = useMessageContext();
618
+ const [context] = useState2(() => {
619
+ const useContentPart = create(
620
+ () => ({})
621
+ );
622
+ syncContentPart(useMessage.getState(), useContentPart, partIndex);
623
+ return { useContentPart };
624
+ });
625
+ useEffect2(() => {
626
+ syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
627
+ return useMessage.subscribe((message) => {
628
+ syncContentPart(message, context.useContentPart, partIndex);
629
+ });
630
+ }, [context, useMessage, partIndex]);
631
+ return context;
632
+ };
633
+ var ContentPartProvider = ({
634
+ partIndex,
635
+ children
636
+ }) => {
637
+ const context = useContentPartContext2(partIndex);
638
+ return /* @__PURE__ */ jsx9(ContentPartContext.Provider, { value: context, children });
639
+ };
640
+
641
+ // src/primitives/contentPart/ContentPartDisplay.tsx
642
+ var ContentPartDisplay = () => {
643
+ const display = useContentPartDisplay();
644
+ return display ?? null;
645
+ };
646
+
647
+ // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
648
+ var ContentPartInProgressIndicator = () => {
649
+ const indicator = useContentPartInProgressIndicator();
650
+ return indicator;
651
+ };
652
+
653
+ // src/primitives/contentPart/ContentPartText.tsx
654
+ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
655
+ import { forwardRef as forwardRef6 } from "react";
656
+ import { jsx as jsx10 } from "react/jsx-runtime";
657
+ var ContentPartText = forwardRef6((props, forwardedRef) => {
658
+ const text = useContentPartText();
659
+ return /* @__PURE__ */ jsx10(Primitive4.span, { ...props, ref: forwardedRef, children: text });
660
+ });
661
+ ContentPartText.displayName = "ContentPartText";
662
+
663
+ // src/primitives/message/MessageContent.tsx
664
+ import { Fragment as Fragment3, jsx as jsx11, jsxs } from "react/jsx-runtime";
665
+ var defaultComponents = {
666
+ Text: () => /* @__PURE__ */ jsxs(Fragment3, { children: [
667
+ /* @__PURE__ */ jsx11(ContentPartText, {}),
668
+ /* @__PURE__ */ jsx11(ContentPartInProgressIndicator, {})
669
+ ] }),
670
+ Image: () => null,
671
+ UI: () => /* @__PURE__ */ jsx11(ContentPartDisplay, {}),
672
+ tools: {
673
+ Fallback: (props) => {
674
+ const { useToolUIs } = useAssistantContext();
675
+ const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
676
+ if (!Render) return null;
677
+ return /* @__PURE__ */ jsx11(Render, { ...props });
678
+ }
679
+ }
680
+ };
681
+ var MessageContentPartComponent = ({
682
+ components: {
683
+ Text = defaultComponents.Text,
684
+ Image = defaultComponents.Image,
685
+ UI = defaultComponents.UI,
686
+ tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
687
+ } = {}
688
+ }) => {
689
+ const { useThreadActions } = useThreadContext();
690
+ const addToolResult = useThreadActions((t) => t.addToolResult);
691
+ const { useContentPart } = useContentPartContext();
692
+ const { part, status } = useContentPart();
693
+ const type = part.type;
694
+ switch (type) {
695
+ case "text":
696
+ return /* @__PURE__ */ jsx11(Text, { part, status });
697
+ case "image":
698
+ return /* @__PURE__ */ jsx11(Image, { part, status });
699
+ case "ui":
700
+ return /* @__PURE__ */ jsx11(UI, { part, status });
701
+ case "tool-call": {
702
+ const Tool = by_name[part.toolName] || Fallback;
703
+ const addResult = (result) => addToolResult(part.toolCallId, result);
704
+ return /* @__PURE__ */ jsx11(Tool, { part, status, addResult });
705
+ }
706
+ default:
707
+ throw new Error(`Unknown content part type: ${type}`);
708
+ }
709
+ };
710
+ var MessageContentPartImpl = ({
711
+ partIndex,
712
+ components
713
+ }) => {
714
+ return /* @__PURE__ */ jsx11(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx11(MessageContentPartComponent, { components }) });
715
+ };
716
+ var MessageContentPart = memo(
717
+ MessageContentPartImpl,
718
+ (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
719
+ );
720
+ var MessageContent = ({ components }) => {
721
+ const { useMessage } = useMessageContext();
722
+ const contentLength = useMessage((s) => s.message.content.length);
723
+ return new Array(contentLength).fill(null).map((_, idx) => {
724
+ const partIndex = idx;
725
+ return /* @__PURE__ */ jsx11(
726
+ MessageContentPart,
727
+ {
728
+ partIndex,
729
+ components
730
+ },
731
+ partIndex
732
+ );
733
+ });
734
+ };
735
+
736
+ // src/primitives/message/MessageInProgress.tsx
737
+ import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
738
+ import {
739
+ forwardRef as forwardRef7,
740
+ useMemo as useMemo2
741
+ } from "react";
742
+ import { jsx as jsx12 } from "react/jsx-runtime";
743
+ var MessageInProgress = forwardRef7((props, ref) => {
744
+ const { useMessageUtils } = useMessageContext();
745
+ useMemo2(() => {
746
+ useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ jsx12(Primitive5.span, { ...props, ref }));
747
+ }, [useMessageUtils, props, ref]);
748
+ return null;
749
+ });
750
+ MessageInProgress.displayName = "MessageInProgress";
751
+
752
+ // src/primitives/branchPicker/BranchPickerRoot.tsx
753
+ import { jsx as jsx13 } from "react/jsx-runtime";
754
+ var BranchPickerRoot = forwardRef8(({ hideWhenSingleBranch, ...rest }, ref) => {
755
+ return /* @__PURE__ */ jsx13(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx13(Primitive6.div, { ...rest, ref }) });
756
+ });
757
+ BranchPickerRoot.displayName = "BranchPickerRoot";
758
+
759
+ // src/primitives/composer/index.ts
760
+ var composer_exports = {};
761
+ __export(composer_exports, {
762
+ Cancel: () => ComposerCancel,
763
+ If: () => ComposerIf,
764
+ Input: () => ComposerInput,
765
+ Root: () => ComposerRoot,
766
+ Send: () => ComposerSend
767
+ });
768
+
769
+ // src/primitives/composer/ComposerRoot.tsx
770
+ import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
771
+ import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
772
+ import {
773
+ forwardRef as forwardRef9
774
+ } from "react";
775
+ import { jsx as jsx14 } from "react/jsx-runtime";
776
+ var ComposerRoot = forwardRef9(
777
+ ({ onSubmit, ...rest }, forwardedRef) => {
778
+ const send = useComposerSend();
779
+ const handleSubmit = (e) => {
780
+ if (!send) return;
781
+ e.preventDefault();
782
+ send();
783
+ };
784
+ return /* @__PURE__ */ jsx14(
785
+ Primitive7.form,
786
+ {
787
+ ...rest,
788
+ ref: forwardedRef,
789
+ onSubmit: composeEventHandlers5(onSubmit, handleSubmit)
790
+ }
791
+ );
792
+ }
793
+ );
794
+ ComposerRoot.displayName = "ComposerRoot";
795
+
796
+ // src/primitives/composer/ComposerInput.tsx
797
+ import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
798
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
799
+ import { Slot } from "@radix-ui/react-slot";
800
+ import {
801
+ forwardRef as forwardRef10,
802
+ useCallback as useCallback10,
803
+ useEffect as useEffect3,
804
+ useRef
805
+ } from "react";
806
+ import TextareaAutosize from "react-textarea-autosize";
807
+ import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
808
+ import { jsx as jsx15 } from "react/jsx-runtime";
809
+ var ComposerInput = forwardRef10(
810
+ ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
811
+ const { useThread } = useThreadContext();
812
+ const { useComposer, type } = useComposerContext();
813
+ const value = useComposer((c) => {
814
+ if (!c.isEditing) return "";
815
+ return c.value;
816
+ });
817
+ const Component = asChild ? Slot : TextareaAutosize;
818
+ const textareaRef = useRef(null);
819
+ const ref = useComposedRefs(forwardedRef, textareaRef);
820
+ useEscapeKeydown((e) => {
821
+ const composer = useComposer.getState();
822
+ if (composer.cancel()) {
823
+ e.preventDefault();
824
+ }
825
+ });
826
+ const handleKeyPress = (e) => {
827
+ if (disabled) return;
828
+ if (e.key === "Enter" && e.shiftKey === false) {
829
+ const isRunning = useThread.getState().isRunning;
830
+ if (!isRunning) {
831
+ e.preventDefault();
832
+ textareaRef.current?.closest("form")?.requestSubmit();
833
+ }
834
+ }
835
+ };
836
+ const autoFocusEnabled = autoFocus && !disabled;
837
+ const focus = useCallback10(() => {
838
+ const textarea = textareaRef.current;
839
+ if (!textarea || !autoFocusEnabled) return;
840
+ textarea.focus({ preventScroll: true });
841
+ textarea.setSelectionRange(
842
+ textareaRef.current.value.length,
843
+ textareaRef.current.value.length
844
+ );
845
+ }, [autoFocusEnabled]);
846
+ useEffect3(() => focus(), [focus]);
847
+ useOnComposerFocus(() => {
848
+ if (type === "new") {
849
+ focus();
850
+ }
851
+ });
852
+ return /* @__PURE__ */ jsx15(
853
+ Component,
854
+ {
855
+ value,
856
+ ...rest,
857
+ ref,
858
+ disabled,
859
+ onChange: composeEventHandlers6(onChange, (e) => {
860
+ const composerState = useComposer.getState();
861
+ if (!composerState.isEditing) return;
862
+ return composerState.setValue(e.target.value);
863
+ }),
864
+ onKeyDown: composeEventHandlers6(onKeyDown, handleKeyPress)
865
+ }
866
+ );
867
+ }
868
+ );
869
+ ComposerInput.displayName = "ComposerInput";
870
+
871
+ // src/primitives/composer/ComposerSend.tsx
872
+ import { forwardRef as forwardRef11 } from "react";
873
+ import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
874
+ import { jsx as jsx16 } from "react/jsx-runtime";
875
+ var ComposerSend = forwardRef11(
876
+ ({ disabled, ...rest }, ref) => {
877
+ const { useComposer } = useComposerContext();
878
+ const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
879
+ return /* @__PURE__ */ jsx16(
880
+ Primitive8.button,
881
+ {
882
+ type: "submit",
883
+ ...rest,
884
+ ref,
885
+ disabled: disabled || !hasValue
886
+ }
887
+ );
888
+ }
889
+ );
890
+ ComposerSend.displayName = "ComposerSend";
891
+
892
+ // src/primitives/composer/ComposerCancel.tsx
893
+ var ComposerCancel = createActionButton(
894
+ "ComposerCancel",
895
+ useComposerCancel
896
+ );
897
+
898
+ // src/primitives/composer/ComposerIf.tsx
899
+ var ComposerIf = ({ children, ...query }) => {
900
+ const result = useComposerIf(query);
901
+ return result ? children : null;
902
+ };
903
+
904
+ // src/primitives/contentPart/index.ts
905
+ var contentPart_exports = {};
906
+ __export(contentPart_exports, {
907
+ Display: () => ContentPartDisplay,
908
+ Image: () => ContentPartImage,
909
+ InProgressIndicator: () => ContentPartInProgressIndicator,
910
+ Text: () => ContentPartText
911
+ });
912
+
913
+ // src/primitives/contentPart/ContentPartImage.tsx
914
+ import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
915
+ import { forwardRef as forwardRef12 } from "react";
916
+ import { jsx as jsx17 } from "react/jsx-runtime";
917
+ var ContentPartImage = forwardRef12((props, forwardedRef) => {
918
+ const image = useContentPartImage();
919
+ return /* @__PURE__ */ jsx17(Primitive9.img, { src: image, ...props, ref: forwardedRef });
920
+ });
921
+ ContentPartImage.displayName = "ContentPartImage";
922
+
923
+ // src/primitives/thread/index.ts
924
+ var thread_exports = {};
925
+ __export(thread_exports, {
926
+ Empty: () => ThreadEmpty,
927
+ If: () => ThreadIf,
928
+ Messages: () => ThreadMessages,
929
+ Root: () => ThreadRoot,
930
+ ScrollToBottom: () => ThreadScrollToBottom,
931
+ Suggestion: () => ThreadSuggestion,
932
+ Viewport: () => ThreadViewport
933
+ });
934
+
935
+ // src/primitives/thread/ThreadRoot.tsx
936
+ import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
937
+ import { forwardRef as forwardRef13 } from "react";
938
+ import { jsx as jsx18 } from "react/jsx-runtime";
939
+ var ThreadRoot = forwardRef13(
940
+ (props, ref) => {
941
+ return /* @__PURE__ */ jsx18(Primitive10.div, { ...props, ref });
942
+ }
943
+ );
944
+ ThreadRoot.displayName = "ThreadRoot";
945
+
946
+ // src/primitives/thread/ThreadEmpty.tsx
947
+ var ThreadEmpty = ({ children }) => {
948
+ const empty = useThreadEmpty();
949
+ return empty ? children : null;
950
+ };
951
+
952
+ // src/primitives/thread/ThreadIf.tsx
953
+ var ThreadIf = ({ children, ...query }) => {
954
+ const result = useThreadIf(query);
955
+ return result ? children : null;
956
+ };
957
+
958
+ // src/primitives/thread/ThreadViewport.tsx
959
+ import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
960
+ import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
961
+ import { forwardRef as forwardRef14 } from "react";
962
+
963
+ // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
964
+ import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
965
+ import { useRef as useRef3 } from "react";
966
+
967
+ // src/utils/hooks/useOnResizeContent.tsx
968
+ import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
969
+ import { useCallback as useCallback12 } from "react";
970
+
971
+ // src/utils/hooks/useManagedRef.ts
972
+ import { useCallback as useCallback11, useRef as useRef2 } from "react";
973
+ var useManagedRef = (callback) => {
974
+ const cleanupRef = useRef2();
975
+ const ref = useCallback11(
976
+ (el) => {
977
+ if (cleanupRef.current) {
978
+ cleanupRef.current();
979
+ }
980
+ if (el) {
981
+ cleanupRef.current = callback(el);
982
+ }
983
+ },
984
+ [callback]
985
+ );
986
+ return ref;
987
+ };
988
+
989
+ // src/utils/hooks/useOnResizeContent.tsx
990
+ var useOnResizeContent = (callback) => {
991
+ const callbackRef = useCallbackRef2(callback);
992
+ const refCallback = useCallback12(
993
+ (el) => {
994
+ const resizeObserver = new ResizeObserver(() => {
995
+ callbackRef();
996
+ });
997
+ const mutationObserver = new MutationObserver((mutations) => {
998
+ for (const mutation of mutations) {
999
+ for (const node of mutation.addedNodes) {
1000
+ if (node instanceof Element) {
1001
+ resizeObserver.observe(node);
1002
+ }
1003
+ }
1004
+ for (const node of mutation.removedNodes) {
1005
+ if (node instanceof Element) {
1006
+ resizeObserver.unobserve(node);
1007
+ }
1008
+ }
1009
+ }
1010
+ callbackRef();
1011
+ });
1012
+ resizeObserver.observe(el);
1013
+ mutationObserver.observe(el, { childList: true });
1014
+ for (const child of el.children) {
1015
+ resizeObserver.observe(child);
1016
+ }
1017
+ return () => {
1018
+ resizeObserver.disconnect();
1019
+ mutationObserver.disconnect();
1020
+ };
1021
+ },
1022
+ [callbackRef]
1023
+ );
1024
+ return useManagedRef(refCallback);
1025
+ };
1026
+
1027
+ // src/utils/hooks/useOnScrollToBottom.tsx
1028
+ import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
1029
+ import { useEffect as useEffect4 } from "react";
1030
+ var useOnScrollToBottom = (callback) => {
1031
+ const callbackRef = useCallbackRef3(callback);
1032
+ const { useViewport } = useThreadContext();
1033
+ useEffect4(() => {
1034
+ return useViewport.getState().onScrollToBottom(() => {
1035
+ callbackRef();
1036
+ });
1037
+ }, [useViewport, callbackRef]);
1038
+ };
1039
+
1040
+ // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1041
+ var useThreadViewportAutoScroll = ({
1042
+ autoScroll = true
1043
+ }) => {
1044
+ const divRef = useRef3(null);
1045
+ const { useViewport } = useThreadContext();
1046
+ const firstRenderRef = useRef3(true);
1047
+ const lastScrollTop = useRef3(0);
1048
+ const isScrollingToBottomRef = useRef3(false);
1049
+ const scrollToBottom = () => {
1050
+ const div = divRef.current;
1051
+ if (!div || !autoScroll) return;
1052
+ const behavior = firstRenderRef.current ? "instant" : "auto";
1053
+ firstRenderRef.current = false;
1054
+ isScrollingToBottomRef.current = true;
1055
+ div.scrollTo({ top: div.scrollHeight, behavior });
1056
+ };
1057
+ const handleScroll = () => {
1058
+ const div = divRef.current;
1059
+ if (!div) return;
1060
+ const isAtBottom = useViewport.getState().isAtBottom;
1061
+ const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
1062
+ if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
1063
+ } else {
1064
+ isScrollingToBottomRef.current = newIsAtBottom;
1065
+ if (newIsAtBottom !== isAtBottom) {
1066
+ useViewport.setState({
1067
+ isAtBottom: newIsAtBottom
1068
+ });
1069
+ }
1070
+ }
1071
+ lastScrollTop.current = div.scrollTop;
1072
+ };
1073
+ const resizeRef = useOnResizeContent(() => {
1074
+ if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom && !firstRenderRef.current) {
1075
+ handleScroll();
1076
+ } else {
1077
+ scrollToBottom();
1078
+ }
1079
+ });
1080
+ const scrollRef = useManagedRef((el) => {
1081
+ el.addEventListener("scroll", handleScroll);
1082
+ return () => {
1083
+ el.removeEventListener("scroll", handleScroll);
1084
+ };
1085
+ });
1086
+ const autoScrollRef = useComposedRefs2(resizeRef, scrollRef, divRef);
1087
+ useOnScrollToBottom(() => {
1088
+ scrollToBottom();
1089
+ });
1090
+ return autoScrollRef;
1091
+ };
1092
+
1093
+ // src/primitives/thread/ThreadViewport.tsx
1094
+ import { jsx as jsx19 } from "react/jsx-runtime";
1095
+ var ThreadViewport = forwardRef14(({ autoScroll, onScroll, children, ...rest }, forwardedRef) => {
1096
+ const autoScrollRef = useThreadViewportAutoScroll({
1097
+ autoScroll
1098
+ });
1099
+ const ref = useComposedRefs3(forwardedRef, autoScrollRef);
1100
+ return /* @__PURE__ */ jsx19(Primitive11.div, { ...rest, ref, children });
1101
+ });
1102
+ ThreadViewport.displayName = "ThreadViewport";
1103
+
1104
+ // src/primitives/thread/ThreadMessages.tsx
1105
+ import { memo as memo2 } from "react";
1106
+
1107
+ // src/context/providers/MessageProvider.tsx
1108
+ import { useEffect as useEffect5, useState as useState3 } from "react";
1109
+ import { create as create4 } from "zustand";
1110
+
1111
+ // src/context/stores/EditComposer.ts
1112
+ import { create as create2 } from "zustand";
1113
+
1114
+ // src/context/stores/BaseComposer.ts
1115
+ var makeBaseComposer = (set) => ({
1116
+ value: "",
1117
+ setValue: (value) => {
1118
+ set({ value });
1119
+ }
1120
+ });
1121
+
1122
+ // src/context/stores/EditComposer.ts
1123
+ var makeEditComposerStore = ({
1124
+ onEdit,
1125
+ onSend
1126
+ }) => create2()((set, get, store) => ({
1127
+ ...makeBaseComposer(set, get, store),
1128
+ isEditing: false,
1129
+ edit: () => {
1130
+ const value = onEdit();
1131
+ set({ isEditing: true, value });
1132
+ },
1133
+ send: () => {
1134
+ const value = get().value;
1135
+ set({ isEditing: false });
1136
+ onSend(value);
1137
+ },
1138
+ cancel: () => {
1139
+ if (!get().isEditing) return false;
1140
+ set({ isEditing: false });
1141
+ return true;
1142
+ }
1143
+ }));
1144
+
1145
+ // src/context/stores/MessageUtils.ts
1146
+ import { create as create3 } from "zustand";
1147
+ var makeMessageUtilsStore = () => create3((set) => ({
1148
+ inProgressIndicator: null,
1149
+ setInProgressIndicator: (value) => {
1150
+ set({ inProgressIndicator: value });
1151
+ },
1152
+ isCopied: false,
1153
+ setIsCopied: (value) => {
1154
+ set({ isCopied: value });
1155
+ },
1156
+ isHovering: false,
1157
+ setIsHovering: (value) => {
1158
+ set({ isHovering: value });
1159
+ }
1160
+ }));
1161
+
1162
+ // src/context/providers/MessageProvider.tsx
1163
+ import { jsx as jsx20 } from "react/jsx-runtime";
1164
+ var getIsLast = (thread, message) => {
1165
+ return thread.messages[thread.messages.length - 1]?.id === message.id;
1166
+ };
1167
+ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
1168
+ const parentId = thread.messages[messageIndex - 1]?.id ?? null;
1169
+ const message = thread.messages[messageIndex];
1170
+ if (!message) return;
529
1171
  const isLast = getIsLast(thread, message);
530
1172
  const branches = getBranches(message.id);
531
1173
  const currentState = useMessage.getState();
@@ -540,8 +1182,8 @@ var syncMessage = (thread, getBranches, useMessage, messageIndex) => {
540
1182
  };
541
1183
  var useMessageContext2 = (messageIndex) => {
542
1184
  const { useThread, useThreadActions } = useThreadContext();
543
- const [context] = useState(() => {
544
- const useMessage = create3(() => ({}));
1185
+ const [context] = useState3(() => {
1186
+ const useMessage = create4(() => ({}));
545
1187
  const useMessageUtils = makeMessageUtilsStore();
546
1188
  const useEditComposer = makeEditComposerStore({
547
1189
  onEdit: () => {
@@ -564,6 +1206,7 @@ var useMessageContext2 = (messageIndex) => {
564
1206
  );
565
1207
  useThreadActions.getState().append({
566
1208
  parentId,
1209
+ role: "user",
567
1210
  content: [{ type: "text", text }, ...nonTextParts]
568
1211
  });
569
1212
  }
@@ -576,7 +1219,7 @@ var useMessageContext2 = (messageIndex) => {
576
1219
  );
577
1220
  return { useMessage, useMessageUtils, useEditComposer };
578
1221
  });
579
- useEffect3(() => {
1222
+ useEffect5(() => {
580
1223
  return useThread.subscribe((thread) => {
581
1224
  syncMessage(
582
1225
  thread,
@@ -585,565 +1228,74 @@ var useMessageContext2 = (messageIndex) => {
585
1228
  messageIndex
586
1229
  );
587
1230
  });
588
- }, [useThread, useThreadActions, context, messageIndex]);
589
- return context;
590
- };
591
- var MessageProvider = ({
592
- messageIndex,
593
- children
594
- }) => {
595
- const context = useMessageContext2(messageIndex);
596
- return /* @__PURE__ */ jsx4(MessageContext.Provider, { value: context, children });
597
- };
598
-
599
- // src/primitives/composer/ComposerIf.tsx
600
- var ComposerIf = ({ children, ...query }) => {
601
- const result = useComposerIf(query);
602
- return result ? children : null;
603
- };
604
-
605
- // src/primitives/message/MessageIf.tsx
606
- var MessageIf = ({ children, ...query }) => {
607
- const result = useMessageIf(query);
608
- return result ? children : null;
609
- };
610
-
611
- // src/primitives/thread/ThreadMessages.tsx
612
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
613
- var getComponents = (components) => {
614
- return {
615
- EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
616
- UserMessage: components.UserMessage ?? components.Message,
617
- AssistantMessage: components.AssistantMessage ?? components.Message
618
- };
619
- };
620
- var ThreadMessageImpl = ({
621
- messageIndex,
622
- components
623
- }) => {
624
- const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
625
- return /* @__PURE__ */ jsxs2(MessageProvider, { messageIndex, children: [
626
- /* @__PURE__ */ jsxs2(MessageIf, { user: true, children: [
627
- /* @__PURE__ */ jsx5(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx5(UserMessage, {}) }),
628
- /* @__PURE__ */ jsx5(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx5(EditComposer, {}) })
629
- ] }),
630
- /* @__PURE__ */ jsx5(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx5(AssistantMessage, {}) })
631
- ] });
632
- };
633
- var ThreadMessage = memo(
634
- ThreadMessageImpl,
635
- (prev, next) => prev.messageIndex === next.messageIndex && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
636
- );
637
- var ThreadMessages = ({ components }) => {
638
- const { useThread } = useThreadContext();
639
- const messagesLength = useThread((t) => t.messages.length);
640
- if (messagesLength === 0) return null;
641
- return new Array(messagesLength).fill(null).map((_, idx) => {
642
- const messageIndex = idx;
643
- return /* @__PURE__ */ jsx5(
644
- ThreadMessage,
645
- {
646
- messageIndex,
647
- components
648
- },
649
- messageIndex
650
- );
651
- });
652
- };
653
-
654
- // src/utils/createActionButton.tsx
655
- import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primitive";
656
- import { Primitive as Primitive3 } from "@radix-ui/react-primitive";
657
- import { forwardRef as forwardRef3 } from "react";
658
- import { jsx as jsx6 } from "react/jsx-runtime";
659
- var createActionButton = (displayName, useActionButton) => {
660
- const ActionButton = forwardRef3((props, forwardedRef) => {
661
- const callback = useActionButton(props);
662
- return /* @__PURE__ */ jsx6(
663
- Primitive3.button,
664
- {
665
- type: "button",
666
- disabled: !callback,
667
- ...props,
668
- ref: forwardedRef,
669
- onClick: composeEventHandlers2(props.onClick, () => {
670
- callback?.();
671
- })
672
- }
673
- );
674
- });
675
- ActionButton.displayName = displayName;
676
- return ActionButton;
677
- };
678
-
679
- // src/primitives/thread/ThreadScrollToBottom.tsx
680
- var ThreadScrollToBottom = createActionButton(
681
- "ThreadScrollToBottom",
682
- useThreadScrollToBottom
683
- );
684
-
685
- // src/primitives/thread/ThreadSuggestion.tsx
686
- var ThreadSuggestion = createActionButton(
687
- "ThreadSuggestion",
688
- useThreadSuggestion
689
- );
690
-
691
- // src/primitives/composer/index.ts
692
- var composer_exports = {};
693
- __export(composer_exports, {
694
- Cancel: () => ComposerCancel,
695
- If: () => ComposerIf,
696
- Input: () => ComposerInput,
697
- Root: () => ComposerRoot,
698
- Send: () => ComposerSend
699
- });
700
-
701
- // src/primitives/composer/ComposerRoot.tsx
702
- import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
703
- import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
704
- import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
705
- import {
706
- forwardRef as forwardRef4,
707
- useRef as useRef2
708
- } from "react";
709
- import { jsx as jsx7 } from "react/jsx-runtime";
710
- var ComposerRoot = forwardRef4(
711
- ({ onSubmit, ...rest }, forwardedRef) => {
712
- const { useViewport } = useThreadContext();
713
- const { useComposer } = useComposerContext();
714
- const formRef = useRef2(null);
715
- const ref = useComposedRefs2(forwardedRef, formRef);
716
- const handleSubmit = (e) => {
717
- const composerState = useComposer.getState();
718
- if (!composerState.isEditing) return;
719
- e.preventDefault();
720
- composerState.send();
721
- useViewport.getState().scrollToBottom();
722
- };
723
- return /* @__PURE__ */ jsx7(
724
- Primitive4.form,
725
- {
726
- ...rest,
727
- ref,
728
- onSubmit: composeEventHandlers3(onSubmit, handleSubmit)
729
- }
730
- );
731
- }
732
- );
733
- ComposerRoot.displayName = "ComposerRoot";
734
-
735
- // src/primitives/composer/ComposerInput.tsx
736
- import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
737
- import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
738
- import { Slot } from "@radix-ui/react-slot";
739
- import {
740
- forwardRef as forwardRef5,
741
- useCallback as useCallback10,
742
- useEffect as useEffect4,
743
- useRef as useRef3
744
- } from "react";
745
- import TextareaAutosize from "react-textarea-autosize";
746
- import { jsx as jsx8 } from "react/jsx-runtime";
747
- var ComposerInput = forwardRef5(
748
- ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
749
- const { useThread } = useThreadContext();
750
- const { useComposer, type } = useComposerContext();
751
- const value = useComposer((c) => {
752
- if (!c.isEditing) return "";
753
- return c.value;
754
- });
755
- const Component = asChild ? Slot : TextareaAutosize;
756
- const textareaRef = useRef3(null);
757
- const ref = useComposedRefs3(forwardedRef, textareaRef);
758
- const handleKeyPress = (e) => {
759
- if (disabled) return;
760
- if (e.key === "Escape") {
761
- const composer = useComposer.getState();
762
- if (composer.cancel()) {
763
- e.preventDefault();
764
- }
765
- } else if (e.key === "Enter" && e.shiftKey === false) {
766
- const isRunning = useThread.getState().isRunning;
767
- if (!isRunning) {
768
- e.preventDefault();
769
- textareaRef.current?.closest("form")?.requestSubmit();
770
- }
771
- }
772
- };
773
- const autoFocusEnabled = autoFocus && !disabled;
774
- const focus = useCallback10(() => {
775
- const textarea = textareaRef.current;
776
- if (!textarea || !autoFocusEnabled) return;
777
- textarea.focus();
778
- textarea.setSelectionRange(
779
- textareaRef.current.value.length,
780
- textareaRef.current.value.length
781
- );
782
- }, [autoFocusEnabled]);
783
- useEffect4(() => focus(), [focus]);
784
- useOnScrollToBottom(() => {
785
- if (type === "new") {
786
- focus();
787
- }
788
- });
789
- return /* @__PURE__ */ jsx8(
790
- Component,
791
- {
792
- value,
793
- ...rest,
794
- ref,
795
- autoFocus,
796
- disabled,
797
- onChange: composeEventHandlers4(onChange, (e) => {
798
- const composerState = useComposer.getState();
799
- if (!composerState.isEditing) return;
800
- return composerState.setValue(e.target.value);
801
- }),
802
- onKeyDown: composeEventHandlers4(onKeyDown, handleKeyPress)
803
- }
804
- );
805
- }
806
- );
807
- ComposerInput.displayName = "ComposerInput";
808
-
809
- // src/primitives/composer/ComposerSend.tsx
810
- var ComposerSend = createActionButton("ComposerSend", useComposerSend);
811
-
812
- // src/primitives/composer/ComposerCancel.tsx
813
- var ComposerCancel = createActionButton(
814
- "ComposerCancel",
815
- useComposerCancel
816
- );
817
-
818
- // src/primitives/message/index.ts
819
- var message_exports = {};
820
- __export(message_exports, {
821
- Content: () => MessageContent,
822
- If: () => MessageIf,
823
- InProgress: () => MessageInProgress,
824
- Root: () => MessageRoot
825
- });
826
-
827
- // src/primitives/message/MessageRoot.tsx
828
- import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
829
- import { Primitive as Primitive5 } from "@radix-ui/react-primitive";
830
- import { forwardRef as forwardRef6 } from "react";
831
- import { jsx as jsx9 } from "react/jsx-runtime";
832
- var MessageRoot = forwardRef6(
833
- ({ onMouseEnter, onMouseLeave, ...rest }, ref) => {
834
- const { useMessageUtils } = useMessageContext();
835
- const setIsHovering = useMessageUtils((s) => s.setIsHovering);
836
- const handleMouseEnter = () => {
837
- setIsHovering(true);
838
- };
839
- const handleMouseLeave = () => {
840
- setIsHovering(false);
841
- };
842
- return /* @__PURE__ */ jsx9(
843
- Primitive5.div,
844
- {
845
- ...rest,
846
- ref,
847
- onMouseEnter: composeEventHandlers5(onMouseEnter, handleMouseEnter),
848
- onMouseLeave: composeEventHandlers5(onMouseLeave, handleMouseLeave)
849
- }
850
- );
851
- }
852
- );
853
- MessageRoot.displayName = "MessageRoot";
854
-
855
- // src/primitives/message/MessageContent.tsx
856
- import { memo as memo2 } from "react";
857
-
858
- // src/context/providers/ContentPartProvider.tsx
859
- import { useEffect as useEffect5, useState as useState2 } from "react";
860
- import { create as create4 } from "zustand";
861
- import { jsx as jsx10 } from "react/jsx-runtime";
862
- var syncContentPart = ({ message }, useContentPart, partIndex) => {
863
- const part = message.content[partIndex];
864
- if (!part) return;
865
- const messageStatus = message.role === "assistant" ? message.status : "done";
866
- const status = partIndex === message.content.length - 1 ? messageStatus : "done";
867
- const currentState = useContentPart.getState();
868
- if (currentState.part === part && currentState.status === status) return;
869
- useContentPart.setState(
870
- Object.freeze({
871
- part,
872
- status
873
- })
874
- );
875
- };
876
- var useContentPartContext2 = (partIndex) => {
877
- const { useMessage } = useMessageContext();
878
- const [context] = useState2(() => {
879
- const useContentPart = create4(
880
- () => ({})
881
- );
882
- syncContentPart(useMessage.getState(), useContentPart, partIndex);
883
- return { useContentPart };
884
- });
885
- useEffect5(() => {
886
- syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
887
- return useMessage.subscribe((message) => {
888
- syncContentPart(message, context.useContentPart, partIndex);
889
- });
890
- }, [context, useMessage, partIndex]);
1231
+ }, [useThread, useThreadActions, context, messageIndex]);
891
1232
  return context;
892
1233
  };
893
- var ContentPartProvider = ({
894
- partIndex,
1234
+ var MessageProvider = ({
1235
+ messageIndex,
895
1236
  children
896
1237
  }) => {
897
- const context = useContentPartContext2(partIndex);
898
- return /* @__PURE__ */ jsx10(ContentPartContext.Provider, { value: context, children });
899
- };
900
-
901
- // src/primitives/contentPart/ContentPartDisplay.tsx
902
- var ContentPartDisplay = () => {
903
- const display = useContentPartDisplay();
904
- return display ?? null;
905
- };
906
-
907
- // src/primitives/contentPart/ContentPartInProgressIndicator.tsx
908
- var ContentPartInProgressIndicator = () => {
909
- const indicator = useContentPartInProgressIndicator();
910
- return indicator;
1238
+ const context = useMessageContext2(messageIndex);
1239
+ return /* @__PURE__ */ jsx20(MessageContext.Provider, { value: context, children });
911
1240
  };
912
1241
 
913
- // src/primitives/contentPart/ContentPartText.tsx
914
- import { Primitive as Primitive6 } from "@radix-ui/react-primitive";
915
- import { forwardRef as forwardRef7 } from "react";
916
- import { jsx as jsx11 } from "react/jsx-runtime";
917
- var ContentPartText = forwardRef7((props, forwardedRef) => {
918
- const text = useContentPartText();
919
- return /* @__PURE__ */ jsx11(Primitive6.span, { ...props, ref: forwardedRef, children: text });
920
- });
921
- ContentPartText.displayName = "ContentPartText";
922
-
923
- // src/primitives/message/MessageContent.tsx
924
- import { Fragment, jsx as jsx12, jsxs as jsxs3 } from "react/jsx-runtime";
925
- var defaultComponents = {
926
- Text: () => /* @__PURE__ */ jsxs3(Fragment, { children: [
927
- /* @__PURE__ */ jsx12(ContentPartText, {}),
928
- /* @__PURE__ */ jsx12(ContentPartInProgressIndicator, {})
929
- ] }),
930
- Image: () => null,
931
- UI: () => /* @__PURE__ */ jsx12(ContentPartDisplay, {}),
932
- tools: {
933
- Fallback: (props) => {
934
- const { useToolUIs } = useAssistantContext();
935
- const Render = useToolUIs((s) => s.getToolUI(props.part.toolName));
936
- if (!Render) return null;
937
- return /* @__PURE__ */ jsx12(Render, { ...props });
938
- }
939
- }
940
- };
941
- var MessageContentPartComponent = ({
942
- components: {
943
- Text = defaultComponents.Text,
944
- Image = defaultComponents.Image,
945
- UI = defaultComponents.UI,
946
- tools: { by_name = {}, Fallback = defaultComponents.tools.Fallback } = {}
947
- } = {}
948
- }) => {
949
- const { useThreadActions } = useThreadContext();
950
- const addToolResult = useThreadActions((t) => t.addToolResult);
951
- const { useContentPart } = useContentPartContext();
952
- const { part, status } = useContentPart();
953
- const type = part.type;
954
- switch (type) {
955
- case "text":
956
- return /* @__PURE__ */ jsx12(Text, { part, status });
957
- case "image":
958
- return /* @__PURE__ */ jsx12(Image, { part, status });
959
- case "ui":
960
- return /* @__PURE__ */ jsx12(UI, { part, status });
961
- case "tool-call": {
962
- const Tool = by_name[part.toolName] || Fallback;
963
- const addResult = (result) => addToolResult(part.toolCallId, result);
964
- return /* @__PURE__ */ jsx12(Tool, { part, status, addResult });
965
- }
966
- default:
967
- throw new Error(`Unknown content part type: ${type}`);
968
- }
1242
+ // src/primitives/thread/ThreadMessages.tsx
1243
+ import { jsx as jsx21, jsxs as jsxs2 } from "react/jsx-runtime";
1244
+ var getComponents = (components) => {
1245
+ return {
1246
+ EditComposer: components.EditComposer ?? components.UserMessage ?? components.Message,
1247
+ UserMessage: components.UserMessage ?? components.Message,
1248
+ AssistantMessage: components.AssistantMessage ?? components.Message
1249
+ };
969
1250
  };
970
- var MessageContentPartImpl = ({
971
- partIndex,
1251
+ var ThreadMessageImpl = ({
1252
+ messageIndex,
972
1253
  components
973
1254
  }) => {
974
- return /* @__PURE__ */ jsx12(ContentPartProvider, { partIndex, children: /* @__PURE__ */ jsx12(MessageContentPartComponent, { components }) });
1255
+ const { UserMessage, EditComposer, AssistantMessage } = getComponents(components);
1256
+ return /* @__PURE__ */ jsxs2(MessageProvider, { messageIndex, children: [
1257
+ /* @__PURE__ */ jsxs2(MessageIf, { user: true, children: [
1258
+ /* @__PURE__ */ jsx21(ComposerIf, { editing: false, children: /* @__PURE__ */ jsx21(UserMessage, {}) }),
1259
+ /* @__PURE__ */ jsx21(ComposerIf, { editing: true, children: /* @__PURE__ */ jsx21(EditComposer, {}) })
1260
+ ] }),
1261
+ /* @__PURE__ */ jsx21(MessageIf, { assistant: true, children: /* @__PURE__ */ jsx21(AssistantMessage, {}) })
1262
+ ] });
975
1263
  };
976
- var MessageContentPart = memo2(
977
- MessageContentPartImpl,
978
- (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
1264
+ var ThreadMessage = memo2(
1265
+ ThreadMessageImpl,
1266
+ (prev, next) => prev.messageIndex === next.messageIndex && prev.components.UserMessage === next.components.UserMessage && prev.components.EditComposer === next.components.EditComposer && prev.components.AssistantMessage === next.components.AssistantMessage
979
1267
  );
980
- var MessageContent = ({ components }) => {
981
- const { useMessage } = useMessageContext();
982
- const contentLength = useMessage((s) => s.message.content.length);
983
- return new Array(contentLength).fill(null).map((_, idx) => {
984
- const partIndex = idx;
985
- return /* @__PURE__ */ jsx12(
986
- MessageContentPart,
1268
+ var ThreadMessages = ({ components }) => {
1269
+ const { useThread } = useThreadContext();
1270
+ const messagesLength = useThread((t) => t.messages.length);
1271
+ if (messagesLength === 0) return null;
1272
+ return new Array(messagesLength).fill(null).map((_, idx) => {
1273
+ const messageIndex = idx;
1274
+ return /* @__PURE__ */ jsx21(
1275
+ ThreadMessage,
987
1276
  {
988
- partIndex,
1277
+ messageIndex,
989
1278
  components
990
1279
  },
991
- partIndex
1280
+ messageIndex
992
1281
  );
993
1282
  });
994
1283
  };
995
1284
 
996
- // src/primitives/message/MessageInProgress.tsx
997
- import { Primitive as Primitive7 } from "@radix-ui/react-primitive";
998
- import {
999
- forwardRef as forwardRef8,
1000
- useMemo as useMemo2
1001
- } from "react";
1002
- import { jsx as jsx13 } from "react/jsx-runtime";
1003
- var MessageInProgress = forwardRef8((props, ref) => {
1004
- const { useMessageUtils } = useMessageContext();
1005
- useMemo2(() => {
1006
- useMessageUtils.getState().setInProgressIndicator(/* @__PURE__ */ jsx13(Primitive7.span, { ...props, ref }));
1007
- }, [useMessageUtils, props, ref]);
1008
- return null;
1009
- });
1010
- MessageInProgress.displayName = "MessageInProgress";
1011
-
1012
- // src/primitives/branchPicker/index.ts
1013
- var branchPicker_exports = {};
1014
- __export(branchPicker_exports, {
1015
- Count: () => BranchPickerCount,
1016
- Next: () => BranchPickerNext,
1017
- Number: () => BranchPickerNumber,
1018
- Previous: () => BranchPickerPrevious,
1019
- Root: () => BranchPickerRoot
1020
- });
1021
-
1022
- // src/primitives/branchPicker/BranchPickerNext.tsx
1023
- var BranchPickerNext = createActionButton(
1024
- "BranchPickerNext",
1025
- useBranchPickerNext
1026
- );
1027
-
1028
- // src/primitives/branchPicker/BranchPickerPrevious.tsx
1029
- var BranchPickerPrevious = createActionButton(
1030
- "BranchPickerPrevious",
1031
- useBranchPickerPrevious
1032
- );
1033
-
1034
- // src/primitives/branchPicker/BranchPickerCount.tsx
1035
- import { Fragment as Fragment2, jsx as jsx14 } from "react/jsx-runtime";
1036
- var BranchPickerCount = () => {
1037
- const branchCount = useBranchPickerCount();
1038
- return /* @__PURE__ */ jsx14(Fragment2, { children: branchCount });
1039
- };
1040
-
1041
- // src/primitives/branchPicker/BranchPickerNumber.tsx
1042
- import { Fragment as Fragment3, jsx as jsx15 } from "react/jsx-runtime";
1043
- var BranchPickerNumber = () => {
1044
- const branchNumber = useBranchPickerNumber();
1045
- return /* @__PURE__ */ jsx15(Fragment3, { children: branchNumber });
1046
- };
1047
-
1048
- // src/primitives/branchPicker/BranchPickerRoot.tsx
1049
- import { Primitive as Primitive8 } from "@radix-ui/react-primitive";
1050
- import { forwardRef as forwardRef9 } from "react";
1051
- import { jsx as jsx16 } from "react/jsx-runtime";
1052
- var BranchPickerRoot = forwardRef9(({ hideWhenSingleBranch, ...rest }, ref) => {
1053
- return /* @__PURE__ */ jsx16(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0, children: /* @__PURE__ */ jsx16(Primitive8.div, { ...rest, ref }) });
1054
- });
1055
- BranchPickerRoot.displayName = "BranchPickerRoot";
1056
-
1057
- // src/primitives/actionBar/index.ts
1058
- var actionBar_exports = {};
1059
- __export(actionBar_exports, {
1060
- Copy: () => ActionBarCopy,
1061
- Edit: () => ActionBarEdit,
1062
- Reload: () => ActionBarReload,
1063
- Root: () => ActionBarRoot
1064
- });
1065
-
1066
- // src/primitives/actionBar/ActionBarRoot.tsx
1067
- import { Primitive as Primitive9 } from "@radix-ui/react-primitive";
1068
- import { forwardRef as forwardRef10 } from "react";
1069
- import { jsx as jsx17 } from "react/jsx-runtime";
1070
- var useActionBarFloatStatus = ({
1071
- hideWhenRunning,
1072
- autohide,
1073
- autohideFloat
1074
- }) => {
1075
- const { useThread } = useThreadContext();
1076
- const { useMessage, useMessageUtils } = useMessageContext();
1077
- return useCombinedStore(
1078
- [useThread, useMessage, useMessageUtils],
1079
- (t, m, mu) => {
1080
- if (hideWhenRunning && t.isRunning) return "hidden" /* Hidden */;
1081
- const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
1082
- if (!autohideEnabled) return "normal" /* Normal */;
1083
- if (!mu.isHovering) return "hidden" /* Hidden */;
1084
- if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branches.length <= 1)
1085
- return "floating" /* Floating */;
1086
- return "normal" /* Normal */;
1087
- }
1088
- );
1089
- };
1090
- var ActionBarRoot = forwardRef10(({ hideWhenRunning, autohide, autohideFloat, ...rest }, ref) => {
1091
- const hideAndfloatStatus = useActionBarFloatStatus({
1092
- hideWhenRunning,
1093
- autohide,
1094
- autohideFloat
1095
- });
1096
- if (hideAndfloatStatus === "hidden" /* Hidden */) return null;
1097
- return /* @__PURE__ */ jsx17(
1098
- Primitive9.div,
1099
- {
1100
- ...hideAndfloatStatus === "floating" /* Floating */ ? { "data-floating": "true" } : null,
1101
- ...rest,
1102
- ref
1103
- }
1104
- );
1105
- });
1106
- ActionBarRoot.displayName = "ActionBarRoot";
1107
-
1108
- // src/primitives/actionBar/ActionBarCopy.tsx
1109
- var ActionBarCopy = createActionButton(
1110
- "ActionBarCopy",
1111
- useActionBarCopy
1112
- );
1113
-
1114
- // src/primitives/actionBar/ActionBarReload.tsx
1115
- var ActionBarReload = createActionButton(
1116
- "ActionBarReload",
1117
- useActionBarReload
1285
+ // src/primitives/thread/ThreadScrollToBottom.tsx
1286
+ var ThreadScrollToBottom = createActionButton(
1287
+ "ThreadScrollToBottom",
1288
+ useThreadScrollToBottom
1118
1289
  );
1119
1290
 
1120
- // src/primitives/actionBar/ActionBarEdit.tsx
1121
- var ActionBarEdit = createActionButton(
1122
- "ActionBarEdit",
1123
- useActionBarEdit
1291
+ // src/primitives/thread/ThreadSuggestion.tsx
1292
+ var ThreadSuggestion = createActionButton(
1293
+ "ThreadSuggestion",
1294
+ useThreadSuggestion
1124
1295
  );
1125
1296
 
1126
- // src/primitives/contentPart/index.ts
1127
- var contentPart_exports = {};
1128
- __export(contentPart_exports, {
1129
- Display: () => ContentPartDisplay,
1130
- Image: () => ContentPartImage,
1131
- InProgressIndicator: () => ContentPartInProgressIndicator,
1132
- Text: () => ContentPartText
1133
- });
1134
-
1135
- // src/primitives/contentPart/ContentPartImage.tsx
1136
- import { Primitive as Primitive10 } from "@radix-ui/react-primitive";
1137
- import { forwardRef as forwardRef11 } from "react";
1138
- import { jsx as jsx18 } from "react/jsx-runtime";
1139
- var ContentPartImage = forwardRef11((props, forwardedRef) => {
1140
- const image = useContentPartImage();
1141
- return /* @__PURE__ */ jsx18(Primitive10.img, { src: image, ...props, ref: forwardedRef });
1142
- });
1143
- ContentPartImage.displayName = "ContentPartImage";
1144
-
1145
1297
  // src/runtime/local/useLocalRuntime.tsx
1146
- import { useInsertionEffect, useState as useState3 } from "react";
1298
+ import { useInsertionEffect, useState as useState4 } from "react";
1147
1299
 
1148
1300
  // src/utils/ModelConfigTypes.ts
1149
1301
  var mergeModelConfigs = (configSet) => {
@@ -1429,7 +1581,7 @@ var LocalRuntime = class {
1429
1581
 
1430
1582
  // src/runtime/local/useLocalRuntime.tsx
1431
1583
  var useLocalRuntime = (adapter) => {
1432
- const [runtime] = useState3(() => new LocalRuntime(adapter));
1584
+ const [runtime] = useState4(() => new LocalRuntime(adapter));
1433
1585
  useInsertionEffect(() => {
1434
1586
  runtime.adapter = adapter;
1435
1587
  });
@@ -1440,7 +1592,7 @@ var useLocalRuntime = (adapter) => {
1440
1592
  import { memo as memo3 } from "react";
1441
1593
 
1442
1594
  // src/context/providers/AssistantProvider.tsx
1443
- import { useEffect as useEffect7, useInsertionEffect as useInsertionEffect3, useRef as useRef5, useState as useState5 } from "react";
1595
+ import { useEffect as useEffect7, useInsertionEffect as useInsertionEffect3, useRef as useRef5, useState as useState6 } from "react";
1444
1596
 
1445
1597
  // src/context/stores/AssistantModelConfig.ts
1446
1598
  import { create as create5 } from "zustand";
@@ -1505,30 +1657,45 @@ var makeAssistantToolUIsStore = () => create6((set) => {
1505
1657
  });
1506
1658
 
1507
1659
  // src/context/providers/ThreadProvider.tsx
1508
- import { useEffect as useEffect6, useInsertionEffect as useInsertionEffect2, useRef as useRef4, useState as useState4 } from "react";
1660
+ import { useEffect as useEffect6, useInsertionEffect as useInsertionEffect2, useRef as useRef4, useState as useState5 } from "react";
1509
1661
 
1510
1662
  // src/context/stores/Composer.ts
1511
1663
  import { create as create7 } from "zustand";
1512
- var makeComposerStore = (useThread, useThreadActions) => create7()((set, get, store) => {
1513
- return {
1514
- ...makeBaseComposer(set, get, store),
1515
- isEditing: true,
1516
- send: () => {
1517
- const { setValue, value } = get();
1518
- setValue("");
1519
- useThreadActions.getState().append({
1520
- parentId: useThread.getState().messages.at(-1)?.id ?? null,
1521
- content: [{ type: "text", text: value }]
1522
- });
1523
- },
1524
- cancel: () => {
1525
- const thread = useThread.getState();
1526
- if (!thread.isRunning) return false;
1527
- useThreadActions.getState().cancelRun();
1528
- return true;
1529
- }
1530
- };
1531
- });
1664
+ var makeComposerStore = (useThread, useThreadActions) => {
1665
+ const focusListeners = /* @__PURE__ */ new Set();
1666
+ return create7()((set, get, store) => {
1667
+ return {
1668
+ ...makeBaseComposer(set, get, store),
1669
+ isEditing: true,
1670
+ send: () => {
1671
+ const { setValue, value } = get();
1672
+ setValue("");
1673
+ useThreadActions.getState().append({
1674
+ parentId: useThread.getState().messages.at(-1)?.id ?? null,
1675
+ role: "user",
1676
+ content: [{ type: "text", text: value }]
1677
+ });
1678
+ },
1679
+ cancel: () => {
1680
+ const thread = useThread.getState();
1681
+ if (!thread.isRunning) return false;
1682
+ useThreadActions.getState().cancelRun();
1683
+ return true;
1684
+ },
1685
+ focus: () => {
1686
+ for (const listener of focusListeners) {
1687
+ listener();
1688
+ }
1689
+ },
1690
+ onFocus: (listener) => {
1691
+ focusListeners.add(listener);
1692
+ return () => {
1693
+ focusListeners.delete(listener);
1694
+ };
1695
+ }
1696
+ };
1697
+ });
1698
+ };
1532
1699
 
1533
1700
  // src/context/stores/Thread.ts
1534
1701
  import { create as create8 } from "zustand";
@@ -1575,7 +1742,7 @@ var makeThreadActionStore = (runtimeRef) => {
1575
1742
  };
1576
1743
 
1577
1744
  // src/context/providers/ThreadProvider.tsx
1578
- import { jsx as jsx19, jsxs as jsxs4 } from "react/jsx-runtime";
1745
+ import { jsx as jsx22, jsxs as jsxs3 } from "react/jsx-runtime";
1579
1746
  var ThreadProvider = ({
1580
1747
  children,
1581
1748
  runtime
@@ -1584,7 +1751,7 @@ var ThreadProvider = ({
1584
1751
  useInsertionEffect2(() => {
1585
1752
  runtimeRef.current = runtime;
1586
1753
  });
1587
- const [context] = useState4(() => {
1754
+ const [context] = useState5(() => {
1588
1755
  const useThread = makeThreadStore(runtimeRef);
1589
1756
  const useThreadActions = makeThreadActionStore(runtimeRef);
1590
1757
  const useViewport = makeThreadViewportStore();
@@ -1610,20 +1777,20 @@ var ThreadProvider = ({
1610
1777
  return runtime.subscribe(onRuntimeUpdate);
1611
1778
  }, [context, runtime]);
1612
1779
  const RuntimeSynchronizer = runtime.unstable_synchronizer;
1613
- return /* @__PURE__ */ jsxs4(ThreadContext.Provider, { value: context, children: [
1614
- RuntimeSynchronizer && /* @__PURE__ */ jsx19(RuntimeSynchronizer, {}),
1780
+ return /* @__PURE__ */ jsxs3(ThreadContext.Provider, { value: context, children: [
1781
+ RuntimeSynchronizer && /* @__PURE__ */ jsx22(RuntimeSynchronizer, {}),
1615
1782
  children
1616
1783
  ] });
1617
1784
  };
1618
1785
 
1619
1786
  // src/context/providers/AssistantProvider.tsx
1620
- import { jsx as jsx20 } from "react/jsx-runtime";
1787
+ import { jsx as jsx23 } from "react/jsx-runtime";
1621
1788
  var AssistantProvider = ({ children, runtime }) => {
1622
1789
  const runtimeRef = useRef5(runtime);
1623
1790
  useInsertionEffect3(() => {
1624
1791
  runtimeRef.current = runtime;
1625
1792
  });
1626
- const [context] = useState5(() => {
1793
+ const [context] = useState6(() => {
1627
1794
  const useModelConfig = makeAssistantModelConfigStore();
1628
1795
  const useToolUIs = makeAssistantToolUIsStore();
1629
1796
  return { useModelConfig, useToolUIs };
@@ -1632,13 +1799,13 @@ var AssistantProvider = ({ children, runtime }) => {
1632
1799
  useEffect7(() => {
1633
1800
  return runtime.registerModelConfigProvider(getModelCOnfig);
1634
1801
  }, [runtime, getModelCOnfig]);
1635
- return /* @__PURE__ */ jsx20(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx20(ThreadProvider, { runtime, children }) });
1802
+ return /* @__PURE__ */ jsx23(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx23(ThreadProvider, { runtime, children }) });
1636
1803
  };
1637
1804
 
1638
1805
  // src/context/providers/AssistantRuntimeProvider.tsx
1639
- import { jsx as jsx21 } from "react/jsx-runtime";
1806
+ import { jsx as jsx24 } from "react/jsx-runtime";
1640
1807
  var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
1641
- return /* @__PURE__ */ jsx21(AssistantProvider, { runtime, children });
1808
+ return /* @__PURE__ */ jsx24(AssistantProvider, { runtime, children });
1642
1809
  };
1643
1810
  var AssistantRuntimeProvider = memo3(AssistantRuntimeProviderImpl);
1644
1811
 
@@ -1650,6 +1817,7 @@ __export(internal_exports, {
1650
1817
  });
1651
1818
  export {
1652
1819
  actionBar_exports as ActionBarPrimitive,
1820
+ assistantModal_exports as AssistantModalPrimitive,
1653
1821
  AssistantRuntimeProvider,
1654
1822
  branchPicker_exports as BranchPickerPrimitive,
1655
1823
  composer_exports as ComposerPrimitive,