Files
roboco/panel/src/components/agents/orchestrator-status.tsx
T
Renn F ec790d18b5 fix(panel): orchestrator status reflects reachability; drop CEO from the agent roster
- The Orchestrator card showed red 'Stopped' whenever zero agents were
  running, even though the service was healthy (it read total_agents > 0).
  Base Running/Stopped on whether the status query resolves; agent count is
  already shown in its own card.
- The human CEO leaked into the Board agent grid (its record carries
  team=board). Exclude the ceo role from getBoardAgents — the CEO is the
  operator, not a spawnable agent.
2026-06-11 23:30:46 +02:00

81 lines
3.1 KiB
TypeScript

import { OrchestratorStatus as OrchestratorStatusType } from "@/types";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import { Server, Users, Clock, Activity } from "lucide-react";
interface OrchestratorStatusCardsProps {
status: OrchestratorStatusType | undefined;
isLoading: boolean;
}
export function OrchestratorStatusCards({ status, isLoading }: OrchestratorStatusCardsProps) {
// Calculate running agents from by_state
const runningCount = status?.by_state?.running || 0;
const readyCount = status?.by_state?.ready || 0;
const activeCount = runningCount + readyCount;
// The orchestrator service is up whenever its status query resolves — agent
// count is shown separately in the cards below. (Previously this read
// `total_agents > 0`, so an idle-but-healthy orchestrator showed "Stopped".)
const isRunning = status !== undefined;
return (
<div className="grid gap-4 md:grid-cols-4">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Orchestrator</CardTitle>
<Server className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
{isLoading ? (
<Skeleton className="h-8 w-24" />
) : (
<Badge className={isRunning ? "bg-green-500" : "bg-red-500"}>
{isRunning ? "Running" : "Stopped"}
</Badge>
)}
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Total Agents</CardTitle>
<Users className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
{isLoading ? (
<Skeleton className="h-8 w-12" />
) : (
<div className="text-2xl font-bold">{status?.total_agents || 0}</div>
)}
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Active</CardTitle>
<Activity className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
{isLoading ? (
<Skeleton className="h-8 w-12" />
) : (
<div className="text-2xl font-bold">{activeCount}</div>
)}
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Waiting</CardTitle>
<Clock className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
{isLoading ? (
<Skeleton className="h-8 w-12" />
) : (
<div className="text-2xl font-bold">{status?.waiting_count || 0}</div>
)}
</CardContent>
</Card>
</div>
);
}