import { useState } from "react"; import type { ConversationMessage as ConversationMessageType } from "../../lib/api"; interface ConversationMessageProps { message: ConversationMessageType; } // Get role styling function getRoleStyle(role: string) { switch (role.toLowerCase()) { case "user": return { label: "User", color: "text-[#9bc3ff]", bg: "bg-[rgba(155,195,255,0.1)]" }; case "assistant": return { label: "Assistant", color: "text-emerald-400", bg: "bg-[rgba(52,211,153,0.1)]" }; case "system": return { label: "System", color: "text-yellow-400", bg: "bg-[rgba(250,204,21,0.1)]" }; case "tool": return { label: "Tool", color: "text-purple-400", bg: "bg-[rgba(192,132,252,0.1)]" }; default: return { label: role, color: "text-[#7788aa]", bg: "bg-[rgba(119,136,170,0.1)]" }; } } // Format JSON for display function formatJson(data: unknown): string { try { return JSON.stringify(data, null, 2); } catch { return String(data); } } export function ConversationMessage({ message }: ConversationMessageProps) { const [showToolDetails, setShowToolDetails] = useState(false); const { label, color, bg } = getRoleStyle(message.role); const hasToolInfo = message.toolName || message.toolCalls?.length; return (
{/* Header */}
{label} {message.toolName && ( {message.toolName} )}
{message.tokenCount && ( {message.tokenCount.toLocaleString()} tokens )} {message.costUsd !== undefined && message.costUsd > 0 && ( ${message.costUsd.toFixed(4)} )} {new Date(message.timestamp).toLocaleTimeString()}
{/* Content */}
{message.content}
{/* Tool calls */} {hasToolInfo && (
{showToolDetails && (
{/* Tool input */} {message.toolInput && (
Input
                    {formatJson(message.toolInput)}
                  
)} {/* Tool result */} {message.toolResult && (
{message.isError ? "Error" : "Result"}
                    {message.toolResult}
                  
)} {/* Multiple tool calls */} {message.toolCalls?.map((call, i) => (
{call.name}
                    {formatJson(call.input)}
                  
))}
)}
)}
); }