/*
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 { memo } from 'react'
import { useTranslation } from 'react-i18next'
import { getSuccessRateDotClass } from '@/features/performance-metrics/lib/format'
import { cn } from '@/lib/utils'
export type ModelPerfBadgeData = {
avg_latency_ms: number
success_rate: number
avg_tps: number
recent_success_rates?: number[]
}
export interface ModelPerfBadgeProps extends React.HTMLAttributes {
perf: ModelPerfBadgeData | undefined
}
function formatCompactNumber(value: number): string {
if (!Number.isFinite(value) || value <= 0) return '—'
return value > 1 ? String(Math.round(value)) : value.toFixed(1)
}
function formatCompactLatency(ms: number): string {
if (!Number.isFinite(ms) || ms <= 0) return '—'
if (ms >= 1_000) return `${formatCompactNumber(ms / 1_000)}s`
return `${formatCompactNumber(ms)}ms`
}
function formatCompactThroughput(tps: number): string {
if (!Number.isFinite(tps) || tps <= 0) return '—'
if (tps >= 1_000) return `${formatCompactNumber(tps / 1_000)}Kt`
return `${formatCompactNumber(tps)}t`
}
export const ModelPerfBadge = memo(function ModelPerfBadge(
props: ModelPerfBadgeProps
) {
const { t } = useTranslation()
if (!props.perf) {
return null
}
const { avg_latency_ms, avg_tps, success_rate } = props.perf
const recentRates =
props.perf.recent_success_rates?.filter((rate) => Number.isFinite(rate)) ??
[]
const statusRates =
recentRates.length > 0 ? recentRates.slice(-3) : [success_rate]
const statusBars = [
...Array(Math.max(0, 3 - statusRates.length)).fill(null),
...statusRates,
].slice(-3)
return (