'use client'; import { useState, useEffect, useCallback } from 'react'; import { Bot, Sparkles, X, Loader2 } from 'lucide-react'; import { toast } from 'sonner'; import { Button } from '@/components/ui/button'; import { Textarea } from '@/components/ui/textarea'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, } from '@/components/ui/sheet'; interface Agent { id: string; name: string; description?: string; status: 'active' | 'disabled'; permission_tier: string; } interface DispatchPanelProps { /** Optional trigger label override */ triggerLabel?: string; /** Optional variant for the trigger button */ triggerVariant?: 'default' | 'outline' | 'ghost'; /** Optional class name for the trigger button */ triggerClassName?: string; } export function DispatchPanel({ triggerLabel = 'Ask AI', triggerVariant = 'default', triggerClassName, }: DispatchPanelProps) { const [open, setOpen] = useState(false); const [agents, setAgents] = useState([]); const [selectedAgentId, setSelectedAgentId] = useState(''); const [prompt, setPrompt] = useState(''); const [entityRef, setEntityRef] = useState(''); const [dispatching, setDispatching] = useState(false); const [loadingAgents, setLoadingAgents] = useState(false); const fetchAgents = useCallback(async () => { setLoadingAgents(true); try { const res = await fetch('/api/agents'); if (!res.ok) throw new Error('Failed to fetch agents'); const data = await res.json(); const activeAgents = (data.items || []).filter( (a: Agent) => a.status === 'active' ); setAgents(activeAgents); if (activeAgents.length > 0 && !selectedAgentId) { setSelectedAgentId(activeAgents[0].id); } } catch (err) { console.error('Failed to fetch agents:', err); } finally { setLoadingAgents(false); } }, [selectedAgentId]); useEffect(() => { if (open) { fetchAgents(); } }, [open, fetchAgents]); async function handleDispatch() { if (!selectedAgentId || !prompt.trim()) { toast.error('Please select an agent and enter a prompt'); return; } setDispatching(true); try { const body: Record = { agent_id: selectedAgentId, task_type: 'custom', input: { prompt: prompt.trim() }, }; if (entityRef.trim()) { // Parse entity reference: "type:id" or just a free-form reference body.entity_type = 'reference'; body.entity_id = entityRef.trim(); } const res = await fetch('/api/agent-tasks', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); if (!res.ok) { const text = await res.text(); console.error('Failed to dispatch task:', text); toast.error('Failed to dispatch task'); return; } toast.success('Task dispatched — see Agent Activity for results'); setPrompt(''); setEntityRef(''); setOpen(false); } catch (err) { console.error('Failed to dispatch task:', err); toast.error('Failed to dispatch task'); } finally { setDispatching(false); } } return ( Dispatch AI Agent Send a task to an AI agent and view results in Agent Activity.
{/* Agent selector */}
{loadingAgents ? (
Loading agents...
) : agents.length === 0 ? (

No active agents available

) : ( )}
{/* Prompt */}