From d1285f6581e26b309cbaeb5b5df25eaf65542b7e Mon Sep 17 00:00:00 2001 From: Yash Datta Date: Tue, 25 Aug 2026 12:34:17 +0800 Subject: [PATCH] fix: size the 1M context window for the bracket alias form (opus[1m]) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `contextWindowForModel` matched only the `-1m` suffix, so the bracket form Claude Code actually emits — `opus[1m]`, `claude-opus-5[1m]` — fell through to the conservative 200k default. Asking EXPLICITLY for the 1M variant therefore sized the window WORSE than the bare `opus` alias, which resolves to 1M. Observed on a live session pinned to `opus[1m]`: codeoid computed a 200k window against ~999k of real usage. Affected consumers: - the percent-of-window figure on SessionInfo (session.ts) — reads ~500% - the fork / provider-switch seed budget (seedBudgetChars via targetContextWindow) — 5x too small, so history seeds over-truncate Auto-rotate is NOT affected: decideRotation is passed the static `Session.CONTEXT_WINDOW` (1M), not this per-model resolution. This also did NOT cause the "prompt is too long" overflow seen on that session — that has a separate cause (compaction firing reactively after the API error rather than proactively). This is an independent defect surfaced while investigating it. Co-Authored-By: Claude Opus 5 (1M context) --- src/daemon/context-windows.test.ts | 17 +++++++++++++++++ src/daemon/context-windows.ts | 9 ++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/daemon/context-windows.test.ts b/src/daemon/context-windows.test.ts index 0ca6ebc..b1f2e79 100644 --- a/src/daemon/context-windows.test.ts +++ b/src/daemon/context-windows.test.ts @@ -35,6 +35,23 @@ describe("contextWindowForModel", () => { expect(contextWindowForModel("claude-sonnet-4-5-1m")).toBe(ONE_MILLION_CONTEXT); }); + test("bracket [1m] form -> 1M (the form Claude Code actually emits)", () => { + // Regression: these resolved to 200k, so asking EXPLICITLY for the 1M + // variant sized the window WORSE than the bare `opus` alias — observed on + // a live session running `opus[1m]`, which reported ~500% occupancy and a + // 5x-too-small fork seed budget. + expect(contextWindowForModel("opus[1m]")).toBe(ONE_MILLION_CONTEXT); + expect(contextWindowForModel("sonnet[1m]")).toBe(ONE_MILLION_CONTEXT); + expect(contextWindowForModel("claude-opus-5[1m]")).toBe(ONE_MILLION_CONTEXT); + // Case-insensitive, like every other branch. + expect(contextWindowForModel("OPUS[1M]")).toBe(ONE_MILLION_CONTEXT); + }); + + test("haiku stays 200k in bracket form too", () => { + // haiku has no 1M variant; a bracket suffix must not manufacture one. + expect(contextWindowForModel("haiku")).toBe(DEFAULT_CONTEXT_WINDOW); + }); + test("unknown claude model -> conservative 200k miss", () => { expect(contextWindowForModel("claude-sonnet-4-0")).toBe(DEFAULT_CONTEXT_WINDOW); expect(contextWindowForModel("custom-model")).toBe(DEFAULT_CONTEXT_WINDOW); diff --git a/src/daemon/context-windows.ts b/src/daemon/context-windows.ts index fea9cc3..33b7527 100644 --- a/src/daemon/context-windows.ts +++ b/src/daemon/context-windows.ts @@ -51,7 +51,14 @@ export function contextWindowForModel(modelId: string | undefined | null): numbe for (const family of ONE_MILLION_FAMILIES) { if (m.includes(family)) return ONE_MILLION_CONTEXT; } - if (m.includes("-1m")) return ONE_MILLION_CONTEXT; + // The 1M variant appears in two forms: the suffix on a full model id + // (`claude-opus-4-5-1m`) and the BRACKET form Claude Code uses on aliases + // and ids alike (`opus[1m]`, `claude-opus-5[1m]`). Matching only the former + // meant an EXPLICIT 1M request resolved to 200k while the bare `opus` alias + // correctly resolved to 1M — inverting the caller's intent, and under-sizing + // the window that drives the percent-of-window display, the fork seed budget + // (seedBudgetChars), and auto-rotate occupancy. + if (m.includes("-1m") || m.includes("[1m]")) return ONE_MILLION_CONTEXT; // Aliases (matching the daemon's model resolver: opus → Opus 4.8, // sonnet → Sonnet 5 — both 1M; haiku → Haiku 4.5 at 200k).