mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-31 00:03:01 +03:00
fix(providers): preserve legacy OrcaRouter custom configs
This commit is contained in:
@@ -49,6 +49,30 @@ def _provider_extra_headers(
|
||||
return headers or None
|
||||
|
||||
|
||||
def _provider_spec_for_config(
|
||||
provider_name: str,
|
||||
provider_config: ProviderConfig | None,
|
||||
) -> ProviderSpec | None:
|
||||
spec = find_by_name(provider_name)
|
||||
if (
|
||||
spec is not None
|
||||
and spec.name == "orcarouter"
|
||||
and provider_config is not None
|
||||
and provider_config.api_base
|
||||
and provider_config.api_base.rstrip("/").lower()
|
||||
!= spec.default_api_base.rstrip("/").lower()
|
||||
):
|
||||
# Before OrcaRouter became a built-in provider, this name was valid for a
|
||||
# dynamic custom provider. Preserve that provider's model-prefix behavior
|
||||
# when an existing config points the name at a different endpoint.
|
||||
return create_dynamic_spec(
|
||||
provider_name,
|
||||
display_name=provider_config.display_name or "",
|
||||
thinking_style=provider_config.thinking_style or "",
|
||||
)
|
||||
return spec
|
||||
|
||||
|
||||
def _resolve_provider_setup(
|
||||
config: Config,
|
||||
*,
|
||||
@@ -61,7 +85,7 @@ def _resolve_provider_setup(
|
||||
p = config.get_provider(model, preset=preset)
|
||||
if not provider_name:
|
||||
raise ValueError(f"No provider is configured for model '{model}'.")
|
||||
spec = find_by_name(provider_name)
|
||||
spec = _provider_spec_for_config(provider_name, p)
|
||||
if not spec and p:
|
||||
if not p.api_base:
|
||||
raise ValueError(f"Provider '{provider_name}' requires api_base in config.")
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
from nanobot.config.schema import Config, ProvidersConfig
|
||||
from nanobot.providers.factory import make_provider
|
||||
from nanobot.providers.openai_compat_provider import OpenAICompatProvider
|
||||
from nanobot.providers.registry import PROVIDERS, find_by_name
|
||||
|
||||
@@ -55,7 +56,7 @@ def test_orcarouter_forced_provider_uses_default_api_base() -> None:
|
||||
assert config.get_api_base("deepseek/deepseek-chat") == "https://api.orcarouter.ai/v1"
|
||||
|
||||
|
||||
def test_orcarouter_gateway_routes_unprefixed_models_when_configured() -> None:
|
||||
def test_orcarouter_gateway_routes_auto_model_when_configured() -> None:
|
||||
config = Config.model_validate({
|
||||
"providers": {
|
||||
"orcarouter": {
|
||||
@@ -74,6 +75,39 @@ def test_orcarouter_gateway_routes_unprefixed_models_when_configured() -> None:
|
||||
assert config.get_api_base("orcarouter/auto") == "https://api.orcarouter.ai/v1"
|
||||
|
||||
|
||||
def test_legacy_custom_provider_named_orcarouter_keeps_prefix_stripping() -> None:
|
||||
config = Config.model_validate({
|
||||
"providers": {
|
||||
"orcarouter": {
|
||||
"apiKey": "legacy-test-key",
|
||||
"apiBase": "https://legacy-gateway.example/v1",
|
||||
},
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": "orcarouter/custom-model",
|
||||
"provider": "orcarouter",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
with patch("nanobot.providers.openai_compat_provider.AsyncOpenAI"):
|
||||
provider = make_provider(config)
|
||||
|
||||
assert isinstance(provider, OpenAICompatProvider)
|
||||
assert provider.api_base == "https://legacy-gateway.example/v1"
|
||||
kwargs = provider._build_kwargs(
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
tools=None,
|
||||
model="orcarouter/custom-model",
|
||||
max_tokens=1024,
|
||||
temperature=0.7,
|
||||
reasoning_effort=None,
|
||||
tool_choice=None,
|
||||
)
|
||||
assert kwargs["model"] == "custom-model"
|
||||
|
||||
|
||||
def test_orcarouter_preserves_model_api_id() -> None:
|
||||
spec = find_by_name("orcarouter")
|
||||
with patch("nanobot.providers.openai_compat_provider.AsyncOpenAI"):
|
||||
|
||||
Reference in New Issue
Block a user