diff --git a/litellm/llms/openai_like/providers.json b/litellm/llms/openai_like/providers.json index fe10293c420..f478800a57f 100644 --- a/litellm/llms/openai_like/providers.json +++ b/litellm/llms/openai_like/providers.json @@ -123,6 +123,14 @@ "max_completion_tokens": "max_tokens" } }, + "demonroute": { + "base_url": "https://api.demonroute.com/v1", + "api_key_env": "DEMONROUTE_API_KEY", + "api_base_env": "DEMONROUTE_API_BASE", + "param_mappings": { + "max_completion_tokens": "max_tokens" + } + }, "neosantara": { "base_url": "https://api.neosantara.xyz/v1", "api_key_env": "NEOSANTARA_API_KEY", diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 4b88072b479..3fc32d2de47 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -59462,6 +59462,160 @@ "supports_tool_choice": true, "supports_vision": false }, + "demonroute/NousResearch/Hermes-4-70B": { + "input_cost_per_token": 8.64e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 8.64e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "demonroute/NousResearch/Hermes-3-Llama-3.1-70B": { + "input_cost_per_token": 2.16e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 2.16e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/EVA-UNIT-01/EVA-Qwen2.5-72B-v0.2": { + "input_cost_per_token": 4.44e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 4.8e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/Sao10K/L3.3-70B-Euryale-v2.3": { + "input_cost_per_token": 1.95e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 2.25e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/anthracite-org/magnum-v4-72b": { + "input_cost_per_token": 9e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 1.5e-05, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/TheDrummer/Cydonia-24B-v4.3": { + "input_cost_per_token": 2.1e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 3.48e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/dphn/Dolphin-Mistral-24B-Venice-Edition": { + "input_cost_per_token": 2.1e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 3.48e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/dphn/Dolphin3.0-Mistral-24B": { + "input_cost_per_token": 2.1e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 3.48e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/thirdeyeai/Qwen2.5-Coder-32B-Instruct-Uncensored": { + "input_cost_per_token": 8.16e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 1.44e-05, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/huihui-ai/Llama-3.3-70B-Instruct-abliterated": { + "input_cost_per_token": 1.95e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 2.25e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/Sao10K/L3-8B-Stheno-v3.2": { + "input_cost_per_token": 1.11e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 8192, + "max_output_tokens": 8192, + "max_tokens": 8192, + "mode": "chat", + "output_cost_per_token": 1.14e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, "tencent/deepseek-v4-pro": { "cache_creation_input_token_cost": 0.0, "cache_read_input_token_cost": 3.625e-09, diff --git a/litellm/provider_endpoints_support_backup.json b/litellm/provider_endpoints_support_backup.json index 1fcb7600a5e..aca34629117 100644 --- a/litellm/provider_endpoints_support_backup.json +++ b/litellm/provider_endpoints_support_backup.json @@ -815,6 +815,23 @@ "interactions": true } }, + "demonroute": { + "display_name": "DemonRoute (`demonroute`)", + "url": "https://docs.litellm.ai/docs/providers/demonroute", + "endpoints": { + "chat_completions": true, + "messages": false, + "responses": false, + "embeddings": false, + "image_generations": false, + "audio_transcriptions": false, + "audio_speech": false, + "moderations": false, + "batches": false, + "rerank": false, + "a2a": false + } + }, "edenai": { "display_name": "Eden AI (`edenai`)", "url": "https://docs.litellm.ai/docs/providers/edenai", diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 4b88072b479..3fc32d2de47 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -59462,6 +59462,160 @@ "supports_tool_choice": true, "supports_vision": false }, + "demonroute/NousResearch/Hermes-4-70B": { + "input_cost_per_token": 8.64e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 8.64e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "demonroute/NousResearch/Hermes-3-Llama-3.1-70B": { + "input_cost_per_token": 2.16e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 2.16e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/EVA-UNIT-01/EVA-Qwen2.5-72B-v0.2": { + "input_cost_per_token": 4.44e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 4.8e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/Sao10K/L3.3-70B-Euryale-v2.3": { + "input_cost_per_token": 1.95e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 2.25e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/anthracite-org/magnum-v4-72b": { + "input_cost_per_token": 9e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 1.5e-05, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/TheDrummer/Cydonia-24B-v4.3": { + "input_cost_per_token": 2.1e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 3.48e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/dphn/Dolphin-Mistral-24B-Venice-Edition": { + "input_cost_per_token": 2.1e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 3.48e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/dphn/Dolphin3.0-Mistral-24B": { + "input_cost_per_token": 2.1e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 3.48e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/thirdeyeai/Qwen2.5-Coder-32B-Instruct-Uncensored": { + "input_cost_per_token": 8.16e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 32768, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 1.44e-05, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/huihui-ai/Llama-3.3-70B-Instruct-abliterated": { + "input_cost_per_token": 1.95e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 2.25e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, + "demonroute/Sao10K/L3-8B-Stheno-v3.2": { + "input_cost_per_token": 1.11e-06, + "litellm_provider": "demonroute", + "max_input_tokens": 8192, + "max_output_tokens": 8192, + "max_tokens": 8192, + "mode": "chat", + "output_cost_per_token": 1.14e-06, + "source": "https://demonroute.com/models", + "supports_function_calling": false, + "supports_system_messages": true, + "supports_tool_choice": false, + "supports_vision": false + }, "tencent/deepseek-v4-pro": { "cache_creation_input_token_cost": 0.0, "cache_read_input_token_cost": 3.625e-09, diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json index e6cb0592a15..e04d3b73d38 100644 --- a/provider_endpoints_support.json +++ b/provider_endpoints_support.json @@ -886,6 +886,23 @@ "interactions": true } }, + "demonroute": { + "display_name": "DemonRoute (`demonroute`)", + "url": "https://docs.litellm.ai/docs/providers/demonroute", + "endpoints": { + "chat_completions": true, + "messages": false, + "responses": false, + "embeddings": false, + "image_generations": false, + "audio_transcriptions": false, + "audio_speech": false, + "moderations": false, + "batches": false, + "rerank": false, + "a2a": false + } + }, "edenai": { "display_name": "Eden AI (`edenai`)", "url": "https://docs.litellm.ai/docs/providers/edenai", diff --git a/tests/unit/llms/openai_like/test_demonroute_provider.py b/tests/unit/llms/openai_like/test_demonroute_provider.py new file mode 100644 index 00000000000..92ab37d8bd6 --- /dev/null +++ b/tests/unit/llms/openai_like/test_demonroute_provider.py @@ -0,0 +1,66 @@ +""" +Unit tests for the DemonRoute OpenAI-like provider (JSON-configured). +""" + +import os +import sys + +sys.path.insert( + 0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../..")) +) + +from litellm.llms.openai_like.dynamic_config import create_config_class +from litellm.llms.openai_like.json_loader import JSONProviderRegistry + +DEMONROUTE_BASE_URL = "https://api.demonroute.com/v1" + + +def _get_config(): + provider = JSONProviderRegistry.get("demonroute") + assert provider is not None + config_class = create_config_class(provider) + return config_class() + + +def test_demonroute_provider_registered(): + provider = JSONProviderRegistry.get("demonroute") + assert provider is not None + assert provider.base_url == DEMONROUTE_BASE_URL + assert provider.api_key_env == "DEMONROUTE_API_KEY" + assert provider.api_base_env == "DEMONROUTE_API_BASE" + + +def test_demonroute_resolves_env_api_key(monkeypatch): + config = _get_config() + monkeypatch.delenv("DEMONROUTE_API_BASE", raising=False) + monkeypatch.setenv("DEMONROUTE_API_KEY", "test-key") + api_base, api_key = config._get_openai_compatible_provider_info(None, None) + assert api_base == DEMONROUTE_BASE_URL + assert api_key == "test-key" + + +def test_demonroute_complete_url_appends_endpoint(): + config = _get_config() + url = config.get_complete_url( + api_base=DEMONROUTE_BASE_URL, + api_key="test-key", + model="demonroute/NousResearch/Hermes-4-70B", + optional_params={}, + litellm_params={}, + stream=False, + ) + assert url == f"{DEMONROUTE_BASE_URL}/chat/completions" + + +def test_demonroute_model_id_keeps_org_segment(): + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + model, provider, _, api_base = get_llm_provider( + model="demonroute/NousResearch/Hermes-4-70B", + custom_llm_provider=None, + api_base=None, + api_key=None, + ) + assert provider == "demonroute" + assert model == "NousResearch/Hermes-4-70B" + assert api_base == DEMONROUTE_BASE_URL