@@ -36,6 +36,7 @@ import { FilterToggle } from '@/components/ui/FilterToggle'
3636import { ListPager , type PageSize } from '@/components/ui/ListPager'
3737import { PageAlert } from '@/components/ui/PageAlert'
3838import { LogsPageSkeleton , LogsRequestListSkeleton , LogsRuntimeListSkeleton , SkeletonBlock } from '@/components/ui/PageSkeletons'
39+ import { LatencyStats } from '@/components/ui/LatencyStats'
3940import { SearchBar } from '@/components/ui/SearchBar'
4041import { dateValueToISO , isoToDateValue , TimeRangePicker , type DateRangeValue } from '@/components/ui/TimeRangePicker'
4142import { useI18n } from '@/hooks/useI18n'
@@ -149,12 +150,6 @@ function RequestDetailSkeleton() {
149150 )
150151}
151152
152- function formatLatency ( ms ?: number | null ) {
153- if ( ms == null ) return '—'
154- if ( ms < 1000 ) return `${ ms } ms`
155- return `${ ( ms / 1000 ) . toFixed ( 1 ) } s`
156- }
157-
158153function formatCredit ( value ?: number | null ) {
159154 if ( value == null || ! Number . isFinite ( value ) ) return '—'
160155 return String ( Math . round ( value * 10000 ) / 10000 )
@@ -729,7 +724,6 @@ export function LogsPage() {
729724 < Table . Column > { t ( 'logsColStatus' ) } </ Table . Column >
730725 < Table . Column > { t ( 'logsColStream' ) } </ Table . Column >
731726 < Table . Column > { t ( 'logsColLatency' ) } </ Table . Column >
732- < Table . Column > { t ( 'logsColTTFT' ) } </ Table . Column >
733727 < Table . Column > { t ( 'logsColTokens' ) } </ Table . Column >
734728 </ Table . Header >
735729 < Table . Body >
@@ -764,8 +758,19 @@ export function LogsPage() {
764758 { item . error_kind ? < div className = "mono mt-1 text-caption text-muted" > { item . error_kind } </ div > : null }
765759 </ Table . Cell >
766760 < Table . Cell > < span className = "text-xs text-muted" > { item . stream ? t ( 'logsStreamYes' ) : t ( 'logsStreamNo' ) } </ span > </ Table . Cell >
767- < Table . Cell > < span className = "mono text-xs" > { formatLatency ( item . latency_ms ) } </ span > </ Table . Cell >
768- < Table . Cell > < span className = "mono text-xs" > { formatLatency ( item . ttfb_ms ) } </ span > </ Table . Cell >
761+ < Table . Cell >
762+ < LatencyStats
763+ latencyMs = { item . latency_ms }
764+ ttfbMs = { item . ttfb_ms }
765+ completionTokens = { item . completion_tokens }
766+ stream = { item . stream }
767+ labels = { {
768+ ttft : t ( 'logsColTTFT' ) ,
769+ total : t ( 'logsLatencyTotal' ) ,
770+ tps : t ( 'logsOutputTPS' ) ,
771+ } }
772+ />
773+ </ Table . Cell >
769774 < Table . Cell >
770775 < TokenSplit
771776 log = { item }
@@ -975,8 +980,6 @@ export function LogsPage() {
975980 [ t ( 'logsColReasoning' ) , selected ? ( reasoningLabel ( selected ) || '—' ) : '—' ] ,
976981 [ t ( 'logsColProvider' ) , selected ? providerLabel ( selected ) : '—' ] ,
977982 [ t ( 'logsColAccount' ) , selected ?. account_id ? ( accountNameById . get ( selected . account_id ) || selected . account_id ) : '—' ] ,
978- [ t ( 'logsColLatency' ) , formatLatency ( selected ?. latency_ms ) ] ,
979- [ t ( 'logsColTTFT' ) , formatLatency ( selected ?. ttfb_ms ) ] ,
980983 [ t ( 'logsColStream' ) , selected ?. stream ? t ( 'logsStreamYes' ) : t ( 'logsStreamNo' ) ] ,
981984 [ t ( 'logsRouting' ) , selected ? routingLabel ( selected . routing ) : '—' ] ,
982985 ] . map ( ( [ label , value ] ) => (
@@ -998,6 +1001,20 @@ export function LogsPage() {
9981001 ) : '—' }
9991002 </ dd >
10001003 </ div >
1004+ < div className = "sm:col-span-2" >
1005+ < LatencyStats
1006+ latencyMs = { selected ?. latency_ms }
1007+ ttfbMs = { selected ?. ttfb_ms }
1008+ completionTokens = { selected ?. completion_tokens }
1009+ stream = { selected ?. stream }
1010+ labels = { {
1011+ heading : t ( 'logsColLatency' ) ,
1012+ ttft : t ( 'logsColTTFT' ) ,
1013+ total : t ( 'logsLatencyTotal' ) ,
1014+ tps : t ( 'logsOutputTPS' ) ,
1015+ } }
1016+ />
1017+ </ div >
10011018 </ dl >
10021019 { selected && selected . message_count ? (
10031020 < div className = "rounded-lg bg-surface-secondary px-3 py-3 text-xs" >
0 commit comments