Status: active
The in-app operational view of an AI agent fleet — live health, provider and agent performance, cost, reliability (alerts + circuit breakers), and short-window trends. Distinct from the infra logging/metrics stack in operations/observability.md and from the deep historical analytics surface.
- What this covers
- Where it lives
- Dashboard sections
- API contract
- Trend semantics
- Operational vs analytics boundary
- See also
The AIOps dashboard answers "how is my AI fleet doing right now, and over the last few
hours?" It reads from Ai::Analytics::DashboardService (the AiopsMetrics concern) which
aggregates Ai::AgentExecution, Ai::ProviderMetric, cost attribution, and circuit-breaker
state — all account-scoped. It is read-only: it surfaces live operational data, it does not
mutate fleet state.
AIOps lives on the dedicated Operations hub (OperationsPage, /app/ai/operations/*),
inside an AiErrorBoundary. It is path-based (canonical PathTabs, one URL segment per tab):
- AIOps tab — the operational core: KPIs + system health + an active-provider-alerts
callout, trend charts, providers table, agents table. Body component:
AiOpsContent(frontend/src/features/ai/aiops/components/AiOpsDashboard.tsx). - Alerts tab — the alert-management center plus provider reliability (circuit breakers +
recent errors) via
ReliabilitySection. - Execution Traces tab — the distributed-trace viewer (
ExecutionTracesContent).
AIOps cost analysis is part of the Cost domain (/app/ai/cost), not Operations. The
monitoring-only Observability hub (/app/ai/observability: Health · Systems ·
Conversations · Evaluation) is a separate sidebar item. See
AI Navigation IA.
Backend: Api::V1::Ai::AiOpsController under scope :aiops — all reads gated by the
ai.aiops.read permission (record_metrics is the only writer, gated by ai.aiops.write
and used by the worker, not the UI).
Data fetching follows the platform standard: @tanstack/react-query hooks
(features/ai/aiops/api/aiopsApi.ts) with a query-key factory. Sections self-fetch via the
shared useAiOpsDashboard hook; react-query dedupes by query key, so all sections share a single
fetch regardless of which tab renders them.
The sections render across the Operations hub tabs:
| Operations tab | AIOps content | Source |
|---|---|---|
| AIOps | execution / latency / cost KPIs, system-health components, active-provider-alerts callout, hourly trend charts, providers table, agents table | dashboard.overview, dashboard.health, dashboard.alerts[], /trends, dashboard.providers[], dashboard.agents[] |
| Alerts | alert-management center + provider reliability: circuit-breaker status + recent execution errors | dashboard.circuit_breakers[], /recent_errors |
AIOps cost_analysis data surfaces in the Cost domain (/app/ai/cost), not Operations.
All responses use the standard { success, data, meta } envelope; the frontend BaseApiService
unwraps data. Endpoints (under /api/v1/ai/aiops):
| Endpoint | Returns |
|---|---|
GET /dashboard?time_range= |
{ dashboard: { health, overview (incl. latency_aggregate), providers[], agents[], cost_analysis, alerts[], circuit_breakers[], real_time, generated_at }, time_range } |
GET /real_time |
live snapshot: { current_requests_per_second, current_avg_latency_ms, current_error_rate (0–1), active_connections, queue_depth, timestamp } |
GET /trends?time_range= |
{ trends: { bucket: "hour", bucket_count, latency[], error_rate[], throughput[], cost[] }, time_range } |
GET /latency_aggregate?time_range= |
{ latency_aggregate: { avg_ms, p95_ms, p99_ms, max_ms, sample_provider_count }, time_range } |
GET /recent_errors?limit= |
{ recent_errors: [{ execution_id, agent_name, error, failed_at }], count, timestamp } |
success_rate fields are percentages (0–100); current_error_rate and trend error_rate are
fractions (0–1). The frontend types latency_aggregate, trends, and recent_errors as
optional so the UI degrades gracefully if a deployment predates those endpoints.
GET /trends returns four parallel time series sharing one x-axis. Key invariants:
- Hourly buckets, capped at 168 (7 days). Bucket keys are ISO8601 UTC timestamps; the frontend localizes for display.
- Zero-filled: every series has exactly
bucket_countpoints — buckets with no activity are emitted as zeros, never omitted. This keeps the chart x-axes aligned. - Latency p95/p99 come from
Ai::ProviderMetric(the only source with true percentiles). When an account has no provider metrics for a window, the series fall back to per-execution aggregates and reportp95 = p99 = avg(a documented approximation).
AIOps is intentionally operational and live: health, providers, alerts, circuit breakers,
real-time, short hourly trends, recent errors. It does not duplicate the deeper
/api/v1/ai/analytics/* surface (ROI, forecasting, insights, recommendations, export, day-level
30-day trends). When you need historical/financial analysis, use that surface and
cost-and-finops.md; when you need "is the fleet healthy now," use AIOps.
- agents-and-autonomy.md — what produces the executions AIOps measures
- cost-and-finops.md — deep cost analytics and budgets
- operations/observability.md — infra logs/metrics (Loki/Grafana/Prometheus)