diff --git a/litellm/constants.py b/litellm/constants.py
index e5b662bd515..cfa68f07535 100644
--- a/litellm/constants.py
+++ b/litellm/constants.py
@@ -938,6 +938,7 @@ openai_compatible_endpoints: Final[list] = [
"https://api.cognition.ai/v1",
"https://api.scx.ai/v1",
"https://gigachat.devices.sberbank.ru/api/v1",
+ "https://api.openzoo.fun/v1",
]
@@ -1010,6 +1011,7 @@ openai_compatible_providers: Final[list] = [
"meta", # Meta Model API (Muse Spark) - JSON-configured provider
"cognition",
"scx-ai",
+ "openzoo",
]
OPENAI_AUDIO_TRANSCRIPTION_PROVIDERS: Final = frozenset({"openai"} | frozenset(openai_compatible_providers))
diff --git a/litellm/llms/openai_like/providers.json b/litellm/llms/openai_like/providers.json
index fe10293c420..efce2d1d8cc 100644
--- a/litellm/llms/openai_like/providers.json
+++ b/litellm/llms/openai_like/providers.json
@@ -200,5 +200,14 @@
"temperature_max": 1.99
},
"supported_endpoints": ["/v1/chat/completions"]
+ },
+ "openzoo": {
+ "base_url": "https://api.openzoo.fun/v1",
+ "api_key_env": "OPENZOO_API_KEY",
+ "api_base_env": "OPENZOO_API_BASE",
+ "param_mappings": {
+ "max_completion_tokens": "max_tokens"
+ },
+ "supported_endpoints": ["/v1/chat/completions"]
}
}
diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json
index 345daa5c8a3..d4b944fdccb 100644
--- a/litellm/model_prices_and_context_window_backup.json
+++ b/litellm/model_prices_and_context_window_backup.json
@@ -41983,6 +41983,48 @@
"max_tokens": 128000,
"mode": "chat"
},
+ "openzoo/nvidia/nemotron-3.5-lightning": {
+ "input_cost_per_token": 8e-08,
+ "litellm_provider": "openzoo",
+ "max_input_tokens": 262144,
+ "max_output_tokens": 131072,
+ "max_tokens": 131072,
+ "mode": "chat",
+ "output_cost_per_token": 2e-07,
+ "source": "https://openzoo.fun",
+ "supports_function_calling": true,
+ "supports_reasoning": true,
+ "supports_tool_choice": true,
+ "supports_vision": false
+ },
+ "openzoo/qwen/qwen3.7-flash": {
+ "input_cost_per_token": 3e-08,
+ "litellm_provider": "openzoo",
+ "max_input_tokens": 1000000,
+ "max_output_tokens": 65536,
+ "max_tokens": 65536,
+ "mode": "chat",
+ "output_cost_per_token": 1.3e-07,
+ "source": "https://openzoo.fun",
+ "supports_function_calling": true,
+ "supports_reasoning": true,
+ "supports_tool_choice": true,
+ "supports_vision": false
+ },
+ "openzoo/z-ai/glm-5.3-flash": {
+ "input_cost_per_token": 7.5e-08,
+ "litellm_provider": "openzoo",
+ "max_input_tokens": 1310720,
+ "max_output_tokens": 131072,
+ "max_tokens": 131072,
+ "mode": "chat",
+ "output_cost_per_token": 2.5e-07,
+ "source": "https://openzoo.fun",
+ "supports_function_calling": true,
+ "supports_reasoning": true,
+ "supports_tool_choice": true,
+ "supports_vision": false
+ },
"ovhcloud/DeepSeek-R1-Distill-Llama-70B": {
"input_cost_per_token": 6.7e-07,
"litellm_provider": "ovhcloud",
diff --git a/litellm/provider_endpoints_support_backup.json b/litellm/provider_endpoints_support_backup.json
index 1fcb7600a5e..a14be193a9a 100644
--- a/litellm/provider_endpoints_support_backup.json
+++ b/litellm/provider_endpoints_support_backup.json
@@ -1802,6 +1802,23 @@
"interactions": true
}
},
+ "openzoo": {
+ "display_name": "OpenZoo (`openzoo`)",
+ "url": "https://docs.litellm.ai/docs/providers/openzoo",
+ "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
+ }
+ },
"ovhcloud": {
"display_name": "OVHCloud AI Endpoints (`ovhcloud`)",
"url": "https://docs.litellm.ai/docs/providers/ovhcloud",
diff --git a/litellm/proxy/public_endpoints/provider_create_fields.json b/litellm/proxy/public_endpoints/provider_create_fields.json
index 0ca08cb7992..c3859bc90d1 100644
--- a/litellm/proxy/public_endpoints/provider_create_fields.json
+++ b/litellm/proxy/public_endpoints/provider_create_fields.json
@@ -3013,6 +3013,34 @@
],
"default_model_placeholder": "scx-ai/GLM-5.2"
},
+ {
+ "provider": "OpenZoo",
+ "provider_display_name": "OpenZoo",
+ "litellm_provider": "openzoo",
+ "credential_fields": [
+ {
+ "key": "api_base",
+ "label": "API Base",
+ "placeholder": "https://api.openzoo.fun/v1",
+ "tooltip": null,
+ "required": false,
+ "field_type": "text",
+ "options": null,
+ "default_value": null
+ },
+ {
+ "key": "api_key",
+ "label": "API Key",
+ "placeholder": "sk-openzoo",
+ "tooltip": "OpenZoo does not require signup. Any key value works; usage is billed per call.",
+ "required": true,
+ "field_type": "password",
+ "options": null,
+ "default_value": null
+ }
+ ],
+ "default_model_placeholder": "openzoo/z-ai/glm-5.3-flash"
+ },
{
"provider": "Snowflake",
"provider_display_name": "Snowflake",
diff --git a/litellm/types/utils.py b/litellm/types/utils.py
index dfc98a9d89d..470b9a6d1b6 100644
--- a/litellm/types/utils.py
+++ b/litellm/types/utils.py
@@ -4296,6 +4296,7 @@ class LlmProviders(str, Enum):
PINSTRIPES = "pinstripes"
COGNITION = "cognition"
SCX_AI = "scx-ai"
+ OPENZOO = "openzoo"
DARKBLOOM = "darkbloom"
META = "meta"
LITELLM_AGENT = "litellm_agent"
diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json
index 345daa5c8a3..d4b944fdccb 100644
--- a/model_prices_and_context_window.json
+++ b/model_prices_and_context_window.json
@@ -41983,6 +41983,48 @@
"max_tokens": 128000,
"mode": "chat"
},
+ "openzoo/nvidia/nemotron-3.5-lightning": {
+ "input_cost_per_token": 8e-08,
+ "litellm_provider": "openzoo",
+ "max_input_tokens": 262144,
+ "max_output_tokens": 131072,
+ "max_tokens": 131072,
+ "mode": "chat",
+ "output_cost_per_token": 2e-07,
+ "source": "https://openzoo.fun",
+ "supports_function_calling": true,
+ "supports_reasoning": true,
+ "supports_tool_choice": true,
+ "supports_vision": false
+ },
+ "openzoo/qwen/qwen3.7-flash": {
+ "input_cost_per_token": 3e-08,
+ "litellm_provider": "openzoo",
+ "max_input_tokens": 1000000,
+ "max_output_tokens": 65536,
+ "max_tokens": 65536,
+ "mode": "chat",
+ "output_cost_per_token": 1.3e-07,
+ "source": "https://openzoo.fun",
+ "supports_function_calling": true,
+ "supports_reasoning": true,
+ "supports_tool_choice": true,
+ "supports_vision": false
+ },
+ "openzoo/z-ai/glm-5.3-flash": {
+ "input_cost_per_token": 7.5e-08,
+ "litellm_provider": "openzoo",
+ "max_input_tokens": 1310720,
+ "max_output_tokens": 131072,
+ "max_tokens": 131072,
+ "mode": "chat",
+ "output_cost_per_token": 2.5e-07,
+ "source": "https://openzoo.fun",
+ "supports_function_calling": true,
+ "supports_reasoning": true,
+ "supports_tool_choice": true,
+ "supports_vision": false
+ },
"ovhcloud/DeepSeek-R1-Distill-Llama-70B": {
"input_cost_per_token": 6.7e-07,
"litellm_provider": "ovhcloud",
diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json
index b8d1621cde3..7805dda9ebd 100644
--- a/provider_endpoints_support.json
+++ b/provider_endpoints_support.json
@@ -1968,6 +1968,23 @@
"interactions": true
}
},
+ "openzoo": {
+ "display_name": "OpenZoo (`openzoo`)",
+ "url": "https://docs.litellm.ai/docs/providers/openzoo",
+ "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
+ }
+ },
"ovhcloud": {
"display_name": "OVHCloud AI Endpoints (`ovhcloud`)",
"url": "https://docs.litellm.ai/docs/providers/ovhcloud",
diff --git a/tests/test_litellm/llms/openai_like/test_openzoo_provider.py b/tests/test_litellm/llms/openai_like/test_openzoo_provider.py
new file mode 100644
index 00000000000..d25df7eacdd
--- /dev/null
+++ b/tests/test_litellm/llms/openai_like/test_openzoo_provider.py
@@ -0,0 +1,195 @@
+"""
+Tests for OpenZoo provider configuration and integration.
+"""
+
+import litellm
+
+
+class TestOpenZooProviderConfig:
+ def test_openzoo_in_provider_list(self):
+ from litellm import LlmProviders
+
+ assert hasattr(LlmProviders, "OPENZOO")
+ assert LlmProviders.OPENZOO.value == "openzoo"
+ assert "openzoo" in litellm.provider_list
+
+ def test_openzoo_json_config_exists(self):
+ from litellm.llms.openai_like.json_loader import JSONProviderRegistry
+
+ assert JSONProviderRegistry.exists("openzoo")
+
+ openzoo = JSONProviderRegistry.get("openzoo")
+ assert openzoo is not None
+ assert openzoo.base_url == "https://api.openzoo.fun/v1"
+ assert openzoo.api_key_env == "OPENZOO_API_KEY"
+ assert openzoo.param_mappings.get("max_completion_tokens") == "max_tokens"
+
+ def test_openzoo_in_openai_compatible_providers(self):
+ from litellm.constants import openai_compatible_providers
+
+ assert "openzoo" in openai_compatible_providers
+
+ def test_openzoo_provider_resolution(self):
+ from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
+
+ model, provider, api_key, api_base = get_llm_provider(
+ model="openzoo/z-ai/glm-5.3-flash",
+ custom_llm_provider=None,
+ api_base=None,
+ api_key=None,
+ )
+
+ assert model == "z-ai/glm-5.3-flash"
+ assert provider == "openzoo"
+ assert api_base == "https://api.openzoo.fun/v1"
+
+ def test_openzoo_api_base_override(self):
+ from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
+
+ model, provider, api_key, api_base = get_llm_provider(
+ model="openzoo/z-ai/glm-5.3-flash",
+ custom_llm_provider=None,
+ api_base="http://localhost:8402/v1",
+ api_key="sk-openzoo",
+ )
+
+ assert provider == "openzoo"
+ assert api_base == "http://localhost:8402/v1"
+ assert api_key == "sk-openzoo"
+
+ def test_openzoo_url_autodetection(self):
+ from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
+
+ model, provider, api_key, api_base = get_llm_provider(
+ model="z-ai/glm-5.3-flash",
+ custom_llm_provider=None,
+ api_base="https://api.openzoo.fun/v1",
+ api_key=None,
+ )
+ assert provider == "openzoo"
+ assert api_base == "https://api.openzoo.fun/v1"
+
+ def test_openzoo_temperature_passthrough(self):
+ from litellm.llms.openai_like.dynamic_config import create_config_class
+ from litellm.llms.openai_like.json_loader import JSONProviderRegistry
+
+ provider = JSONProviderRegistry.get("openzoo")
+ assert provider is not None
+ config = create_config_class(provider)()
+
+ optional_params = config.map_openai_params(
+ non_default_params={"temperature": 0.4},
+ optional_params={},
+ model="z-ai/glm-5.3-flash",
+ drop_params=False,
+ )
+ assert optional_params["temperature"] == 0.4
+
+ def test_openzoo_max_completion_tokens_mapped(self):
+ from litellm.llms.openai_like.dynamic_config import create_config_class
+ from litellm.llms.openai_like.json_loader import JSONProviderRegistry
+
+ provider = JSONProviderRegistry.get("openzoo")
+ assert provider is not None
+ config = create_config_class(provider)()
+
+ optional_params = config.map_openai_params(
+ non_default_params={"max_completion_tokens": 256},
+ optional_params={},
+ model="z-ai/glm-5.3-flash",
+ drop_params=False,
+ )
+ assert optional_params["max_tokens"] == 256
+ assert "max_completion_tokens" not in optional_params
+
+ def test_openzoo_router_config(self):
+ from litellm import Router
+
+ router = Router(
+ model_list=[
+ {
+ "model_name": "openzoo-chat",
+ "litellm_params": {
+ "model": "openzoo/z-ai/glm-5.3-flash",
+ "api_key": "sk-openzoo",
+ },
+ }
+ ]
+ )
+
+ assert len(router.model_list) == 1
+ assert router.model_list[0]["model_name"] == "openzoo-chat"
+
+
+class TestOpenZooModelMetadata:
+ OPENZOO_MODELS = (
+ "openzoo/z-ai/glm-5.3-flash",
+ "openzoo/qwen/qwen3.7-flash",
+ "openzoo/nvidia/nemotron-3.5-lightning",
+ )
+ MIN_INPUT_TOKENS = {
+ "openzoo/z-ai/glm-5.3-flash": 1310720,
+ "openzoo/qwen/qwen3.7-flash": 1000000,
+ "openzoo/nvidia/nemotron-3.5-lightning": 262144,
+ }
+
+ @staticmethod
+ def _load(path_parts):
+ import json
+ from pathlib import Path
+
+ json_path = Path(__file__).parents[4].joinpath(*path_parts)
+ with open(json_path) as f:
+ return json.load(f)
+
+ def test_openzoo_models_registered_with_correct_metadata(self):
+ model_cost = self._load(("model_prices_and_context_window.json",))
+ for model in self.OPENZOO_MODELS:
+ info = model_cost.get(model)
+ assert info is not None, f"{model} missing from model_prices_and_context_window.json"
+ assert info["litellm_provider"] == "openzoo"
+ assert info["mode"] == "chat"
+ assert info["input_cost_per_token"] > 0
+ assert info["output_cost_per_token"] > 0
+ assert info["supports_function_calling"] is True
+ assert info["supports_tool_choice"] is True
+ assert info["supports_reasoning"] is True
+ assert info.get("supports_vision", False) is False
+
+ assert info["max_output_tokens"] > 0
+ assert info["max_tokens"] == info["max_output_tokens"]
+ assert info["max_input_tokens"] == self.MIN_INPUT_TOKENS[model]
+
+ def test_openzoo_models_synced_to_backup(self):
+ model_cost = self._load(("model_prices_and_context_window.json",))
+ backup = self._load(("litellm", "model_prices_and_context_window_backup.json"))
+ for model in self.OPENZOO_MODELS:
+ assert model in backup, f"{model} missing from backup json"
+ assert backup[model] == model_cost[model], f"{model} differs between root and backup json"
+
+
+class TestOpenZooDashboardRegistration:
+ @staticmethod
+ def _provider_create_fields():
+ import json
+ from pathlib import Path
+
+ import litellm
+
+ path = Path(litellm.__file__).parent / "proxy" / "public_endpoints" / "provider_create_fields.json"
+ with open(path) as f:
+ return json.load(f)
+
+ def test_openzoo_is_selectable_in_the_add_model_form(self):
+ entries = [e for e in self._provider_create_fields() if e["litellm_provider"] == "openzoo"]
+ assert len(entries) == 1, "openzoo must appear exactly once in provider_create_fields.json"
+
+ entry = entries[0]
+ assert entry["provider"] == "OpenZoo"
+ assert entry["provider_display_name"] == "OpenZoo"
+ assert entry["default_model_placeholder"].startswith("openzoo/")
+
+ fields = {f["key"]: f for f in entry["credential_fields"]}
+ assert fields["api_key"]["required"] is True
+ assert fields["api_key"]["field_type"] == "password"
+ assert fields["api_base"]["required"] is False
diff --git a/ui/litellm-dashboard/public/assets/logos/openzoo.svg b/ui/litellm-dashboard/public/assets/logos/openzoo.svg
new file mode 100644
index 00000000000..6aa48565137
--- /dev/null
+++ b/ui/litellm-dashboard/public/assets/logos/openzoo.svg
@@ -0,0 +1,4 @@
+
diff --git a/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx b/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx
index d6b8d00a023..9e901f369ac 100644
--- a/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx
+++ b/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx
@@ -73,6 +73,17 @@ describe("provider_info_helpers", () => {
expect(fromEnumKey.logo).toBe(providerLogoMap[Providers.SCX_AI]);
});
+ it("should map openzoo slug and OpenZoo enum key to the OpenZoo display name and logo", () => {
+ const fromSlug = getProviderLogoAndName("openzoo");
+ expect(fromSlug.displayName).toBe(Providers.OpenZoo);
+ expect(fromSlug.logo).toBe(providerLogoMap[Providers.OpenZoo]);
+ expect(fromSlug.logo).toBeTruthy();
+
+ const fromEnumKey = getProviderLogoAndName("OpenZoo");
+ expect(fromEnumKey.displayName).toBe(Providers.OpenZoo);
+ expect(fromEnumKey.logo).toBe(providerLogoMap[Providers.OpenZoo]);
+ });
+
it("should map bedrock_mantle slug to Bedrock Mantle display name and logo", () => {
const result = getProviderLogoAndName("bedrock_mantle");
expect(result.displayName).toBe(Providers.BedrockMantle);
@@ -227,6 +238,10 @@ describe("provider_info_helpers", () => {
expect(getPlaceholder(Providers.EDENAI)).toBe("edenai/openai/gpt-mini-latest");
});
+ it("should return an openzoo model placeholder for OpenZoo provider", () => {
+ expect(getPlaceholder(Providers.OpenZoo)).toBe("openzoo/z-ai/glm-5.3-flash");
+ });
+
it("should return claude-3-opus placeholder for Anthropic provider", () => {
expect(getPlaceholder(Providers.Anthropic)).toBe("claude-3-opus");
});
diff --git a/ui/litellm-dashboard/src/components/provider_info_helpers.tsx b/ui/litellm-dashboard/src/components/provider_info_helpers.tsx
index eab55503da8..8bf83b5353e 100644
--- a/ui/litellm-dashboard/src/components/provider_info_helpers.tsx
+++ b/ui/litellm-dashboard/src/components/provider_info_helpers.tsx
@@ -44,6 +44,7 @@ import nvidiaTritonLogo from "../../public/assets/logos/nvidia_triton.png";
import ollamaLogo from "../../public/assets/logos/ollama.svg";
import openaiSmallLogo from "../../public/assets/logos/openai_small.svg";
import openrouterLogo from "../../public/assets/logos/openrouter.svg";
+import openzooLogo from "../../public/assets/logos/openzoo.svg";
import oracleLogo from "../../public/assets/logos/oracle.svg";
import perplexityAiLogo from "../../public/assets/logos/perplexity-ai.svg";
import qwenLogo from "../../public/assets/logos/qwen.png";
@@ -148,6 +149,7 @@ export enum Providers {
OpenAI_Text = "OpenAI Text Completion",
OpenAI_Text_Compatible = "OpenAI-Compatible Completions (legacy /v1/completions)",
Openrouter = "Openrouter",
+ OpenZoo = "OpenZoo",
Oracle = "Oracle Cloud Infrastructure (OCI)",
OVHCLOUD = "Ovhcloud",
Perplexity = "Perplexity",
@@ -265,6 +267,7 @@ export const provider_map: Record = {
OpenAI_Text: "text-completion-openai",
OpenAI_Text_Compatible: "text-completion-openai",
Openrouter: "openrouter",
+ OpenZoo: "openzoo",
Oracle: "oci",
OVHCLOUD: "ovhcloud",
Perplexity: "perplexity",
@@ -369,6 +372,7 @@ export const providerLogoMap: Partial> = {
[Providers.OpenAI_Text_Compatible]: openaiSmallLogo.src,
[Providers.OpenAI_Compatible]: openaiSmallLogo.src,
[Providers.Openrouter]: openrouterLogo.src,
+ [Providers.OpenZoo]: openzooLogo.src,
[Providers.Oracle]: oracleLogo.src,
[Providers.Perplexity]: perplexityAiLogo.src,
[Providers.Qwen_AI_Platform]: qwenLogo.src,
@@ -445,6 +449,7 @@ const providerPlaceholderMap: Partial> = {
[Providers.Google_AI_Studio]: "gemini-pro",
[Providers.JinaAI]: "jina_ai/",
[Providers.NVIDIA_RIVA]: "nvidia_riva/nvidia/parakeet-ctc-1_1b-asr",
+ [Providers.OpenZoo]: "openzoo/z-ai/glm-5.3-flash",
[Providers.Oracle]: "oci/xai.grok-4",
[Providers.RunwayML]: "runwayml/gen4_turbo",
[Providers.SageMaker]: "sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b",