From ce28485be256461c5819433dc0ab8137956dafcd Mon Sep 17 00:00:00 2001 From: Benson Wong Date: Sat, 25 Apr 2026 16:13:07 -0700 Subject: [PATCH] ui-svelte: add prompt processing histogram (#705) Activities page shows histograms for prompt processing and token generation times. Fix: #691 Fix: #703 --- ui-svelte/src/components/ActivityStats.svelte | 77 ++++++++++++------- ui-svelte/src/components/Header.svelte | 8 +- .../src/components/TokenHistogram.svelte | 48 ++++++++++-- ui-svelte/src/lib/histogram.test.ts | 24 +++--- ui-svelte/src/lib/histogram.ts | 11 ++- ui-svelte/src/routes/Activity.svelte | 1 - 6 files changed, 117 insertions(+), 52 deletions(-) diff --git a/ui-svelte/src/components/ActivityStats.svelte b/ui-svelte/src/components/ActivityStats.svelte index 527967d3..316d2abe 100644 --- a/ui-svelte/src/components/ActivityStats.svelte +++ b/ui-svelte/src/components/ActivityStats.svelte @@ -11,57 +11,82 @@ const totalRequests = $metrics.length; const totalInputTokens = $metrics.reduce((sum, m) => sum + m.input_tokens, 0); const totalOutputTokens = $metrics.reduce((sum, m) => sum + m.output_tokens, 0); + const totalCacheTokens = $metrics.reduce((sum, m) => sum + m.cache_tokens, 0); - const tokensPerSecond = $metrics - .filter((m) => m.tokens_per_second > 0) - .map((m) => m.tokens_per_second); + const promptPerSecond = $metrics.filter((m) => m.prompt_per_second > 0).map((m) => m.prompt_per_second); - const histogramData = tokensPerSecond.length > 0 - ? calculateHistogramData(tokensPerSecond, { minBins: 20, maxBins: 80, binScaling: 3 }) - : null; + const tokensPerSecond = $metrics.filter((m) => m.tokens_per_second > 0).map((m) => m.tokens_per_second); + + const promptHistogramData = + promptPerSecond.length > 0 ? calculateHistogramData(promptPerSecond) : null; + + const genHistogramData = + tokensPerSecond.length > 0 ? calculateHistogramData(tokensPerSecond) : null; return { totalRequests, totalInputTokens, totalOutputTokens, + totalCacheTokens, inFlightRequests: $inFlightRequests, - histogramData, + promptHistogramData, + genHistogramData, }; }); -
+
{#if !$histogramCollapsed} - {#if stats.histogramData} - - {:else} -
- No token speed data yet +
+
+
Prompt Processing
+ {#if stats.promptHistogramData} + + {:else} +
No prompt speed data yet
+ {/if}
- {/if} +
+
Token Generation
+ {#if stats.genHistogramData} + + {:else} +
No generation speed data yet
+ {/if} +
+
{/if} -
+
Requests
+
Cached
Processed
Generated
{nf.format(stats.totalRequests)} completed, {nf.format(stats.inFlightRequests)} waiting
+
+ {nf.format(stats.totalCacheTokens)} tokens +
{nf.format(stats.totalInputTokens)} tokens
diff --git a/ui-svelte/src/components/Header.svelte b/ui-svelte/src/components/Header.svelte index c3cf4a8f..1c9529d0 100644 --- a/ui-svelte/src/components/Header.svelte +++ b/ui-svelte/src/components/Header.svelte @@ -50,7 +50,7 @@ Playground @@ -59,6 +59,8 @@ use:link class="text-gray-600 hover:text-black dark:text-gray-300 dark:hover:text-gray-100 p-1 whitespace-nowrap" class:font-semibold={isActive("/models", $currentRoute)} + class:underline={isActive("/models", $currentRoute)} + class:underline-offset-4={isActive("/models", $currentRoute)} > Models @@ -67,6 +69,8 @@ use:link class="text-gray-600 hover:text-black dark:text-gray-300 dark:hover:text-gray-100 p-1 whitespace-nowrap" class:font-semibold={isActive("/activity", $currentRoute)} + class:underline={isActive("/activity", $currentRoute)} + class:underline-offset-4={isActive("/activity", $currentRoute)} > Activity @@ -75,6 +79,8 @@ use:link class="text-gray-600 hover:text-black dark:text-gray-300 dark:hover:text-gray-100 p-1 whitespace-nowrap" class:font-semibold={isActive("/logs", $currentRoute)} + class:underline={isActive("/logs", $currentRoute)} + class:underline-offset-4={isActive("/logs", $currentRoute)} > Logs diff --git a/ui-svelte/src/components/TokenHistogram.svelte b/ui-svelte/src/components/TokenHistogram.svelte index 0d4fc45d..4a6ed57b 100644 --- a/ui-svelte/src/components/TokenHistogram.svelte +++ b/ui-svelte/src/components/TokenHistogram.svelte @@ -1,10 +1,18 @@
-

Activity