/*
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 { useQuery } from '@tanstack/react-query'
import { Gauge, HeartPulse, Timer } from 'lucide-react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { Skeleton } from '@/components/ui/skeleton'
import { getPerfMetricsSummary } from '@/features/performance-metrics/api'
import {
formatLatency,
formatThroughput,
formatUptimePct,
getSuccessRateDotClass,
getSuccessRateTextClass,
} from '@/features/performance-metrics/lib/format'
import type { PerfModelSummary } from '@/features/performance-metrics/types'
import { cn } from '@/lib/utils'
const PERFORMANCE_WINDOW_HOURS = 24
const TOP_MODEL_LIMIT = 6
type WeightedMetric = 'avg_latency_ms' | 'avg_tps' | 'success_rate'
type PerformanceSummary = {
totalRequests: number
avgLatencyMs: number
avgTps: number
successRate: number
}
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 buildPerformanceSummary(rows: PerfModelSummary[]): PerformanceSummary {
return {
totalRequests: rows.length,
avgLatencyMs: Math.round(
simpleAverage(
rows,
'avg_latency_ms',
(value) => Number.isFinite(value) && value > 0
)
),
avgTps: simpleAverage(
rows,
'avg_tps',
(value) => Number.isFinite(value) && value > 0
),
successRate: simpleAverage(rows, 'success_rate', Number.isFinite),
}
}
export function PerformanceOverview() {
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(() => buildPerformanceSummary(models), [models])
const topModels = useMemo(() => models.slice(0, TOP_MODEL_LIMIT), [models])
const loading = metricsQuery.isLoading
const hasData = models.length > 0
if (!loading && !hasData) {
return (
{t('No performance data available')}
)
}
return (
{/* Title */}
{t('Performance health')}
{/* Separator */}
{/* 3 KPI inline metrics */}
{loading ? (
{Array.from({ length: 3 }).map((_, i) => (
))}
) : (
)}
{/* Separator */}
{/* Top models inline badges */}
{!loading && hasData && (
{topModels.map((model) => (
))}
)}
)
}
function InlineMetric(props: {
icon: React.ComponentType<{ className?: string }>
label: string
value: string
valueClassName?: string
}) {
const Icon = props.icon
return (
{props.label}
{props.value}
)
}
function ModelBadge(props: { model: PerfModelSummary }) {
const model = props.model
return (
{model.model_name}
{formatUptimePct(model.success_rate)}
)
}