From 99a6a6277a2fd23c3af52527ab8b776830a7d47a Mon Sep 17 00:00:00 2001 From: hezhihao Date: Sun, 1 Nov 2026 18:47:16 +0800 Subject: [PATCH] feat(providers): add HopBase as a JSON-configured OpenAI-compatible provider --- litellm/llms/openai_like/providers.json | 5 + ...odel_prices_and_context_window_backup.json | 345 ++++++++++++++++++ .../provider_endpoints_support_backup.json | 26 ++ .../provider_create_fields.json | 28 ++ litellm/types/utils.py | 1 + model_prices_and_context_window.json | 345 ++++++++++++++++++ provider_endpoints_support.json | 26 ++ .../llms/openai_like/test_hopbase_provider.py | 116 ++++++ 8 files changed, 892 insertions(+) create mode 100644 tests/unit/llms/openai_like/test_hopbase_provider.py diff --git a/litellm/llms/openai_like/providers.json b/litellm/llms/openai_like/providers.json index a71a9c3bb9b..5daef2a543f 100644 --- a/litellm/llms/openai_like/providers.json +++ b/litellm/llms/openai_like/providers.json @@ -302,5 +302,10 @@ "preserve_cache_control": true }, "supported_endpoints": ["/v1/chat/completions"] + }, + "hopbase": { + "base_url": "https://api.hop-base.com/v1", + "api_key_env": "HOPBASE_API_KEY", + "api_base_env": "HOPBASE_API_BASE" } } diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index e1fdfc89a9f..b6c44a3149a 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -81447,5 +81447,350 @@ "supports_response_schema": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true + }, + "hopbase/deepseek-v4-pro-202606": { + "cache_read_input_token_cost": 2.42e-08, + "input_cost_per_token": 7.26e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 393216, + "mode": "chat", + "output_cost_per_token": 2.178e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "hopbase/deepseek-v4.1-flash-1017": { + "cache_read_input_token_cost": 5.9e-09, + "input_cost_per_token": 1.765e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1000000, + "max_output_tokens": 393216, + "mode": "chat", + "off_peak_pricing": { + "cache_read_input_token_cost": 2.95e-09, + "input_cost_per_token": 8.825e-08, + "output_cost_per_token": 3.5295e-07, + "weekday_timezone": "Asia/Shanghai", + "windows": [ + { + "hours_utc": [ + "00:00-01:00", + "04:00-06:00", + "10:00-00:00" + ], + "weekdays": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + { + "hours_utc": "00:00-00:00", + "weekdays": [ + 6, + 7 + ] + } + ] + }, + "output_cost_per_token": 7.059e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/deepseek-v4.1-flash-1017-sg": { + "cache_read_input_token_cost": 3.6e-09, + "input_cost_per_token": 1.765e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1000000, + "max_output_tokens": 393216, + "mode": "chat", + "off_peak_pricing": { + "cache_read_input_token_cost": 1.8e-09, + "input_cost_per_token": 8.825e-08, + "output_cost_per_token": 3.5295e-07, + "weekday_timezone": "Asia/Shanghai", + "windows": [ + { + "hours_utc": [ + "00:00-01:00", + "04:00-06:00", + "10:00-00:00" + ], + "weekdays": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + { + "hours_utc": "00:00-00:00", + "weekdays": [ + 6, + 7 + ] + } + ] + }, + "output_cost_per_token": 7.059e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-0-mini-260428": { + "cache_read_input_token_cost": 5.9e-09, + "cache_read_input_token_cost_above_32768_tokens": 1.18e-08, + "input_cost_per_token": 2.95e-08, + "input_cost_per_token_above_32768_tokens": 5.89e-08, + "litellm_provider": "hopbase", + "max_input_tokens": 256000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 2.942e-07, + "output_cost_per_token_above_32768_tokens": 5.883e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-1-lite-260915": { + "cache_read_input_token_cost": 2.36e-08, + "input_cost_per_token": 1.177e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 3.971e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-1-pro-260628": { + "cache_read_input_token_cost": 1.765e-07, + "input_cost_per_token": 8.824e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 256000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 4.4118e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-1-pro-260915": { + "cache_read_input_token_cost": 1.765e-07, + "input_cost_per_token": 8.824e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 4.4118e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-1-turbo-260628": { + "cache_read_input_token_cost": 8.83e-08, + "input_cost_per_token": 4.412e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 256000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 2.2059e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-character-260628": { + "cache_read_input_token_cost": 2.36e-08, + "cache_read_input_token_cost_above_32768_tokens": 2.36e-08, + "input_cost_per_token": 1.177e-07, + "input_cost_per_token_above_32768_tokens": 1.765e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 2.942e-07, + "output_cost_per_token_above_32768_tokens": 8.824e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-evolving": { + "cache_read_input_token_cost": 1.765e-07, + "input_cost_per_token": 8.824e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 256000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 4.4118e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/gemini-3.1-pro-preview": { + "cache_read_input_token_cost": 9.12e-08, + "input_cost_per_token": 9.118e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 65536, + "mode": "chat", + "output_cost_per_token": 5.4706e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/gemini-3.8-flash": { + "cache_read_input_token_cost": 3.42e-08, + "input_cost_per_token": 3.42e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 65536, + "mode": "chat", + "output_cost_per_token": 1.7096e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/glm-5.3": { + "cache_read_input_token_cost": 2.21e-07, + "input_cost_per_token": 1.19e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 1000000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 3.74e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "hopbase/gpt-5.6-sol": { + "cache_read_input_token_cost": 2.6e-07, + "cache_read_input_token_cost_above_272k_tokens": 5.2e-07, + "input_cost_per_token": 2.6e-06, + "input_cost_per_token_above_272k_tokens": 5.2e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 922000, + "max_output_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.3e-05, + "output_cost_per_token_above_272k_tokens": 1.95e-05, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/grok-4.20-multi-agent-0309": { + "cache_read_input_token_cost": 1.2e-07, + "cache_read_input_token_cost_above_200k_tokens": 2.4e-07, + "input_cost_per_token": 7.5e-07, + "input_cost_per_token_above_200k_tokens": 1.5e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 1000000, + "max_output_tokens": 30000, + "mode": "chat", + "output_cost_per_token": 1.5e-06, + "output_cost_per_token_above_200k_tokens": 3e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": false, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": false, + "supports_tool_choice": false, + "supports_vision": true + }, + "hopbase/grok-4.7": { + "cache_read_input_token_cost": 3e-07, + "cache_read_input_token_cost_above_200k_tokens": 6e-07, + "input_cost_per_token": 1.2e-06, + "input_cost_per_token_above_200k_tokens": 2.4e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 500000, + "max_output_tokens": 500000, + "mode": "chat", + "output_cost_per_token": 3.6e-06, + "output_cost_per_token_above_200k_tokens": 7.2e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/kimi-k3": { + "cache_read_input_token_cost": 1.95e-07, + "input_cost_per_token": 1.95e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 9.75e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true } } diff --git a/litellm/provider_endpoints_support_backup.json b/litellm/provider_endpoints_support_backup.json index 700a35edb06..5a85dee4f2c 100644 --- a/litellm/provider_endpoints_support_backup.json +++ b/litellm/provider_endpoints_support_backup.json @@ -2084,6 +2084,32 @@ "generateContent": true } }, + "hopbase": { + "display_name": "HopBase (`hopbase`)", + "url": "https://docs.litellm.ai/docs/providers/hopbase", + "endpoints": { + "chat_completions": true, + "responses": true, + "text_completion": true, + "embeddings": false, + "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": true, + "systemone": false, + "a2a": true, + "generateContent": true + } + }, "hosted_vllm": { "display_name": "Hosted VLLM (`hosted_vllm`)", "url": "https://docs.litellm.ai/docs/providers/vllm", diff --git a/litellm/proxy/public_endpoints/provider_create_fields.json b/litellm/proxy/public_endpoints/provider_create_fields.json index 044b8a1de6e..51fd777e728 100644 --- a/litellm/proxy/public_endpoints/provider_create_fields.json +++ b/litellm/proxy/public_endpoints/provider_create_fields.json @@ -1959,6 +1959,34 @@ ], "default_model_placeholder": "gpt-3.5-turbo" }, + { + "provider": "HOPBASE", + "provider_display_name": "HopBase", + "litellm_provider": "hopbase", + "credential_fields": [ + { + "key": "api_key", + "label": "API Key", + "placeholder": null, + "tooltip": null, + "required": true, + "field_type": "password", + "options": null, + "default_value": null + }, + { + "key": "api_base", + "label": "API Base", + "placeholder": "https://api.hop-base.com/v1", + "tooltip": "Optional. Leave blank to use the provider's default endpoint.", + "required": false, + "field_type": "text", + "options": null, + "default_value": null + } + ], + "default_model_placeholder": "hopbase/glm-5.3" + }, { "provider": "HUGGINGFACE", "provider_display_name": "Huggingface", diff --git a/litellm/types/utils.py b/litellm/types/utils.py index da1d99957a7..dd868e517e5 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -4649,6 +4649,7 @@ class LlmProviders(str, Enum): MONGODB = "mongodb" OPENSEARCH = "opensearch" HELICONE = "helicone" + HOPBASE = "hopbase" HYPERBOLIC = "hyperbolic" RECRAFT = "recraft" FAL_AI = "fal_ai" diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index e1fdfc89a9f..b6c44a3149a 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -81447,5 +81447,350 @@ "supports_response_schema": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true + }, + "hopbase/deepseek-v4-pro-202606": { + "cache_read_input_token_cost": 2.42e-08, + "input_cost_per_token": 7.26e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 393216, + "mode": "chat", + "output_cost_per_token": 2.178e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "hopbase/deepseek-v4.1-flash-1017": { + "cache_read_input_token_cost": 5.9e-09, + "input_cost_per_token": 1.765e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1000000, + "max_output_tokens": 393216, + "mode": "chat", + "off_peak_pricing": { + "cache_read_input_token_cost": 2.95e-09, + "input_cost_per_token": 8.825e-08, + "output_cost_per_token": 3.5295e-07, + "weekday_timezone": "Asia/Shanghai", + "windows": [ + { + "hours_utc": [ + "00:00-01:00", + "04:00-06:00", + "10:00-00:00" + ], + "weekdays": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + { + "hours_utc": "00:00-00:00", + "weekdays": [ + 6, + 7 + ] + } + ] + }, + "output_cost_per_token": 7.059e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/deepseek-v4.1-flash-1017-sg": { + "cache_read_input_token_cost": 3.6e-09, + "input_cost_per_token": 1.765e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1000000, + "max_output_tokens": 393216, + "mode": "chat", + "off_peak_pricing": { + "cache_read_input_token_cost": 1.8e-09, + "input_cost_per_token": 8.825e-08, + "output_cost_per_token": 3.5295e-07, + "weekday_timezone": "Asia/Shanghai", + "windows": [ + { + "hours_utc": [ + "00:00-01:00", + "04:00-06:00", + "10:00-00:00" + ], + "weekdays": [ + 1, + 2, + 3, + 4, + 5 + ] + }, + { + "hours_utc": "00:00-00:00", + "weekdays": [ + 6, + 7 + ] + } + ] + }, + "output_cost_per_token": 7.059e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-0-mini-260428": { + "cache_read_input_token_cost": 5.9e-09, + "cache_read_input_token_cost_above_32768_tokens": 1.18e-08, + "input_cost_per_token": 2.95e-08, + "input_cost_per_token_above_32768_tokens": 5.89e-08, + "litellm_provider": "hopbase", + "max_input_tokens": 256000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 2.942e-07, + "output_cost_per_token_above_32768_tokens": 5.883e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-1-lite-260915": { + "cache_read_input_token_cost": 2.36e-08, + "input_cost_per_token": 1.177e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 3.971e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-1-pro-260628": { + "cache_read_input_token_cost": 1.765e-07, + "input_cost_per_token": 8.824e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 256000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 4.4118e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-1-pro-260915": { + "cache_read_input_token_cost": 1.765e-07, + "input_cost_per_token": 8.824e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 4.4118e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-2-1-turbo-260628": { + "cache_read_input_token_cost": 8.83e-08, + "input_cost_per_token": 4.412e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 256000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 2.2059e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-character-260628": { + "cache_read_input_token_cost": 2.36e-08, + "cache_read_input_token_cost_above_32768_tokens": 2.36e-08, + "input_cost_per_token": 1.177e-07, + "input_cost_per_token_above_32768_tokens": 1.765e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 131072, + "max_output_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 2.942e-07, + "output_cost_per_token_above_32768_tokens": 8.824e-07, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/doubao-seed-evolving": { + "cache_read_input_token_cost": 1.765e-07, + "input_cost_per_token": 8.824e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 256000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 4.4118e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/gemini-3.1-pro-preview": { + "cache_read_input_token_cost": 9.12e-08, + "input_cost_per_token": 9.118e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 65536, + "mode": "chat", + "output_cost_per_token": 5.4706e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/gemini-3.8-flash": { + "cache_read_input_token_cost": 3.42e-08, + "input_cost_per_token": 3.42e-07, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 65536, + "mode": "chat", + "output_cost_per_token": 1.7096e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/glm-5.3": { + "cache_read_input_token_cost": 2.21e-07, + "input_cost_per_token": 1.19e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 1000000, + "max_output_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 3.74e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "hopbase/gpt-5.6-sol": { + "cache_read_input_token_cost": 2.6e-07, + "cache_read_input_token_cost_above_272k_tokens": 5.2e-07, + "input_cost_per_token": 2.6e-06, + "input_cost_per_token_above_272k_tokens": 5.2e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 922000, + "max_output_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.3e-05, + "output_cost_per_token_above_272k_tokens": 1.95e-05, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/grok-4.20-multi-agent-0309": { + "cache_read_input_token_cost": 1.2e-07, + "cache_read_input_token_cost_above_200k_tokens": 2.4e-07, + "input_cost_per_token": 7.5e-07, + "input_cost_per_token_above_200k_tokens": 1.5e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 1000000, + "max_output_tokens": 30000, + "mode": "chat", + "output_cost_per_token": 1.5e-06, + "output_cost_per_token_above_200k_tokens": 3e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": false, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": false, + "supports_tool_choice": false, + "supports_vision": true + }, + "hopbase/grok-4.7": { + "cache_read_input_token_cost": 3e-07, + "cache_read_input_token_cost_above_200k_tokens": 6e-07, + "input_cost_per_token": 1.2e-06, + "input_cost_per_token_above_200k_tokens": 2.4e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 500000, + "max_output_tokens": 500000, + "mode": "chat", + "output_cost_per_token": 3.6e-06, + "output_cost_per_token_above_200k_tokens": 7.2e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "hopbase/kimi-k3": { + "cache_read_input_token_cost": 1.95e-07, + "input_cost_per_token": 1.95e-06, + "litellm_provider": "hopbase", + "max_input_tokens": 1048576, + "max_output_tokens": 32768, + "mode": "chat", + "output_cost_per_token": 9.75e-06, + "source": "https://hop-base.com/pricing", + "supports_function_calling": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true } } diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json index 700a35edb06..5a85dee4f2c 100644 --- a/provider_endpoints_support.json +++ b/provider_endpoints_support.json @@ -2084,6 +2084,32 @@ "generateContent": true } }, + "hopbase": { + "display_name": "HopBase (`hopbase`)", + "url": "https://docs.litellm.ai/docs/providers/hopbase", + "endpoints": { + "chat_completions": true, + "responses": true, + "text_completion": true, + "embeddings": false, + "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": true, + "systemone": false, + "a2a": true, + "generateContent": true + } + }, "hosted_vllm": { "display_name": "Hosted VLLM (`hosted_vllm`)", "url": "https://docs.litellm.ai/docs/providers/vllm", diff --git a/tests/unit/llms/openai_like/test_hopbase_provider.py b/tests/unit/llms/openai_like/test_hopbase_provider.py new file mode 100644 index 00000000000..c1e45494d72 --- /dev/null +++ b/tests/unit/llms/openai_like/test_hopbase_provider.py @@ -0,0 +1,116 @@ +import json +from datetime import datetime, timezone +from typing import Final + +import pytest +import respx + +import litellm +from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider +from litellm.utils import trim_messages + + +def _chat_response(model: str, prompt_tokens: int, cached_tokens: int, completion_tokens: int) -> dict: + return { + "id": "chatcmpl-test", + "object": "chat.completion", + "created": 1, + "model": model, + "choices": [{"index": 0, "message": {"role": "assistant", "content": "hello"}, "finish_reason": "stop"}], + "usage": { + "prompt_tokens": prompt_tokens, + "completion_tokens": completion_tokens, + "total_tokens": prompt_tokens + completion_tokens, + "prompt_tokens_details": {"cached_tokens": cached_tokens}, + }, + } + + +def test_hopbase_resolves_environment_and_explicit_credentials(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("HOPBASE_API_KEY", "fake-environment-key") + assert get_llm_provider(model="hopbase/glm-5.3") == ( + "glm-5.3", + "hopbase", + "fake-environment-key", + "https://api.hop-base.com/v1", + ) + assert get_llm_provider( + model="hopbase/glm-5.3", api_key="fake-explicit-key", api_base="https://gateway.example/v1" + ) == ("glm-5.3", "hopbase", "fake-explicit-key", "https://gateway.example/v1") + + +def test_hopbase_chat_sends_openai_request_and_accounts_for_cache(local_model_cost_map: None) -> None: + with respx.mock() as upstream: + route: Final = upstream.post("https://api.hop-base.com/v1/chat/completions").respond( + 200, json=_chat_response("glm-5.3", prompt_tokens=100, cached_tokens=80, completion_tokens=5) + ) + response: Final = litellm.completion( + model="hopbase/glm-5.3", + api_key="fake-test-key", + messages=[{"role": "user", "content": "Say hello"}], + ) + request: Final = route.calls.last.request + assert request.headers["authorization"] == "Bearer fake-test-key" + assert json.loads(request.content)["model"] == "glm-5.3" + assert response.choices[0].message.content == "hello" + rates: Final = litellm.model_cost["hopbase/glm-5.3"] + expected: Final = ( + 20 * rates["input_cost_per_token"] + + 80 * rates["cache_read_input_token_cost"] + + 5 * rates["output_cost_per_token"] + ) + assert litellm.completion_cost(completion_response=response) == pytest.approx(expected) + + +def test_hopbase_long_prompt_uses_the_upper_tier(local_model_cost_map: None) -> None: + rates: Final = litellm.model_cost["hopbase/gpt-5.6-sol"] + with respx.mock() as upstream: + upstream.post("https://api.hop-base.com/v1/chat/completions").respond( + 200, json=_chat_response("gpt-5.6-sol", prompt_tokens=300_000, cached_tokens=0, completion_tokens=10) + ) + response: Final = litellm.completion( + model="hopbase/gpt-5.6-sol", api_key="fake-test-key", messages=[{"role": "user", "content": "hi"}] + ) + expected: Final = ( + 300_000 * rates["input_cost_per_token_above_272k_tokens"] + + 10 * rates["output_cost_per_token_above_272k_tokens"] + ) + assert litellm.completion_cost(completion_response=response) == pytest.approx(expected) + + +@pytest.mark.parametrize( + ("when", "rate_source"), + [ + (datetime(2026, 11, 2, 2, 0, tzinfo=timezone.utc), "peak"), # Monday 10:00 Beijing + (datetime(2026, 11, 2, 12, 0, tzinfo=timezone.utc), "off_peak"), # Monday 20:00 Beijing + (datetime(2026, 11, 1, 2, 0, tzinfo=timezone.utc), "off_peak"), # Sunday + ], +) +def test_hopbase_deepseek_flash_bills_off_peak_hours( + local_model_cost_map: None, monkeypatch: pytest.MonkeyPatch, when: datetime, rate_source: str +) -> None: + from litellm.litellm_core_utils.llm_cost_calc import utils as cost_utils + + monkeypatch.setattr(cost_utils, "current_billing_time", lambda: when) + info: Final = litellm.model_cost["hopbase/deepseek-v4.1-flash-1017"] + rates: Final = info if rate_source == "peak" else info["off_peak_pricing"] + prompt_cost, completion_cost = litellm.cost_per_token( + model="hopbase/deepseek-v4.1-flash-1017", prompt_tokens=1000, completion_tokens=100 + ) + assert prompt_cost == pytest.approx(1000 * rates["input_cost_per_token"]) + assert completion_cost == pytest.approx(100 * rates["output_cost_per_token"]) + + +def test_hopbase_models_trim_to_their_input_budget(local_model_cost_map: None) -> None: + model_names: Final = tuple(model for model in litellm.model_cost if model.startswith("hopbase/")) + assert model_names + messages: Final = [{"role": "user", "content": "hello " * 500}] + budget: Final = 100 + for model in model_names: + trimmed = trim_messages( + messages, + model=model, + trim_ratio=budget / litellm.model_cost[model]["max_input_tokens"], + ) + assert litellm.token_counter(model=model, messages=messages) > budget + assert litellm.token_counter(model=model, messages=trimmed) <= budget