fix(suggest-compact): recognize large-window model families without a [1m] marker (#2468)

* fix(suggest-compact): recognize large-window model families without a [1m] marker

resolveContextWindowTokens() only detected a 1M window via the env
override, the [1m] model-id marker, or observed tokens already above
200k. Large-window models whose ids carry none of these (e.g.
claude-fable-5) were misclassified as 200k windows, overstating
context usage ~5x in the compact suggestion.

Add a known-model-family substring table (claude-fable-5,
claude-mythos-5) checked after the env override and [1m] marker and
before the token-count heuristic. Env overrides still win, and unknown
model ids still fall back to the 200k default.

Closes #2461

* fix(suggest-compact): anchor known-model-family match at a token boundary

Unanchored substring matching would misclassify a hypothetical smaller
tier sharing a known family prefix (e.g. claude-fable-5-mini) as a 1M
window. Require the family id to end at a token boundary: end of id, a
delimiter, or a dated/versioned suffix (-20260115). Alphanumeric
continuations and letter suffixes no longer match.

Addresses CodeRabbit/Greptile review on #2468
This commit is contained in:
Girish Kanjiyani 2026-07-22 12:17:11 -04:00 committed by GitHub
parent e7b3ba07bb
commit cd39df154c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 69 additions and 3 deletions

View file

@ -180,6 +180,36 @@ test('detects a 1M window when observed tokens exceed 200k (marker dropped)', ()
assert.strictEqual(resolveContextWindowTokens(220000, 'claude-opus-4-5'), LARGE_CONTEXT_WINDOW_TOKENS);
});
test('recognizes claude-fable-5 as a 1M window without a [1m] marker or 200k+ tokens (#2461)', () => {
assert.strictEqual(resolveContextWindowTokens(187000, 'claude-fable-5'), LARGE_CONTEXT_WINDOW_TOKENS);
});
test('recognizes claude-mythos-5 as a 1M window from the known-model table (#2461)', () => {
assert.strictEqual(resolveContextWindowTokens(50000, 'claude-mythos-5'), LARGE_CONTEXT_WINDOW_TOKENS);
});
test('recognizes dated/prefixed variants of known large-window model ids (#2461)', () => {
assert.strictEqual(resolveContextWindowTokens(50000, 'us.anthropic.claude-fable-5-20260115-v1:0'), LARGE_CONTEXT_WINDOW_TOKENS);
});
test('env window override still wins over the known-model table (#2461)', () => {
process.env.ECC_CONTEXT_WINDOW_TOKENS = '400000';
try {
assert.strictEqual(resolveContextWindowTokens(50000, 'claude-fable-5'), 400000);
} finally {
delete process.env.ECC_CONTEXT_WINDOW_TOKENS;
}
});
test('does not match hypothetical smaller tiers sharing a known-family prefix (#2461)', () => {
assert.strictEqual(resolveContextWindowTokens(50000, 'claude-fable-5-mini'), STANDARD_CONTEXT_WINDOW_TOKENS);
assert.strictEqual(resolveContextWindowTokens(50000, 'claude-mythos-5-haiku-20260201'), STANDARD_CONTEXT_WINDOW_TOKENS);
});
test('keeps the 200k default for unknown model ids at low token counts (no false positives, #2461)', () => {
assert.strictEqual(resolveContextWindowTokens(187000, 'claude-haiku-4-5-20251001'), STANDARD_CONTEXT_WINDOW_TOKENS);
});
test('treats an empty model id as standard window', () => {
assert.strictEqual(resolveContextWindowTokens(100000, ''), STANDARD_CONTEXT_WINDOW_TOKENS);
});