mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-06-15 07:14:08 +00:00
fix: reject custom provider alias conflicts
maintainer edit: reject arbitrary custom provider keys that normalize to built-in provider names so runtime and WebUI settings cannot disagree about whether a provider is dynamic or built in.
This commit is contained in:
parent
b2d00a4ce0
commit
af9f9ebfd7
@ -234,7 +234,7 @@ If you have more than one custom OpenAI-compatible endpoint, give each endpoint
|
||||
}
|
||||
```
|
||||
|
||||
Custom provider keys are treated as direct OpenAI-compatible providers. `apiBase` is required because nanobot cannot know the endpoint URL. `apiKey` is optional for local servers or private proxies that do not require one. Do not set `apiType` on custom provider keys; `apiType` is only for `providers.openai`.
|
||||
Custom provider keys are treated as direct OpenAI-compatible providers. `apiBase` is required because nanobot cannot know the endpoint URL. `apiKey` is optional for local servers or private proxies that do not require one. Choose a name that does not conflict with a built-in provider name or alias, such as `openai`, `openai-codex`, `github-copilot`, or `lm-studio`. Do not set `apiType` on custom provider keys; `apiType` is only for `providers.openai`.
|
||||
|
||||
This named custom provider path is not for Anthropic-compatible endpoints. For Anthropic-compatible proxies, use `providers.anthropic.apiBase` and set the preset provider to `anthropic`.
|
||||
|
||||
|
||||
@ -245,7 +245,14 @@ class ProvidersConfig(Base):
|
||||
def convert_extra_providers(self):
|
||||
"""Convert extra fields (custom providers) to ProviderConfig objects."""
|
||||
if self.model_extra:
|
||||
from nanobot.providers.registry import find_by_name
|
||||
|
||||
for key, value in self.model_extra.items():
|
||||
if spec := find_by_name(key):
|
||||
raise ValueError(
|
||||
f"providers.{key} conflicts with built-in provider {spec.name!r}; "
|
||||
"use the built-in provider key or choose a different custom provider name"
|
||||
)
|
||||
if isinstance(value, dict):
|
||||
self.model_extra[key] = ProviderConfig.model_validate(value)
|
||||
return self
|
||||
|
||||
@ -60,6 +60,18 @@ def test_provider_api_type_is_openai_only() -> None:
|
||||
})
|
||||
|
||||
|
||||
@pytest.mark.parametrize("provider_name", ["openai-codex", "github-copilot", "lm-studio"])
|
||||
def test_dynamic_custom_provider_rejects_builtin_provider_aliases(provider_name: str) -> None:
|
||||
with pytest.raises(ValueError, match="conflicts with built-in provider"):
|
||||
Config.model_validate({
|
||||
"providers": {
|
||||
provider_name: {
|
||||
"apiBase": "https://example.test/v1",
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def test_custom_provider_fallback_uses_model_extra_without_pydantic_warnings() -> None:
|
||||
config = Config.model_validate({
|
||||
"agents": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user