Free mode: wrong context window/max-output everywhere (catalog hardcode, footer fallback, compact heuristic) — real registry values never consulted
Author: 7jrxt42BxFZo4iAnN4CXCreated Aug 22, 2026Updated Aug 22, 2026
Environment
- Claurst master @
595b0eb(built as0.1.7.r85.g595b0eb); the same code paths exist in v0.1.7 - OS: Arch Linux, kitty/tmux
- Provider/model: Free Mode, pinned
opencode-zen/x-preview-f-free(real limits per models.devopencode/x-preview-f-free: context 1,000,000 / output 131,072)
Summary
In Free mode the effective context window ends up wrong in three independent
places, because none of them consult ModelRegistry/models.dev for the actual
(upstream, model) pair, and models.dev has no opencode-zen entry at all:
| Consumer | Source of the window | Value seen |
|---|---|---|
Footer / token warnings — App::refresh_context_window_size() (crates/tui/src/app.rs:1921) |
registry miss → hardcoded fallback table | 128_000 |
Auto-compact sizing — compact::resolve_context_window() (crates/query/src/compact.rs:851) |
registry miss → Claude-only name heuristic | 100_000 |
/model picker — Free provider catalog() (crates/api/src/providers/free.rs:374,389) |
constants for every upstream model | 128_000 / max_output 8_192 |
So for a 1M-context model the footer claims 128k, auto-compact was sized from a
~100k heuristic, and the picker lists every free upstream model as 128k/8k —
including e.g. google/gemini-2.5-flash (real: 1M) or the Zen default
minimax-m2.5-free (real: 204,800).
Root cause
free.rscatalog()passes literal128_000/8_192for all chained upstream models instead of resolving them per(upstream_id, model)from the registry.refresh_context_window_size()only strips the active provider prefix and then doesregistry.get("free", "<model-id>"). It does not try the embedded"provider/model"split the wayresolve_context_window()does (compact.rs:867-873), so the two consumers derive different registry keys for the same model.- models.dev has no
opencode-zenprovider entry; Zen gateway models are listed under provider idopencode. Registry lookups keyed byopencode-zen/<model>therefore always miss.
Steps to reproduce
/connect→ Free Mode, add a Zen-capable key, pinopencode-zen/x-preview-f-free- Footer shows
Nk/128000; before any override, compaction sizing came from the 100k heuristic /modellists the entry as 128k / 8k output- Cross-check models.dev:
opencode/x-preview-f-free= 1,000,000 / 131,072
Workaround (verified working)
Duplicate the metadata override under both key schemas in settings.json
(the registry synthesizes entries for unknown keys):
{
"modelOverrides": {
"opencode-zen/x-preview-f-free": { "contextWindow": 1000000, "maxOutputTokens": 131072 },
"free/opencode-zen/x-preview-f-free": { "contextWindow": 1000000, "maxOutputTokens": 131072 }
}
}##Suggested fix
- In the Free catalog, resolve context_window / max_output_tokens per (upstream_id, default_model) from ModelRegistry, keeping the current constants only as last-resort defaults (reuse the existing MIN_PLAUSIBLE_REGISTRY_WINDOW plausibility guard).
- Make App::refresh_context_window_size() delegate to compact::resolve_context_window() so both consumers share one key-derivation path instead of maintaining parallel lookup logic.
- (Upstream data) file against models.dev: missing opencode-zen entry.
Happy to test a patch.
Source: Kuberwastaken/claurst