11import { formatCurrencyAccurate } from "~/utils/numberFormatter" ;
2+ import { Header3 } from "~/components/primitives/Headers" ;
23import type { AISpanData } from "./types" ;
34
45export function AITagsRow ( { aiData } : { aiData : AISpanData } ) {
56 return (
6- < div className = "flex flex-wrap items-center gap-1.5 py-2.5" >
7- < Pill > { aiData . model } </ Pill >
8- { aiData . provider !== "unknown" && < Pill variant = "dimmed" > { aiData . provider } </ Pill > }
9- { aiData . resolvedProvider && (
10- < Pill variant = "dimmed" > via { aiData . resolvedProvider } </ Pill >
11- ) }
12- { aiData . finishReason && < Pill variant = "dimmed" > { aiData . finishReason } </ Pill > }
13- { aiData . serviceTier && < Pill variant = "dimmed" > tier: { aiData . serviceTier } </ Pill > }
14- { aiData . toolChoice && < Pill variant = "dimmed" > tools: { aiData . toolChoice } </ Pill > }
15- { aiData . toolCount != null && aiData . toolCount > 0 && (
16- < Pill variant = "dimmed" >
17- { aiData . toolCount } { aiData . toolCount === 1 ? "tool" : "tools" }
18- </ Pill >
19- ) }
20- { aiData . messageCount != null && (
21- < Pill variant = "dimmed" >
22- { aiData . messageCount } { aiData . messageCount === 1 ? "msg" : "msgs" }
23- </ Pill >
24- ) }
25- { aiData . telemetryMetadata &&
26- Object . entries ( aiData . telemetryMetadata ) . map ( ( [ key , value ] ) => (
27- < Pill key = { key } variant = "dimmed" >
28- { key } : { value }
29- </ Pill >
30- ) ) }
7+ < div className = "flex flex-col gap-1 py-2.5" >
8+ < div className = "flex flex-col text-xs @container" >
9+ < MetricRow label = "Model" value = { aiData . model } />
10+ { aiData . provider !== "unknown" && < MetricRow label = "Provider" value = { aiData . provider } /> }
11+ { aiData . resolvedProvider && (
12+ < MetricRow label = "Resolved provider" value = { aiData . resolvedProvider } />
13+ ) }
14+ { aiData . finishReason && < MetricRow label = "Finish reason" value = { aiData . finishReason } /> }
15+ { aiData . serviceTier && < MetricRow label = "Service tier" value = { aiData . serviceTier } /> }
16+ { aiData . toolChoice && < MetricRow label = "Tool choice" value = { aiData . toolChoice } /> }
17+ { aiData . toolCount != null && aiData . toolCount > 0 && (
18+ < MetricRow
19+ label = "Tools provided"
20+ value = { `${ aiData . toolCount } ${ aiData . toolCount === 1 ? "tool" : "tools" } ` }
21+ />
22+ ) }
23+ { aiData . messageCount != null && (
24+ < MetricRow
25+ label = "Messages"
26+ value = { `${ aiData . messageCount } ${ aiData . messageCount === 1 ? "message" : "messages" } ` }
27+ />
28+ ) }
29+ { aiData . telemetryMetadata &&
30+ Object . entries ( aiData . telemetryMetadata ) . map ( ( [ key , value ] ) => (
31+ < MetricRow key = { key } label = { key } value = { value } />
32+ ) ) }
33+ </ div >
3134 </ div >
3235 ) ;
3336}
3437
3538export function AIStatsSummary ( { aiData } : { aiData : AISpanData } ) {
3639 return (
3740 < div className = "flex flex-col gap-1 py-2.5" >
38- < span className = "text-xs font-medium uppercase tracking-wide text-text-dimmed" > Stats</ span >
39-
40- < div className = "flex flex-col text-[11px]" >
41+ < Header3 > Stats</ Header3 >
42+ < div className = "flex flex-col text-xs @container" >
4143 < MetricRow label = "Input" value = { aiData . inputTokens . toLocaleString ( ) } unit = "tokens" />
4244 < MetricRow label = "Output" value = { aiData . outputTokens . toLocaleString ( ) } unit = "tokens" />
4345 { aiData . cachedTokens != null && aiData . cachedTokens > 0 && (
44- < MetricRow label = "Cache read" value = { aiData . cachedTokens . toLocaleString ( ) } unit = "tokens" />
46+ < MetricRow
47+ label = "Cache read"
48+ value = { aiData . cachedTokens . toLocaleString ( ) }
49+ unit = "tokens"
50+ />
4551 ) }
4652 { aiData . cacheCreationTokens != null && aiData . cacheCreationTokens > 0 && (
4753 < MetricRow
@@ -57,13 +63,7 @@ export function AIStatsSummary({ aiData }: { aiData: AISpanData }) {
5763 unit = "tokens"
5864 />
5965 ) }
60- < MetricRow
61- label = "Total"
62- value = { aiData . totalTokens . toLocaleString ( ) }
63- unit = "tokens"
64- bold
65- border
66- />
66+ < MetricRow label = "Total" value = { aiData . totalTokens . toLocaleString ( ) } unit = "tokens" bold />
6767
6868 { aiData . totalCost != null && (
6969 < MetricRow label = "Cost" value = { formatCurrencyAccurate ( aiData . totalCost ) } />
@@ -84,22 +84,20 @@ function MetricRow({
8484 value,
8585 unit,
8686 bold,
87- border,
8887} : {
8988 label : string ;
9089 value : string ;
9190 unit ?: string ;
9291 bold ?: boolean ;
93- border ?: boolean ;
9492} ) {
9593 return (
96- < div
97- className = { `flex items-center justify-between py-1 ${
98- border ? "border-t border-grid-dimmed" : ""
99- } `}
100- >
94+ < div className = "grid h-7 grid-cols-[1fr_auto] items-center gap-4 rounded-sm px-1.5 transition odd:bg-charcoal-750/40 @[28rem]:grid-cols-[8rem_1fr] hover:bg-white/[0.04]" >
10195 < span className = "text-text-dimmed" > { label } </ span >
102- < span className = { bold ? "font-medium text-text-bright" : "text-text-bright" } >
96+ < span
97+ className = { `text-right @[28rem]:text-left ${
98+ bold ? "font-medium text-text-bright" : "text-text-bright"
99+ } `}
100+ >
103101 { value }
104102 { unit && < span className = "ml-1 text-text-dimmed" > { unit } </ span > }
105103 </ span >
@@ -113,23 +111,3 @@ function formatTtfc(ms: number): string {
113111 }
114112 return `${ Math . round ( ms ) } ms` ;
115113}
116-
117- function Pill ( {
118- children,
119- variant = "default" ,
120- } : {
121- children : React . ReactNode ;
122- variant ?: "default" | "dimmed" ;
123- } ) {
124- return (
125- < span
126- className = { `inline-flex items-center rounded-sm px-1.5 py-0.5 text-[11px] font-medium ${
127- variant === "dimmed"
128- ? "bg-charcoal-750 text-text-dimmed"
129- : "bg-charcoal-700 text-text-bright"
130- } `}
131- >
132- { children }
133- </ span >
134- ) ;
135- }
0 commit comments