summaryrefslogtreecommitdiffhomepage
path: root/src/features
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-12 01:01:32 +0900
committerAdam Malczewski <[email protected]>2026-06-12 01:01:32 +0900
commit6bd7b39f6f53dd8f3743347a1cb72c2f74424dd8 (patch)
treeb41911099883e8386ea8edbd88d42911de401d27 /src/features
parentfd565a6555e8bc9f37f21cf9d900523ef3be531b (diff)
downloaddispatch-web-6bd7b39f6f53dd8f3743347a1cb72c2f74424dd8.tar.gz
dispatch-web-6bd7b39f6f53dd8f3743347a1cb72c2f74424dd8.zip
feat(metrics): consume contextSize — current context-usage readout
Backend context-size handoff: re-pin [email protected] / [email protected] (+ re-mirror .dispatch reference snapshots). Thread the optional contextSize through core/metrics (done fold + durable + selectCurrentContextSize: latest turn's defined value, undefined=>unknown never 0, durable-wins-over-live). Chat store exposes currentContextSize; ContextSizeBadge renders "N tokens in context" / "context size unknown" above the composer. GLOSSARY: add context size / context window. 533 tests green.
Diffstat (limited to 'src/features')
-rw-r--r--src/features/chat/index.ts1
-rw-r--r--src/features/chat/store.svelte.ts10
-rw-r--r--src/features/chat/ui/ContextSizeBadge.svelte20
3 files changed, 31 insertions, 0 deletions
diff --git a/src/features/chat/index.ts b/src/features/chat/index.ts
index 18ed693..adfb670 100644
--- a/src/features/chat/index.ts
+++ b/src/features/chat/index.ts
@@ -6,6 +6,7 @@ export type { ChatStore, ChatStoreDependencies } from "./store.svelte";
export { createChatStore } from "./store.svelte";
export { default as ChatView } from "./ui/ChatView.svelte";
export { default as Composer } from "./ui/Composer.svelte";
+export { default as ContextSizeBadge } from "./ui/ContextSizeBadge.svelte";
export { default as ModelSelector } from "./ui/ModelSelector.svelte";
/** Public module manifest — aggregated by the shell's "Loaded Modules" view. */
diff --git a/src/features/chat/store.svelte.ts b/src/features/chat/store.svelte.ts
index f4ad07b..6344aec 100644
--- a/src/features/chat/store.svelte.ts
+++ b/src/features/chat/store.svelte.ts
@@ -18,6 +18,7 @@ import {
applyDurableMetrics,
foldMetricsEvent,
initialMetricsState,
+ selectCurrentContextSize,
selectOrderedTurnMetrics,
} from "../../core/metrics";
import type { ConversationCache } from "../conversation-cache";
@@ -36,6 +37,12 @@ export interface ChatStore {
readonly messages: readonly ChatMessage[];
readonly chunks: readonly RenderedChunk[];
readonly turnMetrics: readonly TurnMetricsEntry[];
+ /**
+ * The conversation's current context size (tokens occupied) — the latest
+ * finalized turn's `contextSize`, or `undefined` ("unknown") when none is
+ * known yet. Never `0` for the unknown case.
+ */
+ readonly currentContextSize: number | undefined;
readonly pendingSync: boolean;
readonly error: string | null;
readonly model: string | undefined;
@@ -91,6 +98,9 @@ export function createChatStore(deps: ChatStoreDependencies): ChatStore {
get turnMetrics(): readonly TurnMetricsEntry[] {
return selectOrderedTurnMetrics(metrics);
},
+ get currentContextSize(): number | undefined {
+ return selectCurrentContextSize(metrics);
+ },
get pendingSync(): boolean {
return _pendingSync;
},
diff --git a/src/features/chat/ui/ContextSizeBadge.svelte b/src/features/chat/ui/ContextSizeBadge.svelte
new file mode 100644
index 0000000..475d54f
--- /dev/null
+++ b/src/features/chat/ui/ContextSizeBadge.svelte
@@ -0,0 +1,20 @@
+<script lang="ts">
+ import { formatContextSize } from "../../../core/metrics";
+
+ let {
+ contextSize,
+ }: {
+ // The conversation's current context size (tokens occupied), or `undefined`
+ // ("unknown") when no finalized turn has reported one yet. Never `0` for the
+ // unknown case — `formatContextSize` renders a placeholder instead.
+ contextSize: number | undefined;
+ } = $props();
+
+ const label = $derived(formatContextSize(contextSize));
+</script>
+
+<div class="px-4 pb-1 text-xs opacity-60" aria-live="polite">
+ <span title="The model's max context window is not reported yet — current usage only.">
+ {label}
+ </span>
+</div>