From ea17ee231384b3edeab2de9e64271312dfa8cee9 Mon Sep 17 00:00:00 2001 From: Zoe <62722391+juls0730@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:22:56 -0600 Subject: [PATCH] feat: more in-depth token details dropdown --- .../Message/TokenDetailsDropdown.vue | 161 ++++++++++-------- 1 file changed, 92 insertions(+), 69 deletions(-) diff --git a/app/components/Message/TokenDetailsDropdown.vue b/app/components/Message/TokenDetailsDropdown.vue index e95dcb5..6e773f8 100644 --- a/app/components/Message/TokenDetailsDropdown.vue +++ b/app/components/Message/TokenDetailsDropdown.vue @@ -16,24 +16,35 @@ const { floatingStyles } = useFloating(triggerElement, tokenDetailsDropdownRef, }); const outputPercentage = computed(() => { - if (!generation.value?.tokens?.output || !generation.value.tokens.thinking) return 0; - return (generation.value.tokens.thinking / generation.value.tokens.output) * 100; + const total = generation.value?.tokens?.output ?? 0; + const thinking = generation.value?.tokens?.thinking ?? 0; + if (total === 0) return 0; + return (thinking / total) * 100; }); -const cacheReadPercentage = computed(() => { - const cache = generation.value?.tokens?.cache; - if (!cache || !cache.read || !cache.write) return 0; - return (cache.read / (cache.read + cache.write)) * 100; +const inputStats = computed(() => { + const totalInput = generation.value?.tokens?.input ?? 0; + const cachedInput = generation.value?.tokens?.cache?.read ?? 0; + const uncachedInput = Math.max(0, totalInput - cachedInput); + const output = generation.value?.tokens?.output ?? 0; + + const combinedTotal = totalInput + output; + + if (combinedTotal === 0) return { uncached: 0, cached: 0, output: 0, rawUncached: 0, rawCached: 0, rawOutput: 0 }; + + return { + uncached: (uncachedInput / combinedTotal) * 100, + cached: (cachedInput / combinedTotal) * 100, + output: (output / combinedTotal) * 100, + rawUncached: uncachedInput, + rawCached: cachedInput, + rawOutput: output + }; }); -const hasCache = computed(() => { - const cache = generation.value?.tokens?.cache; - return cache && ((cache.read ?? 0) > 0 || (cache.write ?? 0) > 0); -}); - -const formatNumber = (num?: number) => { +const formatNumber = (num: number | null | undefined) => { if (num === undefined || num === null) return '0'; - return num.toLocaleString(); + return num.toLocaleString(undefined, { maximumFractionDigits: 1 }); }; @@ -47,81 +58,93 @@ const formatNumber = (num?: number) => {
-
- Token Details -
+ class="absolute z-50 flex flex-col min-w-[280px] bg-[var(--bg-surface)] rounded-md border border-[var(--color-border)] shadow-2xl text-[var(--text-secondary)] font-sans"> -
-
- Output - {{ formatNumber(generation.tokens.output ?? 0) }} - tokens + +
+
Output Details
+ +
+
+
-
-
+ +
+
+
+ + Deep Thinking +
+ + {{ formatNumber(generation.tokens.thinking ?? 0) }} +
-
-
-
-
-
- - Reasoning - {{ formatNumber(generation.tokens.thinking ?? 0) }} -
-
- - Output - +
+
+ + Text Output +
+ {{ formatNumber((generation.tokens.output ?? 0) - (generation.tokens.thinking ?? 0)) }}
-
-
- Cache - {{ formatNumber((generation.tokens.cache?.read || 0) + - (generation.tokens.cache?.write || 0)) }} tokens + +
+
+
+
+
-
-
+ +
+
+
+ + Uncached Input +
+ + {{ formatNumber(inputStats.rawUncached) }} +
-
+
+
+ + Cached Input +
+ + {{ formatNumber(inputStats.rawCached) }} +
-
-
-
- - Read - {{ formatNumber(generation.tokens.cache?.read ?? 0) }} -
-
- - Write - {{ formatNumber(generation.tokens.cache?.write ?? 0) }} +
+
+ + Output +
+ + {{ formatNumber(inputStats.rawOutput) }} +
-
-
-
TTFT + +
+
+
+ TTFT
+
+ {{ formatNumber(generation.tokens.ttft) }}ms
-
{{ generation.tokens.ttft?.toFixed(1) || '0' }}ms
-
-
Speed +
+
+ Speed
+
+ {{ formatNumber(generation.tokens.tps) }} tps
-
{{ generation.tokens.tps?.toFixed(1) || '0' }} tps