import { Wrench, ChevronDown, CheckSquare, Square, Loader2, } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Popover, PopoverButton, PopoverPanel, Transition, } from '@headlessui/react'; import { Fragment, useEffect, useState } from 'react'; interface Tool { name: string; description: string; } interface ToolSelectorProps { selectedToolNames: string[]; onSelectedToolNamesChange: (names: string[]) => void; } const ToolSelector = ({ selectedToolNames, onSelectedToolNamesChange, }: ToolSelectorProps) => { const [availableTools, setAvailableTools] = useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchTools = async () => { try { setIsLoading(true); const response = await fetch('/api/tools'); if (response.ok) { const tools = await response.json(); setAvailableTools(tools); // Check if any currently selected tool names are not in the API response const availableToolNames = tools.map((tool: Tool) => tool.name); const validSelectedNames = selectedToolNames.filter((name) => availableToolNames.includes(name), ); // If some selected names are no longer available, update the selection if (validSelectedNames.length !== selectedToolNames.length) { onSelectedToolNamesChange(validSelectedNames); } } else { console.error('Failed to load tools.'); } } catch (error) { console.error('Error loading tools.'); console.error(error); } finally { setIsLoading(false); } }; // Only fetch tools once when the component mounts fetchTools(); }, [selectedToolNames, onSelectedToolNamesChange]); const handleToggleTool = (toolName: string) => { const newSelectedNames = selectedToolNames.includes(toolName) ? selectedToolNames.filter((name) => name !== toolName) : [...selectedToolNames, toolName]; onSelectedToolNamesChange(newSelectedNames); }; const selectedCount = selectedToolNames.length; return ( {({ open }) => ( <> 0 ? 'text-[#24A0ED] hover:text-blue-200' : 'text-black/60 hover:text-black/30 dark:text-white/60 dark:hover:*:text-white/30', )} title="Select Tools" > {selectedCount > 0 ? {selectedCount} : null}

Select Tools

Choose tools to assist the AI.

{isLoading ? (
) : (
{availableTools.length === 0 && (

No tools available.

)} {availableTools.map((tool) => (
handleToggleTool(tool.name)} className="flex items-start gap-2.5 p-2.5 rounded-md hover:bg-light-100 dark:hover:bg-dark-100 cursor-pointer" > {selectedToolNames.includes(tool.name) ? ( ) : ( )}
{tool.name.replace(/_/g, ' ')}

{tool.description}

))}
)}
)}
); }; export default ToolSelector;