/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Gauge, HeartPulse, Timer } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Skeleton } from '@/components/ui/skeleton'
import { getPerfMetricsSummary } from '@/features/performance-metrics/api'
import {
formatLatency,
formatThroughput,
formatUptimePct,
} from '@/features/performance-metrics/lib/format'
import type { PerfModelSummary } from '@/features/performance-metrics/types'
const PERFORMANCE_WINDOW_HOURS = 24
const TOP_MODEL_LIMIT = 5
type WeightedMetric = 'avg_latency_ms' | 'avg_tps' | 'success_rate'
function simpleAverage(
rows: PerfModelSummary[],
metric: WeightedMetric,
isValid: (value: number) => boolean
): number {
let total = 0
let count = 0
for (const row of rows) {
const value = Number(row[metric])
if (!isValid(value)) continue
total += value
count++
}
return count > 0 ? total / count : NaN
}
function rateTextClass(rate: number): string {
if (!Number.isFinite(rate)) return 'text-muted-foreground'
if (rate >= 99.9) return 'text-success'
if (rate >= 99) return 'text-warning'
return 'text-destructive'
}
function rateDotClass(rate: number): string {
if (!Number.isFinite(rate)) return 'bg-muted-foreground'
if (rate >= 99.9) return 'bg-success'
if (rate >= 99) return 'bg-warning'
return 'bg-destructive'
}
export function PerformanceHealthPanel() {
const { t } = useTranslation()
const metricsQuery = useQuery({
queryKey: ['perf-metrics-summary', PERFORMANCE_WINDOW_HOURS],
queryFn: () => getPerfMetricsSummary(PERFORMANCE_WINDOW_HOURS),
staleTime: 60 * 1000,
retry: false,
})
const models = useMemo(
() => metricsQuery.data?.data.models ?? [],
[metricsQuery.data]
)
const summary = useMemo(() => {
return {
avgLatencyMs: Math.round(
simpleAverage(models, 'avg_latency_ms', (v) => Number.isFinite(v) && v > 0)
),
avgTps: simpleAverage(models, 'avg_tps', (v) => Number.isFinite(v) && v > 0),
successRate: simpleAverage(models, 'success_rate', Number.isFinite),
}
}, [models])
const topModels = useMemo(() => models.slice(0, TOP_MODEL_LIMIT), [models])
const loading = metricsQuery.isLoading
const hasData = models.length > 0
return (
{t('Performance health')}
{t('Performance metrics for the last 24 hours')}
{/* KPI metrics */}
{/* Top models */}
{t('Top models by traffic')}
{loading ? (
{Array.from({ length: 3 }).map((_, i) => (
))}
) : !hasData ? (
{t('No performance data available')}
) : (
{topModels.map((model) => (
{model.model_name}
{formatUptimePct(model.success_rate)}
))}
)}
)
}
function MetricCell(props: {
icon: React.ComponentType<{ className?: string }>
label: string
value: string
loading: boolean
valueClassName?: string
}) {
const Icon = props.icon
return (
{props.label}
{props.loading ? (
) : (
{props.value}
)}
)
}