@assistant-ui/react 0.0.7 → 0.0.8
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.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +290 -192
- package/dist/index.mjs +278 -179
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
@@ -11,6 +11,7 @@ __export(thread_exports, {
|
|
11
11
|
If: () => ThreadIf,
|
12
12
|
Messages: () => ThreadMessages,
|
13
13
|
Root: () => ThreadRoot,
|
14
|
+
ScrollToBottom: () => ThreadScrollToBottom,
|
14
15
|
Viewport: () => ThreadViewport
|
15
16
|
});
|
16
17
|
|
@@ -68,7 +69,7 @@ import { useComposedRefs } from "@radix-ui/react-compose-refs";
|
|
68
69
|
import {
|
69
70
|
Primitive as Primitive2
|
70
71
|
} from "@radix-ui/react-primitive";
|
71
|
-
import { forwardRef as forwardRef2, useRef as
|
72
|
+
import { forwardRef as forwardRef2, useRef as useRef3 } from "react";
|
72
73
|
|
73
74
|
// src/utils/hooks/useOnResizeContent.tsx
|
74
75
|
import { useLayoutEffect, useRef } from "react";
|
@@ -109,22 +110,51 @@ var useOnResizeContent = (ref, callback) => {
|
|
109
110
|
}, [ref.current]);
|
110
111
|
};
|
111
112
|
|
113
|
+
// src/utils/hooks/useOnScrollToBottom.tsx
|
114
|
+
import { useEffect, useRef as useRef2 } from "react";
|
115
|
+
var useOnScrollToBottom = (callback) => {
|
116
|
+
const callbackRef = useRef2(callback);
|
117
|
+
callbackRef.current = callback;
|
118
|
+
const { useThread } = useAssistantContext();
|
119
|
+
useEffect(() => {
|
120
|
+
return useThread.getState().onScrollToBottom(() => {
|
121
|
+
callbackRef.current();
|
122
|
+
});
|
123
|
+
}, [useThread]);
|
124
|
+
};
|
125
|
+
|
112
126
|
// src/primitives/thread/ThreadViewport.tsx
|
113
|
-
var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef) => {
|
114
|
-
const
|
127
|
+
var ThreadViewport = forwardRef2(({ autoScroll = true, onScroll, children, ...rest }, forwardedRef) => {
|
128
|
+
const messagesEndRef = useRef3(null);
|
129
|
+
const divRef = useRef3(null);
|
115
130
|
const ref = useComposedRefs(forwardedRef, divRef);
|
116
|
-
const
|
131
|
+
const { useThread } = useAssistantContext();
|
132
|
+
const firstRenderRef = useRef3(true);
|
133
|
+
const scrollToBottom = () => {
|
134
|
+
const div = messagesEndRef.current;
|
135
|
+
if (!div || !autoScroll)
|
136
|
+
return;
|
137
|
+
const behavior = firstRenderRef.current ? "instant" : "auto";
|
138
|
+
firstRenderRef.current = false;
|
139
|
+
div.scrollIntoView({ behavior });
|
140
|
+
};
|
117
141
|
useOnResizeContent(divRef, () => {
|
118
|
-
|
119
|
-
if (!div || !isAtBottom)
|
142
|
+
if (!useThread.getState().isAtBottom)
|
120
143
|
return;
|
121
|
-
|
144
|
+
scrollToBottom();
|
145
|
+
});
|
146
|
+
useOnScrollToBottom(() => {
|
147
|
+
scrollToBottom();
|
122
148
|
});
|
123
149
|
const handleScroll = () => {
|
124
150
|
const div = divRef.current;
|
125
151
|
if (!div)
|
126
152
|
return;
|
127
|
-
|
153
|
+
const isAtBottom = useThread.getState().isAtBottom;
|
154
|
+
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight + 50;
|
155
|
+
if (newIsAtBottom !== isAtBottom) {
|
156
|
+
useThread.setState({ isAtBottom: newIsAtBottom });
|
157
|
+
}
|
128
158
|
};
|
129
159
|
return /* @__PURE__ */ React.createElement(
|
130
160
|
Primitive2.div,
|
@@ -133,12 +163,13 @@ var ThreadViewport = forwardRef2(({ onScroll, children, ...rest }, forwardedRef)
|
|
133
163
|
onScroll: composeEventHandlers(onScroll, handleScroll),
|
134
164
|
ref
|
135
165
|
},
|
136
|
-
children
|
166
|
+
children,
|
167
|
+
/* @__PURE__ */ React.createElement("div", { ref: messagesEndRef })
|
137
168
|
);
|
138
169
|
});
|
139
170
|
|
140
171
|
// src/vercel/useVercelAIBranches.tsx
|
141
|
-
import { useCallback, useMemo, useRef as
|
172
|
+
import { useCallback, useMemo, useRef as useRef4 } from "react";
|
142
173
|
var ROOT_ID = "__ROOT_ID__";
|
143
174
|
var UPCOMING_MESSAGE_ID = "__UPCOMING_MESSAGE_ID__";
|
144
175
|
var updateBranchData = (data, messages) => {
|
@@ -205,8 +236,8 @@ var sliceMessagesUntil = (messages, message) => {
|
|
205
236
|
throw new Error("Unexpected: Message not found");
|
206
237
|
return messages.slice(0, messageIdx);
|
207
238
|
};
|
208
|
-
var useVercelAIBranches = (chat) => {
|
209
|
-
const data =
|
239
|
+
var useVercelAIBranches = (chat, context) => {
|
240
|
+
const data = useRef4({
|
210
241
|
parentMap: /* @__PURE__ */ new Map(),
|
211
242
|
branchMap: /* @__PURE__ */ new Map(),
|
212
243
|
snapshots: /* @__PURE__ */ new Map()
|
@@ -237,9 +268,10 @@ var useVercelAIBranches = (chat) => {
|
|
237
268
|
throw new Error("Reload not supported by Vercel AI SDK's useAssistant");
|
238
269
|
const newMessages = sliceMessagesUntil(chat.messages, message);
|
239
270
|
chat.setMessages(newMessages);
|
271
|
+
context.useThread.getState().scrollToBottom();
|
240
272
|
await reloadMaybe();
|
241
273
|
},
|
242
|
-
[chat.messages, chat.setMessages, reloadMaybe]
|
274
|
+
[context, chat.messages, chat.setMessages, reloadMaybe]
|
243
275
|
);
|
244
276
|
const editAt = useCallback(
|
245
277
|
async (message, newMessage) => {
|
@@ -247,12 +279,13 @@ var useVercelAIBranches = (chat) => {
|
|
247
279
|
chat.setMessages(newMessages);
|
248
280
|
if (newMessage.content[0]?.type !== "text")
|
249
281
|
throw new Error("Only text content is currently supported");
|
282
|
+
context.useThread.getState().scrollToBottom();
|
250
283
|
await chat.append({
|
251
284
|
role: "user",
|
252
285
|
content: newMessage.content[0].text
|
253
286
|
});
|
254
287
|
},
|
255
|
-
[chat.messages, chat.setMessages, chat.append]
|
288
|
+
[context, chat.messages, chat.setMessages, chat.append]
|
256
289
|
);
|
257
290
|
return useMemo(
|
258
291
|
() => ({
|
@@ -268,10 +301,10 @@ var hasUpcomingMessage = (thread) => {
|
|
268
301
|
return thread.isLoading && thread.messages[thread.messages.length - 1]?.role !== "assistant";
|
269
302
|
};
|
270
303
|
|
271
|
-
// src/utils/context/
|
304
|
+
// src/utils/context/useComposerContext.ts
|
272
305
|
import { useContext as useContext3 } from "react";
|
273
306
|
|
274
|
-
// src/utils/context/
|
307
|
+
// src/utils/context/useMessageContext.ts
|
275
308
|
import { createContext as createContext2, useContext as useContext2 } from "react";
|
276
309
|
var MessageContext = createContext2(null);
|
277
310
|
var useMessageContext = () => {
|
@@ -281,11 +314,14 @@ var useMessageContext = () => {
|
|
281
314
|
return context;
|
282
315
|
};
|
283
316
|
|
284
|
-
// src/utils/context/
|
317
|
+
// src/utils/context/useComposerContext.ts
|
285
318
|
var useComposerContext = () => {
|
286
319
|
const { useComposer: useAssisstantComposer } = useAssistantContext();
|
287
320
|
const { useComposer: useMessageComposer } = useContext3(MessageContext) ?? {};
|
288
|
-
return {
|
321
|
+
return {
|
322
|
+
useComposer: useMessageComposer ?? useAssisstantComposer,
|
323
|
+
type: useMessageComposer ? "message" : "assistant"
|
324
|
+
};
|
289
325
|
};
|
290
326
|
|
291
327
|
// src/primitives/composer/ComposerIf.tsx
|
@@ -314,7 +350,7 @@ __export(message_exports, {
|
|
314
350
|
});
|
315
351
|
|
316
352
|
// src/primitives/message/MessageProvider.tsx
|
317
|
-
import { useMemo as useMemo2, useState
|
353
|
+
import { useMemo as useMemo2, useState } from "react";
|
318
354
|
import { create } from "zustand";
|
319
355
|
import { useShallow } from "zustand/react/shallow";
|
320
356
|
var getIsLast = (thread, message) => {
|
@@ -323,7 +359,7 @@ var getIsLast = (thread, message) => {
|
|
323
359
|
};
|
324
360
|
var useMessageContext2 = () => {
|
325
361
|
const { useBranchObserver } = useAssistantContext();
|
326
|
-
const [context] =
|
362
|
+
const [context] = useState(() => {
|
327
363
|
const useMessage = create(() => ({
|
328
364
|
message: null,
|
329
365
|
isLast: false,
|
@@ -380,8 +416,8 @@ var MessageProvider = ({
|
|
380
416
|
useShallow((b) => b.getBranchState(message))
|
381
417
|
);
|
382
418
|
const isLast = useThread((thread) => getIsLast(thread, message));
|
383
|
-
const [isCopied, setIsCopied] =
|
384
|
-
const [isHovering, setIsHovering] =
|
419
|
+
const [isCopied, setIsCopied] = useState(false);
|
420
|
+
const [isHovering, setIsHovering] = useState(false);
|
385
421
|
useMemo2(() => {
|
386
422
|
context.useMessage.setState(
|
387
423
|
{
|
@@ -530,6 +566,31 @@ var ThreadMessages = ({ components }) => {
|
|
530
566
|
));
|
531
567
|
};
|
532
568
|
|
569
|
+
// src/primitives/thread/ThreadScrollToBottom.tsx
|
570
|
+
import { composeEventHandlers as composeEventHandlers3 } from "@radix-ui/primitive";
|
571
|
+
import {
|
572
|
+
Primitive as Primitive4
|
573
|
+
} from "@radix-ui/react-primitive";
|
574
|
+
import { forwardRef as forwardRef4 } from "react";
|
575
|
+
var ThreadScrollToBottom = forwardRef4(({ onClick, ...rest }, ref) => {
|
576
|
+
const { useThread } = useAssistantContext();
|
577
|
+
const isAtBottom = useThread((s) => s.isAtBottom);
|
578
|
+
const handleScrollToBottom = () => {
|
579
|
+
const thread = useThread.getState();
|
580
|
+
thread.scrollToBottom();
|
581
|
+
};
|
582
|
+
if (isAtBottom)
|
583
|
+
return null;
|
584
|
+
return /* @__PURE__ */ React.createElement(
|
585
|
+
Primitive4.button,
|
586
|
+
{
|
587
|
+
...rest,
|
588
|
+
ref,
|
589
|
+
onClick: composeEventHandlers3(onClick, handleScrollToBottom)
|
590
|
+
}
|
591
|
+
);
|
592
|
+
});
|
593
|
+
|
533
594
|
// src/primitives/composer/index.ts
|
534
595
|
var composer_exports = {};
|
535
596
|
__export(composer_exports, {
|
@@ -541,41 +602,17 @@ __export(composer_exports, {
|
|
541
602
|
});
|
542
603
|
|
543
604
|
// src/primitives/composer/ComposerRoot.tsx
|
544
|
-
import { composeEventHandlers as
|
605
|
+
import { composeEventHandlers as composeEventHandlers4 } from "@radix-ui/primitive";
|
545
606
|
import { useComposedRefs as useComposedRefs2 } from "@radix-ui/react-compose-refs";
|
546
607
|
import {
|
547
|
-
Primitive as
|
608
|
+
Primitive as Primitive5
|
548
609
|
} from "@radix-ui/react-primitive";
|
549
|
-
import {
|
550
|
-
|
551
|
-
forwardRef as forwardRef4,
|
552
|
-
useContext as useContext4,
|
553
|
-
useMemo as useMemo3,
|
554
|
-
useRef as useRef4
|
555
|
-
} from "react";
|
556
|
-
var ComposerFormContext = createContext3(null);
|
557
|
-
var useComposerFormContext = () => {
|
558
|
-
const context = useContext4(ComposerFormContext);
|
559
|
-
if (!context) {
|
560
|
-
throw new Error(
|
561
|
-
"Composer compound components cannot be rendered outside the Composer component"
|
562
|
-
);
|
563
|
-
}
|
564
|
-
return context;
|
565
|
-
};
|
566
|
-
var ComposerRoot = forwardRef4(
|
610
|
+
import { forwardRef as forwardRef5, useRef as useRef5 } from "react";
|
611
|
+
var ComposerRoot = forwardRef5(
|
567
612
|
({ onSubmit, ...rest }, forwardedRef) => {
|
568
613
|
const { useComposer } = useComposerContext();
|
569
|
-
const formRef =
|
614
|
+
const formRef = useRef5(null);
|
570
615
|
const ref = useComposedRefs2(forwardedRef, formRef);
|
571
|
-
const composerContextValue = useMemo3(
|
572
|
-
() => ({
|
573
|
-
submit: () => formRef.current?.dispatchEvent(
|
574
|
-
new Event("submit", { cancelable: true, bubbles: true })
|
575
|
-
)
|
576
|
-
}),
|
577
|
-
[]
|
578
|
-
);
|
579
616
|
const handleSubmit = (e) => {
|
580
617
|
const composerState = useComposer.getState();
|
581
618
|
if (!composerState.isEditing)
|
@@ -583,75 +620,103 @@ var ComposerRoot = forwardRef4(
|
|
583
620
|
e.preventDefault();
|
584
621
|
composerState.send();
|
585
622
|
};
|
586
|
-
return /* @__PURE__ */ React.createElement(
|
587
|
-
|
623
|
+
return /* @__PURE__ */ React.createElement(
|
624
|
+
Primitive5.form,
|
588
625
|
{
|
589
626
|
...rest,
|
590
627
|
ref,
|
591
|
-
onSubmit:
|
628
|
+
onSubmit: composeEventHandlers4(onSubmit, handleSubmit)
|
592
629
|
}
|
593
|
-
)
|
630
|
+
);
|
594
631
|
}
|
595
632
|
);
|
596
633
|
|
597
634
|
// src/primitives/composer/ComposerInput.tsx
|
598
|
-
import { composeEventHandlers as
|
635
|
+
import { composeEventHandlers as composeEventHandlers5 } from "@radix-ui/primitive";
|
636
|
+
import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
|
599
637
|
import { Slot } from "@radix-ui/react-slot";
|
600
|
-
import {
|
638
|
+
import {
|
639
|
+
forwardRef as forwardRef6,
|
640
|
+
useCallback as useCallback2,
|
641
|
+
useEffect as useEffect2,
|
642
|
+
useRef as useRef6
|
643
|
+
} from "react";
|
601
644
|
import TextareaAutosize from "react-textarea-autosize";
|
602
|
-
var ComposerInput =
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
}
|
641
|
-
|
642
|
-
|
645
|
+
var ComposerInput = forwardRef6(
|
646
|
+
({ autoFocus, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
|
647
|
+
const { useThread } = useAssistantContext();
|
648
|
+
const { useComposer, type } = useComposerContext();
|
649
|
+
const value = useComposer((c) => {
|
650
|
+
if (!c.isEditing)
|
651
|
+
return "";
|
652
|
+
return c.value;
|
653
|
+
});
|
654
|
+
const Component = asChild ? Slot : TextareaAutosize;
|
655
|
+
const handleKeyPress = (e) => {
|
656
|
+
if (disabled)
|
657
|
+
return;
|
658
|
+
const composer = useComposer.getState();
|
659
|
+
if (e.key === "Escape" && composer.canCancel) {
|
660
|
+
e.preventDefault();
|
661
|
+
useComposer.getState().cancel();
|
662
|
+
}
|
663
|
+
if (e.key === "Enter" && e.shiftKey === false) {
|
664
|
+
const isLoading = useThread.getState().isLoading;
|
665
|
+
if (!isLoading) {
|
666
|
+
e.preventDefault();
|
667
|
+
composer.send();
|
668
|
+
}
|
669
|
+
}
|
670
|
+
};
|
671
|
+
const textareaRef = useRef6(null);
|
672
|
+
const ref = useComposedRefs3(forwardedRef, textareaRef);
|
673
|
+
const autoFocusEnabled = autoFocus !== false && !disabled;
|
674
|
+
const focus = useCallback2(() => {
|
675
|
+
const textarea = textareaRef.current;
|
676
|
+
if (!textarea || !autoFocusEnabled)
|
677
|
+
return;
|
678
|
+
textarea.focus();
|
679
|
+
textarea.setSelectionRange(
|
680
|
+
textareaRef.current.value.length,
|
681
|
+
textareaRef.current.value.length
|
682
|
+
);
|
683
|
+
}, [autoFocusEnabled]);
|
684
|
+
useEffect2(() => focus(), [focus]);
|
685
|
+
useOnScrollToBottom(() => {
|
686
|
+
if (type === "assistant") {
|
687
|
+
focus();
|
688
|
+
}
|
689
|
+
});
|
690
|
+
return /* @__PURE__ */ React.createElement(
|
691
|
+
Component,
|
692
|
+
{
|
693
|
+
value,
|
694
|
+
...rest,
|
695
|
+
ref,
|
696
|
+
disabled,
|
697
|
+
onChange: composeEventHandlers5(onChange, (e) => {
|
698
|
+
const composerState = useComposer.getState();
|
699
|
+
if (!composerState.isEditing)
|
700
|
+
return;
|
701
|
+
return composerState.setValue(e.target.value);
|
702
|
+
}),
|
703
|
+
onKeyDown: composeEventHandlers5(onKeyDown, handleKeyPress)
|
704
|
+
}
|
705
|
+
);
|
706
|
+
}
|
707
|
+
);
|
643
708
|
|
644
709
|
// src/primitives/composer/ComposerSend.tsx
|
645
710
|
import {
|
646
|
-
Primitive as
|
711
|
+
Primitive as Primitive6
|
647
712
|
} from "@radix-ui/react-primitive";
|
648
|
-
import { forwardRef as
|
649
|
-
var ComposerSend =
|
713
|
+
import { forwardRef as forwardRef7 } from "react";
|
714
|
+
var ComposerSend = forwardRef7(
|
650
715
|
({ disabled, ...rest }, ref) => {
|
651
716
|
const { useComposer } = useComposerContext();
|
652
717
|
const hasValue = useComposer((c) => c.isEditing && c.value.length > 0);
|
653
718
|
return /* @__PURE__ */ React.createElement(
|
654
|
-
|
719
|
+
Primitive6.button,
|
655
720
|
{
|
656
721
|
type: "submit",
|
657
722
|
...rest,
|
@@ -663,24 +728,24 @@ var ComposerSend = forwardRef6(
|
|
663
728
|
);
|
664
729
|
|
665
730
|
// src/primitives/composer/ComposerCancel.tsx
|
666
|
-
import { composeEventHandlers as
|
731
|
+
import { composeEventHandlers as composeEventHandlers6 } from "@radix-ui/primitive";
|
667
732
|
import {
|
668
|
-
Primitive as
|
733
|
+
Primitive as Primitive7
|
669
734
|
} from "@radix-ui/react-primitive";
|
670
|
-
import { forwardRef as
|
671
|
-
var ComposerCancel =
|
735
|
+
import { forwardRef as forwardRef8 } from "react";
|
736
|
+
var ComposerCancel = forwardRef8(({ disabled, onClick, ...rest }, ref) => {
|
672
737
|
const { useComposer } = useComposerContext();
|
673
738
|
const hasValue = useComposer((c) => c.canCancel);
|
674
739
|
const handleClose = () => {
|
675
740
|
useComposer.getState().cancel();
|
676
741
|
};
|
677
742
|
return /* @__PURE__ */ React.createElement(
|
678
|
-
|
743
|
+
Primitive7.button,
|
679
744
|
{
|
680
745
|
type: "button",
|
681
746
|
...rest,
|
682
747
|
ref,
|
683
|
-
onClick:
|
748
|
+
onClick: composeEventHandlers6(onClick, handleClose),
|
684
749
|
disabled: disabled || !hasValue
|
685
750
|
}
|
686
751
|
);
|
@@ -696,16 +761,41 @@ __export(branchPicker_exports, {
|
|
696
761
|
Root: () => BranchPickerRoot
|
697
762
|
});
|
698
763
|
|
764
|
+
// src/utils/context/combined/useCombinedStore.ts
|
765
|
+
import { useMemo as useMemo3 } from "react";
|
766
|
+
|
767
|
+
// src/utils/context/combined/createCombinedStore.ts
|
768
|
+
import { useSyncExternalStore } from "react";
|
769
|
+
var createCombinedStore = (stores) => {
|
770
|
+
const subscribe = (callback) => {
|
771
|
+
const unsubscribes = stores.map((store) => store.subscribe(callback));
|
772
|
+
return () => {
|
773
|
+
for (const unsub of unsubscribes) {
|
774
|
+
unsub();
|
775
|
+
}
|
776
|
+
};
|
777
|
+
};
|
778
|
+
return (selector) => {
|
779
|
+
const getSnapshot = () => selector(...stores.map((store) => store.getState()));
|
780
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
781
|
+
};
|
782
|
+
};
|
783
|
+
|
784
|
+
// src/utils/context/combined/useCombinedStore.ts
|
785
|
+
var useCombinedStore = (stores, selector) => {
|
786
|
+
const useCombined = useMemo3(() => createCombinedStore(stores), stores);
|
787
|
+
return useCombined(selector);
|
788
|
+
};
|
789
|
+
|
699
790
|
// src/actions/useGoToNextBranch.tsx
|
700
791
|
var useGoToNextBranch = () => {
|
701
792
|
const { useThread, useBranchObserver } = useAssistantContext();
|
702
793
|
const { useComposer, useMessage } = useMessageContext();
|
703
|
-
const
|
704
|
-
|
705
|
-
|
706
|
-
({ branchState: { branchId, branchCount } }) => branchId + 1 < branchCount
|
794
|
+
const disabled = useCombinedStore(
|
795
|
+
[useThread, useComposer, useMessage],
|
796
|
+
(t, c, m) => t.isLoading || c.isEditing || m.branchState.branchId + 1 >= m.branchState.branchCount
|
707
797
|
);
|
708
|
-
if (
|
798
|
+
if (disabled)
|
709
799
|
return null;
|
710
800
|
return () => {
|
711
801
|
const {
|
@@ -717,23 +807,23 @@ var useGoToNextBranch = () => {
|
|
717
807
|
};
|
718
808
|
|
719
809
|
// src/utils/createActionButton.tsx
|
720
|
-
import { forwardRef as
|
810
|
+
import { forwardRef as forwardRef9 } from "react";
|
721
811
|
import {
|
722
|
-
Primitive as
|
812
|
+
Primitive as Primitive8
|
723
813
|
} from "@radix-ui/react-primitive";
|
724
|
-
import { composeEventHandlers as
|
814
|
+
import { composeEventHandlers as composeEventHandlers7 } from "@radix-ui/primitive";
|
725
815
|
var createActionButton = (useActionButton) => {
|
726
|
-
return
|
816
|
+
return forwardRef9(
|
727
817
|
(props, forwardedRef) => {
|
728
818
|
const onClick = useActionButton(props);
|
729
819
|
return /* @__PURE__ */ React.createElement(
|
730
|
-
|
820
|
+
Primitive8.button,
|
731
821
|
{
|
732
822
|
type: "button",
|
733
823
|
disabled: !onClick,
|
734
824
|
...props,
|
735
825
|
ref: forwardedRef,
|
736
|
-
onClick:
|
826
|
+
onClick: composeEventHandlers7(props.onClick, onClick ?? void 0)
|
737
827
|
}
|
738
828
|
);
|
739
829
|
}
|
@@ -747,10 +837,11 @@ var BranchPickerNext = createActionButton(useGoToNextBranch);
|
|
747
837
|
var useGoToPreviousBranch = () => {
|
748
838
|
const { useThread, useBranchObserver } = useAssistantContext();
|
749
839
|
const { useComposer, useMessage } = useMessageContext();
|
750
|
-
const
|
751
|
-
|
752
|
-
|
753
|
-
|
840
|
+
const disabled = useCombinedStore(
|
841
|
+
[useThread, useComposer, useMessage],
|
842
|
+
(t, c, m) => t.isLoading || c.isEditing || m.branchState.branchId <= 0
|
843
|
+
);
|
844
|
+
if (disabled)
|
754
845
|
return null;
|
755
846
|
return () => {
|
756
847
|
const {
|
@@ -780,11 +871,11 @@ var BranchPickerNumber = () => {
|
|
780
871
|
|
781
872
|
// src/primitives/branchPicker/BranchPickerRoot.tsx
|
782
873
|
import {
|
783
|
-
Primitive as
|
874
|
+
Primitive as Primitive9
|
784
875
|
} from "@radix-ui/react-primitive";
|
785
|
-
import { forwardRef as
|
786
|
-
var BranchPickerRoot =
|
787
|
-
return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(
|
876
|
+
import { forwardRef as forwardRef10 } from "react";
|
877
|
+
var BranchPickerRoot = forwardRef10(({ hideWhenSingleBranch, ...rest }, ref) => {
|
878
|
+
return /* @__PURE__ */ React.createElement(MessageIf, { hasBranches: hideWhenSingleBranch ? true : void 0 }, /* @__PURE__ */ React.createElement(Primitive9.div, { ...rest, ref }));
|
788
879
|
});
|
789
880
|
|
790
881
|
// src/primitives/actionBar/index.ts
|
@@ -798,29 +889,31 @@ __export(actionBar_exports, {
|
|
798
889
|
|
799
890
|
// src/primitives/actionBar/ActionBarRoot.tsx
|
800
891
|
import {
|
801
|
-
Primitive as
|
892
|
+
Primitive as Primitive10
|
802
893
|
} from "@radix-ui/react-primitive";
|
803
|
-
import { forwardRef as
|
804
|
-
var ActionBarRoot =
|
894
|
+
import { forwardRef as forwardRef11 } from "react";
|
895
|
+
var ActionBarRoot = forwardRef11(({ hideWhenBusy, autohide, autohideFloat, ...rest }, ref) => {
|
805
896
|
const { useThread } = useAssistantContext();
|
806
897
|
const { useMessage } = useMessageContext();
|
807
|
-
const hideAndfloatStatus =
|
808
|
-
|
809
|
-
|
898
|
+
const hideAndfloatStatus = useCombinedStore(
|
899
|
+
[useThread, useMessage],
|
900
|
+
(t, m) => {
|
901
|
+
if (hideWhenBusy && t.isLoading)
|
902
|
+
return "hidden" /* Hidden */;
|
903
|
+
const autohideEnabled = autohide === "always" || autohide === "not-last" && !m.isLast;
|
904
|
+
if (!autohideEnabled)
|
905
|
+
return "normal" /* Normal */;
|
906
|
+
if (!m.isHovering)
|
907
|
+
return "hidden" /* Hidden */;
|
908
|
+
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branchState.branchCount <= 1)
|
909
|
+
return "floating" /* Floating */;
|
810
910
|
return "normal" /* Normal */;
|
811
|
-
|
812
|
-
|
813
|
-
if (autohideFloat === "always" || autohideFloat === "single-branch" && m.branchState.branchCount <= 1)
|
814
|
-
return "floating" /* Floating */;
|
815
|
-
return "normal" /* Normal */;
|
816
|
-
});
|
817
|
-
const busy = useThread((t) => t.isLoading);
|
818
|
-
if (hideWhenBusy && busy)
|
819
|
-
return null;
|
911
|
+
}
|
912
|
+
);
|
820
913
|
if (hideAndfloatStatus === "hidden" /* Hidden */)
|
821
914
|
return null;
|
822
915
|
return /* @__PURE__ */ React.createElement(
|
823
|
-
|
916
|
+
Primitive10.div,
|
824
917
|
{
|
825
918
|
"data-floating": hideAndfloatStatus === "floating" /* Floating */,
|
826
919
|
...rest,
|
@@ -852,9 +945,11 @@ var ActionBarCopy = createActionButton(useCopyMessage);
|
|
852
945
|
var useReloadMessage = () => {
|
853
946
|
const { useThread, useBranchObserver } = useAssistantContext();
|
854
947
|
const { useMessage } = useMessageContext();
|
855
|
-
const
|
856
|
-
|
857
|
-
|
948
|
+
const disabled = useCombinedStore(
|
949
|
+
[useThread, useMessage],
|
950
|
+
(t, m) => t.isLoading || m.message.role !== "assistant"
|
951
|
+
);
|
952
|
+
if (disabled)
|
858
953
|
return null;
|
859
954
|
return () => {
|
860
955
|
const message = useMessage.getState().message;
|
@@ -870,9 +965,11 @@ var ActionBarReload = createActionButton(useReloadMessage);
|
|
870
965
|
// src/actions/useBeginMessageEdit.tsx
|
871
966
|
var useBeginMessageEdit = () => {
|
872
967
|
const { useMessage, useComposer } = useMessageContext();
|
873
|
-
const
|
874
|
-
|
875
|
-
|
968
|
+
const disabled = useCombinedStore(
|
969
|
+
[useMessage, useComposer],
|
970
|
+
(m, c) => m.message.role !== "user" || c.isEditing
|
971
|
+
);
|
972
|
+
if (disabled)
|
876
973
|
return null;
|
877
974
|
return () => {
|
878
975
|
const { edit } = useComposer.getState();
|
@@ -884,24 +981,34 @@ var useBeginMessageEdit = () => {
|
|
884
981
|
var ActionBarEdit = createActionButton(useBeginMessageEdit);
|
885
982
|
|
886
983
|
// src/vercel/VercelAIAssistantProvider.tsx
|
887
|
-
import { useCallback as
|
984
|
+
import { useCallback as useCallback3, useMemo as useMemo4 } from "react";
|
888
985
|
|
889
986
|
// src/vercel/useDummyAIAssistantContext.tsx
|
890
|
-
import { useState as
|
987
|
+
import { useState as useState2 } from "react";
|
891
988
|
import { create as create2 } from "zustand";
|
892
989
|
var useDummyAIAssistantContext = () => {
|
893
|
-
const [context] =
|
990
|
+
const [context] = useState2(() => {
|
991
|
+
const scrollToBottomListeners = /* @__PURE__ */ new Set();
|
894
992
|
const useThread = create2()(() => ({
|
895
993
|
messages: [],
|
896
994
|
isLoading: false,
|
897
|
-
reload: async () => {
|
898
|
-
throw new Error("Not implemented");
|
899
|
-
},
|
900
995
|
append: async () => {
|
901
996
|
throw new Error("Not implemented");
|
902
997
|
},
|
903
998
|
stop: () => {
|
904
999
|
throw new Error("Not implemented");
|
1000
|
+
},
|
1001
|
+
isAtBottom: true,
|
1002
|
+
scrollToBottom: () => {
|
1003
|
+
for (const listener of scrollToBottomListeners) {
|
1004
|
+
listener();
|
1005
|
+
}
|
1006
|
+
},
|
1007
|
+
onScrollToBottom: (callback) => {
|
1008
|
+
scrollToBottomListeners.add(callback);
|
1009
|
+
return () => {
|
1010
|
+
scrollToBottomListeners.delete(callback);
|
1011
|
+
};
|
905
1012
|
}
|
906
1013
|
}));
|
907
1014
|
const useComposer = create2()(() => ({
|
@@ -975,25 +1082,20 @@ var VercelAIAssistantProvider = ({
|
|
975
1082
|
const messages = useMemo4(() => {
|
976
1083
|
return vercelToCachedThreadMessages(vercel.messages);
|
977
1084
|
}, [vercel.messages]);
|
978
|
-
const
|
979
|
-
const reload = useCallback2(async () => {
|
980
|
-
if (!maybeReload)
|
981
|
-
throw new Error("Reload not supported");
|
982
|
-
await maybeReload();
|
983
|
-
}, [maybeReload]);
|
984
|
-
const append = useCallback2(
|
1085
|
+
const append = useCallback3(
|
985
1086
|
async (message) => {
|
986
1087
|
if (message.content[0]?.type !== "text") {
|
987
1088
|
throw new Error("Only text content is currently supported");
|
988
1089
|
}
|
1090
|
+
context.useThread.getState().scrollToBottom();
|
989
1091
|
await vercel.append({
|
990
1092
|
role: message.role,
|
991
1093
|
content: message.content[0].text
|
992
1094
|
});
|
993
1095
|
},
|
994
|
-
[vercel.append]
|
1096
|
+
[context, vercel.append]
|
995
1097
|
);
|
996
|
-
const stop =
|
1098
|
+
const stop = useCallback3(() => {
|
997
1099
|
const lastMessage = vercel.messages.at(-1);
|
998
1100
|
vercel.stop();
|
999
1101
|
if (lastMessage?.role === "user") {
|
@@ -1002,17 +1104,13 @@ var VercelAIAssistantProvider = ({
|
|
1002
1104
|
}, [vercel.messages, vercel.stop, vercel.setInput]);
|
1003
1105
|
const isLoading = "isLoading" in vercel ? vercel.isLoading : vercel.status === "in_progress";
|
1004
1106
|
useMemo4(() => {
|
1005
|
-
context.useThread.setState(
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
},
|
1013
|
-
true
|
1014
|
-
);
|
1015
|
-
}, [context, messages, reload, append, stop, isLoading]);
|
1107
|
+
context.useThread.setState({
|
1108
|
+
messages,
|
1109
|
+
isLoading,
|
1110
|
+
append,
|
1111
|
+
stop
|
1112
|
+
});
|
1113
|
+
}, [context, messages, append, stop, isLoading]);
|
1016
1114
|
useMemo4(() => {
|
1017
1115
|
context.useComposer.setState({
|
1018
1116
|
canCancel: isLoading,
|
@@ -1020,7 +1118,7 @@ var VercelAIAssistantProvider = ({
|
|
1020
1118
|
setValue: vercel.setInput
|
1021
1119
|
});
|
1022
1120
|
}, [context, isLoading, vercel.input, vercel.setInput]);
|
1023
|
-
const branches = useVercelAIBranches(vercel);
|
1121
|
+
const branches = useVercelAIBranches(vercel, context);
|
1024
1122
|
useMemo4(() => {
|
1025
1123
|
context.useBranchObserver.setState(branches, true);
|
1026
1124
|
}, [context, branches]);
|
@@ -1029,7 +1127,7 @@ var VercelAIAssistantProvider = ({
|
|
1029
1127
|
|
1030
1128
|
// src/vercel/VercelRSCAssistantProvider.tsx
|
1031
1129
|
import {
|
1032
|
-
useCallback as
|
1130
|
+
useCallback as useCallback4,
|
1033
1131
|
useMemo as useMemo5
|
1034
1132
|
} from "react";
|
1035
1133
|
var ThreadMessageCache2 = /* @__PURE__ */ new WeakMap();
|
@@ -1061,17 +1159,18 @@ var VercelRSCAssistantProvider = ({
|
|
1061
1159
|
const messages = useMemo5(() => {
|
1062
1160
|
return vercelToCachedThreadMessages2(vercelMessages);
|
1063
1161
|
}, [vercelMessages]);
|
1064
|
-
const append =
|
1162
|
+
const append = useCallback4(
|
1065
1163
|
async (message) => {
|
1066
1164
|
if (message.content[0]?.type !== "text") {
|
1067
1165
|
throw new Error("Only text content is currently supported");
|
1068
1166
|
}
|
1167
|
+
context.useThread.getState().scrollToBottom();
|
1069
1168
|
await vercelAppend({
|
1070
1169
|
role: message.role,
|
1071
1170
|
content: [{ type: "text", text: message.content[0].text }]
|
1072
1171
|
});
|
1073
1172
|
},
|
1074
|
-
[vercelAppend]
|
1173
|
+
[context, vercelAppend]
|
1075
1174
|
);
|
1076
1175
|
useMemo5(() => {
|
1077
1176
|
context.useThread.setState({
|