From 78783400317281f8e3ee6680de056a6526f2f90e Mon Sep 17 00:00:00 2001 From: Matt von Rohr Date: Mon, 16 Mar 2026 08:13:43 +0100 Subject: [PATCH] feat(providers): add Mistral AI provider Register Mistral as a first-class provider with LiteLLM routing, MISTRAL_API_KEY env var, and https://api.mistral.ai/v1 default base. Includes schema field, registry entry, and tests. --- nanobot/config/schema.py | 1 + nanobot/providers/registry.py | 17 +++++++++++++++++ tests/test_mistral_provider.py | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 tests/test_mistral_provider.py diff --git a/nanobot/config/schema.py b/nanobot/config/schema.py index 5937b2e..9c841ca 100644 --- a/nanobot/config/schema.py +++ b/nanobot/config/schema.py @@ -73,6 +73,7 @@ class ProvidersConfig(Base): gemini: ProviderConfig = Field(default_factory=ProviderConfig) moonshot: ProviderConfig = Field(default_factory=ProviderConfig) minimax: ProviderConfig = Field(default_factory=ProviderConfig) + mistral: ProviderConfig = Field(default_factory=ProviderConfig) aihubmix: ProviderConfig = Field(default_factory=ProviderConfig) # AiHubMix API gateway siliconflow: ProviderConfig = Field(default_factory=ProviderConfig) # SiliconFlow (硅基流动) volcengine: ProviderConfig = Field(default_factory=ProviderConfig) # VolcEngine (火山引擎) diff --git a/nanobot/providers/registry.py b/nanobot/providers/registry.py index 42c1d24..825653f 100644 --- a/nanobot/providers/registry.py +++ b/nanobot/providers/registry.py @@ -399,6 +399,23 @@ PROVIDERS: tuple[ProviderSpec, ...] = ( strip_model_prefix=False, model_overrides=(), ), + # Mistral AI: OpenAI-compatible API at api.mistral.ai/v1. + ProviderSpec( + name="mistral", + keywords=("mistral",), + env_key="MISTRAL_API_KEY", + display_name="Mistral", + litellm_prefix="mistral", # mistral-large-latest → mistral/mistral-large-latest + skip_prefixes=("mistral/",), # avoid double-prefix + env_extras=(), + is_gateway=False, + is_local=False, + detect_by_key_prefix="", + detect_by_base_keyword="", + default_api_base="https://api.mistral.ai/v1", + strip_model_prefix=False, + model_overrides=(), + ), # === Local deployment (matched by config key, NOT by api_base) ========= # vLLM / any OpenAI-compatible local server. # Detected when config key is "vllm" (provider_name="vllm"). diff --git a/tests/test_mistral_provider.py b/tests/test_mistral_provider.py new file mode 100644 index 0000000..4011221 --- /dev/null +++ b/tests/test_mistral_provider.py @@ -0,0 +1,22 @@ +"""Tests for the Mistral provider registration.""" + +from nanobot.config.schema import ProvidersConfig +from nanobot.providers.registry import PROVIDERS + + +def test_mistral_config_field_exists(): + """ProvidersConfig should have a mistral field.""" + config = ProvidersConfig() + assert hasattr(config, "mistral") + + +def test_mistral_provider_in_registry(): + """Mistral should be registered in the provider registry.""" + specs = {s.name: s for s in PROVIDERS} + assert "mistral" in specs + + mistral = specs["mistral"] + assert mistral.env_key == "MISTRAL_API_KEY" + assert mistral.litellm_prefix == "mistral" + assert mistral.default_api_base == "https://api.mistral.ai/v1" + assert "mistral/" in mistral.skip_prefixes