Summary
utils/agents/detection.py gates agent model selection against a hardcoded CLAUDE_MODELS list, and the detected list overrides whatever is configured. A model the bundled claude binary supports but that postdates the cptr release cannot be selected at all — agent:claude-code/<model> fails to resolve and cptr falls back to an API model silently.
Filing this as a design question rather than a defect; the current behaviour is clearly intentional, and the version gating around it is well built. The issue is only that the list and the CLI ship on independent cadences.
Current shape (v0.9.15, L26–34)
CLAUDE_MODELS = [
"claude-fable-5",
"claude-opus-4-8",
"claude-opus-4-7",
"claude-opus-4-6",
"claude-opus-4-5",
"claude-sonnet-4-6",
"claude-haiku-4-5",
]
MIN_CLAUDE_FABLE_5 = (2, 1, 169)
MIN_CLAUDE_OPUS_4_8 = (2, 1, 154)
The MIN_CLAUDE_* gates show the intended mechanism is already there and works — a model is offered only when the detected CLI is new enough. The list itself is the part that has to be hand-edited to keep pace; between the v0.9.10 and v0.9.15 tags detection.py is the only one of these files that changed, which is consistent with it needing regular manual maintenance.
Why it bites
The bundled CLI can be updated independently of cptr (and is, frequently). When it gains a model the pinned list doesn't know about, the user's configured agent:claude-code/<model> silently resolves to something else. There is no warning — the fallback to an API model is indistinguishable from having configured an API model in the first place, which makes it hard to notice you are not running the agent you asked for.
Possible directions
- Let a configured model through when the bundled CLI accepts it, using the existing detection probe as the source of truth rather than the static list.
- Or keep the allowlist as-is and simply warn on silent fallback, so the failure is visible even if the behaviour doesn't change. This alone would remove most of the pain.
The second option is small and non-controversial if the first is a bigger design change than you want.
Summary
utils/agents/detection.pygates agent model selection against a hardcodedCLAUDE_MODELSlist, and the detected list overrides whatever is configured. A model the bundledclaudebinary supports but that postdates the cptr release cannot be selected at all —agent:claude-code/<model>fails to resolve and cptr falls back to an API model silently.Filing this as a design question rather than a defect; the current behaviour is clearly intentional, and the version gating around it is well built. The issue is only that the list and the CLI ship on independent cadences.
Current shape (v0.9.15, L26–34)
The
MIN_CLAUDE_*gates show the intended mechanism is already there and works — a model is offered only when the detected CLI is new enough. The list itself is the part that has to be hand-edited to keep pace; between thev0.9.10andv0.9.15tagsdetection.pyis the only one of these files that changed, which is consistent with it needing regular manual maintenance.Why it bites
The bundled CLI can be updated independently of cptr (and is, frequently). When it gains a model the pinned list doesn't know about, the user's configured
agent:claude-code/<model>silently resolves to something else. There is no warning — the fallback to an API model is indistinguishable from having configured an API model in the first place, which makes it hard to notice you are not running the agent you asked for.Possible directions
The second option is small and non-controversial if the first is a bigger design change than you want.