harden #5511: canonicalise active provider for ownership set (latent alias bug)

Codex 3rd CORE (pre-existing latent bug the providers: scan exposes): the
_provider_models_set ownership lookup used the RAW config_provider (e.g. 'z-ai')
but _PROVIDER_MODELS is keyed by canonical slug ('zai'), so an aliased active
provider got an empty ownership set -> _skip_custom_providers guard-2 silently
failed -> another providers.<slug>.models entry could hijack an active-owned
model (verified: active z-ai + glm-5 + providers.openai.models.glm-5 -> openai).
Fix: canonicalise config_provider before the _PROVIDER_MODELS lookup (and reuse
the canonical slug for the scan's ownership guard). Regression test with an
aliased active provider (verified fail-without-fix).

This is the root-cause fix for the alias class — the ownership guard now holds
for every aliased provider (zai/kilo/etc.), not just the reported site.

Co-authored-by: akay64 <akay64@users.noreply.github.com>
This commit is contained in:
nesquena-hermes
2026-07-04 07:17:05 +00:00
parent f8c9f9e08c
commit 4399ff02e0
2 changed files with 37 additions and 5 deletions
+11 -5
View File
@@ -2522,14 +2522,20 @@ def resolve_model_provider(model_id: str) -> tuple:
)
_default_model = model_cfg.get('default') if isinstance(model_cfg, dict) else None
# Owns model if it appears in the static catalog for the configured provider.
# _PROVIDER_MODELS is keyed by CANONICAL slug (e.g. 'zai', not the 'z-ai'
# alias a user may write in config), so canonicalise config_provider before
# the lookup — otherwise an aliased active provider gets an empty ownership
# set and _skip_custom_providers guard-2 silently fails, letting another
# providers.<slug>.models entry hijack an active-owned model (#5511).
_canon_config_provider = _canonicalise_provider_id(config_provider) if config_provider else ""
_provider_models_set: set[str] = set()
if (
config_provider is not None
and config_provider in _PROVIDER_MODELS
and isinstance(_PROVIDER_MODELS[config_provider], list)
_canon_config_provider
and _canon_config_provider in _PROVIDER_MODELS
and isinstance(_PROVIDER_MODELS[_canon_config_provider], list)
):
_provider_models_set = {
m.get('id', '') for m in _PROVIDER_MODELS[config_provider]
m.get('id', '') for m in _PROVIDER_MODELS[_canon_config_provider]
if isinstance(m, dict) and isinstance(m.get('id'), str)
}
_skip_custom_providers = (
@@ -2577,7 +2583,7 @@ def resolve_model_provider(model_id: str) -> tuple:
# active provider (#5511 gate finding — e.g. active ai-gateway + default
# gpt-5 was being pulled to providers.openai.models.gpt-5). In that case
# restrict the scan to the active provider's own canonical slug.
_active_slug = _canonicalise_provider_id(config_provider) if config_provider else ""
_active_slug = _canon_config_provider
for slug, pdef in providers_cfg.items():
if not isinstance(pdef, dict):
continue
+26
View File
@@ -845,3 +845,29 @@ def test_providers_scan_active_provider_own_entry_still_matches_5511():
)
assert provider == 'myprov', f"active provider's own entry must match; got {provider!r}"
assert base_url == 'https://my.example/v1'
def test_providers_scan_ownership_guard_canonicalises_aliased_active_provider_5511():
"""An ALIASED active provider (e.g. 'z-ai' → canonical 'zai') must still be
recognized as owning its catalog models, so another providers.<slug>.models
entry can't hijack an active-owned model (#5511 latent-bug gate finding —
_provider_models_set was built with the raw alias, missing the canonical
_PROVIDER_MODELS key, so the ownership guard silently failed)."""
import api.config as config
# Pick a real catalog model id owned by the canonical 'zai' provider.
zai_models = config._PROVIDER_MODELS.get('zai') or []
zai_ids = [m.get('id') for m in zai_models if isinstance(m, dict) and m.get('id')]
if not zai_ids:
import pytest
pytest.skip("no zai catalog models to exercise the alias ownership guard")
owned = zai_ids[0]
model, provider, base_url = _resolve_with_providers(
owned,
{'openai': {'models': [owned]}},
provider='z-ai', # aliased form the user may write in config
)
assert config._canonicalise_provider_id('z-ai') == 'zai'
assert provider == 'z-ai', (
"aliased active provider (z-ai→zai) that owns the model must not be "
f"hijacked by providers.openai.models; got {provider!r}"
)