fix: preserve dynamic custom provider semantics
maintainer edit: treat arbitrary custom provider names as direct OpenAI-compatible providers, validate their api_type consistently, and avoid Pydantic instance-field warnings in fallback routing.
This commit is contained in:
@@ -664,6 +664,30 @@ def test_make_provider_passes_extra_headers_to_custom_provider():
|
||||
assert kwargs["default_headers"]["x-session-affinity"] == "sticky-session"
|
||||
|
||||
|
||||
def test_make_provider_treats_dynamic_custom_provider_as_direct():
|
||||
config = Config.model_validate(
|
||||
{
|
||||
"agents": {"defaults": {"provider": "my-company-api", "model": "gpt-4o-mini"}},
|
||||
"providers": {
|
||||
"my-company-api": {
|
||||
"apiBase": "https://example.com/v1",
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
with patch("nanobot.providers.openai_compat_provider.AsyncOpenAI") as mock_async_openai:
|
||||
provider = make_provider(config)
|
||||
asyncio.run(provider._ensure_client())
|
||||
|
||||
assert provider.get_default_model() == "gpt-4o-mini"
|
||||
assert provider._spec.name == "my_company_api"
|
||||
assert provider._spec.is_direct is True
|
||||
kwargs = mock_async_openai.call_args.kwargs
|
||||
assert kwargs["api_key"] == "no-key"
|
||||
assert kwargs["base_url"] == "https://example.com/v1"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_agent_runtime(tmp_path):
|
||||
"""Mock agent command dependencies for focused CLI tests."""
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import warnings
|
||||
|
||||
import pytest
|
||||
|
||||
from nanobot.config.schema import Config
|
||||
@@ -47,6 +49,35 @@ def test_provider_api_type_is_openai_only() -> None:
|
||||
}
|
||||
})
|
||||
|
||||
with pytest.raises(ValueError, match="only supported"):
|
||||
Config.model_validate({
|
||||
"providers": {
|
||||
"my-company-api": {
|
||||
"apiBase": "https://example.test/v1",
|
||||
"apiType": "responses",
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def test_custom_provider_fallback_uses_model_extra_without_pydantic_warnings() -> None:
|
||||
config = Config.model_validate({
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": "unmatched-model",
|
||||
}
|
||||
},
|
||||
"providers": {
|
||||
"my-company-api": {
|
||||
"apiBase": "https://example.test/v1",
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("error")
|
||||
assert config.get_provider_name() == "my-company-api"
|
||||
|
||||
|
||||
def test_legacy_defaults_config_without_presets_still_resolves() -> None:
|
||||
config = Config.model_validate({
|
||||
|
||||
Reference in New Issue
Block a user