From 2c3fb40e35bb54a0de675b58b5ffa0cf333cbce9 Mon Sep 17 00:00:00 2001 From: superbot <5358899+ux-xd@users.noreply.github.com> Date: Tue, 20 Oct 2026 00:28:18 -0600 Subject: [PATCH] fix(superbot): register the provider as superbot-gg so the model id superbot resolves A provider whose id equals one of its model ids loops back into get_llm_provider, which splits the bare name on '/' and raises IndexError, so superbot/superbot never reached the API. The provider key, the enum value, the endpoint-support and Add Model entries and the two cost-map keys are now superbot-gg; the model ids stay superbot and superbot-fast. --- litellm/constants.py | 2 +- litellm/llms/openai_like/providers.json | 2 +- ...odel_prices_and_context_window_backup.json | 8 ++-- .../provider_endpoints_support_backup.json | 4 +- .../provider_create_fields.json | 4 +- litellm/types/utils.py | 2 +- model_prices_and_context_window.json | 8 ++-- provider_endpoints_support.json | 4 +- .../openai_like/test_superbot_provider.py | 38 +++++++++---------- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/litellm/constants.py b/litellm/constants.py index b569b92c8fb..c1a4814b0e1 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -1130,7 +1130,7 @@ openai_compatible_providers: Final[list[str]] = [ "prism", "sail", "reka", - "superbot", + "superbot-gg", ] 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 12f737f75fc..bcea187d624 100644 --- a/litellm/llms/openai_like/providers.json +++ b/litellm/llms/openai_like/providers.json @@ -250,7 +250,7 @@ "/v1/messages" ] }, - "superbot": { + "superbot-gg": { "base_url": "https://api.superbot.gg/v1", "api_key_env": "SUPERBOT_API_KEY", "api_base_env": "SUPERBOT_API_BASE" diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index bfa47f0fb3b..e299ff9adfe 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -76119,7 +76119,7 @@ "supports_reasoning": true, "source": "https://api.openinfer.ai/v1/models" }, - "superbot/superbot": { + "superbot-gg/superbot": { "max_tokens": 65536, "max_input_tokens": 1000000, "max_output_tokens": 65536, @@ -76127,13 +76127,13 @@ "output_cost_per_token": 5e-06, "cache_read_input_token_cost": 5e-08, "cache_creation_input_token_cost": 1.25e-06, - "litellm_provider": "superbot", + "litellm_provider": "superbot-gg", "mode": "chat", "supports_function_calling": true, "supports_reasoning": true, "source": "https://superbot.gg/pricing" }, - "superbot/superbot-fast": { + "superbot-gg/superbot-fast": { "max_tokens": 65536, "max_input_tokens": 500000, "max_output_tokens": 65536, @@ -76141,7 +76141,7 @@ "output_cost_per_token": 5e-06, "cache_read_input_token_cost": 5e-08, "cache_creation_input_token_cost": 1.25e-06, - "litellm_provider": "superbot", + "litellm_provider": "superbot-gg", "mode": "chat", "supports_function_calling": true, "supports_reasoning": true, diff --git a/litellm/provider_endpoints_support_backup.json b/litellm/provider_endpoints_support_backup.json index 7d512d65cac..1fe16f27d92 100644 --- a/litellm/provider_endpoints_support_backup.json +++ b/litellm/provider_endpoints_support_backup.json @@ -2207,8 +2207,8 @@ "interactions": false } }, - "superbot": { - "display_name": "superbot (`superbot`)", + "superbot-gg": { + "display_name": "superbot (`superbot-gg`)", "url": "https://docs.litellm.ai/docs/providers/superbot", "endpoints": { "chat_completions": true, diff --git a/litellm/proxy/public_endpoints/provider_create_fields.json b/litellm/proxy/public_endpoints/provider_create_fields.json index bf7610bcd03..6131b53e02d 100644 --- a/litellm/proxy/public_endpoints/provider_create_fields.json +++ b/litellm/proxy/public_endpoints/provider_create_fields.json @@ -3318,7 +3318,7 @@ { "provider": "Superbot", "provider_display_name": "superbot", - "litellm_provider": "superbot", + "litellm_provider": "superbot-gg", "credential_fields": [ { "key": "api_base", @@ -3341,7 +3341,7 @@ "default_value": null } ], - "default_model_placeholder": "superbot/superbot" + "default_model_placeholder": "superbot-gg/superbot" }, { "provider": "Sambanova", diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 9fe80f3680b..f63b3383787 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -4534,7 +4534,7 @@ class LlmProviders(str, Enum): META = "meta" SAIL = "sail" REKA = "reka" - SUPERBOT = "superbot" + SUPERBOT = "superbot-gg" LITELLM_AGENT = "litellm_agent" CURSOR = "cursor" BEDROCK_MANTLE = "bedrock_mantle" diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index bfa47f0fb3b..e299ff9adfe 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -76119,7 +76119,7 @@ "supports_reasoning": true, "source": "https://api.openinfer.ai/v1/models" }, - "superbot/superbot": { + "superbot-gg/superbot": { "max_tokens": 65536, "max_input_tokens": 1000000, "max_output_tokens": 65536, @@ -76127,13 +76127,13 @@ "output_cost_per_token": 5e-06, "cache_read_input_token_cost": 5e-08, "cache_creation_input_token_cost": 1.25e-06, - "litellm_provider": "superbot", + "litellm_provider": "superbot-gg", "mode": "chat", "supports_function_calling": true, "supports_reasoning": true, "source": "https://superbot.gg/pricing" }, - "superbot/superbot-fast": { + "superbot-gg/superbot-fast": { "max_tokens": 65536, "max_input_tokens": 500000, "max_output_tokens": 65536, @@ -76141,7 +76141,7 @@ "output_cost_per_token": 5e-06, "cache_read_input_token_cost": 5e-08, "cache_creation_input_token_cost": 1.25e-06, - "litellm_provider": "superbot", + "litellm_provider": "superbot-gg", "mode": "chat", "supports_function_calling": true, "supports_reasoning": true, diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json index 414f7dde8e7..4032b4ecd7e 100644 --- a/provider_endpoints_support.json +++ b/provider_endpoints_support.json @@ -2479,8 +2479,8 @@ "interactions": false } }, - "superbot": { - "display_name": "superbot (`superbot`)", + "superbot-gg": { + "display_name": "superbot (`superbot-gg`)", "url": "https://docs.litellm.ai/docs/providers/superbot", "endpoints": { "chat_completions": true, diff --git a/tests/unit/llms/openai_like/test_superbot_provider.py b/tests/unit/llms/openai_like/test_superbot_provider.py index 77b23f4cbc1..c9764de19dc 100644 --- a/tests/unit/llms/openai_like/test_superbot_provider.py +++ b/tests/unit/llms/openai_like/test_superbot_provider.py @@ -29,9 +29,9 @@ _CHAT_COMPLETION: Final = { def test_superbot_is_a_registered_provider(): - assert litellm.LlmProviders.SUPERBOT.value == "superbot" - assert "superbot" in litellm.provider_list - assert "superbot" in litellm.constants.openai_compatible_providers + assert litellm.LlmProviders.SUPERBOT.value == "superbot-gg" + assert "superbot-gg" in litellm.provider_list + assert "superbot-gg" in litellm.constants.openai_compatible_providers def test_superbot_provider_resolution(monkeypatch: pytest.MonkeyPatch): @@ -40,14 +40,14 @@ def test_superbot_provider_resolution(monkeypatch: pytest.MonkeyPatch): monkeypatch.setenv("SUPERBOT_API_KEY", ENV_CREDENTIAL) model, provider, resolved_key, api_base = get_llm_provider( - model="superbot/superbot-fast", + model="superbot-gg/superbot-fast", custom_llm_provider=None, api_base=None, api_key=None, ) assert model == "superbot-fast" - assert provider == "superbot" + assert provider == "superbot-gg" assert resolved_key == ENV_CREDENTIAL assert api_base == "https://api.superbot.gg/v1" @@ -59,13 +59,13 @@ def test_superbot_provider_keeps_explicit_credentials(monkeypatch: pytest.Monkey monkeypatch.setenv("SUPERBOT_API_BASE", "https://superbot.env.example/v1") _, provider, resolved_key, api_base = get_llm_provider( - model="superbot/superbot", + model="superbot-gg/superbot", custom_llm_provider=None, api_base="https://superbot.internal.example/v1", api_key=EXPLICIT_CREDENTIAL, ) - assert provider == "superbot" + assert provider == "superbot-gg" assert resolved_key == EXPLICIT_CREDENTIAL assert api_base == "https://superbot.internal.example/v1" @@ -77,13 +77,13 @@ def test_superbot_api_base_env_overrides_default(monkeypatch: pytest.MonkeyPatch monkeypatch.setenv("SUPERBOT_API_BASE", "https://superbot.env.example/v1") _, provider, _, api_base = get_llm_provider( - model="superbot/superbot", + model="superbot-gg/superbot", custom_llm_provider=None, api_base=None, api_key=None, ) - assert provider == "superbot" + assert provider == "superbot-gg" assert api_base == "https://superbot.env.example/v1" @@ -100,7 +100,7 @@ def test_superbot_api_base_autodetects_provider(monkeypatch: pytest.MonkeyPatch) ) assert model == "superbot" - assert provider == "superbot" + assert provider == "superbot-gg" assert resolved_key == ENV_CREDENTIAL assert api_base == "https://api.superbot.gg/v1" @@ -108,11 +108,11 @@ def test_superbot_api_base_autodetects_provider(monkeypatch: pytest.MonkeyPatch) def test_superbot_is_available_in_add_model_form(): fields_path = Path(litellm.__file__).parent / "proxy" / "public_endpoints" / "provider_create_fields.json" providers = json.loads(fields_path.read_text()) - superbot = next(provider for provider in providers if provider["litellm_provider"] == "superbot") + superbot = next(provider for provider in providers if provider["litellm_provider"] == "superbot-gg") assert superbot["provider"] == "Superbot" assert superbot["provider_display_name"] == "superbot" - assert superbot["default_model_placeholder"] == "superbot/superbot" + assert superbot["default_model_placeholder"] == "superbot-gg/superbot" assert {field["key"]: field["required"] for field in superbot["credential_fields"]} == { "api_base": False, "api_key": True, @@ -137,13 +137,13 @@ def test_superbot_supported_endpoints(): backup_path = Path(litellm.__file__).parent / "provider_endpoints_support_backup.json" root_path = Path(litellm.__file__).parent.parent / "provider_endpoints_support.json" - assert json.loads(backup_path.read_text())["providers"]["superbot"]["endpoints"] == expected - assert json.loads(root_path.read_text())["providers"]["superbot"]["endpoints"] == expected + assert json.loads(backup_path.read_text())["providers"]["superbot-gg"]["endpoints"] == expected + assert json.loads(root_path.read_text())["providers"]["superbot-gg"]["endpoints"] == expected @pytest.mark.parametrize( "model_id, context", - [("superbot/superbot", 1_000_000), ("superbot/superbot-fast", 500_000)], + [("superbot-gg/superbot", 1_000_000), ("superbot-gg/superbot-fast", 500_000)], ) def test_superbot_models_are_priced_in_both_cost_maps(model_id: str, context: int): root = Path(litellm.__file__).parent.parent @@ -153,7 +153,7 @@ def test_superbot_models_are_priced_in_both_cost_maps(model_id: str, context: in ] for path in maps: row = json.loads(path.read_text())[model_id] - assert row["litellm_provider"] == "superbot" + assert row["litellm_provider"] == "superbot-gg" assert row["mode"] == "chat" assert row["max_input_tokens"] == context assert row["max_output_tokens"] == 65_536 @@ -168,7 +168,7 @@ def test_superbot_chat_completion_request(): with respx.mock() as upstream: route: Final = upstream.post("https://api.superbot.gg/v1/chat/completions").respond(200, json=_CHAT_COMPLETION) response: Final = litellm.completion( - model="superbot/superbot", + model="superbot-gg/superbot", messages=[{"role": "user", "content": "Say hello"}], api_key=EXPLICIT_CREDENTIAL, ) @@ -187,7 +187,7 @@ def test_superbot_responses_request_is_bridged_to_chat_completions(): with respx.mock() as upstream: route: Final = upstream.post("https://api.superbot.gg/v1/chat/completions").respond(200, json=_CHAT_COMPLETION) response: Final = litellm.responses( - model="superbot/superbot", + model="superbot-gg/superbot", input="Say hello", api_key=EXPLICIT_CREDENTIAL, ) @@ -208,7 +208,7 @@ async def test_superbot_anthropic_messages_request_is_bridged_to_chat_completion with respx.mock() as upstream: route: Final = upstream.post("https://api.superbot.gg/v1/chat/completions").respond(200, json=_CHAT_COMPLETION) response: Final = await litellm.anthropic.messages.acreate( - model="superbot/superbot", + model="superbot-gg/superbot", messages=[{"role": "user", "content": "Say hello"}], max_tokens=32, api_key=EXPLICIT_CREDENTIAL,