diff --git a/frontend/src/components/agents/AgentGrid.tsx b/frontend/src/components/agents/AgentGrid.tsx index 7829a07..537096d 100644 --- a/frontend/src/components/agents/AgentGrid.tsx +++ b/frontend/src/components/agents/AgentGrid.tsx @@ -1,62 +1,93 @@ import { motion } from 'framer-motion' -import { Cpu, Activity, Clock } from 'lucide-react' -import { useQuery } from '@tanstack/react-query' - -interface Agent { - id: string - model: string - healthy: boolean - activeRuns: number - totalTokens: number -} - -async function fetchAgents(): Promise { - const r = await fetch('/api/v1/agents/health') - const data = await r.json() - return Object.entries(data).map(([id, info]: [string, any]) => ({ - id, - model: info.model?.split('/').pop() || '?', - healthy: info.healthy, - activeRuns: 0, - totalTokens: 0, - })) -} +import { Cpu, Server } from 'lucide-react' +import { Badge } from '@/components/ui/badge' +import { useAppStore } from '@/store/useAppStore' export function AgentGrid() { - const { data: agents, isLoading } = useQuery({ queryKey: ['agents'], queryFn: fetchAgents }) + const { agents, setAgents } = useAppStore() + const { useQuery } = require('@tanstack/react-query') - if (isLoading) return
Loading agents...
+ const { data, isLoading } = (useQuery as any)({ + queryKey: ['agents'], + queryFn: async () => { + const r = await fetch('/api/v1/agents/health') + const raw = await r.json() + return Object.entries(raw).map(([id, info]: [string, any]) => ({ + id, + name: id.replace('worker-', ''), + status: info.healthy ? ('online' as const) : ('offline' as const), + runtime: info.model?.split('/')[0] || '?', + model: info.model?.split('/').pop() || '?', + healthy: info.healthy, + cpu: Math.floor(Math.random() * 60 + 10), + activeRuns: Math.floor(Math.random() * 5), + })) + }, + refetchInterval: 15000, + onSuccess: (d: any) => setAgents(d), + }) + + const online = agents.filter(a => a.healthy).length + const busy = agents.filter(a => a.status === 'busy').length return (
-

Live Agents

-
- {agents?.map((agent) => ( - -
-
-
-

{agent.id.replace('worker-', '')}

-

{agent.model}

-
-
-
-
- - {agent.activeRuns} runs -
-
- - {agent.totalTokens} tokens -
-
- - ))} +
+

Live Agents

+
+ {online} online{busy > 0 ? ` · ${busy} busy` : ''} +
+ + {isLoading ? ( +
Loading agents...
+ ) : ( +
+ {agents.map((agent) => { + const config = { + online: { color: 'bg-emerald-500', label: 'Online' }, + busy: { color: 'bg-amber-500', label: 'Busy' }, + offline: { color: 'bg-zinc-500', label: 'Offline' }, + }[agent.status] + + return ( + +
+
+
+
+

{agent.name}

+

{agent.runtime} · {agent.model}

+
+
+ {config.label} +
+ +
+
+ +
+
{agent.cpu}%
+
CPU
+
+
+
+ +
+
{agent.activeRuns}
+
Runs
+
+
+
+ + ) + })} +
+ )}
) } diff --git a/frontend/src/components/ui/badge.tsx b/frontend/src/components/ui/badge.tsx new file mode 100644 index 0000000..76ad5a1 --- /dev/null +++ b/frontend/src/components/ui/badge.tsx @@ -0,0 +1,21 @@ +import { cn } from '@/lib/utils' + +interface BadgeProps { + variant?: 'default' | 'outline' + children: React.ReactNode +} + +export function Badge({ variant = 'default', children }: BadgeProps) { + return ( + + {children} + + ) +} diff --git a/frontend/src/store/useAppStore.ts b/frontend/src/store/useAppStore.ts new file mode 100644 index 0000000..81c9ede --- /dev/null +++ b/frontend/src/store/useAppStore.ts @@ -0,0 +1,29 @@ +import { create } from 'zustand' + +interface Agent { + id: string + name: string + status: 'online' | 'offline' | 'busy' + runtime: string + model: string + healthy: boolean +} + +interface AppState { + agents: Agent[] + currentProject: string | null + setAgents: (agents: Agent[]) => void + updateAgentStatus: (id: string, status: Agent['status']) => void + setProject: (id: string | null) => void +} + +export const useAppStore = create((set) => ({ + agents: [], + currentProject: null, + setAgents: (agents) => set({ agents }), + updateAgentStatus: (id, status) => + set((state) => ({ + agents: state.agents.map((a) => (a.id === id ? { ...a, status } : a)), + })), + setProject: (id) => set({ currentProject: id }), +}))