diff --git a/litellm/llms/openai_like/providers.json b/litellm/llms/openai_like/providers.json index 164100d4194..b965ae07407 100644 --- a/litellm/llms/openai_like/providers.json +++ b/litellm/llms/openai_like/providers.json @@ -130,7 +130,10 @@ "param_mappings": { "max_completion_tokens": "max_tokens" }, - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"] + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ] }, "tensormesh": { "base_url": "https://serverless.tensormesh.ai/v1", @@ -140,13 +143,19 @@ "param_mappings": { "max_completion_tokens": "max_tokens" }, - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"] + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ] }, "parasail": { "base_url": "https://api.parasail.io/v1", "api_key_env": "PARASAIL_API_KEY", "api_base_env": "PARASAIL_API_BASE", - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"], + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ], "special_handling": { "force_store_false": true } @@ -166,14 +175,21 @@ "param_mappings": { "max_completion_tokens": "max_tokens" }, - "supported_endpoints": ["/v1/chat/completions", "/v1/responses"] + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ] }, "meta": { "base_url": "https://api.meta.ai/v1", "api_key_env": "META_API_KEY", "api_base_env": "META_API_BASE", "base_class": "openai_gpt", - "supported_endpoints": ["/v1/chat/completions", "/v1/responses", "/v1/messages"] + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses", + "/v1/messages" + ] }, "pinstripes": { "base_url": "https://pinstripes.io/v1", @@ -182,6 +198,22 @@ "param_mappings": { "max_completion_tokens": "max_tokens" }, - "supported_endpoints": ["/v1/chat/completions", "/v1/responses", "/v1/embeddings"] + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses", + "/v1/embeddings" + ] + }, + "stepfun": { + "base_url": "https://api.stepfun.ai/v1", + "api_key_env": "STEPFUN_API_KEY", + "api_base_env": "STEPFUN_API_BASE", + "param_mappings": { + "max_completion_tokens": "max_tokens" + }, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ] } } diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 90ea99ceb23..25787e167c4 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -3405,6 +3405,7 @@ class LlmProviders(str, Enum): NEOSANTARA = "neosantara" PARASAIL = "parasail" XIAOMI_MIMO = "xiaomi_mimo" + STEPFUN = "stepfun" TENSORMESH = "tensormesh" LIBERTAI = "libertai" PINSTRIPES = "pinstripes" diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json index 65db63dc045..e546de0a5f9 100644 --- a/provider_endpoints_support.json +++ b/provider_endpoints_support.json @@ -488,9 +488,7 @@ "audio_speech": false, "moderations": false, "batches": false, - "rerank": false, - "a2a": false, - "interactions": false + "rerank": false } }, "chutes": { @@ -2909,22 +2907,6 @@ "rerank": false } }, - "charity_engine": { - "display_name": "Charity Engine (`charity_engine`)", - "url": "https://docs.litellm.ai/docs/providers/charity_engine", - "endpoints": { - "chat_completions": true, - "messages": true, - "responses": true, - "embeddings": false, - "image_generations": false, - "audio_transcriptions": false, - "audio_speech": false, - "moderations": false, - "batches": false, - "rerank": false - } - }, "empiriolabs": { "display_name": "EmpirioLabs (`empiriolabs`)", "url": "https://docs.litellm.ai/docs/providers/empiriolabs", @@ -2941,6 +2923,24 @@ "rerank": false, "a2a": false } + }, + "stepfun": { + "display_name": "StepFun (`stepfun`)", + "url": "https://docs.litellm.ai/docs/providers/stepfun", + "endpoints": { + "chat_completions": true, + "messages": false, + "responses": true, + "embeddings": false, + "image_generations": false, + "audio_transcriptions": false, + "audio_speech": false, + "moderations": false, + "batches": false, + "rerank": false, + "a2a": false, + "interactions": false + } } }, "endpoints": { diff --git a/tests/test_litellm/llms/openai_like/test_stepfun.py b/tests/test_litellm/llms/openai_like/test_stepfun.py new file mode 100644 index 00000000000..a99bd5dea82 --- /dev/null +++ b/tests/test_litellm/llms/openai_like/test_stepfun.py @@ -0,0 +1,65 @@ +"""Tests for the JSON-configured StepFun provider.""" + +import litellm + + +def test_stepfun_in_provider_list(): + from litellm import LlmProviders + + assert LlmProviders.STEPFUN.value == "stepfun" + assert "stepfun" in litellm.provider_list + + +def test_stepfun_json_config(): + from litellm.llms.openai_like.json_loader import JSONProviderRegistry + + config = JSONProviderRegistry.get("stepfun") + + assert config is not None + assert config.base_url == "https://api.stepfun.ai/v1" + assert config.api_key_env == "STEPFUN_API_KEY" + assert config.api_base_env == "STEPFUN_API_BASE" + assert config.param_mappings["max_completion_tokens"] == "max_tokens" + assert config.supported_endpoints == [ + "/v1/chat/completions", + "/v1/responses", + ] + + +def test_stepfun_provider_resolution(): + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + model, provider, api_key, api_base = get_llm_provider( + model="stepfun/step-3.7-flash", + custom_llm_provider=None, + api_base=None, + api_key=None, + ) + + assert model == "step-3.7-flash" + assert provider == "stepfun" + assert api_key is None + assert api_base == "https://api.stepfun.ai/v1" + + +def test_stepfun_supports_responses_api(): + from litellm.llms.openai_like.json_loader import JSONProviderRegistry + + assert JSONProviderRegistry.supports_responses_api("stepfun") is True + + +def test_stepfun_router_config(): + router = litellm.Router( + model_list=[ + { + "model_name": "step-3.7-flash", + "litellm_params": { + "model": "stepfun/step-3.7-flash", + "api_key": "test-key", + }, + } + ] + ) + + assert len(router.model_list) == 1 + assert router.model_list[0]["model_name"] == "step-3.7-flash"