/** * JARVIS — Tools Panel * Direct tool execution: calculator, web search, code runner */ import React, { useState, useEffect } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { Wrench, Search, Calculator, Code2, Play, Loader2, ChevronDown, ChevronUp, CheckCircle, XCircle, } from 'lucide-react' import clsx from 'clsx' import toast from 'react-hot-toast' import { toolsAPI } from '../../services/api' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism' const TOOLS = [ { id: 'web_search', label: 'Web Search', icon: Search, placeholder: 'Enter search query…', example: 'latest AI research 2025', color: 'text-blue-400', }, { id: 'calculator', label: 'Calculator', icon: Calculator, placeholder: 'Math expression…', example: 'sqrt(144) + 2**10', color: 'text-yellow-400', }, { id: 'code_executor', label: 'Code Runner', icon: Code2, placeholder: 'Python code…', example: 'print([x**2 for x in range(10)])', color: 'text-green-400', multiline: true, }, ] export default function ToolsPanel() { const [expanded, setExpanded] = useState(true) const [activeTool, setActiveTool] = useState('calculator') const [argument, setArgument] = useState('') const [result, setResult] = useState(null) const [loading, setLoading] = useState(false) const tool = TOOLS.find((t) => t.id === activeTool) const run = async () => { if (!argument.trim()) return setLoading(true) setResult(null) try { const data = await toolsAPI.executeTool(activeTool, argument.trim()) setResult(data) if (!data.success) toast.error('Tool returned an error') } catch (err) { toast.error(err.message) } finally { setLoading(false) } } const loadExample = () => { setArgument(tool.example) } return (
{/* Header */}
setExpanded((v) => !v)} >
Tool Executor Direct access
{expanded ? : }
{expanded && (
{/* Tool selector */}
{TOOLS.map((t) => { const Icon = t.icon return ( ) })}
{/* Input */}
{tool.multiline ? (