"use client"; import { cn } from "@/lib/utils"; import { ActionBarPrimitive, ActionBarMorePrimitive, AuiIf, AttachmentPrimitive, BranchPickerPrimitive, ComposerPrimitive, MessagePrimitive, ThreadPrimitive, useAui, useAuiState, } from "@assistant-ui/react"; import { useEffect, useState, type FC } from "react"; import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button"; import { useShallow } from "zustand/shallow"; import { ArrowUpIcon, AudioLines, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, CopyIcon, Download, Mic, MoreHorizontal, PencilIcon, PlusIcon, RefreshCwIcon, Share, ThumbsDown, ThumbsUp, Volume2, XIcon, } from "lucide-react"; import { MarkdownText } from "@/components/assistant-ui/markdown-text"; import { ToolFallback } from "@/components/assistant-ui/tool-fallback"; export const ChatGPT: FC = () => { return ( s.thread.isEmpty}> !s.thread.isEmpty}> {({ message }) => { if (message.composer.isEditing) return ; if (message.role === "user") return ; return ; }}

ChatGPT can make mistakes. Check important info.

); }; const EmptyState: FC = () => { return (

Where should we begin?

); }; const Composer: FC<{ placeholder: string }> = ({ placeholder }) => { return ( s.composer.attachments.length > 0}>
); }; const ComposerPrimaryAction: FC = () => { return (
s.thread.isRunning}>
!s.thread.isRunning && s.composer.dictation != null} >
!s.thread.isRunning && s.composer.dictation == null && !s.composer.isEmpty } > !s.thread.isRunning && s.composer.dictation == null && s.composer.isEmpty } >
); }; const ThreadScrollToBottom: FC = () => { return ( ); }; const UserMessage: FC = () => { return (
s.message.isCopied}> !s.message.isCopied}>
); }; const EditComposer: FC = () => { return (
Cancel Send
); }; const assistantActionClassName = "flex size-8 items-center justify-center rounded-lg text-[#5d5d5d] transition-colors hover:bg-black/[0.07] hover:text-[#5d5d5d] dark:text-[#cdcdcd] dark:hover:bg-white/15 dark:hover:text-[#cdcdcd]"; const AssistantMessage: FC = () => { return (
{({ part }) => { if (part.type === "text") return ; if (part.type === "tool-call") return part.toolUI ?? ; return null; }}
s.message.isCopied}> !s.message.isCopied}> Export as Markdown
); }; const BranchPicker: FC<{ className?: string }> = ({ className }) => { return ( / ); }; const useFileSrc = (file: File | undefined) => { const [src, setSrc] = useState(undefined); useEffect(() => { if (!file) { setSrc(undefined); return; } const objectUrl = URL.createObjectURL(file); setSrc(objectUrl); return () => { URL.revokeObjectURL(objectUrl); }; }, [file]); return src; }; const useAttachmentSrc = () => { const { file, src } = useAuiState( useShallow((s): { file?: File; src?: string } => { if (s.attachment.type !== "image") return {}; if (s.attachment.file) return { file: s.attachment.file }; const src = s.attachment.content?.filter((c) => c.type === "image")[0] ?.image; if (!src) return {}; return { src }; }), ); return useFileSrc(file) ?? src; }; const ChatGPTAttachmentUI: FC = () => { const aui = useAui(); const isComposer = aui.attachment.source !== "message"; const src = useAttachmentSrc(); return (
s.attachment.type === "image"}> {src ? ( Attachment ) : (
)}
s.attachment.type !== "image"}>
{isComposer && ( )}
); };