mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-15 09:12:18 +00:00
feat: add MixRoute provider with model-specific endpoint routing
This commit is contained in:
parent
a713ed6bab
commit
79904d6869
6 changed files with 117 additions and 0 deletions
|
|
@ -1079,6 +1079,7 @@ openai_compatible_endpoints: Final[list[str]] = [
|
|||
"https://api.meta.ai/v1",
|
||||
"https://api.sailresearch.com/v1",
|
||||
"https://api.cognition.ai/v1",
|
||||
"https://api.mixroute.ai/v1",
|
||||
"https://inference.coralbricks.ai/v1",
|
||||
"https://api.cortecs.ai/v1",
|
||||
"https://api.scx.ai/v1",
|
||||
|
|
@ -1163,6 +1164,7 @@ openai_compatible_providers: Final[list[str]] = [
|
|||
"darkbloom",
|
||||
"meta", # Meta Model API (Muse Spark) - JSON-configured provider
|
||||
"cognition",
|
||||
"mixroute",
|
||||
"coralbricks",
|
||||
"cortecs",
|
||||
"scx-ai",
|
||||
|
|
|
|||
|
|
@ -302,5 +302,16 @@
|
|||
"preserve_cache_control": true
|
||||
},
|
||||
"supported_endpoints": ["/v1/chat/completions"]
|
||||
},
|
||||
"mixroute": {
|
||||
"base_url": "https://api.mixroute.ai/v1",
|
||||
"api_key_env": "MIXROUTE_API_KEY",
|
||||
"api_base_env": "MIXROUTE_API_BASE",
|
||||
"supported_endpoints": ["/v1/chat/completions", "/v1/embeddings"],
|
||||
"model_supported_endpoints": {
|
||||
"claude-opus-5-5": ["/v1/messages"],
|
||||
"claude-sonnet-5-5": ["/v1/messages"],
|
||||
"gpt-6.1-sol": ["/v1/responses"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -905,6 +905,32 @@
|
|||
"generateContent": true
|
||||
}
|
||||
},
|
||||
"mixroute": {
|
||||
"display_name": "MixRoute (`mixroute`)",
|
||||
"url": "https://mixroute.ai/docs/api-reference/endpoint/chat-openai",
|
||||
"endpoints": {
|
||||
"chat_completions": true,
|
||||
"responses": true,
|
||||
"text_completion": false,
|
||||
"embeddings": true,
|
||||
"image_generations": false,
|
||||
"image_edits": false,
|
||||
"audio_transcriptions": false,
|
||||
"audio_speech": false,
|
||||
"rerank": false,
|
||||
"ocr": false,
|
||||
"search": false,
|
||||
"moderations": false,
|
||||
"realtime": false,
|
||||
"video_generations": false,
|
||||
"batches": false,
|
||||
"messages": true,
|
||||
"interactions": false,
|
||||
"systemone": false,
|
||||
"a2a": false,
|
||||
"generateContent": false
|
||||
}
|
||||
},
|
||||
"cognition": {
|
||||
"display_name": "Cognition (`cognition`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/cognition",
|
||||
|
|
|
|||
|
|
@ -4677,6 +4677,7 @@ class LlmProviders(str, Enum):
|
|||
LIBERTAI = "libertai"
|
||||
PINSTRIPES = "pinstripes"
|
||||
COGNITION = "cognition"
|
||||
MIXROUTE = "mixroute"
|
||||
CORALBRICKS = "coralbricks"
|
||||
CORTECS = "cortecs"
|
||||
SCX_AI = "scx-ai"
|
||||
|
|
|
|||
|
|
@ -905,6 +905,32 @@
|
|||
"generateContent": true
|
||||
}
|
||||
},
|
||||
"mixroute": {
|
||||
"display_name": "MixRoute (`mixroute`)",
|
||||
"url": "https://mixroute.ai/docs/api-reference/endpoint/chat-openai",
|
||||
"endpoints": {
|
||||
"chat_completions": true,
|
||||
"responses": true,
|
||||
"text_completion": false,
|
||||
"embeddings": true,
|
||||
"image_generations": false,
|
||||
"image_edits": false,
|
||||
"audio_transcriptions": false,
|
||||
"audio_speech": false,
|
||||
"rerank": false,
|
||||
"ocr": false,
|
||||
"search": false,
|
||||
"moderations": false,
|
||||
"realtime": false,
|
||||
"video_generations": false,
|
||||
"batches": false,
|
||||
"messages": true,
|
||||
"interactions": false,
|
||||
"systemone": false,
|
||||
"a2a": false,
|
||||
"generateContent": false
|
||||
}
|
||||
},
|
||||
"cognition": {
|
||||
"display_name": "Cognition (`cognition`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/cognition",
|
||||
|
|
|
|||
51
tests/unit/llms/openai_like/test_mixroute_provider.py
Normal file
51
tests/unit/llms/openai_like/test_mixroute_provider.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
from typing import Final
|
||||
|
||||
import pytest
|
||||
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
from litellm.llms.openai_like.dynamic_config import create_config_class
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
|
||||
|
||||
def test_mixroute_prefix_preserves_model_and_resolves_credentials(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("MIXROUTE_API_KEY", "mixroute-test-key")
|
||||
monkeypatch.delenv("MIXROUTE_API_BASE", raising=False)
|
||||
config: Final = JSONProviderRegistry.get("mixroute")
|
||||
assert config is not None
|
||||
model, provider, key, base = get_llm_provider(model="mixroute/example-model")
|
||||
assert (model, provider, key, base) == ("example-model", "mixroute", "mixroute-test-key", config.base_url)
|
||||
|
||||
|
||||
def test_mixroute_endpoint_detection_preserves_explicit_key(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("MIXROUTE_API_KEY", "environment-key")
|
||||
config: Final = JSONProviderRegistry.get("mixroute")
|
||||
assert config is not None
|
||||
model, provider, key, base = get_llm_provider(
|
||||
model="example-model", api_base=config.base_url, api_key="caller-key"
|
||||
)
|
||||
assert (model, provider, key, base) == ("example-model", "mixroute", "caller-key", config.base_url)
|
||||
|
||||
|
||||
def test_mixroute_base_override_and_chat_url(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("MIXROUTE_API_KEY", "environment-key")
|
||||
monkeypatch.setenv("MIXROUTE_API_BASE", "https://mixroute.example.test/v1")
|
||||
config: Final = JSONProviderRegistry.get("mixroute")
|
||||
assert config is not None
|
||||
handler: Final = create_config_class(config)()
|
||||
base, key = handler.get_openai_compatible_provider_info(None, None)
|
||||
assert (base, key) == ("https://mixroute.example.test/v1", "environment-key")
|
||||
assert handler.get_complete_url(base, key, "example-model", {}, {}) == (
|
||||
"https://mixroute.example.test/v1/chat/completions"
|
||||
)
|
||||
assert handler.get_openai_compatible_provider_info("https://override.example.test/v1", "explicit-key") == (
|
||||
"https://override.example.test/v1", "explicit-key"
|
||||
)
|
||||
|
||||
|
||||
def test_mixroute_native_endpoints_do_not_apply_to_other_models() -> None:
|
||||
assert JSONProviderRegistry.serves_endpoint("mixroute", "claude-opus-5-5", "/v1/messages")
|
||||
assert JSONProviderRegistry.serves_endpoint("mixroute", "mixroute/claude-sonnet-5-5", "/v1/messages")
|
||||
assert JSONProviderRegistry.serves_endpoint("mixroute", "gpt-6.1-sol", "/v1/responses")
|
||||
assert not JSONProviderRegistry.serves_endpoint("mixroute", "unlisted-model", "/v1/messages")
|
||||
assert not JSONProviderRegistry.serves_endpoint("mixroute", "unlisted-model", "/v1/responses")
|
||||
assert JSONProviderRegistry.supports_embeddings("mixroute")
|
||||
Loading…
Add table
Reference in a new issue