import { Download, MessageCircle, Wrench } from "lucide-react"; import { memo, useEffect, useRef, useState } from "react"; import { initials } from "../lib/context"; import type { ConnectionStatus } from "../lib/contracts"; import { displayTime, exportConversation, renderMarkdown, type Message } from "../lib/messages"; import { LIVE_STATES } from "../realtime/controller"; const MessageRow = memo(function MessageRow({ message, userName }: { message: Message; userName: string }) { const [expanded, setExpanded] = useState(false); const time = displayTime(message.timestamp); if (message.role === "tool") { return (
Llamada a herramienta
Entrada
{message.toolArguments}
Salida
{message.text}
); } const data = { "data-user-name": userName, "data-user-initials": initials(userName), "data-asst-name": "Vocero", "data-timestamp": time, }; return (
{message.role === "user" ? userName : "Vocero"}
{message.role === "assistant" ? (
) : (
{message.text}
)} {message.interrupted &&
Interrumpido
}
); }); export const Conversation = memo(function Conversation({ messages, userName, status, white, }: { messages: Message[]; userName: string; status: ConnectionStatus; white: boolean; }) { const history = useRef(null); const atBottom = useRef(true); useEffect(() => { const element = history.current; if (element && atBottom.current) { element.scrollTop = element.scrollHeight; } }, [messages]); const live = LIVE_STATES.has(status); const waiting = ["connecting", "queued", "your-turn"].includes(status); return (

Conversación

{white && ( )}
{ const element = history.current; if (element) { atBottom.current = element.scrollHeight - element.scrollTop - element.clientHeight < 60; } }} > {messages.length ? ( messages.map((message) => ) ) : (
)}
); });