bytelyst-devops-tools/dashboard/web/src/app/hermes/agents/page.tsx
2026-05-27 13:04:36 +00:00

60 lines
4.0 KiB
TypeScript

'use client';
import Link from 'next/link';
import { ArrowLeft, Gauge, ShieldAlert, ServerCog } from 'lucide-react';
import { Badge, Button } from '@/components/ui/Primitives';
import { HermesShell, MetricCard, SectionCard } from '@/components/hermes-shell';
import { getHermesAgents } from '@/lib/hermes';
export default function HermesAgentsPage() {
const agents = getHermesAgents();
const healthy = agents.filter((agent) => agent.status === 'healthy').length;
const degraded = agents.filter((agent) => agent.status === 'degraded').length;
const offline = agents.filter((agent) => agent.status === 'offline').length;
return (
<HermesShell
title="Agent & Tool Observability"
description="Status board for Hermes core, integrations, runners, scheduler, and notification tooling."
actions={<Button asChild><Link href="/hermes"><ArrowLeft className="mr-2 h-4 w-4" />Back to mission control</Link></Button>}
>
<section className="grid gap-4 md:grid-cols-3">
<MetricCard label="Healthy" value={healthy} tone="success" icon={<Gauge className="h-5 w-5" />} />
<MetricCard label="Degraded" value={degraded} tone="warning" icon={<ShieldAlert className="h-5 w-5" />} />
<MetricCard label="Offline" value={offline} tone="danger" icon={<ServerCog className="h-5 w-5" />} />
</section>
<SectionCard title="Tool and integration health" subtitle="Each item includes last success, failure rate, latency, and config warnings.">
<div className="grid gap-4 lg:grid-cols-2">
{agents.map((agent) => (
<div key={agent.id} className="rounded-3xl border border-[var(--bl-border)] bg-[var(--bl-surface-muted)] p-5">
<div className="flex items-start justify-between gap-3">
<div>
<p className="text-lg font-semibold text-[var(--bl-text-primary)]">{agent.name}</p>
<p className="text-sm text-[var(--bl-text-secondary)]">{agent.type} · {agent.callsToday} calls today</p>
</div>
<Badge variant={agent.status === 'healthy' ? 'success' : agent.status === 'degraded' ? 'warning' : 'error'}>{agent.status}</Badge>
</div>
<div className="mt-4 grid gap-3 text-sm text-[var(--bl-text-secondary)] md:grid-cols-2">
<div className="rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-surface-card)] p-3">Last success: {agent.lastSuccessAt ? new Date(agent.lastSuccessAt).toLocaleString() : '—'}</div>
<div className="rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-surface-card)] p-3">Last failure: {agent.lastFailureAt ? new Date(agent.lastFailureAt).toLocaleString() : '—'}</div>
<div className="rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-surface-card)] p-3">Failure rate: {(agent.failureRate * 100).toFixed(1)}%</div>
<div className="rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-surface-card)] p-3">Latency: {agent.averageLatencyMs ?? '—'}ms</div>
</div>
{agent.configIssue ? <div className="mt-3 rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-warning-muted)] p-3 text-sm text-[var(--bl-warning)]">{agent.configIssue}</div> : null}
</div>
))}
</div>
</SectionCard>
<SectionCard title="Ecosystem coverage" subtitle="The dashboard should make each subsystem accountable and observable.">
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
{['Hermes core', 'GitHub integration', 'Local VM runner', 'CLI runner', 'Scheduler / cron', 'Deployment tools', 'Monitoring tools', 'Notification tools', 'Model / LLM provider', 'Secrets / config health', 'OpenClaw integration placeholder', 'Telemetry ingest'].map((item) => (
<div key={item} className="rounded-2xl border border-[var(--bl-border)] bg-[var(--bl-surface-muted)] p-4 text-sm text-[var(--bl-text-secondary)]">{item}</div>
))}
</div>
</SectionCard>
</HermesShell>
);
}