import { useState } from 'react'; import { FileText, Terminal, Pencil, Search, Globe, Wrench, ChevronRight } from 'lucide-react'; import type { ChatMessage } from './types'; type ToolMessage = Extract; type ToolActivityProps = { message: ToolMessage; }; const toolIcons: Record = { Read: FileText, Edit: Pencil, Write: Pencil, Bash: Terminal, Grep: Search, Glob: Search, WebFetch: Globe, WebSearch: Globe, }; function getToolSummary(toolName: string, toolInput: Record): string { switch (toolName) { case 'Read': case 'Edit': case 'Write': return (toolInput.file_path as string) ?? ''; case 'Bash': return truncate((toolInput.command as string) ?? '', 80); case 'Grep': case 'Glob': return (toolInput.pattern as string) ?? ''; case 'WebFetch': return (toolInput.url as string) ?? ''; case 'WebSearch': return (toolInput.query as string) ?? ''; default: return ( Object.values(toolInput) .find((v) => typeof v === 'string') ?.toString() ?? '' ); } } function truncate(str: string, max: number): string { return str.length > max ? str.slice(0, max) + '...' : str; } export const ToolActivity = ({ message }: ToolActivityProps) => { const [open, setOpen] = useState(false); const Icon = toolIcons[message.toolName] ?? Wrench; const summary = getToolSummary(message.toolName, message.toolInput); const pending = message.output === undefined; const isError = message.isError === true; return (
{open && (
Input
{message.toolName === 'Bash' ? (
                {(message.toolInput.command as string) ?? JSON.stringify(message.toolInput, null, 2)}
              
) : (
                {Object.entries(message.toolInput)
                  .map(([k, v]) => `${k}: ${typeof v === 'string' ? v : JSON.stringify(v)}`)
                  .join('\n')}
              
)}
{message.output !== undefined && (
Output
)}
)}
); }; type ToolOutputProps = { toolName: string; output: string; isError: boolean; }; const ToolOutput = ({ toolName, output, isError }: ToolOutputProps) => { const [expanded, setExpanded] = useState(false); const maxLines = 20; const lines = output.split('\n'); const needsTruncation = lines.length > maxLines; const displayText = expanded ? output : lines.slice(0, maxLines).join('\n'); const isBash = toolName === 'Bash'; return ( <>
        {displayText}
      
{needsTruncation && ( )} ); };