Add a setting to display message generation statistics (#16901)

* feat: Add setting to display message generation statistics

* chore: build static webui output
This commit is contained in:
Aleksander Grygier
2025-11-01 15:35:57 +01:00
committed by GitHub
parent 1ae74882f8
commit d8b860a219
4 changed files with 67 additions and 14 deletions

Binary file not shown.

View File

@@ -3,7 +3,16 @@
import { useProcessingState } from '$lib/hooks/use-processing-state.svelte'; import { useProcessingState } from '$lib/hooks/use-processing-state.svelte';
import { isLoading } from '$lib/stores/chat.svelte'; import { isLoading } from '$lib/stores/chat.svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import { Check, Copy, Package, X } from '@lucide/svelte'; import {
Check,
Copy,
Package,
X,
Gauge,
Clock,
WholeWord,
ChartNoAxesColumn
} from '@lucide/svelte';
import { Button } from '$lib/components/ui/button'; import { Button } from '$lib/components/ui/button';
import { Checkbox } from '$lib/components/ui/checkbox'; import { Checkbox } from '$lib/components/ui/checkbox';
import { INPUT_CLASSES } from '$lib/constants/input-classes'; import { INPUT_CLASSES } from '$lib/constants/input-classes';
@@ -160,22 +169,58 @@
</div> </div>
{/if} {/if}
{#if displayedModel()} <div class="info my-6 grid gap-4">
<span class="mt-6 mb-4 inline-flex items-center gap-1 text-xs text-muted-foreground"> {#if displayedModel()}
<Package class="h-3.5 w-3.5" /> <span class="inline-flex items-center gap-2 text-xs text-muted-foreground">
<span class="inline-flex items-center gap-1">
<Package class="h-3.5 w-3.5" />
<span>Model used:</span> <span>Model used:</span>
</span>
<button <button
class="inline-flex cursor-pointer items-center gap-1 rounded-sm bg-muted-foreground/15 px-1.5 py-0.75" class="inline-flex cursor-pointer items-center gap-1 rounded-sm bg-muted-foreground/15 px-1.5 py-0.75"
onclick={handleCopyModel} onclick={handleCopyModel}
> >
{displayedModel()} {displayedModel()}
<Copy class="ml-1 h-3 w-3 " /> <Copy class="ml-1 h-3 w-3 " />
</button> </button>
</span> </span>
{/if} {/if}
{#if currentConfig.showMessageStats && message.timings && message.timings.predicted_n && message.timings.predicted_ms}
{@const tokensPerSecond = (message.timings.predicted_n / message.timings.predicted_ms) * 1000}
<span class="inline-flex items-center gap-2 text-xs text-muted-foreground">
<span class="inline-flex items-center gap-1">
<ChartNoAxesColumn class="h-3.5 w-3.5" />
<span>Statistics:</span>
</span>
<div class="inline-flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
<span
class="inline-flex items-center gap-1 rounded-sm bg-muted-foreground/15 px-1.5 py-0.75"
>
<Gauge class="h-3 w-3" />
{tokensPerSecond.toFixed(2)} tokens/s
</span>
<span
class="inline-flex items-center gap-1 rounded-sm bg-muted-foreground/15 px-1.5 py-0.75"
>
<WholeWord class="h-3 w-3" />
{message.timings.predicted_n} tokens
</span>
<span
class="inline-flex items-center gap-1 rounded-sm bg-muted-foreground/15 px-1.5 py-0.75"
>
<Clock class="h-3 w-3" />
{(message.timings.predicted_ms / 1000).toFixed(2)}s
</span>
</div>
</span>
{/if}
</div>
{#if message.timestamp && !isEditing} {#if message.timestamp && !isEditing}
<ChatMessageActions <ChatMessageActions

View File

@@ -52,6 +52,11 @@
{ value: 'dark', label: 'Dark', icon: Moon } { value: 'dark', label: 'Dark', icon: Moon }
] ]
}, },
{
key: 'showMessageStats',
label: 'Show message generation statistics',
type: 'checkbox'
},
{ {
key: 'showTokensPerSecond', key: 'showTokensPerSecond',
label: 'Show tokens per second', label: 'Show tokens per second',

View File

@@ -8,6 +8,7 @@ export const SETTING_CONFIG_DEFAULT: Record<string, string | number | boolean> =
showThoughtInProgress: false, showThoughtInProgress: false,
disableReasoningFormat: false, disableReasoningFormat: false,
keepStatsVisible: false, keepStatsVisible: false,
showMessageStats: true,
askForTitleConfirmation: false, askForTitleConfirmation: false,
pasteLongTextToFileLen: 2500, pasteLongTextToFileLen: 2500,
pdfAsImage: false, pdfAsImage: false,
@@ -82,6 +83,8 @@ export const SETTING_CONFIG_INFO: Record<string, string> = {
disableReasoningFormat: disableReasoningFormat:
'Show raw LLM output without backend parsing and frontend Markdown rendering to inspect streaming across different models.', 'Show raw LLM output without backend parsing and frontend Markdown rendering to inspect streaming across different models.',
keepStatsVisible: 'Keep processing statistics visible after generation finishes.', keepStatsVisible: 'Keep processing statistics visible after generation finishes.',
showMessageStats:
'Display generation statistics (tokens/second, token count, duration) below each assistant message.',
askForTitleConfirmation: askForTitleConfirmation:
'Ask for confirmation before automatically changing conversation title when editing the first message.', 'Ask for confirmation before automatically changing conversation title when editing the first message.',
pdfAsImage: 'Parse PDF as image instead of text (requires vision-capable model).', pdfAsImage: 'Parse PDF as image instead of text (requires vision-capable model).',