From ef1cde433ea7c6dd1515de06c6d0d748fae4a197 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Thu, 20 Aug 2026 18:22:14 -0700 Subject: [PATCH 1/2] fix: add moonshot/kimi-k3 to the cost map models.litellm.ai and released litellm versions read model_prices_and_context_window.json from main at runtime, so Kimi K3 is missing from the hosted catalog even though the entry is in review for litellm_internal_staging in #37552. This copies that entry onto main so the catalog picks it up on its next fetch. Data only: the cost map and its backup copy, no code changes. Pricing matches Moonshot's published rates ($3/M input, $0.30/M cache read, $15/M output, 1,048,576-token context). The fireworks_ai and Azure Foundry kimi-k3 variants are separate work in #37512 and #37658; neither touches the native moonshot/kimi-k3 key. --- .../model_prices_and_context_window_backup.json | 17 +++++++++++++++++ model_prices_and_context_window.json | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 07f9027313b..53d069c4a71 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -30025,6 +30025,23 @@ "supports_video_input": true, "supports_vision": true }, + "moonshot/kimi-k3": { + "cache_read_input_token_cost": 3e-07, + "input_cost_per_token": 3e-06, + "litellm_provider": "moonshot", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 1.5e-05, + "source": "https://platform.kimi.ai/docs/pricing/chat-k3", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_video_input": true, + "supports_vision": true + }, "moonshot/kimi-latest": { "cache_read_input_token_cost": 1.5e-07, "deprecation_date": "2026-01-28", diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 07f9027313b..53d069c4a71 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -30025,6 +30025,23 @@ "supports_video_input": true, "supports_vision": true }, + "moonshot/kimi-k3": { + "cache_read_input_token_cost": 3e-07, + "input_cost_per_token": 3e-06, + "litellm_provider": "moonshot", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 1.5e-05, + "source": "https://platform.kimi.ai/docs/pricing/chat-k3", + "supports_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_video_input": true, + "supports_vision": true + }, "moonshot/kimi-latest": { "cache_read_input_token_cost": 1.5e-07, "deprecation_date": "2026-01-28", From b0c4f7a89cd5c7084cd0667550880d36fcda1935 Mon Sep 17 00:00:00 2001 From: Artem Burei Date: Mon, 24 Aug 2026 18:45:24 +0200 Subject: [PATCH 2/2] feat: add LLM Tech (llmtech) as JSON-configured OpenAI-compatible provider --- litellm/constants.py | 3 ++ .../get_llm_provider_logic.py | 3 ++ litellm/llms/openai_like/providers.json | 5 ++ litellm/types/utils.py | 1 + provider_endpoints_support.json | 16 ++++++ .../llms/openai_like/test_json_providers.py | 51 +++++++++++++++++++ 6 files changed, 79 insertions(+) diff --git a/litellm/constants.py b/litellm/constants.py index c33e5a53b76..2121620c463 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -768,6 +768,7 @@ openai_compatible_endpoints: Final[list] = [ "https://serverless.tensormesh.ai/v1", "https://api.stima.tech/v1", "https://nano-gpt.com/api/v1", + "https://api.llmtech.eu/v1", "https://api.poe.com/v1", "https://llm.chutes.ai/v1/", "https://api.v0.dev/v1", @@ -825,6 +826,7 @@ openai_compatible_providers: Final[list] = [ "tensormesh", # Tensormesh - JSON-configured provider "apertis", # Apertis - JSON-configured provider "nano-gpt", # Nano-GPT - JSON-configured provider + "llmtech", # LLM Tech - JSON-configured provider "poe", # Poe - JSON-configured provider "chutes", # Chutes - JSON-configured provider "parasail", # Parasail - JSON-configured provider @@ -870,6 +872,7 @@ openai_text_completion_compatible_providers: Final[list] = [ # providers that s "tensormesh", "apertis", "nano-gpt", + "llmtech", "poe", "chutes", "v0", diff --git a/litellm/litellm_core_utils/get_llm_provider_logic.py b/litellm/litellm_core_utils/get_llm_provider_logic.py index e674fc37673..b5a365abaa8 100644 --- a/litellm/litellm_core_utils/get_llm_provider_logic.py +++ b/litellm/litellm_core_utils/get_llm_provider_logic.py @@ -319,6 +319,9 @@ def get_llm_provider( elif endpoint == "https://nano-gpt.com/api/v1": custom_llm_provider = "nano-gpt" dynamic_api_key = get_secret_str("NANOGPT_API_KEY") + elif endpoint == "https://api.llmtech.eu/v1": + custom_llm_provider = "llmtech" + dynamic_api_key = get_secret_str("LLMTECH_API_KEY") elif endpoint == "https://api.poe.com/v1": custom_llm_provider = "poe" dynamic_api_key = get_secret_str("POE_API_KEY") diff --git a/litellm/llms/openai_like/providers.json b/litellm/llms/openai_like/providers.json index a458a209ea9..4ab2d7beca9 100644 --- a/litellm/llms/openai_like/providers.json +++ b/litellm/llms/openai_like/providers.json @@ -200,5 +200,10 @@ "temperature_max": 1.99 }, "supported_endpoints": ["/v1/chat/completions"] + }, + "llmtech": { + "base_url": "https://api.llmtech.eu/v1", + "api_key_env": "LLMTECH_API_KEY", + "api_base_env": "LLMTECH_API_BASE" } } diff --git a/litellm/types/utils.py b/litellm/types/utils.py index 94526de0757..49dd2286c65 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -3781,6 +3781,7 @@ class LlmProviders(str, Enum): SYNTHETIC = "synthetic" APERTIS = "apertis" NANOGPT = "nano-gpt" + LLMTECH = "llmtech" POE = "poe" CHUTES = "chutes" NEOSANTARA = "neosantara" diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json index 1d8d374c2c4..3ab6329f54e 100644 --- a/provider_endpoints_support.json +++ b/provider_endpoints_support.json @@ -1618,6 +1618,22 @@ "interactions": true } }, + "llmtech": { + "display_name": "LLM Tech (`llmtech`)", + "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 + } + }, "nanogpt": { "display_name": "NanoGPT (`nanogpt`)", "endpoints": { diff --git a/tests/test_litellm/llms/openai_like/test_json_providers.py b/tests/test_litellm/llms/openai_like/test_json_providers.py index c8743e1809d..8e0d2b84c5a 100644 --- a/tests/test_litellm/llms/openai_like/test_json_providers.py +++ b/tests/test_litellm/llms/openai_like/test_json_providers.py @@ -529,3 +529,54 @@ if __name__ == "__main__": print("\n" + "=" * 50) print("✓ All tests passed!") print("=" * 50) + +class TestLLMTech: + """Tests for LLM Tech JSON-configured provider""" + + def test_llmtech_json_config_exists(self): + from litellm.llms.openai_like.json_loader import JSONProviderRegistry + + provider = JSONProviderRegistry.get("llmtech") + assert provider is not None + assert provider.base_url == "https://api.llmtech.eu/v1" + assert provider.api_key_env == "LLMTECH_API_KEY" + assert provider.api_base_env == "LLMTECH_API_BASE" + + def test_llmtech_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="llmtech/unsloth/Qwen3.8-27B-NVFP4", + custom_llm_provider=None, + api_base=None, + api_key=None, + ) + + assert model == "unsloth/Qwen3.8-27B-NVFP4" + assert provider == "llmtech" + assert api_base == "https://api.llmtech.eu/v1" + + def test_llmtech_endpoint_detection(self): + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + model, provider, api_key, api_base = get_llm_provider( + model="unsloth/Qwen3.8-27B-NVFP4", + custom_llm_provider=None, + api_base="https://api.llmtech.eu/v1", + api_key=None, + ) + + assert provider == "llmtech" + assert api_base == "https://api.llmtech.eu/v1" + + def test_llmtech_dynamic_config(self): + from litellm.llms.openai_like.dynamic_config import create_config_class + from litellm.llms.openai_like.json_loader import JSONProviderRegistry + + provider = JSONProviderRegistry.get("llmtech") + config_class = create_config_class(provider) + config = config_class() + + api_base, api_key = config._get_openai_compatible_provider_info(None, None) + assert api_base == "https://api.llmtech.eu/v1" +