From 9bcddad91b36adf8e5bfb7d7fa28b58d8995bca2 Mon Sep 17 00:00:00 2001 From: Wojciech <207363903+oytech@users.noreply.github.com> Date: Fri, 19 Jun 2026 05:55:02 +0200 Subject: [PATCH] internal/server,ui: add new Acitivty page column - Drafted (#859) Add draft metrics to activity log --- internal/server/metrics.go | 10 ++++++++++ ui-svelte/src/lib/types.ts | 2 ++ ui-svelte/src/routes/Activity.svelte | 9 +++++++++ 3 files changed, 21 insertions(+) diff --git a/internal/server/metrics.go b/internal/server/metrics.go index 8157104b..3c70652a 100644 --- a/internal/server/metrics.go +++ b/internal/server/metrics.go @@ -25,6 +25,8 @@ import ( // TokenMetrics holds token usage and performance metrics. type TokenMetrics struct { CachedTokens int `json:"cache_tokens"` + DraftTokens int `json:"draft_tokens"` + DraftAccTokens int `json:"draft_acc_tokens"` InputTokens int `json:"input_tokens"` OutputTokens int `json:"output_tokens"` PromptPerSecond float64 `json:"prompt_per_second"` @@ -345,6 +347,8 @@ func buildMetrics(modelID string, start time.Time, inputTokens, outputTokens, ca durationMs := wallDurationMs tokensPerSecond := -1.0 promptPerSecond := -1.0 + draftTokens := -1 + draftAccTokens := -1 if timings.Exists() { inputTokens = timings.Get("prompt_n").Int() @@ -358,6 +362,10 @@ func buildMetrics(modelID string, start time.Time, inputTokens, outputTokens, ca if cachedValue := timings.Get("cache_n"); cachedValue.Exists() { cachedTokens = cachedValue.Int() } + if timings.Get("draft_n").Exists() && timings.Get("draft_n_accepted").Exists() { + draftTokens = int(timings.Get("draft_n").Int()) + draftAccTokens = int(timings.Get("draft_n_accepted").Int()) + } } return ActivityLogEntry{ @@ -365,6 +373,8 @@ func buildMetrics(modelID string, start time.Time, inputTokens, outputTokens, ca Model: modelID, Tokens: TokenMetrics{ CachedTokens: int(cachedTokens), + DraftTokens: draftTokens, + DraftAccTokens: draftAccTokens, InputTokens: int(inputTokens), OutputTokens: int(outputTokens), PromptPerSecond: promptPerSecond, diff --git a/ui-svelte/src/lib/types.ts b/ui-svelte/src/lib/types.ts index 1fced1cb..815c1bd4 100644 --- a/ui-svelte/src/lib/types.ts +++ b/ui-svelte/src/lib/types.ts @@ -25,6 +25,8 @@ export interface Model { export interface TokenMetrics { cache_tokens: number; + draft_tokens: number; + draft_acc_tokens: number; input_tokens: number; output_tokens: number; prompt_per_second: number; diff --git a/ui-svelte/src/routes/Activity.svelte b/ui-svelte/src/routes/Activity.svelte index c0974e22..17dcefee 100644 --- a/ui-svelte/src/routes/Activity.svelte +++ b/ui-svelte/src/routes/Activity.svelte @@ -26,6 +26,7 @@ { key: "cached", label: "Cached", defaultVisible: true }, { key: "prompt", label: "Prompt", defaultVisible: true }, { key: "generated", label: "Generated", defaultVisible: true }, + { key: "drafted", label: "Drafted", defaultVisible: false }, { key: "prompt_speed", label: "Prompt Speed", defaultVisible: true }, { key: "gen_speed", label: "Gen Speed", defaultVisible: true }, { key: "duration", label: "Duration", defaultVisible: true }, @@ -158,6 +159,10 @@ return speed < 0 ? "unknown" : speed.toFixed(2) + " t/s"; } + function formatDrafted(drafted: number, accepted: number): string { + return drafted > 0 ? (accepted * 100 / drafted).toFixed(1) + "% (" + accepted + "/" + drafted + ")" : "-"; + } + function formatDuration(ms: number): string { return (ms / 1000).toFixed(2) + "s"; } @@ -273,6 +278,8 @@ Cached {:else if key === "prompt"} Prompt + {:else if key === "drafted"} + Drafted {:else} {columnLabelMap[key] ?? key} {/if} @@ -310,6 +317,8 @@ {metric.tokens.input_tokens.toLocaleString()} {:else if key === "generated"} {metric.tokens.output_tokens.toLocaleString()} + {:else if key === "drafted"} + {formatDrafted(metric.tokens.draft_tokens, metric.tokens.draft_acc_tokens)} {:else if key === "prompt_speed"} {formatSpeed(metric.tokens.prompt_per_second)} {:else if key === "gen_speed"}