import { ComposerAddAttachment, ComposerAttachments, UserMessageAttachments, } from "@/components/assistant-ui/attachment"; import { MarkdownText } from "@/components/assistant-ui/markdown-text"; import { ToolFallback } from "@/components/assistant-ui/tool-fallback"; import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { ActionBarMorePrimitive, ActionBarPrimitive, AuiIf, type AssistantState, BranchPickerPrimitive, ComposerPrimitive, ErrorPrimitive, MessagePrimitive, SuggestionPrimitive, ThreadPrimitive, useAuiState, } from "@assistant-ui/react"; import { ArrowDownIcon, ArrowUpIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, CopyIcon, DownloadIcon, MicIcon, MoreHorizontalIcon, PencilIcon, RefreshCwIcon, SquareIcon, } from "lucide-react"; import type { FC } from "react"; // Startup exposes a loading placeholder thread; treat it as a new chat so // the composer mounts centered. Loads after startup keep the docked layout. const isNewChatView = (s: AssistantState) => s.thread.messages.length === 0 && (!s.thread.isLoading || s.threads.isLoading); export const Thread: FC = () => { const isEmpty = useAuiState(isNewChatView); return (
{() => }
isNewChatView(s) && s.composer.isEmpty}>
); }; const ThreadMessage: FC = () => { const role = useAuiState((s) => s.message.role); const isEditing = useAuiState((s) => s.message.composer.isEditing); if (isEditing) return ; if (role === "user") return ; return ; }; const ThreadScrollToBottom: FC = () => { return ( ); }; const ThreadWelcome: FC = () => { return (

How can I help you today?

); }; const ThreadSuggestions: FC = () => { return (
{() => }
); }; const ThreadSuggestionItem: FC = () => { return (
); }; const Composer: FC = () => { return (
); }; const ComposerAction: FC = () => { return (
s.thread.capabilities.dictation}> s.composer.dictation == null}> s.composer.dictation != null}> !s.thread.isRunning}> s.thread.isRunning}>
); }; const MessageError: FC = () => { return ( ); }; const AssistantMessage: FC = () => { const ACTION_BAR_PT = "pt-1.5"; const ACTION_BAR_HEIGHT = `min-h-7.5 ${ACTION_BAR_PT}`; return (
{({ part }) => { if (part.type === "text") return ; if (part.type === "tool-call") return part.toolUI ?? ; return null; }} s.message.status?.type === "running" && s.message.parts.length === 0 } > {"●"}
); }; const AssistantActionBar: FC = () => { return ( s.message.isCopied}> !s.message.isCopied}> Export as Markdown ); }; const UserMessage: FC = () => { return (
); }; const UserActionBar: FC = () => { return ( ); }; const EditComposer: FC = () => { return (
); }; const BranchPicker: FC = ({ className, ...rest }) => { return ( / ); };