import React, { useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { ChevronRight, Loader2, CheckCircle2, AlertCircle, Terminal, FileText, Search, Edit, FolderOpen, Code } from "lucide-react"; import { cn } from "@/lib/utils"; import type { ToolCall, ToolResult } from "@/types/enhanced-messages"; interface CollapsibleToolResultProps { toolCall: ToolCall; toolResult?: ToolResult; className?: string; children?: React.ReactNode; } // Map tool names to icons const toolIcons: Record = { read: , write: , edit: , multiedit: , bash: , ls: , glob: , grep: , task: , default: }; // Get tool icon based on tool name function getToolIcon(toolName: string): React.ReactNode { const lowerName = toolName.toLowerCase(); return toolIcons[lowerName] || toolIcons.default; } // Get display name for tools function getToolDisplayName(toolName: string): string { const displayNames: Record = { ls: "List directory", read: "Read file", write: "Write file", edit: "Edit file", multiedit: "Multi-edit file", bash: "Run command", glob: "Find files", grep: "Search files", task: "Run task", todowrite: "Update todos", todoread: "Read todos", websearch: "Search web", webfetch: "Fetch webpage" }; const lowerName = toolName.toLowerCase(); return displayNames[lowerName] || toolName; } // Get a brief description of the tool call function getToolDescription(toolCall: ToolCall): string { const name = toolCall.name.toLowerCase(); const input = toolCall.input; switch (name) { case "read": return input?.file_path ? `${input.file_path}` : "Reading file"; case "write": return input?.file_path ? `${input.file_path}` : "Writing file"; case "edit": case "multiedit": return input?.file_path ? `${input.file_path}` : "Editing file"; case "bash": return input?.command ? `${input.command}` : "Running command"; case "ls": return input?.path ? `${input.path}` : "Listing directory"; case "glob": return input?.pattern ? `${input.pattern}` : "Finding files"; case "grep": return input?.pattern ? `${input.pattern}` : "Searching files"; case "task": return input?.description || "Running task"; default: return toolCall.name; } } export const CollapsibleToolResult: React.FC = ({ toolCall, toolResult, className }) => { const [isExpanded, setIsExpanded] = useState(false); const isPending = !toolResult; const isError = toolResult?.isError; return (
{/* Tool Call Header */}
setIsExpanded(!isExpanded)} > {/* Expand/Collapse Icon */} {/* Tool Icon */}
{getToolIcon(toolCall.name)}
{/* Tool Name */} {getToolDisplayName(toolCall.name)} {/* Tool Description */} {getToolDescription(toolCall)} {/* Status Icon */}
{isPending ? ( ) : isError ? ( ) : ( )}
{/* Tool Result (collapsible) */} {isExpanded && toolResult && (
{isError ? ( ) : ( )} {isError ? "Tool Error" : "Tool Result"}
{/* Result Content */}
{typeof toolResult.content === 'string' ? toolResult.content : JSON.stringify(toolResult.content, null, 2)}
)}
); };