mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
feat(usage): highlight latency by fixed thresholds (#412)
Color first-output and total latency independently using fixed thresholds. Keep the existing layout and details popover without a side indicator. Closes #407 Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -10,6 +10,14 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const latencyDetails = computed(() => usageLatencyDetails(props.record))
|
||||
|
||||
const latencyTones = {
|
||||
good: 'text-cp-success-text',
|
||||
warn: 'text-cp-warning-text',
|
||||
// 主题的 Orange 与 Warning 共用色种,混入 Error 让相邻两档可区分
|
||||
slow: 'latency-slow',
|
||||
critical: 'text-cp-error-text',
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -18,9 +26,13 @@ const latencyDetails = computed(() => usageLatencyDetails(props.record))
|
||||
class="grid grid-cols-[auto_auto] items-center justify-end gap-x-2 gap-y-1.5 whitespace-nowrap font-mono text-cp-sm leading-none font-heavy tabular-nums"
|
||||
>
|
||||
<span class="text-cp-xs text-cp-text-quaternary">首字</span>
|
||||
<span class="text-cp-text-secondary">{{ latencyDetails.firstOutputDisplay }}</span>
|
||||
<span :class="latencyDetails.firstOutputSeverity === null ? 'text-cp-text-quaternary' : latencyTones[latencyDetails.firstOutputSeverity]">
|
||||
{{ latencyDetails.firstOutputDisplay }}
|
||||
</span>
|
||||
<span class="text-cp-xs text-cp-text-quaternary">总耗时</span>
|
||||
<span class="text-cp-text">{{ latencyDetails.totalDisplay }}</span>
|
||||
<span :class="latencyDetails.totalSeverity === null ? 'text-cp-text-quaternary' : latencyTones[latencyDetails.totalSeverity]">
|
||||
{{ latencyDetails.totalDisplay }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<UsageDetailPopover trigger-label="查看延迟明细">
|
||||
@@ -58,3 +70,9 @@ const latencyDetails = computed(() => usageLatencyDetails(props.record))
|
||||
</UsageDetailPopover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.latency-slow {
|
||||
color: color-mix(in oklab, var(--cp-color-warning-text) 65%, var(--cp-color-error-text));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -224,11 +224,26 @@ export function usageLatencyDetails(record: UsageLatencyRecord) {
|
||||
return {
|
||||
upstreamDisplay,
|
||||
firstOutputDisplay: formatDuration(firstTokenMs),
|
||||
firstOutputSeverity: latencySeverity(firstTokenMs, [10_000, 30_000, 60_000]),
|
||||
totalDisplay: formatDuration(totalMs),
|
||||
totalSeverity: latencySeverity(totalMs, [60_000, 180_000, 300_000]),
|
||||
sections,
|
||||
}
|
||||
}
|
||||
|
||||
function latencySeverity(ms: number | null, thresholds: readonly [number, number, number]): 'good' | 'warn' | 'slow' | 'critical' | null {
|
||||
if (ms === null)
|
||||
return null
|
||||
// 沿用 sub2api 的固定分档,边界值进入下一档,不改变请求状态
|
||||
if (ms >= thresholds[2])
|
||||
return 'critical'
|
||||
if (ms >= thresholds[1])
|
||||
return 'slow'
|
||||
if (ms >= thresholds[0])
|
||||
return 'warn'
|
||||
return 'good'
|
||||
}
|
||||
|
||||
export function usageBillingText(record: Pick<UsageCommonRecord, 'billing'>) {
|
||||
return record.billing?.totalAmountDisplay || '—'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user