'use client'; import React from 'react'; import { ParsedTag, ToolComponentProps } from '@/lib/types/tool-calls'; import { File, FileText, Terminal, FolderPlus, Folder, Code, Search as SearchIcon, Bell, Replace, Plus, Minus, Globe, Search } from 'lucide-react'; import { cn } from '@/lib/utils'; import { diffLines } from 'diff'; // Shared compact mode component const CompactToolDisplay: React.FC<{ icon: React.ReactNode, name: string, input: string, isRunning?: boolean }> = ({ icon, name, input, isRunning }) => { return (
{icon} {name}: {input} {isRunning && (
Running
)}
); }; /** * Create File Tool Component */ export const CreateFileTool: React.FC = ({ tag, mode }) => { const filePath = tag.attributes.file_path || ''; const fileContent = tag.content || ''; const isRunning = tag.status === 'running'; if (mode === 'compact') { return ( } name={isRunning ? "Creating file" : "Created file"} input={filePath} isRunning={isRunning} /> ); } return (
{isRunning ? "Creating file" : "Created file"}: {filePath}
{isRunning && (
Running
)}
{filePath}
            {fileContent}
          
); }; /** * Full File Rewrite Tool Component */ export const FullFileRewriteTool: React.FC = ({ tag, mode }) => { const filePath = tag.attributes.file_path || ''; const fileContent = tag.content || ''; const isRunning = tag.status === 'running'; if (mode === 'compact') { return ( } name={isRunning ? "Rewriting file" : "Rewrote file"} input={filePath} isRunning={isRunning} /> ); } return (
{isRunning ? "Rewriting file" : "Rewrote file"}: {filePath}
{isRunning && (
Running
)}
{filePath}
            {fileContent}
          
); }; /** * Read File Tool Component */ export const ReadFileTool: React.FC = ({ tag, mode }) => { const filePath = tag.attributes.file_path || ''; const fileContent = tag.content || ''; const isRunning = tag.status === 'running'; if (mode === 'compact') { return ( } name={isRunning ? "Reading file" : "Read file"} input={filePath} isRunning={isRunning} /> ); } return (
{isRunning ? "Reading file" : "Read file"}: {filePath}
{isRunning && (
Running
)}
{filePath}
            {fileContent}
          
); }; /** * Execute Command Tool Component */ export const ExecuteCommandTool: React.FC = ({ tag, mode }) => { const output = tag.content || ''; const command = tag.resultTag?.content || ''; const isRunning = tag.status === 'running'; if (mode === 'compact') { return ( } name={isRunning ? "Executing" : "Executed"} input={tag.content} // in compact mode, the command is in the content isRunning={isRunning} /> ); } return (
{isRunning ? `Executing: ${command}` : `Executed: ${command}`}
{isRunning && (
Running
)}
Terminal
user@localhost : ~ $ {command}
{output && (
{output}
)} {!isRunning && (
user@localhost : ~ $
)}
); }; /** * String Replace Tool Component */ export const StringReplaceTool: React.FC = ({ tag, mode }) => { const content = tag.content || ''; const isRunning = tag.status === 'running'; // Parse the old and new strings from the content const oldStrMatch = content.match(/([\s\S]*?)<\/old_str>/); const newStrMatch = content.match(/([\s\S]*?)<\/new_str>/); const oldStr = oldStrMatch ? oldStrMatch[1] : ''; const newStr = newStrMatch ? newStrMatch[1] : ''; // Calculate the diff between old and new strings const diff = diffLines(oldStr, newStr); interface DiffPart { added?: boolean; removed?: boolean; value: string; } if (mode === 'compact') { return ( } name={isRunning ? "Updating file" : "Updated file"} input="" isRunning={isRunning} /> ); } return (
{isRunning ? "Updating file" : "Updated file"}
{isRunning && (
Running
)}
{diff.map((part: DiffPart, index: number) => (
{part.added ? : part.removed ? : }
{part.value}
))}
); }; /** * Notification Tool Component */ export const NotifyTool: React.FC = ({ tag, mode }) => { const message = tag.attributes.message || ''; const type = tag.attributes.type || 'info'; const isRunning = tag.status === 'running'; if (mode === 'compact') { return ( } name={isRunning ? "Sending notification" : "Sent notification"} input={message.substring(0, 30) + (message.length > 30 ? '...' : '')} isRunning={isRunning} /> ); } return (
{isRunning ? "Sending notification" : "Sent notification"}: {message.substring(0, 30)}{message.length > 30 ? '...' : ''}
{isRunning && (
Running
)}
{message}
); }; /** * Directory Tool Component (for create-directory and list-directory) */ export const DirectoryTool: React.FC = ({ tag, mode }) => { const path = tag.attributes.path || ''; const content = tag.content || ''; const isListDirectory = tag.tagName === 'list-directory'; const isRunning = tag.status === 'running'; if (mode === 'compact') { return ( : } name={isListDirectory ? (isRunning ? "Listing directory" : "Listed directory") : (isRunning ? "Creating directory" : "Created directory")} input={path} isRunning={isRunning} /> ); } return (
{isListDirectory ? : }
{isListDirectory ? (isRunning ? `Listing directory: ${path}` : `Listed directory: ${path}`) : (isRunning ? `Creating directory: ${path}` : `Created directory: ${path}`)}
{isRunning && (
Running
)}
{path}
{isListDirectory && content && (
              {content}
            
)}
); }; /** * Search Code Tool Component */ export const SearchCodeTool: React.FC = ({ tag, mode }) => { const query = tag.attributes.query || ''; const content = tag.content || ''; const isRunning = tag.status === 'running'; if (mode === 'compact') { return ( } name={isRunning ? "Searching code" : "Searched code"} input={query} isRunning={isRunning} /> ); } return (
{isRunning ? "Searching code" : "Searched code"}: {query}
{isRunning && (
Running
)}
{query}
            {content}
          
); }; /** * Browser Navigate Tool Component */ export const BrowserNavigateTool: React.FC = ({ tag, mode }) => { const url = tag.content || ''; const isRunning = tag.status === 'running'; if (mode === 'compact') { return ( } name={isRunning ? "Navigating to" : "Navigated to"} input={url} isRunning={isRunning} /> ); } return (
{isRunning ? `Navigating to` : `Navigated to`}: {url}
{isRunning && (
Running
)}
{url}
{/* Display VNC preview if available */} {tag.vncPreview && (
VNC Preview