Repository navigation
fix: default an unknown model's context window to 1M, not 200k - #94
Merged
Merged
Conversation
An Opus 5 session read 6% of its context as 30% in the footer. The window the percent is measured against came from a table listing the 1M models; `opus-5` was not in it, so the read fell through to inferring a window from the token count — the smallest standard size the session still fit inside, which is 200k until a session passes 200k tokens. Adding the missing row would have fixed this launch and left the next one broken. The table's default was the actual bug: it enumerated the large windows and assumed small for anything unlisted, so every model release needed a release here to read right. Inverted. Haiku is the 200k exception and everything else is 1M, which is what a model released after the build reads with no new version. The bet is that an unknown id is a model newer than the binary rather than a legacy one, and it holds — every Claude generation since 4.6 ships at 1M. A token count past 200k disproves the Haiku guess (a window cannot hold more than its size) and widens, so a future Haiku at 1M corrects itself. That collapsed `modelWindows`, `contextWindows` and `contextWindowFor` into four lines. The deprecated ids the old table carried went with them: nothing in a provider's model picker offers them today, and the entries were noise. The tradeoff is that a session on a still-live 200k model outside the exception (Sonnet 4.5, Opus 4.5) now reads low — the widen guard only ever widens. Two tests changed because the contract did, not to stay green: an unlisted model now takes 1M instead of the smallest window that fits. The deprecated-model rows were dropped for the same reason as the code. The `CLAUDE.md` ceiling for this went too. That section carries what breaks if nobody knows it; an approximate readout does not qualify, and the mechanism now lives in the comment on `windowForModel` where it is read. Not done here, deliberately: reading the exact window per session. It exists only in the provider's status-line payload — a slot the user's own status line owns — and the Models API's `max_input_tokens` needs auth and network and still cannot see a window capped below the model's native size.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An Opus 5 session read 6% of its context as 30% in the footer.
What was wrong
The window the percent is measured against came from a table listing the 1M
models.
opus-5was not in it, so the read fell through to inferring a windowfrom the token count — the smallest standard size the session still fit inside,
which is 200k until a session passes 200k tokens. Hence 5×.
Adding the missing row would have fixed this launch and left the next one
broken. The table's default was the actual bug: it enumerated the large
windows and assumed small for anything unlisted, so every model release needed a
release here to read right.
What changed
Inverted. Haiku is the 200k exception, everything else is 1M:
The bet is that an unknown id is a model newer than the binary rather than a
legacy one, and it holds — every Claude generation since 4.6 ships at 1M. A
token count past 200k disproves the Haiku guess (a window cannot hold more than
its size) and widens, so a future Haiku at 1M corrects itself.
That collapsed
modelWindows,contextWindowsandcontextWindowForinto thefour lines above: 42 insertions, 70 deletions. The deprecated ids the old
table carried went with them — nothing in a provider's model picker offers them
today.
Two tests changed because the contract did, not to stay green: an unlisted model
now takes 1M instead of the smallest window that fits. The deprecated-model rows
were dropped for the same reason as the code.
The
CLAUDE.mdceiling for this went too. That section carries what breaks ifnobody knows it; an approximate readout does not qualify, and the mechanism now
lives in the comment on
windowForModel, where someone changing it will read it.Tradeoff
A session on a still-live 200k model outside the exception (Sonnet 4.5, Opus
4.5) now reads low. The widen guard only ever widens, never narrows. Accepted:
those are not what the providers spawn today, and under-reading a model nobody
runs beats a table that needs a release per model launch.
Not done here, deliberately
Reading the exact window per session. Checked and ruled out:
claudeCLImodelssubcommandcontext_window.context_window_size)max_input_tokens)So a 1M-capable model held at 200k still reads low. Same ceiling as before this
PR, now stated in the code rather than the prompt.
Test plan
go test ./...— 400 passgo vet ./...andgofmt -l .cleanGOOS=linux|darwin|windows go build ./... && go vet ./...task dev: footer reads ~6% on an Opus 5 session, not ~30% — verified manually before merge