"use client"; import { useDeferredValue, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Select } from "@/components/ui/select"; import type { AgentFamily, FleetAgent } from "@/lib/types"; function heartbeatTone(agent: FleetAgent) { if (agent.heartbeatAgeMinutes === null) { return "warning"; } if (agent.heartbeatAgeMinutes > 180) { return "warning"; } return "success"; } export function AgentsClient({ agents, defaultFamily = "", }: { agents: FleetAgent[]; defaultFamily?: AgentFamily | ""; }) { const [query, setQuery] = useState(""); const [family, setFamily] = useState(defaultFamily); const deferredQuery = useDeferredValue(query); const filteredAgents = agents.filter((agent) => { const matchesQuery = deferredQuery.length === 0 || agent.name.toLowerCase().includes(deferredQuery.toLowerCase()) || agent.host.toLowerCase().includes(deferredQuery.toLowerCase()) || agent.role.toLowerCase().includes(deferredQuery.toLowerCase()); const matchesFamily = family.length === 0 || agent.family === family; return matchesQuery && matchesFamily; }); return (
Configured Agent Runtimes OpenClaw swarm members, ZeroClaw runtimes, and direct host targets from the tracked fleet model with heartbeat and dispatch overlays. setQuery(event.target.value)} />
{filteredAgents.map((agent) => (
{agent.emoji} {agent.name} {agent.role}
{agent.family} {agent.status}
Host
{agent.host}
Model
{agent.model || "Host-local/runtime-defined"}
Dispatch
{agent.defaultDispatchMethod}
Workload
{agent.workload} active
Runtime
{agent.runtimePath}
Current task
{agent.currentTask || "No heartbeat task"}
Heartbeat
{agent.heartbeatAgeMinutes === null ? "No heartbeat" : `${agent.heartbeatAgeMinutes}m ago`}

Channels

{agent.channels.map((channel) => ( {channel.label}: {channel.value} ))}

Last dispatch event

{agent.lastEvent ? (

{agent.lastEvent.summary}

{agent.lastEvent.detail || "No detail captured."}

{agent.lastEvent.event_type} Failures: {agent.failureStreak}
) : (

No audit events recorded yet.

)}

Tools

{agent.tools.length ? ( agent.tools.map((tool) => ( {tool} )) ) : ( No parsed tools. )}
))}
); }