mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-04 08:28:36 +00:00
fix(providers): respect explicit cloud namespaces
This commit is contained in:
parent
5eb818e800
commit
e1894d6f0b
@ -504,6 +504,7 @@ class Config(BaseSettings):
|
||||
model_normalized = model_lower.replace("-", "_")
|
||||
model_prefix = model_lower.split("/", 1)[0] if "/" in model_lower else ""
|
||||
normalized_prefix = model_prefix.replace("-", "_")
|
||||
prefixed_provider = find_by_name(model_prefix) if model_prefix else None
|
||||
|
||||
def _kw_matches(kw: str) -> bool:
|
||||
kw = kw.lower()
|
||||
@ -540,8 +541,15 @@ class Config(BaseSettings):
|
||||
# honor a local keyword match when the user has actually
|
||||
# configured that local endpoint via `api_base` — mirrors the
|
||||
# gate already used by the local-fallback loop below.
|
||||
if spec.is_local and not p.api_base:
|
||||
continue
|
||||
if spec.is_local:
|
||||
# A qualified model belongs to its explicit provider or a
|
||||
# gateway fallback, never to a different local provider
|
||||
# whose model-family keyword happens to match.
|
||||
foreign_prefix = bool(
|
||||
prefixed_provider is not None and prefixed_provider.name != spec.name
|
||||
)
|
||||
if not p.api_base or foreign_prefix:
|
||||
continue
|
||||
if spec.is_oauth or spec.is_local or spec.is_direct or p.api_key:
|
||||
return p, spec.name
|
||||
|
||||
@ -550,16 +558,17 @@ class Config(BaseSettings):
|
||||
# Prefer providers whose detect_by_base_keyword matches the configured api_base
|
||||
# (e.g. Ollama's "11434" in "http://localhost:11434") over plain registry order.
|
||||
local_fallback: tuple[ProviderConfig, str] | None = None
|
||||
for spec in PROVIDERS:
|
||||
if not spec.is_local:
|
||||
continue
|
||||
p = getattr(self.providers, spec.name, None)
|
||||
if not (p and p.api_base):
|
||||
continue
|
||||
if spec.detect_by_base_keyword and spec.detect_by_base_keyword in p.api_base:
|
||||
return p, spec.name
|
||||
if local_fallback is None:
|
||||
local_fallback = (p, spec.name)
|
||||
if prefixed_provider is None:
|
||||
for spec in PROVIDERS:
|
||||
if not spec.is_local:
|
||||
continue
|
||||
p = getattr(self.providers, spec.name, None)
|
||||
if not (p and p.api_base):
|
||||
continue
|
||||
if spec.detect_by_base_keyword and spec.detect_by_base_keyword in p.api_base:
|
||||
return p, spec.name
|
||||
if local_fallback is None:
|
||||
local_fallback = (p, spec.name)
|
||||
if local_fallback:
|
||||
return local_fallback
|
||||
|
||||
|
||||
@ -1196,6 +1196,27 @@ def test_config_bare_nemotron_still_auto_routes_to_configured_ollama():
|
||||
assert config.get_api_base() == "http://localhost:11434/v1"
|
||||
|
||||
|
||||
def test_config_cloud_nemotron_is_not_hijacked_by_configured_ollama():
|
||||
"""An explicit cloud namespace takes precedence over local keywords."""
|
||||
config = Config.model_validate(
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"provider": "auto",
|
||||
"model": "nvidia/nemotron-3-super-120b-a12b",
|
||||
}
|
||||
},
|
||||
"providers": {
|
||||
"ollama": {"apiBase": "http://localhost:11434/v1"},
|
||||
"openrouter": {"apiKey": "sk-or-test"},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
assert config.get_provider_name() == "openrouter"
|
||||
assert config.get_api_base() == "https://openrouter.ai/api/v1"
|
||||
|
||||
|
||||
def test_openai_compat_provider_passes_model_through():
|
||||
from nanobot.providers.openai_compat_provider import OpenAICompatProvider
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user