"use client"; import { isToolUIPart, type ChatStatus, type UIMessage } from "ai"; import { Conversation, ConversationContent, ConversationScrollButton, } from "@/components/ai-elements/conversation"; import { Message, MessageAttachment, MessageAttachments, MessageContent, MessageResponse, } from "@/components/ai-elements/message"; import { Reasoning, ReasoningContent, ReasoningTrigger, } from "@/components/ai-elements/reasoning"; import { Loader } from "@/components/ai-elements/loader"; import { ToolPartRenderer } from "@/components/tools/tool-part-renderer"; import { getTextContent, getReasoningPart } from "@/lib/chat/messages"; interface ChatMessagesProps { messages: UIMessage[]; status?: ChatStatus; } function LoadingIndicator() { return ( ); } export function ChatMessages({ messages, status = "ready" }: ChatMessagesProps) { const hasReasoningPart = (parts: typeof messages[0]["parts"]) => parts.some((p) => p.type === "reasoning" && p.text); const visibleMessages = messages.filter( (message) => message.role === "user" || getTextContent(message.parts).trim() !== "" || message.parts.some((p) => p.type === "file" || isToolUIPart(p)) || hasReasoningPart(message.parts) ); const lastMessage = messages[messages.length - 1]; const hasContent = getTextContent(lastMessage?.parts || []).trim() !== "" || lastMessage?.parts.some((p) => p.type === "file" || isToolUIPart(p)) || hasReasoningPart(lastMessage?.parts || []); const isLoading = status === "submitted" || status === "streaming"; const showLoading = isLoading && !(lastMessage?.role === "assistant" && hasContent); return ( {visibleMessages.map((message) => { const isStreaming = status === "streaming" && message.role === "assistant" && message.id === lastMessage?.id; const textContent = getTextContent(message.parts); const reasoningPart = getReasoningPart(message.parts); const fileParts = message.parts.filter((p) => p.type === "file"); const toolParts = message.parts.filter((p) => isToolUIPart(p)); return ( {fileParts.length > 0 && ( {fileParts.map((part, index) => ( ))} )} {message.role === "assistant" && reasoningPart && ( {reasoningPart.text || ""} )} {toolParts.map((part, index) => ( ))} {textContent && ( part.type === "text" && part.state === "streaming" ) } > {textContent} )} ); })} {showLoading && } ); }