"use client"; import Link from "next/link"; import { startTransition, useEffect, useState } from "react"; import { AgentAvatar } from "@/components/agents/agent-avatar"; import { agentStatusFilters } from "@/data/demo-agents"; import { AgentFeed, AgentStatus } from "@/types/agent"; const statusClassMap = { working: "status-pill status-pill--working", idle: "status-pill status-pill--idle", warning: "status-pill status-pill--warning", offline: "status-pill status-pill--offline" } as const; type AgentsDashboardProps = { initialFeed: AgentFeed; initialStatus: "all" | AgentStatus; }; function isAgentStatus(value: string): value is AgentStatus { return value === "working" || value === "idle" || value === "warning" || value === "offline"; } function formatTimeLabel(value: string) { return new Date(value).toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit", second: "2-digit" }); } export function AgentsDashboard({ initialFeed, initialStatus }: AgentsDashboardProps) { const [feed, setFeed] = useState(initialFeed); const [activeStatus, setActiveStatus] = useState<"all" | AgentStatus>(initialStatus); useEffect(() => { let mounted = true; async function loadAgents() { const query = activeStatus === "all" ? "" : `?status=${activeStatus}`; const response = await fetch(`/api/agents${query}`, { cache: "no-store" }); if (!response.ok) { throw new Error("Failed to load agents"); } const data = (await response.json()) as AgentFeed; if (!mounted) { return; } startTransition(() => { setFeed(data); }); } loadAgents().catch(() => undefined); const interval = window.setInterval(() => { loadAgents().catch(() => undefined); }, 10000); return () => { mounted = false; window.clearInterval(interval); }; }, [activeStatus]); const agents = feed.agents; const counts = { working: agents.filter((agent) => agent.status === "working").length, idle: agents.filter((agent) => agent.status === "idle").length, warning: agents.filter((agent) => agent.status === "warning").length, offline: agents.filter((agent) => agent.status === "offline").length }; return (
{feed.source === "file" ? "已接入真实数据源" : "当前使用演示数据"} 来源 {feed.sourceLabel} · 最近刷新 {formatTimeLabel(feed.fetchedAt)}
{agentStatusFilters.map((filter) => ( ))}
工作中 {counts.working}
待命 {counts.idle}
待确认 {counts.warning}
离线 {counts.offline}
总计 {agents.length}
{agents.map((agent) => (
{agent.name} {agent.statusLabel}
{agent.role}
心跳 {agent.lastHeartbeat} 队列 {agent.queueDepth} 今日完成 {agent.todayCompleted}
当前任务
{agent.currentTask}
任务ID {agent.taskId} 阶段 {agent.taskStage} 主机 {agent.host} Owner {agent.owner} 运行时长 {agent.uptime} 更新时间 {agent.updatedAt}
最近输出
{agent.lastOutput}
{agent.lastError ?
异常: {agent.lastError}
: null}
))}
); }