mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-09 10:57:03 +08:00
feat(usage): 新增输出速度统计与请求详情性能分析
- 把 upstream_is_stream 物化到 usage 与 billing facts,避免 Provider 聚合回连 public.usage - 统一前端标准/流式 TPS 计算与显示,流式按首字后生成耗时计算 - 新增请求详情抽屉展示单请求输出速度与 Provider 聚合 TPS
This commit is contained in:
@@ -179,6 +179,47 @@
|
||||
<span class="text-lg font-bold">{{ detail.response_time_ms ? formatResponseTime(detail.response_time_ms).value : 'N/A' }}</span>
|
||||
<span class="text-sm text-muted-foreground ml-1">{{ detail.response_time_ms ? formatResponseTime(detail.response_time_ms).unit : '' }}</span>
|
||||
</div>
|
||||
<template v-if="detailOutputRate != null">
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
class="h-6 mx-6"
|
||||
/>
|
||||
<div class="flex items-center">
|
||||
<span class="text-xs text-muted-foreground w-[56px]">输出速度</span>
|
||||
<span class="text-lg font-bold text-primary">{{ formatOutputRateValue(detailOutputRate) }}</span>
|
||||
<span class="text-sm text-muted-foreground ml-1">tps</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasDetailPerformanceBreakdown"
|
||||
class="grid grid-cols-1 sm:grid-cols-3 gap-2 mb-4 text-xs"
|
||||
>
|
||||
<div class="rounded-md border border-border/50 bg-muted/20 px-3 py-2">
|
||||
<div class="text-muted-foreground mb-1">
|
||||
首字时间
|
||||
</div>
|
||||
<div class="font-mono text-foreground">
|
||||
{{ formatDurationMs(detail.first_byte_time_ms) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="rounded-md border border-border/50 bg-muted/20 px-3 py-2">
|
||||
<div class="text-muted-foreground mb-1">
|
||||
生成耗时
|
||||
</div>
|
||||
<div class="font-mono text-foreground">
|
||||
{{ formatDurationMs(detailGenerationTimeMs) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="rounded-md border border-border/50 bg-muted/20 px-3 py-2">
|
||||
<div class="text-muted-foreground mb-1">
|
||||
输出 Tokens
|
||||
</div>
|
||||
<div class="font-mono text-foreground">
|
||||
{{ formatNumber(detailOutputTokens) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
@@ -714,6 +755,13 @@ import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
import { formatShortRequestId } from '@/utils/format'
|
||||
import { log } from '@/utils/logger'
|
||||
import { getEffectiveInputTokens } from '../token-normalization'
|
||||
import {
|
||||
formatDurationMs,
|
||||
formatOutputRate,
|
||||
formatOutputRateValue,
|
||||
getDisplayOutputRate,
|
||||
getGenerationTimeMs,
|
||||
} from '../performance'
|
||||
import {
|
||||
formatUsageStreamLabel,
|
||||
isUsageUpstreamStream,
|
||||
@@ -892,6 +940,37 @@ const displayInputTokens = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
const detailOutputTokens = computed(() => {
|
||||
if (!detail.value) return 0
|
||||
return detail.value.tokens?.output ?? detail.value.output_tokens ?? 0
|
||||
})
|
||||
|
||||
const detailGenerationTimeMs = computed(() => {
|
||||
if (!detail.value) return null
|
||||
return getGenerationTimeMs({
|
||||
response_time_ms: detail.value.response_time_ms,
|
||||
first_byte_time_ms: detail.value.first_byte_time_ms,
|
||||
is_stream: detail.value.is_stream,
|
||||
upstream_is_stream: detail.value.upstream_is_stream,
|
||||
})
|
||||
})
|
||||
|
||||
const detailOutputRate = computed(() => {
|
||||
if (!detail.value) return null
|
||||
return getDisplayOutputRate({
|
||||
output_tokens: detailOutputTokens.value,
|
||||
response_time_ms: detail.value.response_time_ms,
|
||||
first_byte_time_ms: detail.value.first_byte_time_ms,
|
||||
is_stream: detail.value.is_stream,
|
||||
upstream_is_stream: detail.value.upstream_is_stream,
|
||||
})
|
||||
})
|
||||
|
||||
const hasDetailPerformanceBreakdown = computed(() => {
|
||||
if (!detail.value) return false
|
||||
return detail.value.first_byte_time_ms != null || detailGenerationTimeMs.value != null || detailOutputTokens.value > 0
|
||||
})
|
||||
|
||||
// 监听标签页切换
|
||||
watch(activeTab, (newTab) => {
|
||||
if (!['request-headers', 'response-headers'].includes(newTab) && viewMode.value === 'compare') {
|
||||
|
||||
Reference in New Issue
Block a user