import { motion } from "framer-motion"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import { format } from "date-fns"; import { Brain, FileText, User, Copy, Check } from "lucide-react"; import { useState } from "react"; function CopyButton({ text }) { const [copied, setCopied] = useState(false); const handleCopy = async () => { await navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }; return ( ); } export default function MessageBubble({ message, isStreaming = false }) { const isUser = message.role === "user"; const timestamp = message.timestamp ? format(new Date(message.timestamp), "HH:mm") : ""; const memoriesUsed = message.metadata?.memories_used || 0; const docsRetrieved = message.metadata?.docs_retrieved || 0; if (isUser) { return ( {/* User Avatar */}
{timestamp}
{message.content}
); } // Assistant message return ( {/* Nexus Avatar */}
N
Nexus {timestamp}
{/* Message content */}
{message.content}
{/* Streaming cursor */} {isStreaming && ( )}
{/* Metadata badges */} {(memoriesUsed > 0 || docsRetrieved > 0) && (
{memoriesUsed > 0 && ( {memoriesUsed} memories )} {docsRetrieved > 0 && ( {docsRetrieved} chunks )}
)}
); }