feat(webui): global activity spine
This commit is contained in:
parent
33dab85c1c
commit
79821e11d5
54
webui/src/lib/components/ActivitySpine.svelte
Normal file
54
webui/src/lib/components/ActivitySpine.svelte
Normal file
@ -0,0 +1,54 @@
|
||||
<script>
|
||||
import { chat } from "../chat.svelte.js";
|
||||
|
||||
let { version = "" } = $props();
|
||||
let lastTokens = $state(null); // { at, completion }
|
||||
let rate = $state(null);
|
||||
|
||||
$effect(() => {
|
||||
const turn = chat.turn;
|
||||
if (!turn || turn.status !== "running") { rate = null; return; }
|
||||
const completion = turn.usage?.completion_tokens;
|
||||
const now = Date.now();
|
||||
if (completion != null && lastTokens && now > lastTokens.at) {
|
||||
const delta = completion - lastTokens.completion;
|
||||
const secs = (now - lastTokens.at) / 1000;
|
||||
if (delta >= 0 && secs > 0) rate = Math.round(delta / secs);
|
||||
}
|
||||
if (completion != null) lastTokens = { at: now, completion };
|
||||
});
|
||||
|
||||
const running = $derived(chat.turn?.status === "running");
|
||||
const turnLabel = $derived(chat.turn ? `TURN ${String(chat.turn.id ?? "").slice(0, 6).toUpperCase()}` : "");
|
||||
const ctx = $derived(chat.turn?.usage?.prompt_tokens != null
|
||||
? `${(chat.turn.usage.prompt_tokens / 1000).toFixed(1)}k` : null);
|
||||
</script>
|
||||
|
||||
<div class="spine mono">
|
||||
{#if running}
|
||||
<span class="spine-turn active"><i class="pulse-dot" style="background:var(--accent);box-shadow:0 0 10px var(--accent)"></i>{turnLabel} · STREAMING</span>
|
||||
{#if rate != null}<span class="spine-rate">▲ {rate} tok/s</span>{/if}
|
||||
{#if ctx}<span>ctx {ctx}</span>{/if}
|
||||
{:else if chat.turn}
|
||||
<span class="spine-turn idle"><i class="pulse-dot" style="background:var(--signal);animation:none"></i>IDLE</span>
|
||||
<span>最近 {turnLabel}</span>
|
||||
{:else}
|
||||
<span class="spine-turn idle"><i class="pulse-dot" style="background:var(--signal);animation:none"></i>READY</span>
|
||||
{/if}
|
||||
<span class="spine-right">
|
||||
<span class:spine-ok={chat.connected} class:spine-down={!chat.connected}>{chat.connected ? "已连接" : "重连中"}</span>
|
||||
{#if version}<span>{version}</span>{/if}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.spine { display: flex; align-items: center; gap: 14px; font-size: 10.5px; color: var(--muted);
|
||||
background: var(--spine-bg); border-bottom: 1px solid var(--line); padding: 8px 16px; }
|
||||
.spine-turn { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; }
|
||||
.spine-turn.active { color: var(--accent); }
|
||||
.spine-turn.idle { color: var(--signal); }
|
||||
.spine-rate { color: var(--signal); }
|
||||
.spine-right { margin-left: auto; display: inline-flex; gap: 14px; color: var(--faint); }
|
||||
.spine-ok { color: var(--signal); }
|
||||
.spine-down { color: var(--warning); }
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user