"use client" import { useState } from "react" import type { UIMessage } from "@ai-sdk/react" import { Streamdown } from "streamdown" import { ChevronDownIcon, ChevronRightIcon, Loader2, SearchIcon, PlusIcon, BookOpenIcon, ClockIcon, ListIcon, XCircleIcon, WrenchIcon, } from "lucide-react" import { cn } from "@lib/utils" import { RelatedMemories } from "./related-memories" import { MessageActions } from "./message-actions" import { FollowUpQuestions } from "./follow-up-questions" const TOOL_META: Record = { searchMemories: { label: "Search Memories", icon: SearchIcon }, addMemory: { label: "Add Memory", icon: PlusIcon }, fetchMemory: { label: "Fetch Memory", icon: BookOpenIcon }, scheduleTask: { label: "Schedule Task", icon: ClockIcon }, listSchedules: { label: "List Schedules", icon: ListIcon }, cancelSchedule: { label: "Cancel Schedule", icon: XCircleIcon }, } function ToolCallDisplay({ part }: { part: { type: string; state: string; input?: unknown; output?: unknown; toolCallId?: string } }) { const [expanded, setExpanded] = useState(false) const toolName = part.type.replace("tool-", "") const meta = TOOL_META[toolName] const Icon = meta?.icon ?? WrenchIcon const label = meta?.label ?? toolName const isLoading = part.state === "input-streaming" || part.state === "input-available" const isDone = part.state === "output-available" const isError = part.state === "error" return (
{expanded && (
{part.input !== undefined && (
Input
								{typeof part.input === "string" ? part.input : JSON.stringify(part.input, null, 2)}
							
)} {isDone && part.output !== undefined && (
Output
								{typeof part.output === "string" ? part.output : JSON.stringify(part.output, null, 2)}
							
)}
)}
) } interface AgentMessageProps { message: UIMessage index: number messagesLength: number hoveredMessageId: string | null copiedMessageId: string | null messageFeedback: Record expandedMemories: string | null followUpQuestions?: string[] isLoadingFollowUps?: boolean onCopy: (messageId: string, text: string) => void onLike: (messageId: string) => void onDislike: (messageId: string) => void onToggleMemories: (messageId: string) => void onQuestionClick?: (question: string) => void } export function AgentMessage({ message, index, messagesLength, hoveredMessageId, copiedMessageId, messageFeedback, expandedMemories, followUpQuestions = [], isLoadingFollowUps = false, onCopy, onLike, onDislike, onToggleMemories, onQuestionClick, }: AgentMessageProps) { const isLastAgentMessage = index === messagesLength - 1 && message.role === "assistant" const isHovered = hoveredMessageId === message.id const messageText = message.parts .filter((part) => part.type === "text") .map((part) => part.text) .join(" ") return (
{message.parts.map((part, partIndex) => { if (part.type === "text") { return (
{part.text}
) } if (part.type.startsWith("tool-")) { return ( ) } return null })} {})} />
) }