@talk2view/sdk 0.14.0 → 0.16.0
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/README.md +336 -69
- package/dist/assistant-ui/convert.d.ts +40 -0
- package/dist/assistant-ui/convert.d.ts.map +1 -0
- package/dist/assistant-ui/convert.js +113 -0
- package/dist/assistant-ui/convert.js.map +1 -0
- package/dist/assistant-ui/dictation.d.ts +39 -0
- package/dist/assistant-ui/dictation.d.ts.map +1 -0
- package/dist/assistant-ui/dictation.js +128 -0
- package/dist/assistant-ui/dictation.js.map +1 -0
- package/dist/assistant-ui/index.d.ts +43 -0
- package/dist/assistant-ui/index.d.ts.map +1 -0
- package/dist/assistant-ui/index.js +227 -0
- package/dist/assistant-ui/index.js.map +1 -0
- package/dist/auth.d.ts +38 -3
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +101 -16
- package/dist/auth.js.map +1 -1
- package/dist/chat/auth-gate.d.ts +42 -0
- package/dist/chat/auth-gate.d.ts.map +1 -0
- package/dist/chat/auth-gate.js +93 -0
- package/dist/chat/auth-gate.js.map +1 -0
- package/dist/chat/chat.d.ts +36 -0
- package/dist/chat/chat.d.ts.map +1 -0
- package/dist/chat/chat.js +124 -0
- package/dist/chat/chat.js.map +1 -0
- package/dist/chat/composer-extras.d.ts +23 -0
- package/dist/chat/composer-extras.d.ts.map +1 -0
- package/dist/chat/composer-extras.js +48 -0
- package/dist/chat/composer-extras.js.map +1 -0
- package/dist/chat/hooks/use-attachment-src.d.ts +2 -0
- package/dist/chat/hooks/use-attachment-src.d.ts.map +1 -0
- package/dist/chat/hooks/use-attachment-src.js +38 -0
- package/dist/chat/hooks/use-attachment-src.js.map +1 -0
- package/dist/chat/hooks/use-copy-to-clipboard.d.ts +8 -0
- package/dist/chat/hooks/use-copy-to-clipboard.d.ts.map +1 -0
- package/dist/chat/hooks/use-copy-to-clipboard.js +16 -0
- package/dist/chat/hooks/use-copy-to-clipboard.js.map +1 -0
- package/dist/chat/index.d.ts +32 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +35 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/inject-styles.d.ts +2 -0
- package/dist/chat/inject-styles.d.ts.map +1 -0
- package/dist/chat/inject-styles.js +23 -0
- package/dist/chat/inject-styles.js.map +1 -0
- package/dist/chat/launcher.d.ts +37 -0
- package/dist/chat/launcher.d.ts.map +1 -0
- package/dist/chat/launcher.js +343 -0
- package/dist/chat/launcher.js.map +1 -0
- package/dist/chat/lib/cn.d.ts +19 -0
- package/dist/chat/lib/cn.d.ts.map +1 -0
- package/dist/chat/lib/cn.js +20 -0
- package/dist/chat/lib/cn.js.map +1 -0
- package/dist/chat/lib/dictation-phase.d.ts +9 -0
- package/dist/chat/lib/dictation-phase.d.ts.map +1 -0
- package/dist/chat/lib/dictation-phase.js +33 -0
- package/dist/chat/lib/dictation-phase.js.map +1 -0
- package/dist/chat/lib/guard.d.ts +4 -0
- package/dist/chat/lib/guard.d.ts.map +1 -0
- package/dist/chat/lib/guard.js +41 -0
- package/dist/chat/lib/guard.js.map +1 -0
- package/dist/chat/lib/launcher-variant.d.ts +33 -0
- package/dist/chat/lib/launcher-variant.d.ts.map +1 -0
- package/dist/chat/lib/launcher-variant.js +109 -0
- package/dist/chat/lib/launcher-variant.js.map +1 -0
- package/dist/chat/lib/portal-host.d.ts +13 -0
- package/dist/chat/lib/portal-host.d.ts.map +1 -0
- package/dist/chat/lib/portal-host.js +58 -0
- package/dist/chat/lib/portal-host.js.map +1 -0
- package/dist/chat/markdown.d.ts +32 -0
- package/dist/chat/markdown.d.ts.map +1 -0
- package/dist/chat/markdown.js +18 -0
- package/dist/chat/markdown.js.map +1 -0
- package/dist/chat/provider.d.ts +113 -0
- package/dist/chat/provider.d.ts.map +1 -0
- package/dist/chat/provider.js +176 -0
- package/dist/chat/provider.js.map +1 -0
- package/dist/chat/tool-fallback.d.ts +39 -0
- package/dist/chat/tool-fallback.d.ts.map +1 -0
- package/dist/chat/tool-fallback.js +167 -0
- package/dist/chat/tool-fallback.js.map +1 -0
- package/dist/chat/ui/avatar.d.ts +12 -0
- package/dist/chat/ui/avatar.d.ts.map +1 -0
- package/dist/chat/ui/avatar.js +24 -0
- package/dist/chat/ui/avatar.js.map +1 -0
- package/dist/chat/ui/button.d.ts +9 -0
- package/dist/chat/ui/button.d.ts.map +1 -0
- package/dist/chat/ui/button.js +35 -0
- package/dist/chat/ui/button.js.map +1 -0
- package/dist/chat/ui/collapsible.d.ts +6 -0
- package/dist/chat/ui/collapsible.d.ts.map +1 -0
- package/dist/chat/ui/collapsible.js +13 -0
- package/dist/chat/ui/collapsible.js.map +1 -0
- package/dist/chat/ui/dialog.d.ts +18 -0
- package/dist/chat/ui/dialog.d.ts.map +1 -0
- package/dist/chat/ui/dialog.js +42 -0
- package/dist/chat/ui/dialog.js.map +1 -0
- package/dist/chat/ui/input.d.ts +4 -0
- package/dist/chat/ui/input.d.ts.map +1 -0
- package/dist/chat/ui/input.js +8 -0
- package/dist/chat/ui/input.js.map +1 -0
- package/dist/chat/ui/skeleton.d.ts +3 -0
- package/dist/chat/ui/skeleton.d.ts.map +1 -0
- package/dist/chat/ui/skeleton.js +7 -0
- package/dist/chat/ui/skeleton.js.map +1 -0
- package/dist/chat/ui/textarea.d.ts +4 -0
- package/dist/chat/ui/textarea.d.ts.map +1 -0
- package/dist/chat/ui/textarea.js +7 -0
- package/dist/chat/ui/textarea.js.map +1 -0
- package/dist/chat/ui/tooltip.d.ts +7 -0
- package/dist/chat/ui/tooltip.d.ts.map +1 -0
- package/dist/chat/ui/tooltip.js +22 -0
- package/dist/chat/ui/tooltip.js.map +1 -0
- package/dist/chat/vendor/attachment.aui.d.ts +5 -0
- package/dist/chat/vendor/attachment.aui.d.ts.map +1 -0
- package/dist/chat/vendor/attachment.aui.js +79 -0
- package/dist/chat/vendor/attachment.aui.js.map +1 -0
- package/dist/chat/vendor/file.d.ts +41 -0
- package/dist/chat/vendor/file.d.ts.map +1 -0
- package/dist/chat/vendor/file.js +137 -0
- package/dist/chat/vendor/file.js.map +1 -0
- package/dist/chat/vendor/follow-up-suggestions.aui.d.ts +3 -0
- package/dist/chat/vendor/follow-up-suggestions.aui.d.ts.map +1 -0
- package/dist/chat/vendor/follow-up-suggestions.aui.js +45 -0
- package/dist/chat/vendor/follow-up-suggestions.aui.js.map +1 -0
- package/dist/chat/vendor/image.d.ts +47 -0
- package/dist/chat/vendor/image.d.ts.map +1 -0
- package/dist/chat/vendor/image.js +258 -0
- package/dist/chat/vendor/image.js.map +1 -0
- package/dist/chat/vendor/markdown-text.d.ts +8 -0
- package/dist/chat/vendor/markdown-text.d.ts.map +1 -0
- package/dist/chat/vendor/markdown-text.js +73 -0
- package/dist/chat/vendor/markdown-text.js.map +1 -0
- package/dist/chat/vendor/reasoning.aui.d.ts +22 -0
- package/dist/chat/vendor/reasoning.aui.d.ts.map +1 -0
- package/dist/chat/vendor/reasoning.aui.js +56 -0
- package/dist/chat/vendor/reasoning.aui.js.map +1 -0
- package/dist/chat/vendor/reasoning.d.ts +35 -0
- package/dist/chat/vendor/reasoning.d.ts.map +1 -0
- package/dist/chat/vendor/reasoning.js +112 -0
- package/dist/chat/vendor/reasoning.js.map +1 -0
- package/dist/chat/vendor/thread-list.aui.d.ts +37 -0
- package/dist/chat/vendor/thread-list.aui.d.ts.map +1 -0
- package/dist/chat/vendor/thread-list.aui.js +154 -0
- package/dist/chat/vendor/thread-list.aui.js.map +1 -0
- package/dist/chat/vendor/thread.aui.d.ts +47 -0
- package/dist/chat/vendor/thread.aui.d.ts.map +1 -0
- package/dist/chat/vendor/thread.aui.js +176 -0
- package/dist/chat/vendor/thread.aui.js.map +1 -0
- package/dist/chat/vendor/tool-fallback.aui.d.ts +39 -0
- package/dist/chat/vendor/tool-fallback.aui.d.ts.map +1 -0
- package/dist/chat/vendor/tool-fallback.aui.js +251 -0
- package/dist/chat/vendor/tool-fallback.aui.js.map +1 -0
- package/dist/chat/vendor/tool-group.aui.d.ts +34 -0
- package/dist/chat/vendor/tool-group.aui.d.ts.map +1 -0
- package/dist/chat/vendor/tool-group.aui.js +60 -0
- package/dist/chat/vendor/tool-group.aui.js.map +1 -0
- package/dist/chat/vendor/tooltip-icon-button.d.ts +8 -0
- package/dist/chat/vendor/tooltip-icon-button.d.ts.map +1 -0
- package/dist/chat/vendor/tooltip-icon-button.js +11 -0
- package/dist/chat/vendor/tooltip-icon-button.js.map +1 -0
- package/dist/chat/views/account.d.ts +6 -0
- package/dist/chat/views/account.d.ts.map +1 -0
- package/dist/chat/views/account.js +128 -0
- package/dist/chat/views/account.js.map +1 -0
- package/dist/chat/views/settings.d.ts +2 -0
- package/dist/chat/views/settings.d.ts.map +1 -0
- package/dist/chat/views/settings.js +104 -0
- package/dist/chat/views/settings.js.map +1 -0
- package/dist/chat/views/thread-list.d.ts +10 -0
- package/dist/chat/views/thread-list.d.ts.map +1 -0
- package/dist/chat/views/thread-list.js +21 -0
- package/dist/chat/views/thread-list.js.map +1 -0
- package/dist/chat/welcome.d.ts +10 -0
- package/dist/chat/welcome.d.ts.map +1 -0
- package/dist/chat/welcome.js +9 -0
- package/dist/chat/welcome.js.map +1 -0
- package/dist/chat-css.d.ts +1 -0
- package/dist/chat-css.js +1 -0
- package/dist/chat.css +2 -0
- package/dist/chat.isolated.css +3819 -0
- package/dist/chat.raw.css +3829 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -4
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +5 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +28 -6
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +68 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +236 -35
- package/dist/index.js.map +1 -1
- package/dist/react/T2VProvider.d.ts +2 -2
- package/dist/react/T2VProvider.d.ts.map +1 -1
- package/dist/react/T2VProvider.js +1 -1
- package/dist/react/T2VProvider.js.map +1 -1
- package/dist/react/index.d.ts +14 -14
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +7 -7
- package/dist/react/index.js.map +1 -1
- package/dist/react/usePartnerConfig.d.ts +1 -1
- package/dist/react/usePartnerConfig.d.ts.map +1 -1
- package/dist/react/usePartnerConfig.js +1 -1
- package/dist/react/usePartnerConfig.js.map +1 -1
- package/dist/react/useT2VAuth.d.ts +8 -1
- package/dist/react/useT2VAuth.d.ts.map +1 -1
- package/dist/react/useT2VAuth.js +25 -6
- package/dist/react/useT2VAuth.js.map +1 -1
- package/dist/react/useT2VChat.d.ts +3 -3
- package/dist/react/useT2VChat.d.ts.map +1 -1
- package/dist/react/useT2VChat.js +1 -1
- package/dist/react/useT2VChat.js.map +1 -1
- package/dist/react/useT2VTools.d.ts +1 -1
- package/dist/react/useT2VTools.d.ts.map +1 -1
- package/dist/react/useT2VTools.js +1 -1
- package/dist/react/useT2VTools.js.map +1 -1
- package/dist/react/useUserPreferences.d.ts +1 -1
- package/dist/react/useUserPreferences.d.ts.map +1 -1
- package/dist/react/useUserPreferences.js +1 -1
- package/dist/react/useUserPreferences.js.map +1 -1
- package/dist/sessions.d.ts +3 -3
- package/dist/sessions.d.ts.map +1 -1
- package/dist/sessions.js +6 -2
- package/dist/sessions.js.map +1 -1
- package/dist/skills.d.ts +2 -2
- package/dist/skills.d.ts.map +1 -1
- package/dist/streaming.d.ts +1 -1
- package/dist/streaming.d.ts.map +1 -1
- package/dist/tools.d.ts +2 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/types.d.ts +119 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/components/ApprovalCard.d.ts +1 -1
- package/dist/ui/components/ApprovalCard.d.ts.map +1 -1
- package/dist/ui/components/ChatHeader.js +1 -1
- package/dist/ui/components/ChatHeader.js.map +1 -1
- package/dist/ui/components/ChatPanel.d.ts +1 -1
- package/dist/ui/components/ChatPanel.d.ts.map +1 -1
- package/dist/ui/components/ChatPanel.js +14 -13
- package/dist/ui/components/ChatPanel.js.map +1 -1
- package/dist/ui/components/ChatWidget.d.ts +1 -1
- package/dist/ui/components/ChatWidget.d.ts.map +1 -1
- package/dist/ui/components/ChatWidget.js +2 -2
- package/dist/ui/components/ChatWidget.js.map +1 -1
- package/dist/ui/components/Composer.d.ts.map +1 -1
- package/dist/ui/components/Composer.js +13 -6
- package/dist/ui/components/Composer.js.map +1 -1
- package/dist/ui/components/LoginForm.d.ts.map +1 -1
- package/dist/ui/components/LoginForm.js +19 -5
- package/dist/ui/components/LoginForm.js.map +1 -1
- package/dist/ui/components/MarkdownRenderer.d.ts +4 -0
- package/dist/ui/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/ui/components/MarkdownRenderer.js +7 -35
- package/dist/ui/components/MarkdownRenderer.js.map +1 -1
- package/dist/ui/components/MessageActions.js +1 -1
- package/dist/ui/components/MessageActions.js.map +1 -1
- package/dist/ui/components/MessageBubble.d.ts +1 -1
- package/dist/ui/components/MessageBubble.d.ts.map +1 -1
- package/dist/ui/components/MessageBubble.js +9 -9
- package/dist/ui/components/MessageBubble.js.map +1 -1
- package/dist/ui/components/MessageList.js +2 -2
- package/dist/ui/components/MessageList.js.map +1 -1
- package/dist/ui/components/SettingsPanel.js +4 -4
- package/dist/ui/components/SettingsPanel.js.map +1 -1
- package/dist/ui/components/Talk2View.d.ts +1 -1
- package/dist/ui/components/Talk2View.d.ts.map +1 -1
- package/dist/ui/components/Talk2View.js +16 -12
- package/dist/ui/components/Talk2View.js.map +1 -1
- package/dist/ui/components/ThinkingBlock.js +2 -2
- package/dist/ui/components/ThinkingBlock.js.map +1 -1
- package/dist/ui/components/WelcomeScreen.js +2 -2
- package/dist/ui/components/WelcomeScreen.js.map +1 -1
- package/dist/ui/context.d.ts +4 -2
- package/dist/ui/context.d.ts.map +1 -1
- package/dist/ui/context.js.map +1 -1
- package/dist/ui/index.d.ts +27 -26
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +21 -20
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/safeMarkdown.d.ts +17 -0
- package/dist/ui/safeMarkdown.d.ts.map +1 -0
- package/dist/ui/safeMarkdown.js +196 -0
- package/dist/ui/safeMarkdown.js.map +1 -0
- package/dist/ui/theme.d.ts +1 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/utils.d.ts +1 -1
- package/dist/ui/utils.d.ts.map +1 -1
- package/package.json +64 -5
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useRef, useState, } from "react";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import { BrainIcon, ChevronDownIcon } from "lucide-react";
|
|
6
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "../ui/collapsible.js";
|
|
7
|
+
import { cn } from "../lib/cn.js";
|
|
8
|
+
export const ANIMATION_DURATION = 200;
|
|
9
|
+
const ReasoningPreviewContext = createContext(false);
|
|
10
|
+
const reasoningVariants = cva("aui-reasoning-root mb-4 w-full", {
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
outline: "rounded-lg border px-3 py-2",
|
|
14
|
+
ghost: "",
|
|
15
|
+
muted: "bg-muted/50 rounded-lg px-3 py-2",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
variant: "outline",
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
function ReasoningRoot({ className, variant, open: controlledOpen, onOpenChange: controlledOnOpenChange, defaultOpen = false, streaming, onAnimationStart, children, ...props }) {
|
|
23
|
+
const [initialOpen] = useState(defaultOpen);
|
|
24
|
+
const [userOpen, setUserOpen] = useState(null);
|
|
25
|
+
const isControlled = controlledOpen !== undefined;
|
|
26
|
+
const isOpen = isControlled
|
|
27
|
+
? controlledOpen
|
|
28
|
+
: (userOpen ?? (streaming || initialOpen));
|
|
29
|
+
const isPreview = streaming === true && isOpen;
|
|
30
|
+
const prevStreamingRef = useRef(streaming);
|
|
31
|
+
useLayoutEffect(() => {
|
|
32
|
+
if (prevStreamingRef.current === streaming)
|
|
33
|
+
return;
|
|
34
|
+
prevStreamingRef.current = streaming;
|
|
35
|
+
// A streaming transition only animates the panel when the resting state
|
|
36
|
+
// is collapsed; with `defaultOpen` the disclosure stays open across it.
|
|
37
|
+
if (!isControlled && userOpen === null && !initialOpen) {
|
|
38
|
+
onAnimationStart?.();
|
|
39
|
+
}
|
|
40
|
+
}, [streaming, isControlled, userOpen, initialOpen, onAnimationStart]);
|
|
41
|
+
const handleOpenChange = useCallback((open) => {
|
|
42
|
+
onAnimationStart?.();
|
|
43
|
+
if (!isControlled) {
|
|
44
|
+
setUserOpen(open);
|
|
45
|
+
}
|
|
46
|
+
controlledOnOpenChange?.(open);
|
|
47
|
+
}, [onAnimationStart, isControlled, controlledOnOpenChange]);
|
|
48
|
+
return (_jsx(Collapsible, { "data-slot": "reasoning-root", "data-variant": variant, open: isOpen, onOpenChange: handleOpenChange, className: cn("group/reasoning-root", reasoningVariants({ variant, className })), style: {
|
|
49
|
+
"--animation-duration": `${ANIMATION_DURATION}ms`,
|
|
50
|
+
}, ...props, children: _jsx(ReasoningPreviewContext.Provider, { value: isPreview, children: children }) }));
|
|
51
|
+
}
|
|
52
|
+
function ReasoningFade({ side = "bottom", className, ...props }) {
|
|
53
|
+
if (side === "top") {
|
|
54
|
+
return (_jsx("div", { "data-slot": "reasoning-fade", className: cn("aui-reasoning-fade pointer-events-none absolute inset-x-0 top-0 z-10 h-8", "bg-[linear-gradient(to_bottom,var(--color-background),transparent)]", "group-data-[variant=muted]/reasoning-root:bg-[linear-gradient(to_bottom,color-mix(in_oklab,var(--color-muted)_50%,var(--color-background)),transparent)]", "fade-in-0 animate-in", "animation-duration-(--animation-duration)", className), ...props }));
|
|
55
|
+
}
|
|
56
|
+
return (_jsx("div", { "data-slot": "reasoning-fade", className: cn("aui-reasoning-fade pointer-events-none absolute inset-x-0 bottom-0 z-10 h-8", "bg-[linear-gradient(to_top,var(--color-background),transparent)]", "group-data-[variant=muted]/reasoning-root:bg-[linear-gradient(to_top,color-mix(in_oklab,var(--color-muted)_50%,var(--color-background)),transparent)]", "fade-in-0 animate-in", "animation-duration-(--animation-duration)", className), ...props }));
|
|
57
|
+
}
|
|
58
|
+
function ReasoningTrigger({ active, duration, className, ...props }) {
|
|
59
|
+
const durationText = duration ? ` (${duration}s)` : "";
|
|
60
|
+
return (_jsxs(CollapsibleTrigger, { "data-slot": "reasoning-trigger", className: cn("aui-reasoning-trigger group/trigger text-muted-foreground hover:text-foreground flex max-w-[75%] origin-left items-center gap-2 py-1.5 text-sm transition-[color,scale] active:scale-[0.98]", className), ...props, children: [_jsx(BrainIcon, { "data-slot": "reasoning-trigger-icon", className: "aui-reasoning-trigger-icon size-4 shrink-0" }), _jsxs("span", { "data-slot": "reasoning-trigger-label", className: cn("aui-reasoning-trigger-label-wrapper inline-block leading-none tabular-nums", active && "shimmer motion-reduce:animate-none"), children: ["Reasoning", durationText] }), _jsx(ChevronDownIcon, { "data-slot": "reasoning-trigger-chevron", className: cn("aui-reasoning-trigger-chevron mt-0.5 size-4 shrink-0", "transition-transform duration-(--animation-duration) ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none", "-rotate-90", "group-data-open/trigger:rotate-0", "group-data-panel-open/trigger:rotate-0") })] }));
|
|
61
|
+
}
|
|
62
|
+
function ReasoningContent({ className, children, ...props }) {
|
|
63
|
+
const isPreview = useContext(ReasoningPreviewContext);
|
|
64
|
+
return (_jsxs(CollapsibleContent, { "data-slot": "reasoning-content", className: cn("aui-reasoning-content text-muted-foreground relative overflow-hidden text-sm outline-none", "group/collapsible-content ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:animate-none", "data-closed:animate-collapsible-up", "data-open:animate-collapsible-down", "data-closed:fill-mode-forwards", "data-closed:pointer-events-none", "[--tw-duration:var(--animation-duration)]", className), ...props, children: [_jsx(ReasoningFade, { side: "top" }), children, isPreview ? _jsx(ReasoningFade, {}) : null] }));
|
|
65
|
+
}
|
|
66
|
+
function ReasoningText({ className, children, ...props }) {
|
|
67
|
+
const isPreview = useContext(ReasoningPreviewContext);
|
|
68
|
+
const scrollRef = useRef(null);
|
|
69
|
+
const contentRef = useRef(null);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (!isPreview)
|
|
72
|
+
return;
|
|
73
|
+
const scrollEl = scrollRef.current;
|
|
74
|
+
const contentEl = contentRef.current;
|
|
75
|
+
if (!scrollEl || !contentEl)
|
|
76
|
+
return;
|
|
77
|
+
let pinned = true;
|
|
78
|
+
let lastScrollTop = scrollEl.scrollTop;
|
|
79
|
+
let lastScrollHeight = scrollEl.scrollHeight;
|
|
80
|
+
const isAtBottom = () => Math.abs(scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight) <= 1 || scrollEl.scrollHeight <= scrollEl.clientHeight;
|
|
81
|
+
const pin = () => {
|
|
82
|
+
if (!pinned)
|
|
83
|
+
return;
|
|
84
|
+
scrollEl.scrollTop = scrollEl.scrollHeight;
|
|
85
|
+
};
|
|
86
|
+
// A pin's own scroll event can arrive after new content grew the scroll
|
|
87
|
+
// height and read as "not at bottom"; only an upward move at unchanged
|
|
88
|
+
// scroll height is user intent.
|
|
89
|
+
const onScroll = () => {
|
|
90
|
+
if (isAtBottom()) {
|
|
91
|
+
pinned = true;
|
|
92
|
+
}
|
|
93
|
+
else if (scrollEl.scrollTop < lastScrollTop &&
|
|
94
|
+
scrollEl.scrollHeight === lastScrollHeight) {
|
|
95
|
+
pinned = false;
|
|
96
|
+
}
|
|
97
|
+
lastScrollTop = scrollEl.scrollTop;
|
|
98
|
+
lastScrollHeight = scrollEl.scrollHeight;
|
|
99
|
+
};
|
|
100
|
+
pin();
|
|
101
|
+
scrollEl.addEventListener("scroll", onScroll);
|
|
102
|
+
const observer = new ResizeObserver(pin);
|
|
103
|
+
observer.observe(contentEl);
|
|
104
|
+
return () => {
|
|
105
|
+
scrollEl.removeEventListener("scroll", onScroll);
|
|
106
|
+
observer.disconnect();
|
|
107
|
+
};
|
|
108
|
+
}, [isPreview]);
|
|
109
|
+
return (_jsx("div", { ref: scrollRef, "data-slot": "reasoning-text", className: cn("aui-reasoning-text relative z-0 max-h-64 overflow-y-auto ps-6 pt-2 pb-2 leading-relaxed text-pretty", "transform-gpu transition-[transform,opacity] ease-[cubic-bezier(0.32,0.72,0,1)]", "motion-reduce:animate-none", "group-data-open/collapsible-content:animate-in", "group-data-closed/collapsible-content:animate-out", "group-data-open/collapsible-content:fade-in-0", "group-data-closed/collapsible-content:fade-out-0", "group-data-open/collapsible-content:slide-in-from-top-4", "group-data-closed/collapsible-content:slide-out-to-top-4", "group-data-open/collapsible-content:blur-in-[2px]", "group-data-closed/collapsible-content:blur-out-[2px]", "group-data-open/collapsible-content:animation-duration-(--animation-duration)", "group-data-closed/collapsible-content:animation-duration-(--animation-duration)", className), ...props, children: _jsx("div", { ref: contentRef, className: "aui-reasoning-text-content space-y-4", children: children }) }));
|
|
110
|
+
}
|
|
111
|
+
export { ReasoningRoot, ReasoningTrigger, ReasoningContent, ReasoningText, ReasoningFade, reasoningVariants, };
|
|
112
|
+
//# sourceMappingURL=reasoning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reasoning.js","sourceRoot":"","sources":["../../../src/chat/vendor/reasoning.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ThreadListPrimitive } from "@assistant-ui/react";
|
|
2
|
+
import { type ComponentPropsWithoutRef, type FC } from "react";
|
|
3
|
+
export declare const ThreadList: FC;
|
|
4
|
+
export declare const ThreadListSearch: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").ClassAttributes<HTMLInputElement> & import("react").InputHTMLAttributes<HTMLInputElement>, "ref">, "value" | "onChange"> & {
|
|
5
|
+
value: string;
|
|
6
|
+
onValueChange: (value: string) => void;
|
|
7
|
+
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
8
|
+
export declare const ThreadListRoot: FC<ComponentPropsWithoutRef<typeof ThreadListPrimitive.Root>>;
|
|
9
|
+
export declare const ThreadListItems: FC<ComponentPropsWithoutRef<"div"> & {
|
|
10
|
+
searchQuery?: string;
|
|
11
|
+
}>;
|
|
12
|
+
export type ThreadListGroup = {
|
|
13
|
+
label: string;
|
|
14
|
+
indices: number[];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Filters the thread list by title and buckets the matches by last activity
|
|
18
|
+
* (Today, Yesterday, Earlier). `groups` is null when no thread carries a
|
|
19
|
+
* date, in which case `filteredIndices` keeps the runtime order.
|
|
20
|
+
*/
|
|
21
|
+
export declare const useThreadListGroups: (searchQuery?: string) => {
|
|
22
|
+
threadIds: readonly string[];
|
|
23
|
+
filteredIndices: number[];
|
|
24
|
+
groups: null;
|
|
25
|
+
} | {
|
|
26
|
+
threadIds: readonly string[];
|
|
27
|
+
filteredIndices: number[];
|
|
28
|
+
groups: ThreadListGroup[];
|
|
29
|
+
};
|
|
30
|
+
export declare const ThreadListNew: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").ButtonProps & import("class-variance-authority").VariantProps<(props?: ({
|
|
31
|
+
variant?: "default" | "link" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
|
|
32
|
+
size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
33
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string>, "ref"> & {
|
|
34
|
+
labelClassName?: string;
|
|
35
|
+
} & import("react").RefAttributes<HTMLButtonElement>>;
|
|
36
|
+
export declare const ThreadListItem: FC;
|
|
37
|
+
//# sourceMappingURL=thread-list.aui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-list.aui.d.ts","sourceRoot":"","sources":["../../../src/chat/vendor/thread-list.aui.tsx"],"names":[],"mappings":"AAMA,OAAO,EAIL,mBAAmB,EAGpB,MAAM,qBAAqB,CAAC;AAU7B,OAAO,EAOL,KAAK,wBAAwB,EAC7B,KAAK,EAAE,EACR,MAAM,OAAO,CAAC;AAEf,eAAO,MAAM,UAAU,EAAE,EAaxB,CAAC;AAEF,eAAO,MAAM,gBAAgB;WAGlB,MAAM;mBACE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;oDAqBxC,CAAC;AAIH,eAAO,MAAM,cAAc,EAAE,EAAE,CAC7B,wBAAwB,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAS1D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,EAAE,CAC9B,wBAAwB,CAAC,KAAK,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAgB3D,CAAC;AAaF,MAAM,MAAM,eAAe,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,oBAAgB;;;;;;;;CA6CnD,CAAC;AAiDF,eAAO,MAAM,aAAa;;;;qBAEqC,MAAM;qDA2BnE,CAAC;AAyBH,eAAO,MAAM,cAAc,EAAE,EAiD5B,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from "../ui/button.js";
|
|
4
|
+
import { Input } from "../ui/input.js";
|
|
5
|
+
import { Skeleton } from "../ui/skeleton.js";
|
|
6
|
+
import { cn } from "../lib/cn.js";
|
|
7
|
+
import { AuiIf, ThreadListItemMorePrimitive, ThreadListItemPrimitive, ThreadListPrimitive, useAui, useAuiState, } from "@assistant-ui/react";
|
|
8
|
+
import { ArchiveIcon, Loader2Icon, MoreHorizontalIcon, PencilIcon, PlusIcon, SearchIcon, TrashIcon, } from "lucide-react";
|
|
9
|
+
import { forwardRef, Fragment, useEffect, useMemo, useRef, useState, } from "react";
|
|
10
|
+
export const ThreadList = () => {
|
|
11
|
+
const [search, setSearch] = useState("");
|
|
12
|
+
const hasThreads = useAuiState((s) => s.threads.threadIds.length > 0);
|
|
13
|
+
return (_jsxs(ThreadListRoot, { children: [_jsx(ThreadListNew, {}), hasThreads && (_jsx(ThreadListSearch, { value: search, onValueChange: setSearch })), _jsx(ThreadListItems, { searchQuery: hasThreads ? search : "" })] }));
|
|
14
|
+
};
|
|
15
|
+
export const ThreadListSearch = forwardRef(({ className, value, onValueChange, ...props }, ref) => {
|
|
16
|
+
return (_jsxs("div", { "data-slot": "aui_thread-list-search", className: "relative px-0.5 py-1", children: [_jsx(SearchIcon, { "data-slot": "aui_thread-list-search-icon", className: "text-muted-foreground pointer-events-none absolute start-3 top-1/2 size-4 -translate-y-1/2" }), _jsx(Input, { ref: ref, type: "search", value: value, onChange: (event) => onValueChange(event.target.value), "aria-label": "Search threads", placeholder: "Search threads", className: cn("h-8 ps-8 text-sm", className), ...props })] }));
|
|
17
|
+
});
|
|
18
|
+
ThreadListSearch.displayName = "ThreadListSearch";
|
|
19
|
+
export const ThreadListRoot = ({ className, ...props }) => {
|
|
20
|
+
return (_jsx(ThreadListPrimitive.Root, { "data-slot": "aui_thread-list-root", className: cn("flex flex-col gap-0.5", className), ...props }));
|
|
21
|
+
};
|
|
22
|
+
export const ThreadListItems = ({ className, searchQuery = "", ...props }) => {
|
|
23
|
+
return (_jsxs("div", { "data-slot": "aui_thread-list-items", className: cn("flex flex-col gap-0.5", className), ...props, children: [_jsx(AuiIf, { condition: (s) => s.threads.isLoading, children: _jsx(ThreadListSkeleton, {}) }), _jsx(AuiIf, { condition: (s) => !s.threads.isLoading, children: _jsx(ThreadListItemGroups, { searchQuery: searchQuery }) })] }));
|
|
24
|
+
};
|
|
25
|
+
const DAY_IN_MS = 86_400_000;
|
|
26
|
+
const dateGroupLabel = (date, startOfToday) => {
|
|
27
|
+
if (!date || date.getTime() >= startOfToday)
|
|
28
|
+
return "Today";
|
|
29
|
+
if (date.getTime() >= startOfToday - DAY_IN_MS)
|
|
30
|
+
return "Yesterday";
|
|
31
|
+
return "Earlier";
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Filters the thread list by title and buckets the matches by last activity
|
|
35
|
+
* (Today, Yesterday, Earlier). `groups` is null when no thread carries a
|
|
36
|
+
* date, in which case `filteredIndices` keeps the runtime order.
|
|
37
|
+
*/
|
|
38
|
+
export const useThreadListGroups = (searchQuery = "") => {
|
|
39
|
+
const threadIds = useAuiState((s) => s.threads.threadIds);
|
|
40
|
+
const threadItems = useAuiState((s) => s.threads.threadItems);
|
|
41
|
+
const query = searchQuery.trim().toLowerCase();
|
|
42
|
+
return useMemo(() => {
|
|
43
|
+
const itemsById = new Map(threadItems.map((item) => [item.id, item]));
|
|
44
|
+
const dates = threadIds.map((id) => itemsById.get(id)?.lastMessageAt);
|
|
45
|
+
const filteredIndices = threadIds
|
|
46
|
+
.map((id, index) => ({ id, index }))
|
|
47
|
+
.filter(({ id }) => !query ||
|
|
48
|
+
(itemsById.get(id)?.title || "New Chat")
|
|
49
|
+
.toLowerCase()
|
|
50
|
+
.includes(query))
|
|
51
|
+
.map(({ index }) => index);
|
|
52
|
+
if (!filteredIndices.some((index) => dates[index])) {
|
|
53
|
+
return { threadIds, filteredIndices, groups: null };
|
|
54
|
+
}
|
|
55
|
+
const now = new Date();
|
|
56
|
+
const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
|
|
57
|
+
const time = (index) => dates[index]?.getTime() ?? Number.MAX_SAFE_INTEGER;
|
|
58
|
+
const sorted = [...filteredIndices].sort((a, b) => time(b) - time(a));
|
|
59
|
+
const result = [];
|
|
60
|
+
for (const index of sorted) {
|
|
61
|
+
const label = dateGroupLabel(dates[index], startOfToday);
|
|
62
|
+
const lastGroup = result[result.length - 1];
|
|
63
|
+
if (lastGroup?.label === label) {
|
|
64
|
+
lastGroup.indices.push(index);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
result.push({ label, indices: [index] });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { threadIds, filteredIndices, groups: result };
|
|
71
|
+
}, [threadIds, threadItems, query]);
|
|
72
|
+
};
|
|
73
|
+
const ThreadListItemGroups = ({ searchQuery = "", }) => {
|
|
74
|
+
const { threadIds, filteredIndices, groups } = useThreadListGroups(searchQuery);
|
|
75
|
+
const query = searchQuery.trim();
|
|
76
|
+
if (query && filteredIndices.length === 0) {
|
|
77
|
+
return (_jsx("div", { "data-slot": "aui_thread-list-empty", className: "text-muted-foreground px-2.5 py-4 text-sm", children: "No threads found" }));
|
|
78
|
+
}
|
|
79
|
+
if (!groups) {
|
|
80
|
+
return filteredIndices.map((index) => (_jsx(ThreadListPrimitive.ItemByIndex, { index: index, components: { ThreadListItem } }, threadIds[index])));
|
|
81
|
+
}
|
|
82
|
+
return groups.map((group) => (_jsxs(Fragment, { children: [_jsx("div", { "data-slot": "aui_thread-list-group-label", className: "text-muted-foreground px-2.5 pt-3 pb-1 text-xs font-medium", children: group.label }), group.indices.map((index) => (_jsx(ThreadListPrimitive.ItemByIndex, { index: index, components: { ThreadListItem } }, threadIds[index])))] }, group.label)));
|
|
83
|
+
};
|
|
84
|
+
export const ThreadListNew = forwardRef(({ className, labelClassName, children, ...props }, ref) => {
|
|
85
|
+
return (_jsx(ThreadListPrimitive.New, { render: _jsx(Button, { ref: ref, variant: "ghost", "data-slot": "aui_thread-list-new", className: cn("hover:bg-muted data-active:bg-muted h-8 justify-start gap-2 rounded-md px-2.5 text-sm font-normal", className), ...props }), children: children ?? (_jsxs(_Fragment, { children: [_jsx(PlusIcon, { "data-slot": "aui_thread-list-new-icon", className: "size-4 shrink-0" }), _jsx("span", { "data-slot": "aui_thread-list-new-label", className: cn("whitespace-nowrap", labelClassName), children: "New Thread" })] })) }));
|
|
86
|
+
});
|
|
87
|
+
ThreadListNew.displayName = "ThreadListNew";
|
|
88
|
+
const ThreadListSkeleton = () => {
|
|
89
|
+
return (_jsx("div", { className: "flex flex-col gap-0.5", children: Array.from({ length: 5 }, (_, i) => (_jsx("div", { role: "status", "aria-label": "Loading threads", "data-slot": "aui_thread-list-skeleton-wrapper", className: "flex h-8 items-center px-2.5", children: _jsx(Skeleton, { "data-slot": "aui_thread-list-skeleton", className: "h-3.5 w-full" }) }, i))) }));
|
|
90
|
+
};
|
|
91
|
+
export const ThreadListItem = () => {
|
|
92
|
+
const isRunning = useAuiState((s) => s.threadListItem.isRunning);
|
|
93
|
+
const [isRenaming, setIsRenaming] = useState(false);
|
|
94
|
+
const triggerRef = useRef(null);
|
|
95
|
+
const restoreFocusRef = useRef(false);
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (isRenaming || !restoreFocusRef.current)
|
|
98
|
+
return;
|
|
99
|
+
restoreFocusRef.current = false;
|
|
100
|
+
triggerRef.current?.focus();
|
|
101
|
+
}, [isRenaming]);
|
|
102
|
+
return (_jsxs(ThreadListItemPrimitive.Root, { "data-slot": "aui_thread-list-item", className: "group hover:bg-muted focus-visible:bg-muted data-active:bg-muted has-focus-visible:bg-muted has-data-[state=open]:bg-muted relative flex h-8 items-center rounded-md transition-colors focus-visible:outline-none", children: [isRenaming ? (_jsx(ThreadListItemRename, { onDone: (restoreFocus) => {
|
|
103
|
+
restoreFocusRef.current = restoreFocus;
|
|
104
|
+
setIsRenaming(false);
|
|
105
|
+
} })) : (_jsxs(ThreadListItemPrimitive.Trigger, { ref: triggerRef, "data-slot": "aui_thread-list-item-trigger", className: "focus-visible:ring-ring/50 flex h-full min-w-0 flex-1 items-center rounded-md px-2.5 text-start text-sm outline-none group-hover:pe-9 group-has-focus-visible:pe-9 group-has-data-[state=open]:pe-9 group-data-active:pe-9 focus-visible:ring-1", children: [isRunning && (_jsx(Loader2Icon, { "aria-hidden": true, "data-slot": "aui_thread-list-item-running", className: "text-muted-foreground me-1.5 size-3.5 shrink-0 animate-spin" })), _jsx("span", { "data-slot": "aui_thread-list-item-title", className: "min-w-0 flex-1 truncate", children: _jsx(ThreadListItemPrimitive.Title, { fallback: "New Chat" }) }), isRunning && _jsx("span", { className: "sr-only", children: "Running" })] })), _jsx(ThreadListItemMore, { onRename: () => setIsRenaming(true) })] }));
|
|
106
|
+
};
|
|
107
|
+
const ThreadListItemRename = ({ onDone }) => {
|
|
108
|
+
const aui = useAui();
|
|
109
|
+
const title = useAuiState((s) => s.threadListItem.title) ?? "";
|
|
110
|
+
const [value, setValue] = useState(title);
|
|
111
|
+
const inputRef = useRef(null);
|
|
112
|
+
const settledRef = useRef(false);
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
inputRef.current?.select();
|
|
115
|
+
}, []);
|
|
116
|
+
const commit = (restoreFocus) => {
|
|
117
|
+
if (settledRef.current)
|
|
118
|
+
return;
|
|
119
|
+
settledRef.current = true;
|
|
120
|
+
const next = value.trim();
|
|
121
|
+
if (!next || next === title) {
|
|
122
|
+
onDone(restoreFocus);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// Deferred so a synchronous throw lands on the rejection path too.
|
|
126
|
+
Promise.resolve()
|
|
127
|
+
.then(() => aui.threadListItem.rename(next))
|
|
128
|
+
.then(() => onDone(restoreFocus), () => {
|
|
129
|
+
settledRef.current = false;
|
|
130
|
+
if (restoreFocus)
|
|
131
|
+
inputRef.current?.focus();
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
const cancel = () => {
|
|
135
|
+
if (settledRef.current)
|
|
136
|
+
return;
|
|
137
|
+
settledRef.current = true;
|
|
138
|
+
onDone(true);
|
|
139
|
+
};
|
|
140
|
+
return (_jsx(Input, { ref: inputRef, autoFocus: true, "data-slot": "aui_thread-list-item-rename", "aria-label": "Rename thread", value: value, className: "h-7 min-w-0 flex-1 ps-2.5 pe-9 text-sm", onChange: (event) => setValue(event.target.value), onBlur: () => commit(false), onKeyDown: (event) => {
|
|
141
|
+
if (event.key === "Enter") {
|
|
142
|
+
event.preventDefault();
|
|
143
|
+
commit(true);
|
|
144
|
+
}
|
|
145
|
+
else if (event.key === "Escape") {
|
|
146
|
+
event.preventDefault();
|
|
147
|
+
cancel();
|
|
148
|
+
}
|
|
149
|
+
} }));
|
|
150
|
+
};
|
|
151
|
+
const ThreadListItemMore = ({ onRename }) => {
|
|
152
|
+
return (_jsxs(ThreadListItemMorePrimitive.Root, { sharedFocusGroup: true, children: [_jsxs(ThreadListItemMorePrimitive.Trigger, { render: _jsx(Button, { variant: "ghost", size: "icon", "data-slot": "aui_thread-list-item-more", className: "data-[state=open]:bg-accent absolute end-1.5 top-1/2 size-6 -translate-y-1/2 p-0 opacity-0 group-hover:opacity-100 group-has-focus-visible:opacity-100 group-data-active:opacity-100 data-[state=open]:opacity-100" }), children: [_jsx(MoreHorizontalIcon, { className: "size-3.5" }), _jsx("span", { className: "sr-only", children: "More options" })] }), _jsxs(ThreadListItemMorePrimitive.Content, { side: "right", align: "start", sideOffset: 6, "data-slot": "aui_thread-list-item-more-content", className: "bg-popover text-popover-foreground data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:animate-out data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-32 overflow-hidden rounded-xl border p-1.5", children: [_jsxs(ThreadListItemMorePrimitive.Item, { "data-slot": "aui_thread-list-item-more-item", className: "hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground flex cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-sm outline-none select-none", onSelect: onRename, children: [_jsx(PencilIcon, { className: "size-4" }), "Rename"] }), _jsxs(ThreadListItemPrimitive.Archive, { render: _jsx(ThreadListItemMorePrimitive.Item, { "data-slot": "aui_thread-list-item-more-item", className: "hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground flex cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-sm outline-none select-none" }), children: [_jsx(ArchiveIcon, { className: "size-4" }), "Archive"] }), _jsxs(ThreadListItemPrimitive.Delete, { render: _jsx(ThreadListItemMorePrimitive.Item, { "data-slot": "aui_thread-list-item-more-item", className: "text-destructive hover:bg-destructive/10 hover:text-destructive focus:bg-destructive/10 focus:text-destructive flex cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-sm outline-none select-none" }), children: [_jsx(TrashIcon, { className: "size-4" }), "Delete"] })] })] }));
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=thread-list.aui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-list.aui.js","sourceRoot":"","sources":["../../../src/chat/vendor/thread-list.aui.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { MessagePrimitive, type ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
2
|
+
import { type ComponentType, type FC, type PropsWithChildren, type ReactNode } from "react";
|
|
3
|
+
export type ThreadGroupPart = MessagePrimitive.GroupedParts.GroupPart;
|
|
4
|
+
/**
|
|
5
|
+
* Optional component overrides for the thread. `AssistantMessage` and
|
|
6
|
+
* `Welcome` replace whole sections; the remaining slots override how the
|
|
7
|
+
* assistant message renders tool calls and part groups. Tool UIs registered
|
|
8
|
+
* by name (toolkit `render`, `useAssistantDataUI`) take precedence over
|
|
9
|
+
* `ToolFallback`. When `TaskGroup` is set, tool calls that carry a nested
|
|
10
|
+
* conversation and have no registered UI render through it instead of the
|
|
11
|
+
* tool group; without it they render like any other tool call.
|
|
12
|
+
*/
|
|
13
|
+
export type ThreadComponents = {
|
|
14
|
+
AssistantMessage?: ComponentType | undefined;
|
|
15
|
+
Welcome?: ComponentType | undefined;
|
|
16
|
+
ToolFallback?: ToolCallMessagePartComponent | undefined;
|
|
17
|
+
ToolGroup?: ComponentType<PropsWithChildren<{
|
|
18
|
+
group: ThreadGroupPart;
|
|
19
|
+
}>> | undefined;
|
|
20
|
+
ReasoningGroup?: ComponentType<PropsWithChildren<{
|
|
21
|
+
group: ThreadGroupPart;
|
|
22
|
+
}>> | undefined;
|
|
23
|
+
TaskGroup?: ComponentType<{
|
|
24
|
+
group: ThreadGroupPart;
|
|
25
|
+
}> | undefined;
|
|
26
|
+
};
|
|
27
|
+
export type ThreadProps = {
|
|
28
|
+
components?: ThreadComponents | undefined;
|
|
29
|
+
autoFocus?: boolean | undefined;
|
|
30
|
+
};
|
|
31
|
+
export declare const Thread: FC<ThreadProps>;
|
|
32
|
+
/**
|
|
33
|
+
* Talk2View: the composer's two seams. assistant-ui exposes no Composer slot at
|
|
34
|
+
* any level (ThreadComponents carries AssistantMessage, Welcome, ToolFallback,
|
|
35
|
+
* ToolGroup, ReasoningGroup and TaskGroup only, and Composer/ComposerAction are
|
|
36
|
+
* module-private), so mounting our own dictation control would otherwise mean
|
|
37
|
+
* forking the composer. Supplying `dictate` replaces the default mic and stop
|
|
38
|
+
* buttons; `attachments: false` drops the attach button, which upstream renders
|
|
39
|
+
* whether or not a runtime can take a file. Supplying neither leaves upstream's
|
|
40
|
+
* behaviour exactly as it is.
|
|
41
|
+
*/
|
|
42
|
+
export type ComposerExtras = {
|
|
43
|
+
dictate?: ReactNode;
|
|
44
|
+
attachments?: boolean;
|
|
45
|
+
};
|
|
46
|
+
export declare const ComposerExtrasContext: import("react").Context<ComposerExtras>;
|
|
47
|
+
//# sourceMappingURL=thread.aui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread.aui.d.ts","sourceRoot":"","sources":["../../../src/chat/vendor/thread.aui.tsx"],"names":[],"mappings":"AA4BA,OAAO,EASL,gBAAgB,EAMhB,KAAK,4BAA4B,EAElC,MAAM,qBAAqB,CAAC;AAiB7B,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,EAAE,EACP,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC,YAAY,CAAC,SAAS,CAAC;AAEtE;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gBAAgB,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC7C,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACxD,SAAS,CAAC,EACN,aAAa,CAAC,iBAAiB,CAAC;QAAE,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC,GAC5D,SAAS,CAAC;IACd,cAAc,CAAC,EACX,aAAa,CAAC,iBAAiB,CAAC;QAAE,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC,GAC5D,SAAS,CAAC;IACd,SAAS,CAAC,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;CACnE,CAAC;AAgCF,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC,CAAC;AAyCF,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAWlC,CAAC;AAwPF;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG;IAAE,OAAO,CAAC,EAAE,SAAS,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAC5E,eAAO,MAAM,qBAAqB,yCAAoC,CAAC"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ComposerAddAttachment, ComposerAttachments, UserMessageAttachments, } from "./attachment.aui.js";
|
|
4
|
+
import { File } from "./file.js";
|
|
5
|
+
import { ThreadFollowupSuggestions } from "./follow-up-suggestions.aui.js";
|
|
6
|
+
import { Image } from "./image.js";
|
|
7
|
+
import { MarkdownText } from "../markdown.js";
|
|
8
|
+
import { Reasoning, ReasoningContent, ReasoningRoot, ReasoningText, ReasoningTrigger, } from "./reasoning.aui.js";
|
|
9
|
+
import { ToolFallback } from "./tool-fallback.aui.js";
|
|
10
|
+
import { ToolGroupContent, ToolGroupRoot, ToolGroupTrigger, } from "./tool-group.aui.js";
|
|
11
|
+
import { TooltipIconButton } from "./tooltip-icon-button.js";
|
|
12
|
+
import { Button } from "../ui/button.js";
|
|
13
|
+
import { Skeleton } from "../ui/skeleton.js";
|
|
14
|
+
import { cn } from "../lib/cn.js";
|
|
15
|
+
import { ActionBarMorePrimitive, ActionBarPrimitive, AuiIf, BranchPickerPrimitive, ComposerPrimitive, ErrorPrimitive, groupPartByType, MessagePrimitive, SuggestionPrimitive, ThreadPrimitive, useAuiState, } from "@assistant-ui/react";
|
|
16
|
+
import { ArrowDownIcon, ArrowUpIcon, AudioLinesIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, CopyIcon, DownloadIcon, MicIcon, MoreHorizontalIcon, PencilIcon, PhoneIcon, RefreshCwIcon, SquareIcon, } from "lucide-react";
|
|
17
|
+
import { createContext, useContext, } from "react";
|
|
18
|
+
const messageGroupBy = groupPartByType({
|
|
19
|
+
reasoning: ["group-chainOfThought", "group-reasoning"],
|
|
20
|
+
"tool-call": ["group-chainOfThought", "group-tool"],
|
|
21
|
+
"standalone-tool-call": [],
|
|
22
|
+
});
|
|
23
|
+
const TASK_GROUP_PATH = [
|
|
24
|
+
"group-chainOfThought",
|
|
25
|
+
"group-task",
|
|
26
|
+
];
|
|
27
|
+
const taskAwareGroupBy = (part, context) => {
|
|
28
|
+
const path = messageGroupBy(part, context);
|
|
29
|
+
return part.type === "tool-call" &&
|
|
30
|
+
part.messages !== undefined &&
|
|
31
|
+
path.length > 0 &&
|
|
32
|
+
!context?.toolUIs?.[part.toolName]?.length
|
|
33
|
+
? TASK_GROUP_PATH
|
|
34
|
+
: path;
|
|
35
|
+
};
|
|
36
|
+
const EMPTY_COMPONENTS = {};
|
|
37
|
+
const ThreadComponentsContext = createContext(EMPTY_COMPONENTS);
|
|
38
|
+
// Startup exposes a loading placeholder thread; treat it as a new chat so
|
|
39
|
+
// the composer mounts centered. Loads after startup keep the docked layout.
|
|
40
|
+
const isNewChatView = (s) => s.thread.messages.length === 0 &&
|
|
41
|
+
(!s.thread.isLoading || s.threads.isLoading);
|
|
42
|
+
// A switched thread that is still fetching its history: skeleton, not welcome.
|
|
43
|
+
const isHistoryLoadingView = (s) => s.thread.messages.length === 0 &&
|
|
44
|
+
s.thread.isLoading &&
|
|
45
|
+
!s.thread.isDisabled &&
|
|
46
|
+
!s.threads.isLoading;
|
|
47
|
+
const ThreadHistorySkeleton = () => (_jsxs("div", { "data-slot": "aui_thread-history-skeleton", role: "status", className: "animate-in fade-in fill-mode-both flex flex-col gap-y-6 [animation-delay:150ms] [animation-duration:200ms]", children: [_jsx("span", { className: "sr-only", children: "Loading conversation" }), _jsx(Skeleton, { className: "ml-auto h-9 w-2/5 rounded-xl motion-reduce:animate-none" }), _jsxs("div", { className: "flex flex-col gap-y-2", children: [_jsx(Skeleton, { className: "h-4 w-11/12 motion-reduce:animate-none" }), _jsx(Skeleton, { className: "h-4 w-4/5 motion-reduce:animate-none" }), _jsx(Skeleton, { className: "h-4 w-3/5 motion-reduce:animate-none" })] }), _jsx(Skeleton, { className: "ml-auto h-9 w-1/3 rounded-xl motion-reduce:animate-none" }), _jsxs("div", { className: "flex flex-col gap-y-2", children: [_jsx(Skeleton, { className: "h-4 w-10/12 motion-reduce:animate-none" }), _jsx(Skeleton, { className: "h-4 w-2/3 motion-reduce:animate-none" })] })] }));
|
|
48
|
+
export const Thread = ({ components = EMPTY_COMPONENTS, autoFocus = true, }) => {
|
|
49
|
+
const isEmpty = useAuiState(isNewChatView);
|
|
50
|
+
return (_jsx(ThreadComponentsContext.Provider, { value: components, children: _jsx(ThreadRoot, { isEmpty: isEmpty, autoFocus: autoFocus }) }));
|
|
51
|
+
};
|
|
52
|
+
const ThreadRoot = ({ isEmpty, autoFocus, }) => {
|
|
53
|
+
const { Welcome = ThreadWelcome } = useContext(ThreadComponentsContext);
|
|
54
|
+
return (_jsx(ThreadPrimitive.Root, { className: "aui-root aui-thread-root bg-background @container flex h-full flex-col", style: {
|
|
55
|
+
["--thread-max-width"]: "44rem",
|
|
56
|
+
["--composer-bg"]: "color-mix(in oklab, var(--color-muted) 30%, transparent)",
|
|
57
|
+
["--composer-radius"]: "1rem",
|
|
58
|
+
["--composer-padding"]: "8px",
|
|
59
|
+
}, children: _jsx(ThreadPrimitive.Viewport, { turnAnchor: "top", "data-slot": "aui_thread-viewport", className: "relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth", children: _jsxs("div", { className: cn("mx-auto flex w-full max-w-(--thread-max-width) flex-1 flex-col px-4 pt-4", isEmpty && "justify-center"), children: [_jsx(AuiIf, { condition: isNewChatView, children: _jsx(Welcome, {}) }), _jsx(AuiIf, { condition: isHistoryLoadingView, children: _jsx(ThreadHistorySkeleton, {}) }), _jsx("div", { "data-slot": "aui_message-group", className: "mb-14 flex flex-col gap-y-6 empty:hidden", children: _jsx(ThreadPrimitive.Messages, { children: () => _jsx(ThreadMessage, {}) }) }), _jsxs(ThreadPrimitive.ViewportFooter, { className: cn("aui-thread-viewport-footer bg-background flex flex-col gap-4 overflow-visible pb-4 md:pb-6", !isEmpty &&
|
|
60
|
+
"sticky bottom-0 mt-auto rounded-t-(--composer-radius)"), children: [_jsx(ThreadScrollToBottom, {}), _jsx(ThreadFollowupSuggestions, {}), _jsx(Composer, { autoFocus: autoFocus }), _jsx(AuiIf, { condition: (s) => isNewChatView(s) && s.composer.isEmpty, children: _jsx(ThreadSuggestions, {}) })] })] }) }) }));
|
|
61
|
+
};
|
|
62
|
+
const ThreadMessage = () => {
|
|
63
|
+
const { AssistantMessage: AssistantMessageComponent = AssistantMessage } = useContext(ThreadComponentsContext);
|
|
64
|
+
const role = useAuiState((s) => s.message.role);
|
|
65
|
+
const isEditing = useAuiState((s) => s.message.composer.isEditing);
|
|
66
|
+
const isSpoken = useAuiState((s) => s.message.metadata.modality === "voice");
|
|
67
|
+
if (isEditing)
|
|
68
|
+
return _jsx(EditComposer, {});
|
|
69
|
+
if (isSpoken)
|
|
70
|
+
return _jsx(SpokenMessage, {});
|
|
71
|
+
if (role === "user")
|
|
72
|
+
return _jsx(UserMessage, {});
|
|
73
|
+
return _jsx(AssistantMessageComponent, {});
|
|
74
|
+
};
|
|
75
|
+
const useVoiceRunPosition = () => useAuiState((s) => {
|
|
76
|
+
const before = s.thread.messages[s.message.index - 1]?.metadata.modality === "voice";
|
|
77
|
+
const after = s.thread.messages[s.message.index + 1]?.metadata.modality === "voice";
|
|
78
|
+
if (before)
|
|
79
|
+
return after ? "middle" : "end";
|
|
80
|
+
return after ? "start" : "single";
|
|
81
|
+
});
|
|
82
|
+
const SpokenText = ({ text }) => (_jsx("p", { className: "aui-spoken-message-text m-0", children: text }));
|
|
83
|
+
const SpokenMessage = () => {
|
|
84
|
+
const role = useAuiState((s) => s.message.role);
|
|
85
|
+
const position = useVoiceRunPosition();
|
|
86
|
+
const isSpeaking = useAuiState((s) => s.message.role === "assistant" && s.message.status?.type === "running");
|
|
87
|
+
const opensExchange = position === "start" || position === "single";
|
|
88
|
+
return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_spoken-message-root", "data-role": role, "data-voice-run": position, className: cn("aui-spoken-message bg-muted/40 mx-2 px-3 py-1.5 [contain-intrinsic-size:auto_48px] [content-visibility:auto]", position === "single" && "rounded-xl py-2", position === "start" && "rounded-t-xl pt-2", position === "middle" && "-mt-6", position === "end" && "-mt-6 rounded-b-xl pb-2"), children: [opensExchange && (_jsxs("div", { "data-slot": "aui_spoken-exchange-header", className: "text-muted-foreground mb-1.5 flex items-center gap-1.5 text-xs", children: [_jsx(PhoneIcon, { className: "size-3", "aria-hidden": true }), _jsx("span", { children: "Voice conversation" })] })), _jsxs("div", { "data-slot": "aui_spoken-message-content", className: "text-foreground flex items-start gap-2 text-sm leading-relaxed", children: [_jsx("span", { className: "text-muted-foreground mt-1 shrink-0", "aria-hidden": true, children: role === "user" ? (_jsx(MicIcon, { className: "size-3.5" })) : (_jsx(AudioLinesIcon, { className: "size-3.5" })) }), _jsx("span", { className: "sr-only", children: role === "user" ? "You said" : "Assistant said" }), _jsxs("div", { className: "min-w-0 flex-1 wrap-break-word", children: [_jsx(MessagePrimitive.Parts, { components: { Text: SpokenText } }), isSpeaking && (_jsx("span", { "data-slot": "aui_spoken-message-indicator", role: "status", className: "text-muted-foreground ms-1 animate-pulse font-sans", "aria-label": "Assistant is speaking", children: "\u25CF" }))] }), _jsx(SpokenActionBar, {})] })] }));
|
|
89
|
+
};
|
|
90
|
+
const SpokenActionBar = () => {
|
|
91
|
+
return (_jsx(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "always", className: "aui-spoken-action-bar text-muted-foreground flex shrink-0 gap-1", children: _jsxs(ActionBarPrimitive.Copy, { render: _jsx(TooltipIconButton, { tooltip: "Copy", className: "size-6" }), children: [_jsx(AuiIf, { condition: (s) => s.message.isCopied, children: _jsx(CheckIcon, { className: "animate-in zoom-in-50 fade-in duration-200 ease-out" }) }), _jsx(AuiIf, { condition: (s) => !s.message.isCopied, children: _jsx(CopyIcon, { className: "animate-in zoom-in-75 fade-in duration-150" }) })] }) }));
|
|
92
|
+
};
|
|
93
|
+
const ThreadScrollToBottom = () => {
|
|
94
|
+
return (_jsx(ThreadPrimitive.ScrollToBottom, { render: _jsx(TooltipIconButton, { tooltip: "Scroll to bottom", variant: "outline", className: "aui-thread-scroll-to-bottom dark:border-border dark:bg-background dark:hover:bg-accent absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible" }), children: _jsx(ArrowDownIcon, {}) }));
|
|
95
|
+
};
|
|
96
|
+
const ThreadWelcome = () => {
|
|
97
|
+
return (_jsx("div", { className: "aui-thread-welcome-root mb-6 flex flex-col px-2", children: _jsx("p", { className: "aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-2xl font-medium tracking-tight duration-200", children: "How can I help you today?" }) }));
|
|
98
|
+
};
|
|
99
|
+
const ThreadSuggestions = () => {
|
|
100
|
+
return (_jsx("div", { className: "aui-thread-welcome-suggestions flex w-full flex-col", children: _jsx(ThreadPrimitive.Suggestions, { children: () => _jsx(ThreadSuggestionItem, {}) }) }));
|
|
101
|
+
};
|
|
102
|
+
const ThreadSuggestionItem = () => {
|
|
103
|
+
return (_jsx("div", { className: "aui-thread-welcome-suggestion-display fade-in slide-in-from-bottom-2 animate-in fill-mode-both duration-200", children: _jsxs(SuggestionPrimitive.Trigger, { send: true, render: _jsx("button", { type: "button", className: "aui-thread-welcome-suggestion group hover:bg-foreground/[0.03] focus-visible:ring-ring/50 flex w-full items-baseline gap-2.5 rounded-md px-2 py-2 text-start text-sm transition-colors outline-none focus-visible:ring-1 motion-reduce:transition-none" }), children: [_jsx("span", { "aria-hidden": true, className: "text-muted-foreground/60 group-hover:text-foreground font-mono text-xs transition-colors motion-reduce:transition-none", children: ">" }), _jsxs("span", { className: "min-w-0 flex-1 truncate", children: [_jsx(SuggestionPrimitive.Title, { className: "aui-thread-welcome-suggestion-text-1 text-foreground" }), " ", _jsx(SuggestionPrimitive.Description, { className: "aui-thread-welcome-suggestion-text-2 text-muted-foreground empty:hidden" })] })] }) }));
|
|
104
|
+
};
|
|
105
|
+
const Composer = ({ autoFocus }) => {
|
|
106
|
+
return (_jsx(ComposerPrimitive.Root, { className: "aui-composer-root relative flex w-full flex-col", children: _jsxs(ComposerPrimitive.AttachmentDropzone, { render: _jsx("div", { "data-slot": "aui_composer-shell", className: "border-foreground/10 focus-within:border-foreground/25 data-[dragging=true]:border-ring flex w-full cursor-text flex-col gap-2 rounded-(--composer-radius) border bg-(--composer-bg) p-(--composer-padding) transition-[border-color] data-[dragging=true]:border-dashed data-[dragging=true]:bg-[color-mix(in_oklab,var(--color-accent)_50%,var(--color-background))]" }), children: [_jsx(ComposerAttachments, {}), _jsx(ComposerPrimitive.Input, { placeholder: "Send a message...", className: "aui-composer-input caret-primary placeholder:text-muted-foreground/60 max-h-48 min-h-10 w-full resize-none bg-transparent px-2.5 py-1 text-base leading-6 outline-none", rows: 1, autoFocus: autoFocus, enterKeyHint: "send", "aria-label": "Message input" }), _jsx(ComposerAction, {})] }) }));
|
|
107
|
+
};
|
|
108
|
+
export const ComposerExtrasContext = createContext({});
|
|
109
|
+
const ComposerAction = () => {
|
|
110
|
+
const extras = useContext(ComposerExtrasContext);
|
|
111
|
+
return (_jsxs("div", { className: "aui-composer-action-wrapper relative flex items-center justify-between", children: [extras.attachments === false ? _jsx("span", {}) : _jsx(ComposerAddAttachment, {}), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs(AuiIf, { condition: (s) => s.thread.capabilities.dictation, children: [extras.dictate, _jsx(AuiIf, { condition: (s) => extras.dictate == null && s.composer.dictation == null, children: _jsx(ComposerPrimitive.Dictate, { render: _jsx(TooltipIconButton, { tooltip: "Voice input", side: "bottom", type: "button", variant: "ghost", size: "icon", className: "aui-composer-dictate text-muted-foreground hover:text-foreground size-7 rounded-full", "aria-label": "Start voice input" }), children: _jsx(MicIcon, { className: "aui-composer-dictate-icon size-4" }) }) }), _jsx(AuiIf, { condition: (s) => extras.dictate == null && s.composer.dictation != null, children: _jsx(ComposerPrimitive.StopDictation, { render: _jsx(TooltipIconButton, { tooltip: "Stop dictation", side: "bottom", type: "button", variant: "ghost", size: "icon", className: "aui-composer-stop-dictation text-destructive size-7 rounded-full", "aria-label": "Stop voice input" }), children: _jsx(SquareIcon, { className: "aui-composer-stop-dictation-icon size-3.5 animate-pulse fill-current" }) }) })] }), _jsx(AuiIf, { condition: (s) => !s.thread.isRunning, children: _jsx(ComposerPrimitive.Send, { render: _jsx(TooltipIconButton, { tooltip: "Send message", side: "bottom", type: "button", variant: "default", size: "icon", className: "aui-composer-send size-7 rounded-full", "aria-label": "Send message" }), children: _jsx(ArrowUpIcon, { className: "aui-composer-send-icon size-4" }) }) }), _jsx(AuiIf, { condition: (s) => s.thread.isRunning, children: _jsx(ComposerPrimitive.Cancel, { render: _jsx(Button, { type: "button", variant: "default", size: "icon", className: "aui-composer-cancel size-7 rounded-full", "aria-label": "Stop generating" }), children: _jsx(SquareIcon, { className: "aui-composer-cancel-icon size-3.5 fill-current" }) }) })] })] }));
|
|
112
|
+
};
|
|
113
|
+
const MessageError = () => {
|
|
114
|
+
return (_jsx(MessagePrimitive.Error, { children: _jsx(ErrorPrimitive.Root, { className: "aui-message-error-root border-destructive bg-destructive/10 text-destructive dark:bg-destructive/5 mt-2 rounded-md border p-3 text-sm dark:text-red-200", children: _jsx(ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) }));
|
|
115
|
+
};
|
|
116
|
+
const AssistantMessage = () => {
|
|
117
|
+
const { ToolFallback: ToolFallbackComponent = ToolFallback, ToolGroup, ReasoningGroup, TaskGroup: TaskGroupComponent, } = useContext(ThreadComponentsContext);
|
|
118
|
+
const groupBy = TaskGroupComponent ? taskAwareGroupBy : messageGroupBy;
|
|
119
|
+
const ACTION_BAR_PT = "pt-1.5";
|
|
120
|
+
// Keep the action bar inside the contained root's paint box, then cancel its reserved space in flow.
|
|
121
|
+
const ACTION_BAR_HEIGHT = `min-h-7.5 ${ACTION_BAR_PT}`;
|
|
122
|
+
return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_assistant-message-root", "data-role": "assistant", className: "fade-in slide-in-from-bottom-1 animate-in relative -mb-7.5 pb-7.5 duration-150 [contain-intrinsic-size:auto_200px] [content-visibility:auto]", children: [_jsxs("div", { "data-slot": "aui_assistant-message-content", className: "text-foreground px-2 leading-relaxed wrap-break-word", children: [_jsx(MessagePrimitive.GroupedParts, { groupBy: groupBy, children: ({ part, children }) => {
|
|
123
|
+
switch (part.type) {
|
|
124
|
+
case "group-chainOfThought":
|
|
125
|
+
return _jsx("div", { "data-slot": "aui_chain-of-thought", children: children });
|
|
126
|
+
case "group-task":
|
|
127
|
+
return TaskGroupComponent ? (_jsx(TaskGroupComponent, { group: part })) : null;
|
|
128
|
+
case "group-tool":
|
|
129
|
+
if (ToolGroup) {
|
|
130
|
+
return _jsx(ToolGroup, { group: part, children: children });
|
|
131
|
+
}
|
|
132
|
+
return (_jsxs(ToolGroupRoot, { variant: "ghost", children: [_jsx(ToolGroupTrigger, { count: part.indices.length, active: part.status.type === "running" }), _jsx(ToolGroupContent, { children: children })] }));
|
|
133
|
+
case "group-reasoning": {
|
|
134
|
+
if (ReasoningGroup) {
|
|
135
|
+
return (_jsx(ReasoningGroup, { group: part, children: children }));
|
|
136
|
+
}
|
|
137
|
+
const running = part.status.type === "running";
|
|
138
|
+
return (_jsxs(ReasoningRoot, { streaming: running, children: [_jsx(ReasoningTrigger, { active: running }), _jsx(ReasoningContent, { "aria-busy": running, children: _jsx(ReasoningText, { children: children }) })] }));
|
|
139
|
+
}
|
|
140
|
+
case "text":
|
|
141
|
+
return _jsx(MarkdownText, {});
|
|
142
|
+
case "reasoning":
|
|
143
|
+
return _jsx(Reasoning, { ...part });
|
|
144
|
+
case "tool-call":
|
|
145
|
+
return part.toolUI ?? _jsx(ToolFallbackComponent, { ...part });
|
|
146
|
+
case "data":
|
|
147
|
+
return part.dataRendererUI;
|
|
148
|
+
case "file":
|
|
149
|
+
return (_jsx("div", { "data-slot": "aui_assistant-message-file", className: "py-1", children: _jsx(File, { ...part }) }));
|
|
150
|
+
case "image":
|
|
151
|
+
return (_jsx("div", { "data-slot": "aui_assistant-message-image", className: "py-1", children: _jsx(Image, { ...part }) }));
|
|
152
|
+
case "indicator":
|
|
153
|
+
return (_jsx("span", { "data-slot": "aui_assistant-message-indicator", className: "animate-pulse font-sans", "aria-label": "Assistant is working", children: "●" }));
|
|
154
|
+
default:
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
} }), _jsx(MessageError, {})] }), _jsxs("div", { "data-slot": "aui_assistant-message-footer", className: cn("ms-2 flex items-center", ACTION_BAR_HEIGHT), children: [_jsx(BranchPicker, {}), _jsx(AssistantActionBar, {})] })] }));
|
|
158
|
+
};
|
|
159
|
+
const AssistantActionBar = () => {
|
|
160
|
+
return (_jsxs(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "not-last", className: "aui-assistant-action-bar-root text-muted-foreground animate-in fade-in col-start-3 row-start-2 -ms-1 flex gap-1 duration-200", children: [_jsxs(ActionBarPrimitive.Copy, { render: _jsx(TooltipIconButton, { tooltip: "Copy" }), children: [_jsx(AuiIf, { condition: (s) => s.message.isCopied, children: _jsx(CheckIcon, { className: "animate-in zoom-in-50 fade-in duration-200 ease-out" }) }), _jsx(AuiIf, { condition: (s) => !s.message.isCopied, children: _jsx(CopyIcon, { className: "animate-in zoom-in-75 fade-in duration-150" }) })] }), _jsx(ActionBarPrimitive.Reload, { render: _jsx(TooltipIconButton, { tooltip: "Refresh" }), children: _jsx(RefreshCwIcon, {}) }), _jsxs(ActionBarMorePrimitive.Root, { children: [_jsx(ActionBarMorePrimitive.Trigger, { render: _jsx(TooltipIconButton, { tooltip: "More", className: "data-[state=open]:bg-accent" }), children: _jsx(MoreHorizontalIcon, {}) }), _jsx(ActionBarMorePrimitive.Content, { side: "bottom", align: "start", sideOffset: 6, className: "aui-action-bar-more-content bg-popover text-popover-foreground data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:animate-out data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-xl border p-1.5", children: _jsxs(ActionBarPrimitive.ExportMarkdown, { render: _jsx(ActionBarMorePrimitive.Item, { className: "aui-action-bar-more-item hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground flex cursor-pointer items-center gap-2 rounded-lg px-2.5 py-1.5 text-sm outline-none select-none" }), children: [_jsx(DownloadIcon, { className: "size-4" }), "Export as Markdown"] }) })] })] }));
|
|
161
|
+
};
|
|
162
|
+
const UserFilePart = (part) => (_jsx("div", { "data-slot": "aui_user-message-file", className: "py-1", children: _jsx(File, { ...part }) }));
|
|
163
|
+
const UserImagePart = (part) => (_jsx("div", { "data-slot": "aui_user-message-image", className: "py-1", children: _jsx(Image, { ...part }) }));
|
|
164
|
+
const UserMessage = () => {
|
|
165
|
+
return (_jsxs(MessagePrimitive.Root, { "data-slot": "aui_user-message-root", className: "fade-in slide-in-from-bottom-1 animate-in grid auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 duration-150 [contain-intrinsic-size:auto_200px] [content-visibility:auto] [&:where(>*)]:col-start-2", "data-role": "user", children: [_jsx(UserMessageAttachments, {}), _jsxs("div", { className: "aui-user-message-content-wrapper relative col-start-2 min-w-0", children: [_jsx("div", { className: "aui-user-message-content peer bg-muted text-foreground rounded-(--composer-radius) px-4 py-2 wrap-break-word empty:hidden", children: _jsx(MessagePrimitive.Parts, { components: { File: UserFilePart, Image: UserImagePart } }) }), _jsx("div", { className: "aui-user-action-bar-wrapper absolute start-0 top-1/2 -translate-x-full -translate-y-1/2 pe-2 peer-empty:hidden rtl:translate-x-full", children: _jsx(UserActionBar, {}) })] }), _jsx(BranchPicker, { "data-slot": "aui_user-branch-picker", className: "col-span-full col-start-1 row-start-3 -me-1 justify-end" })] }));
|
|
166
|
+
};
|
|
167
|
+
const UserActionBar = () => {
|
|
168
|
+
return (_jsx(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "not-last", className: "aui-user-action-bar-root flex flex-col items-end", children: _jsx(ActionBarPrimitive.Edit, { render: _jsx(TooltipIconButton, { tooltip: "Edit", className: "aui-user-action-edit" }), children: _jsx(PencilIcon, {}) }) }));
|
|
169
|
+
};
|
|
170
|
+
const EditComposer = () => {
|
|
171
|
+
return (_jsx(MessagePrimitive.Root, { "data-slot": "aui_edit-composer-wrapper", className: "flex flex-col px-2 [contain-intrinsic-size:auto_200px] [content-visibility:auto]", children: _jsxs(ComposerPrimitive.Root, { className: "aui-edit-composer-root border-foreground/10 focus-within:border-foreground/25 ms-auto flex w-full max-w-[85%] cursor-text flex-col rounded-(--composer-radius) border bg-(--composer-bg) transition-[border-color]", children: [_jsx(ComposerPrimitive.Input, { className: "aui-edit-composer-input text-foreground min-h-14 w-full resize-none bg-transparent px-4 pt-3 pb-1 text-base outline-none", autoFocus: true }), _jsxs("div", { className: "aui-edit-composer-footer mx-2.5 mb-2.5 flex items-center gap-1.5 self-end", children: [_jsx(ComposerPrimitive.Cancel, { render: _jsx(Button, { variant: "ghost", size: "sm", className: "h-8 px-3" }), children: "Cancel" }), _jsx(ComposerPrimitive.Send, { render: _jsx(Button, { size: "sm", className: "h-8 px-3" }), children: "Update" })] })] }) }));
|
|
172
|
+
};
|
|
173
|
+
const BranchPicker = ({ className, ...rest }) => {
|
|
174
|
+
return (_jsxs(BranchPickerPrimitive.Root, { hideWhenSingleBranch: true, className: cn("aui-branch-picker-root text-muted-foreground -ms-2 me-2 inline-flex items-center text-xs", className), ...rest, children: [_jsx(BranchPickerPrimitive.Previous, { render: _jsx(TooltipIconButton, { tooltip: "Previous" }), children: _jsx(ChevronLeftIcon, {}) }), _jsxs("span", { className: "aui-branch-picker-state font-medium", children: [_jsx(BranchPickerPrimitive.Number, {}), " / ", _jsx(BranchPickerPrimitive.Count, {})] }), _jsx(BranchPickerPrimitive.Next, { render: _jsx(TooltipIconButton, { tooltip: "Next" }), children: _jsx(ChevronRightIcon, {}) })] }));
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=thread.aui.js.map
|