fix: custom/unknown model prefixes must not be stripped on provider switch — v0.50.100 (#752)

## Summary

Regression fix for #751.

Models with custom or unrecognized prefixes (e.g. `custom-provider/my-model`, `test/import-model`) were being incorrectly replaced with the active provider default. Root cause: `_normalize_provider_id("custom-provider")` matched the `"custom"` prefix and returned `"custom"`, which ≠ `active_provider` → normalization fired.

Two-part fix:
1. Add `"custom"` and `"openrouter"` to the `model_provider` exclusion set in `_resolve_compatible_session_model` (parallel to the existing `active_provider` guard)
2. Return `""` for unknown prefixes in `_normalize_provider_id` so the `if model_provider` truthiness check safely short-circuits

Adds a regression test covering `custom-provider/`, `test/`, `my-local-llm/`, and `lmstudio-community/` prefixes.

## Tests

1499 passed, 0 failures (was 2 failures before this fix)
This commit is contained in:
nesquena-hermes
2026-04-19 23:27:24 -07:00
committed by GitHub
parent 7f16a41a31
commit 81ba420716
3 changed files with 40 additions and 2 deletions

View File

@@ -183,7 +183,9 @@ def _normalize_provider_id(value: str | None) -> str:
):
if raw.startswith(prefix):
return normalized
return raw
# Unknown prefix — return empty so callers treat it as "no match" and pass
# the model through unchanged rather than incorrectly stripping it.
return ""
def _resolve_compatible_session_model(model_id: str | None) -> tuple[str, bool]:
@@ -217,7 +219,9 @@ def _resolve_compatible_session_model(model_id: str | None) -> tuple[str, bool]:
return model, False
model_provider = _normalize_provider_id(model[:slash])
if model_provider and model_provider != active_provider and default_model:
# Skip normalization for models on custom/openrouter namespaces — these are
# user-controlled and should never be silently replaced.
if model_provider and model_provider not in {"", "custom", "openrouter"} and model_provider != active_provider and default_model:
return default_model, True
return model, False