feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
import { useMemo } from 'react';
|
|
|
|
|
import { useParams } from 'react-router';
|
|
|
|
|
import {
|
2026-03-19 18:16:16 +01:00
|
|
|
StatCard, StatusDot, Badge,
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
LineChart, AreaChart, EventFeed, Breadcrumb, Spinner,
|
2026-03-19 18:16:16 +01:00
|
|
|
CodeBlock,
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
} from '@cameleer/design-system';
|
2026-03-19 18:16:16 +01:00
|
|
|
import styles from './AgentInstance.module.css';
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
import { useAgents, useAgentEvents } from '../../api/queries/agents';
|
|
|
|
|
import { useStatsTimeseries } from '../../api/queries/executions';
|
|
|
|
|
import { useGlobalFilters } from '@cameleer/design-system';
|
|
|
|
|
|
|
|
|
|
export default function AgentInstance() {
|
|
|
|
|
const { appId, instanceId } = useParams();
|
|
|
|
|
const { timeRange } = useGlobalFilters();
|
|
|
|
|
const timeFrom = timeRange.start.toISOString();
|
|
|
|
|
const timeTo = timeRange.end.toISOString();
|
|
|
|
|
|
|
|
|
|
const { data: agents, isLoading } = useAgents(undefined, appId);
|
|
|
|
|
const { data: events } = useAgentEvents(appId, instanceId);
|
|
|
|
|
const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo, undefined, appId);
|
|
|
|
|
|
|
|
|
|
const agent = useMemo(() =>
|
|
|
|
|
(agents || []).find((a: any) => a.id === instanceId),
|
|
|
|
|
[agents, instanceId],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const chartData = useMemo(() =>
|
|
|
|
|
(timeseries?.buckets || []).map((b: any) => ({
|
|
|
|
|
time: new Date(b.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
|
|
|
|
|
throughput: b.totalCount,
|
|
|
|
|
latency: b.avgDurationMs,
|
|
|
|
|
errors: b.failedCount,
|
|
|
|
|
})),
|
|
|
|
|
[timeseries],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const feedEvents = useMemo(() =>
|
|
|
|
|
(events || []).filter((e: any) => !instanceId || e.agentId === instanceId).map((e: any) => ({
|
|
|
|
|
id: String(e.id),
|
|
|
|
|
severity: e.eventType === 'WENT_DEAD' ? 'error' as const
|
|
|
|
|
: e.eventType === 'WENT_STALE' ? 'warning' as const
|
|
|
|
|
: e.eventType === 'RECOVERED' ? 'success' as const
|
|
|
|
|
: 'running' as const,
|
|
|
|
|
message: `${e.eventType}${e.detail ? ' — ' + e.detail : ''}`,
|
|
|
|
|
timestamp: new Date(e.timestamp),
|
|
|
|
|
})),
|
|
|
|
|
[events, instanceId],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (isLoading) return <Spinner size="lg" />;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<Breadcrumb items={[
|
|
|
|
|
{ label: 'Agents', href: '/agents' },
|
|
|
|
|
{ label: appId || '', href: `/agents/${appId}` },
|
|
|
|
|
{ label: agent?.name || instanceId || '' },
|
|
|
|
|
]} />
|
|
|
|
|
|
|
|
|
|
{agent && (
|
|
|
|
|
<>
|
2026-03-19 18:16:16 +01:00
|
|
|
<div className={styles.agentHeader}>
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
<StatusDot variant={agent.status === 'LIVE' ? 'live' : agent.status === 'STALE' ? 'stale' : 'dead'} />
|
|
|
|
|
<h2>{agent.name}</h2>
|
|
|
|
|
<Badge label={agent.status} color={agent.status === 'LIVE' ? 'success' : agent.status === 'STALE' ? 'warning' : 'error'} />
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-03-19 18:16:16 +01:00
|
|
|
<div className={styles.statStrip}>
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
<StatCard label="TPS" value={agent.tps?.toFixed(1) ?? '0'} />
|
|
|
|
|
<StatCard label="Error Rate" value={agent.errorRate ? `${(agent.errorRate * 100).toFixed(1)}%` : '0%'} accent={agent.errorRate > 0.05 ? 'error' : undefined} />
|
|
|
|
|
<StatCard label="Active Routes" value={`${agent.activeRoutes ?? 0}/${agent.totalRoutes ?? 0}`} />
|
|
|
|
|
<StatCard label="Uptime" value={formatUptime(agent.uptimeSeconds ?? 0)} />
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-03-19 18:16:16 +01:00
|
|
|
<div className={styles.sectionTitle}>Routes</div>
|
|
|
|
|
<div className={styles.routeBadges}>
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
{(agent.routeIds || []).map((r: string) => (
|
|
|
|
|
<Badge key={r} label={r} color="auto" />
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{chartData.length > 0 && (
|
|
|
|
|
<>
|
2026-03-19 18:16:16 +01:00
|
|
|
<div className={styles.sectionTitle}>Performance</div>
|
|
|
|
|
<div className={styles.chartsGrid}>
|
|
|
|
|
<div className={styles.chartCard}>
|
|
|
|
|
<div className={styles.chartHeader}><div className={styles.chartTitle}>Throughput</div></div>
|
|
|
|
|
<AreaChart series={[{ label: 'Throughput', data: chartData.map((d: any, i: number) => ({ x: i, y: d.throughput })) }]} height={200} />
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.chartCard}>
|
|
|
|
|
<div className={styles.chartHeader}><div className={styles.chartTitle}>Latency</div></div>
|
|
|
|
|
<LineChart series={[{ label: 'Latency', data: chartData.map((d: any, i: number) => ({ x: i, y: d.latency })) }]} height={200} />
|
|
|
|
|
</div>
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{feedEvents.length > 0 && (
|
2026-03-19 18:16:16 +01:00
|
|
|
<div className={styles.eventCard}>
|
|
|
|
|
<div className={styles.eventCardHeader}>Events</div>
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
<EventFeed events={feedEvents} maxItems={50} />
|
2026-03-19 18:16:16 +01:00
|
|
|
</div>
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{agent && (
|
|
|
|
|
<>
|
2026-03-19 18:16:16 +01:00
|
|
|
<div className={styles.sectionTitle}>Agent Info</div>
|
|
|
|
|
<div className={styles.infoCard}>
|
|
|
|
|
<CodeBlock content={JSON.stringify({
|
|
|
|
|
id: agent.id,
|
|
|
|
|
name: agent.name,
|
|
|
|
|
group: agent.group,
|
|
|
|
|
registeredAt: agent.registeredAt,
|
|
|
|
|
lastHeartbeat: agent.lastHeartbeat,
|
|
|
|
|
routeIds: agent.routeIds,
|
|
|
|
|
}, null, 2)} />
|
|
|
|
|
</div>
|
feat: migrate UI to @cameleer/design-system, add backend endpoints
Backend:
- Add agent_events table (V5) and lifecycle event recording
- Add route catalog endpoint (GET /routes/catalog)
- Add route metrics endpoint (GET /routes/metrics)
- Add agent events endpoint (GET /agents/events-log)
- Enrich AgentInstanceResponse with tps, errorRate, activeRoutes, uptimeSeconds
- Add TimescaleDB retention/compression policies (V6)
Frontend:
- Replace custom Mission Control UI with @cameleer/design-system components
- Rebuild all pages: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance, RBAC, AuditLog, OIDC, DatabaseAdmin, OpenSearchAdmin, Swagger
- New LayoutShell with design system AppShell, Sidebar, TopBar, CommandPalette
- Consume design system from Gitea npm registry (@cameleer/design-system@0.0.1)
- Add .npmrc for scoped registry, update Dockerfile with REGISTRY_TOKEN arg
CI:
- Pass REGISTRY_TOKEN build-arg to UI Docker build step
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:38:39 +01:00
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatUptime(seconds: number): string {
|
|
|
|
|
if (seconds < 60) return `${seconds}s`;
|
|
|
|
|
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
|
|
|
if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;
|
|
|
|
|
return `${Math.floor(seconds / 86400)}d ${Math.floor((seconds % 86400) / 3600)}h`;
|
|
|
|
|
}
|