diff options
| author | Adam Malczewski <[email protected]> | 2026-06-02 13:25:23 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-02 13:25:23 +0900 |
| commit | 6433cc42de1ceca7210e2b64ad3b98b3a5ce7d02 (patch) | |
| tree | 78b30dedd471ab76177b3631a956ab160615e303 /packages/frontend/src/lib/context-window.ts | |
| parent | 3f629a8469fe483243671e1ca15582a111e96541 (diff) | |
| download | dispatch-6433cc42de1ceca7210e2b64ad3b98b3a5ce7d02.tar.gz dispatch-6433cc42de1ceca7210e2b64ad3b98b3a5ce7d02.zip | |
feat(context-window): show current/max context usage per tab/model
Add a 'Context Window' sidebar view showing the live context occupancy
(latest request's input+output) against the model's maximum context
window, resolved dynamically from the models.dev catalog.
- core: models.dev catalog module (resolveContextLimit) with disk cache,
TTL, stale-fallback + offline penalty memo; null for unknown models.
- api: GET /models/context-limit?provider=&modelId=.
- frontend: ContextWindowPanel + computeContextUsage helper; App resolves
+ caches the active model's max (anthropic/opencode-anthropic only);
percent shown to 2 decimals; degrades to bare token count when max
unknown.
- tests: core catalog (13), api route (3), frontend helper (6).
Diffstat (limited to 'packages/frontend/src/lib/context-window.ts')
| -rw-r--r-- | packages/frontend/src/lib/context-window.ts | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/packages/frontend/src/lib/context-window.ts b/packages/frontend/src/lib/context-window.ts new file mode 100644 index 0000000..c4321f8 --- /dev/null +++ b/packages/frontend/src/lib/context-window.ts @@ -0,0 +1,37 @@ +import type { CacheStats } from "./types.js"; + +/** + * Context-window occupancy for the current tab/model. + * + * `current` is the size of the model's context on the MOST RECENT request — + * the last turn's full prompt (`inputTokens`, which already includes cached + * tokens for Anthropic) plus what the model generated that turn + * (`outputTokens`). This mirrors how opencode derives context fullness from + * the last assistant message, and reflects what actually occupies the model's + * window — NOT the session-cumulative totals shown by the Cache Rate view. + * + * `max` is the model's maximum context window from models.dev (or `null` when + * unknown). `percent` is `current / max * 100` clamped to [0, 100] (unrounded; + * the UI decides the displayed precision), or `null` when + * `max` is unknown — in which case the UI shows the bare token count with no + * denominator or progress bar. + */ +export interface ContextUsage { + current: number; + max: number | null; + percent: number | null; +} + +export function computeContextUsage( + cacheStats: CacheStats | null | undefined, + contextLimit: number | null | undefined, +): ContextUsage { + const last = cacheStats?.last ?? null; + const current = last ? last.inputTokens + last.outputTokens : 0; + const max = typeof contextLimit === "number" && contextLimit > 0 ? contextLimit : null; + // Precise (unrounded) percentage clamped to [0, 100]; the UI formats the + // decimal places. Kept unrounded so small contexts against huge windows + // (e.g. a few thousand tokens vs. 1,000,000) still read non-zero. + const percent = max ? Math.max(0, Math.min(100, (current / max) * 100)) : null; + return { current, max, percent }; +} |
