'use client'; import React, { useState, useRef, useEffect, useCallback } from 'react'; import { Settings, ChevronRight, Bot, Presentation, FileSpreadsheet, Search, Plus, User, Check, ChevronDown } from 'lucide-react'; import Image from 'next/image'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Badge } from '@/components/ui/badge'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from '@/components/ui/tooltip'; import { useAgents, useCreateNewAgent } from '@/hooks/react-query/agents/use-agents'; import { useRouter } from 'next/navigation'; import { cn, truncateString } from '@/lib/utils'; interface PredefinedAgent { id: string; name: string; description: string; icon: React.ReactNode; category: 'productivity' | 'creative' | 'development'; } const PREDEFINED_AGENTS: PredefinedAgent[] = [ // { // id: 'slides', // name: 'Slides', // description: 'Create stunning presentations and slide decks', // icon: , // category: 'productivity' // }, // { // id: 'sheets', // name: 'Sheets', // description: 'Spreadsheet and data analysis expert', // icon: , // category: 'productivity' // } ]; interface AgentSelectorProps { selectedAgentId?: string; onAgentSelect?: (agentId: string | undefined) => void; disabled?: boolean; } export const AgentSelector: React.FC = ({ selectedAgentId, onAgentSelect, disabled = false, }) => { const [isOpen, setIsOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [highlightedIndex, setHighlightedIndex] = useState(-1); const [isCreatingAgent, setIsCreatingAgent] = useState(false); const searchInputRef = useRef(null); const router = useRouter(); const { data: agentsResponse, isLoading: agentsLoading } = useAgents(); const agents = agentsResponse?.agents || []; const createNewAgentMutation = useCreateNewAgent(); // Combine all agents const allAgents = [ { id: undefined, name: 'Suna', description: 'Your personal AI assistant', type: 'default' as const, icon: }, ...PREDEFINED_AGENTS.map(agent => ({ ...agent, type: 'predefined' as const })), ...agents.map((agent: any) => ({ ...agent, id: agent.agent_id, type: 'custom' as const, icon: agent.avatar || })) ]; // Filter agents based on search query const filteredAgents = allAgents.filter((agent) => agent.name.toLowerCase().includes(searchQuery.toLowerCase()) || agent.description?.toLowerCase().includes(searchQuery.toLowerCase()) ); useEffect(() => { if (isOpen && searchInputRef.current) { setTimeout(() => { searchInputRef.current?.focus(); }, 50); } else { setSearchQuery(''); setHighlightedIndex(-1); } }, [isOpen]); const getAgentDisplay = () => { const selectedAgent = allAgents.find(agent => agent.id === selectedAgentId); if (selectedAgent) { console.log('Selected agent found:', selectedAgent.name, 'with ID:', selectedAgent.id); return { name: selectedAgent.name, icon: selectedAgent.icon }; } // If selectedAgentId is not undefined but no agent is found, log a warning if (selectedAgentId !== undefined) { console.warn('Agent with ID', selectedAgentId, 'not found, falling back to Suna'); } // Default to Suna (the first agent which has id: undefined) const defaultAgent = allAgents[0]; console.log('Using default agent:', defaultAgent.name); return { name: defaultAgent.name, icon: defaultAgent.icon }; }; const handleAgentSelect = (agentId: string | undefined) => { console.log('Agent selected:', agentId === undefined ? 'Suna (default)' : agentId); onAgentSelect?.(agentId); setIsOpen(false); }; const handleAgentSettings = (agentId: string, e: React.MouseEvent) => { e.stopPropagation(); setIsOpen(false); router.push(`/agents/config/${agentId}`); }; const handleSearchInputKeyDown = (e: React.KeyboardEvent) => { e.stopPropagation(); if (e.key === 'ArrowDown') { e.preventDefault(); setHighlightedIndex((prev) => prev < filteredAgents.length - 1 ? prev + 1 : 0 ); } else if (e.key === 'ArrowUp') { e.preventDefault(); setHighlightedIndex((prev) => prev > 0 ? prev - 1 : filteredAgents.length - 1 ); } else if (e.key === 'Enter' && highlightedIndex >= 0) { e.preventDefault(); const selectedAgent = filteredAgents[highlightedIndex]; if (selectedAgent) { handleAgentSelect(selectedAgent.id); } } }; const handleExploreAll = () => { setIsOpen(false); router.push('/agents'); }; const handleCreateAgent = useCallback(() => { if (isCreatingAgent || createNewAgentMutation.isPending) { return; // Prevent multiple clicks } setIsCreatingAgent(true); setIsOpen(false); createNewAgentMutation.mutate(undefined, { onSettled: () => { // Reset the debounce state after mutation completes (success or error) setTimeout(() => setIsCreatingAgent(false), 1000); } }); }, [isCreatingAgent, createNewAgentMutation]); const renderAgentItem = (agent: any, index: number) => { const isSelected = agent.id === selectedAgentId; const isHighlighted = index === highlightedIndex; const hasSettings = agent.type === 'custom' && agent.id; return ( handleAgentSelect(agent.id)} onMouseEnter={() => setHighlightedIndex(index)} > {agent.icon} {agent.name} {truncateString(agent.description, 30)} {hasSettings && ( handleAgentSettings(agent.id, e)} > )} {isSelected && ( )} {truncateString(agent.description, 35)} ); }; const agentDisplay = getAgentDisplay(); return ( <> {agentDisplay.icon} {agentDisplay.name} Select Agent setSearchQuery(e.target.value)} onKeyDown={handleSearchInputKeyDown} className={cn( "w-full pl-10 pr-3 py-2 text-sm bg-muted/40 border-0 rounded-xl", "focus:outline-none focus:ring-1 focus:ring-ring focus:ring-offset-0 focus:bg-muted/60", "placeholder:text-muted-foreground/60 transition-all duration-200" )} /> {/* Agent List */} {agentsLoading ? ( Loading agents... ) : filteredAgents.length === 0 ? ( No agents found Try adjusting your search ) : ( {filteredAgents.map((agent, index) => renderAgentItem(agent, index))} )} {/* Footer Actions */} Explore All Agents {isCreatingAgent || createNewAgentMutation.isPending ? 'Creating...' : 'Create Agent'} > ); };
{truncateString(agent.description, 35)}
Select Agent
No agents found
Try adjusting your search