Skip to content

fix: strip provider prefix before matching configured default_model - #1283

Open
asans wants to merge 1825 commits into
1jehuang:masterfrom
asans:fix/default-model-prefix-strip
Open

asans wants to merge 1825 commits into
1jehuang:masterfrom
asans:fix/default-model-prefix-strip

Conversation

@asans

@asans asans commented Sep 16, 2026

Copy link
Copy Markdown

Problem

When config.provider.default_model is set to a provider-prefixed spec (e.g. claude-oauth:claude-sonnet-5, which is exactly what the model picker persists via /model -> "save as default"), running /login to re-authenticate or /refresh-model-list silently reverts the active model to the flagship default (Opus) instead of keeping the configured Sonnet model.

Root cause

provider_model_to_select_after_auth_with_configured_default in crates/jcode-base/src/auth/lifecycle.rs compares the configured default model directly against route.model from the live catalog:

if let Some(configured) = configured_model
    && routes.iter().any(|route| {
        route.available
            && route.model == configured
            && route_matches_activation(route, activation)
    })

route.model in the catalog is always the bare model id (e.g. claude-sonnet-5), but config.provider.default_model is persisted by the model picker as a full spec that may carry an explicit provider/credential prefix (e.g. claude-oauth:claude-sonnet-5, claude-api:claude-fable-5). The direct string comparison never matches when a prefix is present, so the "preserve the configured default" branch silently no-ops and falls through to the flagship-first fallback, which always prefers Opus.

The cold-start path (MultiProvider::set_config_default_model) already handles this correctly by checking explicit_model_provider_prefix before matching — this is why a fresh jcode launch respects the configured Sonnet default, but re-authenticating via /login or refreshing the catalog via /refresh-model-list does not.

Fix

Strip the provider prefix off the configured model (using the existing jcode_provider_core::selection::explicit_model_provider_prefix helper) before comparing against route.model.

Testing

  • Added post_auth_model_selection_preserves_provider_prefixed_configured_default, a regression test reproducing the exact reported scenario (prefixed config default + Claude re-auth), confirmed it fails on the old code and passes with the fix.
  • cargo test -p jcode-base --lib auth::lifecycle:: — 39/40 pass; the one pre-existing failure (every_model_login_provider_has_explicit_lifecycle_normalization, missing grok-build normalization) reproduces identically on master before this change and is unrelated.
  • Built and reloaded onto the fixed binary via self-dev to confirm the fix at runtime.

1jehuang and others added 30 commits August 25, 2026 21:18
Jcode and others added 15 commits September 12, 2026 18:47
…ibutors-20260913

Welcome pull requests from all contributors
config.provider.default_model is persisted by the model picker as a full
model spec that may carry an explicit provider/credential prefix (e.g.
"claude-oauth:claude-sonnet-5"), but route.model in the live catalog is
always the bare model id. The comparison in
provider_model_to_select_after_auth_with_configured_default compared the
raw prefixed string against route.model, which never matched, so the
"preserve configured default" branch silently no-op'd and execution fell
through to the flagship-first fallback (Opus) on every /login or
/refresh-model-list.

Strip the prefix via jcode_provider_core::selection::explicit_model_provider_prefix
before comparing. Added a regression test reproducing the exact scenario.
@greptile-apps

greptile-apps Bot commented Sep 16, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

Not safe to merge until configured provider and credential-route constraints are retained or validated during post-authentication default-model selection.

Findings

  1. P1 Credential Route Is Rewritten
Fix with agent prompt
### Issue 1
crates/jcode-base/src/auth/lifecycle.rs:238-242
When a configured default explicitly selects `claude-api:claude-sonnet-5`, this code removes the `claude-api` credential-route prefix and accepts the bare model during a Claude OAuth login. The later selection rebuild changes it to `claude-oauth:claude-sonnet-5`, so an API-key route configured by the user is silently replaced with OAuth credentials. Preserve the configured route constraint when matching the post-authentication catalog, or do not accept the configured default when it is incompatible with the activated route.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

This change normalizes provider-prefixed configured defaults before matching them to the post-authentication model catalog. A focused check shows that this can discard an explicitly configured Claude API-key route and rebuild the default as a Claude OAuth route, so the configured credential mode is not preserved.

Reviews (1) · Last reviewed commit: "fix: strip provider prefix before matchi..."

Comment on lines +238 to +242
let configured_bare = configured_model.map(|model| {
jcode_provider_core::selection::explicit_model_provider_prefix(model)
.map(|(_, _, bare)| bare)
.unwrap_or(model)
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Credential Route Is Rewritten

When a configured default explicitly selects claude-api:claude-sonnet-5, this code removes the claude-api credential-route prefix and accepts the bare model during a Claude OAuth login. The later selection rebuild changes it to claude-oauth:claude-sonnet-5, so an API-key route configured by the user is silently replaced with OAuth credentials. Preserve the configured route constraint when matching the post-authentication catalog, or do not accept the configured default when it is incompatible with the activated route.

Artifacts

Evidence from the check

  • This is the full temporary Rust test source executed against the changed selection and rebuild path, showing the configured API-key route is expected to become an OAuth route.

Evidence from the check

  • This is the exact shell command wrapper used to copy the temporary test into the crate, run Cargo, capture its status, and remove it afterward.

Command output from the check

  • Cargo executed one focused test successfully and printed the configured, selected, and rebuilt values, confirming the explicit API-key route changed to OAuth.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/jcode-base/src/auth/lifecycle.rs
Line: 238-242

Comment:
**Credential Route Is Rewritten**

When a configured default explicitly selects `claude-api:claude-sonnet-5`, this code removes the `claude-api` credential-route prefix and accepts the bare model during a Claude OAuth login. The later selection rebuild changes it to `claude-oauth:claude-sonnet-5`, so an API-key route configured by the user is silently replaced with OAuth credentials. Preserve the configured route constraint when matching the post-authentication catalog, or do not accept the configured default when it is incompatible with the activated route.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@1jehuang 1jehuang added area: config Configuration, defaults, and environment overrides. area: providers Model providers, API adapters, and provider authentication. size: S Focused change within one component; limited behavior change and few interactions. type: bug Fixes incorrect or broken behavior. and removed area: config Configuration, defaults, and environment overrides. area: providers Model providers, API adapters, and provider authentication. size: S Focused change within one component; limited behavior change and few interactions. type: bug Fixes incorrect or broken behavior. labels Sep 19, 2026
@github-actions github-actions Bot added area: config Configuration, defaults, and environment overrides. area: providers Model providers, API adapters, and provider authentication. size: S Focused change within one component; limited behavior change and few interactions. type: bug Fixes incorrect or broken behavior. labels Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: config Configuration, defaults, and environment overrides. area: providers Model providers, API adapters, and provider authentication. size: S Focused change within one component; limited behavior change and few interactions. type: bug Fixes incorrect or broken behavior.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants