fix(model): repair bare custom-provider suffix on resolver slow path (#5225)
Mirror the #5128 fast-path suffix repair when profile context is present but requested_provider is omitted, which async delegation completion can trigger via process_wakeup. Co-authored-by: b3nw <b3nw@users.noreply.github.com>
This commit is contained in:
parent
c229243f6d
commit
da43de72b8
2 changed files with 59 additions and 0 deletions
|
|
@ -5578,6 +5578,24 @@ def _resolve_compatible_session_model_state(
|
|||
_target = _profile_default or default_model
|
||||
return _target, profile_provider, True
|
||||
|
||||
# Async server-side continuations (for example delegate_task completion
|
||||
# re-entry) can arrive here with profile context but without a usable
|
||||
# requested_provider, bypassing the fast-path custom-provider repair
|
||||
# above. If the profile's configured custom-provider default is a
|
||||
# slash-qualified model whose suffix matches the bare session model,
|
||||
# repair back to the profile default before the provider call (#5225).
|
||||
if (
|
||||
"/" not in model
|
||||
and _profile_default
|
||||
and "/" in _profile_default
|
||||
and _profile_default.rsplit("/", 1)[-1] == model
|
||||
and (
|
||||
_profile_provider_normalized == "custom"
|
||||
or str(profile_provider).startswith("custom:")
|
||||
)
|
||||
):
|
||||
return _profile_default, profile_provider, True
|
||||
|
||||
return model, profile_provider, False
|
||||
|
||||
if not model:
|
||||
|
|
|
|||
|
|
@ -82,6 +82,47 @@ class TestIssue5127CustomProviderBareSuffixRepair:
|
|||
assert mock_catalog.call_count == 0
|
||||
assert result == ("x-ai/grok-composer-2.5-fast", "custom:my-proxy", False)
|
||||
|
||||
def test_slow_path_repairs_bare_suffix_to_profile_default_for_custom_provider(self):
|
||||
"""Regression #5225: async continuations may arrive without usable model_provider."""
|
||||
from api.routes import _resolve_compatible_session_model_state
|
||||
|
||||
with patch("api.routes.get_available_models") as mock_catalog:
|
||||
mock_catalog.return_value = {
|
||||
"active_provider": "openrouter",
|
||||
"default_model": "openai/gpt-5.5",
|
||||
"groups": [],
|
||||
}
|
||||
result = _resolve_compatible_session_model_state(
|
||||
"grok-composer-2.5-fast",
|
||||
None,
|
||||
profile_provider="custom:my-proxy",
|
||||
profile_default_model="x-ai/grok-composer-2.5-fast",
|
||||
prefer_cached_catalog=True,
|
||||
)
|
||||
|
||||
assert mock_catalog.call_count == 1
|
||||
assert result == ("x-ai/grok-composer-2.5-fast", "custom:my-proxy", True)
|
||||
|
||||
def test_slow_path_does_not_rewrite_unrelated_bare_model_for_custom_provider(self):
|
||||
from api.routes import _resolve_compatible_session_model_state
|
||||
|
||||
with patch("api.routes.get_available_models") as mock_catalog:
|
||||
mock_catalog.return_value = {
|
||||
"active_provider": "openrouter",
|
||||
"default_model": "openai/gpt-5.5",
|
||||
"groups": [],
|
||||
}
|
||||
result = _resolve_compatible_session_model_state(
|
||||
"other-model",
|
||||
None,
|
||||
profile_provider="custom:my-proxy",
|
||||
profile_default_model="x-ai/grok-composer-2.5-fast",
|
||||
prefer_cached_catalog=True,
|
||||
)
|
||||
|
||||
assert mock_catalog.call_count == 1
|
||||
assert result == ("other-model", "custom:my-proxy", False)
|
||||
|
||||
def test_openai_codex_stale_openai_slash_still_uses_slow_path(self):
|
||||
"""Regression: openai/... under openai-codex must not take bare fast return."""
|
||||
from api.routes import _resolve_compatible_session_model_state
|
||||
|
|
|
|||
Loading…
Reference in a new issue