From eeb59c8e7c75dd5603572a7d3b5ebc13b1aa14d2 Mon Sep 17 00:00:00 2001 From: Nirupam Bhowmick <48842933+heydryft@users.noreply.github.com> Date: Wed, 28 Oct 2026 14:59:40 +0000 Subject: [PATCH] feat(providers): add Runcrate chat rows to the cost map and regenerate endpoint support --- ...odel_prices_and_context_window_backup.json | 98 +++++++++++++++++++ .../provider_endpoints_support_backup.json | 18 +++- model_prices_and_context_window.json | 98 +++++++++++++++++++ provider_endpoints_support.json | 18 +++- .../openai_like/test_runcrate_provider.py | 41 +++++--- 5 files changed, 248 insertions(+), 25 deletions(-) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 703621b60cf..88e00c57a48 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -81444,5 +81444,103 @@ "supports_response_schema": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true + }, + "runcrate/deepseek-ai/DeepSeek-V3.2": { + "input_cost_per_token": 2.73e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 163840, + "max_output_tokens": 147456, + "mode": "chat", + "output_cost_per_token": 3.99e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "runcrate/deepseek-ai/DeepSeek-V4.1-Flash": { + "input_cost_per_token": 1.47e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 4.41e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "runcrate/moonshotai/Kimi-K2.6": { + "input_cost_per_token": 7.875e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 262144, + "max_output_tokens": 16384, + "mode": "chat", + "output_cost_per_token": 3.675e-06, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "runcrate/openai/gpt-oss-120b": { + "input_cost_per_token": 3.885e-08, + "litellm_provider": "runcrate", + "max_input_tokens": 131072, + "max_output_tokens": 117964, + "mode": "chat", + "output_cost_per_token": 1.785e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "runcrate/Qwen/Qwen3.8-Flash": { + "input_cost_per_token": 1.1865e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 1000000, + "max_output_tokens": 1000000, + "mode": "chat", + "output_cost_per_token": 4.011e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "runcrate/zai-org/GLM-5.3": { + "input_cost_per_token": 5.90625e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 2.625e-06, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "runcrate/zai-org/GLM-5.3-Flash": { + "input_cost_per_token": 1.575e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 5.25e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": 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 3a1db74c299..8879681db88 100644 --- a/litellm/provider_endpoints_support_backup.json +++ b/litellm/provider_endpoints_support_backup.json @@ -3765,17 +3765,25 @@ "url": "https://docs.litellm.ai/docs/providers/runcrate", "endpoints": { "chat_completions": true, - "messages": true, "responses": true, + "text_completion": true, "embeddings": false, "image_generations": false, + "image_edits": false, "audio_transcriptions": false, "audio_speech": false, - "moderations": false, - "batches": false, "rerank": false, - "a2a": false, - "interactions": false + "ocr": false, + "search": false, + "moderations": false, + "realtime": false, + "video_generations": false, + "batches": false, + "messages": true, + "interactions": true, + "systemone": false, + "a2a": true, + "generateContent": true } }, "snowflake": { diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 703621b60cf..88e00c57a48 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -81444,5 +81444,103 @@ "supports_response_schema": true, "supports_vision": true, "supports_xhigh_reasoning_effort": true + }, + "runcrate/deepseek-ai/DeepSeek-V3.2": { + "input_cost_per_token": 2.73e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 163840, + "max_output_tokens": 147456, + "mode": "chat", + "output_cost_per_token": 3.99e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "runcrate/deepseek-ai/DeepSeek-V4.1-Flash": { + "input_cost_per_token": 1.47e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 4.41e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "runcrate/moonshotai/Kimi-K2.6": { + "input_cost_per_token": 7.875e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 262144, + "max_output_tokens": 16384, + "mode": "chat", + "output_cost_per_token": 3.675e-06, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "runcrate/openai/gpt-oss-120b": { + "input_cost_per_token": 3.885e-08, + "litellm_provider": "runcrate", + "max_input_tokens": 131072, + "max_output_tokens": 117964, + "mode": "chat", + "output_cost_per_token": 1.785e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "runcrate/Qwen/Qwen3.8-Flash": { + "input_cost_per_token": 1.1865e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 1000000, + "max_output_tokens": 1000000, + "mode": "chat", + "output_cost_per_token": 4.011e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "runcrate/zai-org/GLM-5.3": { + "input_cost_per_token": 5.90625e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 2.625e-06, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": false + }, + "runcrate/zai-org/GLM-5.3-Flash": { + "input_cost_per_token": 1.575e-07, + "litellm_provider": "runcrate", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 5.25e-07, + "source": "https://www.runcrate.ai/inference/pricing", + "supports_function_calling": 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 3a1db74c299..8879681db88 100644 --- a/provider_endpoints_support.json +++ b/provider_endpoints_support.json @@ -3765,17 +3765,25 @@ "url": "https://docs.litellm.ai/docs/providers/runcrate", "endpoints": { "chat_completions": true, - "messages": true, "responses": true, + "text_completion": true, "embeddings": false, "image_generations": false, + "image_edits": false, "audio_transcriptions": false, "audio_speech": false, - "moderations": false, - "batches": false, "rerank": false, - "a2a": false, - "interactions": false + "ocr": false, + "search": false, + "moderations": false, + "realtime": false, + "video_generations": false, + "batches": false, + "messages": true, + "interactions": true, + "systemone": false, + "a2a": true, + "generateContent": true } }, "snowflake": { diff --git a/tests/unit/llms/openai_like/test_runcrate_provider.py b/tests/unit/llms/openai_like/test_runcrate_provider.py index f01409d9d1b..7572e559414 100644 --- a/tests/unit/llms/openai_like/test_runcrate_provider.py +++ b/tests/unit/llms/openai_like/test_runcrate_provider.py @@ -116,25 +116,36 @@ def test_runcrate_is_available_in_add_model_form(): def test_runcrate_supported_endpoints(): - expected: Final = { - "chat_completions": True, - "messages": True, - "responses": True, - "embeddings": False, - "image_generations": False, - "audio_transcriptions": False, - "audio_speech": False, - "moderations": False, - "batches": False, - "rerank": False, - "a2a": False, - "interactions": False, + """The endpoint flags are generated from the runcrate chat rows in the cost map.""" + supported: Final = {"chat_completions", "messages", "responses"} + unsupported: Final = { + "embeddings", + "image_generations", + "audio_transcriptions", + "audio_speech", + "moderations", + "batches", + "rerank", } 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"]["runcrate"]["endpoints"] == expected - assert json.loads(root_path.read_text())["providers"]["runcrate"]["endpoints"] == expected + for path in (backup_path, root_path): + endpoints = json.loads(path.read_text())["providers"]["runcrate"]["endpoints"] + assert all(endpoints[key] for key in supported) + assert not any(endpoints[key] for key in unsupported) + + +def test_runcrate_cost_map_rows(): + model_cost: Final = json.loads( + (Path(litellm.__file__).parent / "model_prices_and_context_window_backup.json").read_text() + ) + rows: Final = {key: value for key, value in model_cost.items() if key.startswith("runcrate/")} + assert "runcrate/deepseek-ai/DeepSeek-V3.2" in rows + for row in rows.values(): + assert row["litellm_provider"] == "runcrate" + assert row["mode"] == "chat" + assert 0 < row["input_cost_per_token"] < row["output_cost_per_token"] def test_runcrate_chat_completion_request():