diff --git a/ui/src/pages/AgentHealth/AgentHealth.tsx b/ui/src/pages/AgentHealth/AgentHealth.tsx
index 6280750f..fd0da9d5 100644
--- a/ui/src/pages/AgentHealth/AgentHealth.tsx
+++ b/ui/src/pages/AgentHealth/AgentHealth.tsx
@@ -2,15 +2,14 @@ import { useState, useMemo, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router';
import { ExternalLink, RefreshCw, Pencil } from 'lucide-react';
import {
- StatCard, StatusDot, Badge, MonoText, ProgressBar,
- GroupCard, DataTable, LineChart, EventFeed, DetailPanel,
+ StatCard, StatusDot, Badge, MonoText,
+ GroupCard, DataTable, EventFeed,
LogViewer, ButtonGroup, SectionHeader, Toggle, useToast,
} from '@cameleer/design-system';
import type { Column, FeedEvent, LogEntry, ButtonGroupItem } from '@cameleer/design-system';
import styles from './AgentHealth.module.css';
import { useAgents, useAgentEvents } from '../../api/queries/agents';
import { useApplicationLogs } from '../../api/queries/logs';
-import { useAgentMetrics } from '../../api/queries/agent-metrics';
import { useApplicationConfig, useUpdateApplicationConfig } from '../../api/queries/commands';
import type { AgentInstance } from '../../api/types';
@@ -96,132 +95,6 @@ function appHealth(group: AppGroup): 'success' | 'warning' | 'error' {
// ── Detail sub-components ────────────────────────────────────────────────────
-function AgentOverviewContent({ agent }: { agent: AgentInstance }) {
- const { data: memMetrics } = useAgentMetrics(
- agent.id,
- ['jvm.memory.heap.used', 'jvm.memory.heap.max'],
- 1,
- );
- const { data: cpuMetrics } = useAgentMetrics(agent.id, ['jvm.cpu.process'], 1);
-
- const cpuValue = cpuMetrics?.metrics?.['jvm.cpu.process']?.[0]?.value;
- const heapUsed = memMetrics?.metrics?.['jvm.memory.heap.used']?.[0]?.value;
- const heapMax = memMetrics?.metrics?.['jvm.memory.heap.max']?.[0]?.value;
-
- const heapPercent =
- heapUsed != null && heapMax != null && heapMax > 0
- ? Math.round((heapUsed / heapMax) * 100)
- : undefined;
- const cpuPercent = cpuValue != null ? Math.round(cpuValue * 100) : undefined;
-
- const ns = normalizeStatus(agent.status);
-
- return (
-
-
- Status
-
-
-
- Application
- {agent.application}
-
-
- Uptime
- {formatUptime(agent.uptimeSeconds)}
-
-
- Last Seen
- {timeAgo(agent.lastHeartbeat)}
-
-
- Throughput
- {agent.tps != null ? `${agent.tps.toFixed(1)}/s` : '\u2014'}
-
-
- Errors
-
- {formatErrorRate(agent.errorRate)}
-
-
-
- Routes
- {agent.activeRoutes ?? 0}/{agent.totalRoutes ?? 0} active
-
-
-
Heap Memory
- {heapPercent != null ? (
-
-
85 ? 'error' : heapPercent > 70 ? 'warning' : 'success'}
- size="sm"
- />
- {heapPercent}%
-
- ) : (
-
N/A
- )}
-
-
-
CPU
- {cpuPercent != null ? (
-
-
80 ? 'error' : cpuPercent > 60 ? 'warning' : 'success'}
- size="sm"
- />
- {cpuPercent}%
-
- ) : (
-
N/A
- )}
-
-
- );
-}
-
-function AgentPerformanceContent({ agent }: { agent: AgentInstance }) {
- const { data: tpsMetrics } = useAgentMetrics(agent.id, ['cameleer.tps'], 60);
- const { data: errMetrics } = useAgentMetrics(agent.id, ['cameleer.error.rate'], 60);
-
- const tpsSeries = useMemo(() => {
- const raw = tpsMetrics?.metrics?.['cameleer.tps'] ?? [];
- return [{ label: 'TPS', data: raw.map((p) => ({ x: new Date(p.time), y: p.value })) }];
- }, [tpsMetrics]);
-
- const errSeries = useMemo(() => {
- const raw = errMetrics?.metrics?.['cameleer.error.rate'] ?? [];
- return [{
- label: 'Error Rate',
- data: raw.map((p) => ({ x: new Date(p.time), y: p.value * 100 })),
- color: 'var(--error)',
- }];
- }, [errMetrics]);
-
- return (
-
-
-
Throughput (msg/s)
- {tpsSeries[0].data.length > 0 ? (
-
- ) : (
-
No data available
- )}
-
-
-
Error Rate (%)
- {errSeries[0].data.length > 0 ? (
-
- ) : (
-
No data available
- )}
-
-
- );
-}
-
const LOG_LEVEL_ITEMS: ButtonGroupItem[] = [
{ value: 'error', label: 'Error', color: 'var(--error)' },
{ value: 'warn', label: 'Warn', color: 'var(--warning)' },
@@ -301,9 +174,6 @@ export default function AgentHealth() {
.filter((l) => logLevels.size === 0 || logLevels.has(l.level))
.filter((l) => !logSearchLower || l.message.toLowerCase().includes(logSearchLower));
- const [selectedInstance, setSelectedInstance] = useState(null);
- const [panelOpen, setPanelOpen] = useState(false);
-
const agentList = agents ?? [];
const groups = useMemo(() => groupByApp(agentList), [agentList]);
@@ -428,26 +298,9 @@ export default function AgentHealth() {
);
function handleInstanceClick(inst: AgentInstance) {
- setSelectedInstance(inst);
- setPanelOpen(true);
+ navigate(`/runtime/${inst.application}/${inst.id}`);
}
- // Detail panel tabs
- const detailTabs = selectedInstance
- ? [
- {
- label: 'Overview',
- value: 'overview',
- content: ,
- },
- {
- label: 'Performance',
- value: 'performance',
- content: ,
- },
- ]
- : [];
-
const isFullWidth = !!appId;
return (
@@ -677,7 +530,6 @@ export default function AgentHealth() {
columns={instanceColumns}
data={group.instances}
onRowClick={handleInstanceClick}
- selectedId={panelOpen ? selectedInstance?.id : undefined}
pageSize={50}
flush
/>
@@ -758,15 +610,6 @@ export default function AgentHealth() {
- {/* Detail panel — auto-portals to AppShell level via design system */}
- {selectedInstance && (
- { setPanelOpen(false); setSelectedInstance(null); }}
- title={selectedInstance.name ?? selectedInstance.id}
- tabs={detailTabs}
- />
- )}
);
}