From c51847b45b3ba74f00bae72bfdb6c3dc8109e47d Mon Sep 17 00:00:00 2001 From: sundar-flex Date: Tue, 4 Aug 2026 16:22:30 +0530 Subject: [PATCH 1/4] feat: add FlexAI as an OpenAI-compatible provider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FlexAI's Token Service (https://api.flex.ai/v1) is an OpenAI-compatible inference endpoint serving open-weight models. This registers it as the `flexai` provider via the JSON-based openai_like configuration. - litellm/llms/openai_like/providers.json: `flexai` entry, base_url https://api.flex.ai/v1, FLEXAI_API_KEY, FLEXAI_API_BASE override, /v1/chat/completions + /v1/responses - litellm/constants.py: `flexai` in openai_compatible_providers and https://api.flex.ai/v1 in openai_compatible_endpoints, so JSONProviderRegistry.get_by_base_url resolves an api_base override - litellm/types/utils.py: FLEXAI in the LlmProviders enum - litellm/proxy/public_endpoints/provider_create_fields.json: Add Model dropdown entry (api_key required, api_base optional) - model_prices_and_context_window.json (+ the packaged backup copy): 28 priced entries covering the full served roster — 23 chat, 1 embedding, 1 image, 1 speech, 2 transcription — with per-model cache-read pricing so cost tracking stays accurate under prompt caching - provider_endpoints_support.json: endpoint-support block - tests/test_litellm/llms/openai_like/test_flexai_provider.py: 18 tests Token pricing comes from FlexAI's GET /v1/models; per-image, per-character and per-minute media rates come from GET /v1/pricing, which is the only endpoint carrying them. The two agree on every chat row. Context windows come from FlexAI's serving catalog rather than the /v1/models metadata, which under-reports on some models (a 70,043-token prompt is accepted by a model whose metadata advertises 65,536). Non-chat entries use the cost fields the generic calculators actually read (`input_cost_per_image`, `input_cost_per_character`, `input_cost_per_second`); the output_* variants are ignored by those calculators and raise instead. Regression tests exercise the image and speech paths. No provider-specific branch is needed in get_llm_provider_logic.py: the generic JSON-provider lookup resolves flexai from providers.json by base URL, and already prefers an explicitly supplied api_key over the server environment. The tests cover that path. Co-Authored-By: Claude Opus 5 (1M context) --- litellm/constants.py | 2 + litellm/llms/openai_like/providers.json | 7 + ...odel_prices_and_context_window_backup.json | 379 ++++++++++++++++++ .../provider_create_fields.json | 28 ++ litellm/types/utils.py | 1 + model_prices_and_context_window.json | 379 ++++++++++++++++++ provider_endpoints_support.json | 17 + .../llms/openai_like/test_flexai_provider.py | 332 +++++++++++++++ 8 files changed, 1145 insertions(+) create mode 100644 tests/unit/llms/openai_like/test_flexai_provider.py diff --git a/litellm/constants.py b/litellm/constants.py index 8d05115e76e..30052f5ea7f 100644 --- a/litellm/constants.py +++ b/litellm/constants.py @@ -1097,6 +1097,7 @@ openai_compatible_endpoints: Final[list[str]] = [ "https://gigachat.devices.sberbank.ru/api/v1", "https://api.openinfer.ai/v1", "https://vanchin.streamlake.ai/api/gateway/v1/endpoints", + "https://api.flex.ai/v1", ] @@ -1182,6 +1183,7 @@ openai_compatible_providers: Final[list[str]] = [ "reka", "streamlake", "wally", + "flexai", # FlexAI Token Service - JSON-configured provider ] 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 f937e4d2f75..a3949ec41ad 100644 --- a/litellm/llms/openai_like/providers.json +++ b/litellm/llms/openai_like/providers.json @@ -314,5 +314,12 @@ "supports_function_calling": true, "supports_reasoning": true } + }, + "flexai": { + "base_url": "https://api.flex.ai/v1", + "api_key_env": "FLEXAI_API_KEY", + "api_base_env": "FLEXAI_API_BASE", + "base_class": "openai_gpt", + "supported_endpoints": ["/v1/chat/completions", "/v1/responses"] } } diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index a5b9a5cb457..891eea5cbde 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -64728,6 +64728,385 @@ ], "supports_audio_output": true }, + "flexai/bge-m3": { + "input_cost_per_token": 1e-08, + "litellm_provider": "flexai", + "max_input_tokens": 8192, + "max_tokens": 8192, + "mode": "embedding", + "output_cost_per_token": 0.0, + "output_vector_size": 1024, + "source": "https://platform.flex.ai/models" + }, + "flexai/DeepSeek-V4-Flash-0731": { + "cache_read_input_token_cost": 9e-09, + "input_cost_per_token": 6e-08, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 1.8e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/DeepSeek-V4.1-Flash": { + "cache_read_input_token_cost": 2.1e-08, + "input_cost_per_token": 1.4e-07, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 4.2e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/FLUX.1-schnell": { + "input_cost_per_image": 0.0005, + "litellm_provider": "flexai", + "mode": "image_generation", + "source": "https://platform.flex.ai/models" + }, + "flexai/gemma-4-26B-A4B-it": { + "cache_read_input_token_cost": 9e-09, + "input_cost_per_token": 6e-08, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 3.3e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/gemma-4-31b-it": { + "cache_read_input_token_cost": 1.5e-08, + "input_cost_per_token": 1e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 3.4e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/GLM-4.5-Air-FP8": { + "cache_read_input_token_cost": 2.1e-08, + "input_cost_per_token": 1.4e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 8.6e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/GLM-5.2": { + "cache_read_input_token_cost": 8.44e-08, + "input_cost_per_token": 5.625e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 1.8e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/GLM-5.3-Flash": { + "cache_read_input_token_cost": 1.35e-08, + "input_cost_per_token": 9e-08, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 2.8e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/gpt-oss-120b": { + "cache_read_input_token_cost": 4.5e-09, + "input_cost_per_token": 3e-08, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 1.7e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/gpt-oss-20b": { + "cache_read_input_token_cost": 3e-09, + "input_cost_per_token": 2e-08, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 1e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Kokoro-82M": { + "input_cost_per_character": 6.2e-07, + "litellm_provider": "flexai", + "mode": "audio_speech", + "source": "https://platform.flex.ai/models", + "supported_endpoints": [ + "/v1/audio/speech" + ] + }, + "flexai/Llama-3.3-70B-Instruct-FP8": { + "cache_read_input_token_cost": 2.03e-08, + "input_cost_per_token": 1.35e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 4e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Meta-Llama-3.1-8B-Instruct-FP8": { + "cache_read_input_token_cost": 3e-09, + "input_cost_per_token": 2e-08, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 5e-08, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/MiniMax-M2.7": { + "cache_read_input_token_cost": 3.6e-08, + "input_cost_per_token": 2.4e-07, + "litellm_provider": "flexai", + "max_input_tokens": 204800, + "max_output_tokens": 204800, + "max_tokens": 204800, + "mode": "chat", + "output_cost_per_token": 9.6e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Mistral-Nemo-Instruct-2407-FP8": { + "cache_read_input_token_cost": 2.8e-09, + "input_cost_per_token": 1.9e-08, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 3e-08, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Muse-Glimmer-30B": { + "cache_read_input_token_cost": 4.5e-08, + "input_cost_per_token": 3e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 1.2e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/NVIDIA-Nemotron-3.5-Lightning-30B-A3B": { + "cache_read_input_token_cost": 1.2e-08, + "input_cost_per_token": 8e-08, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 2e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/PaddleOCR-VL": { + "input_cost_per_token": 1.4e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 8e-07, + "source": "https://platform.flex.ai/models", + "supports_vision": true + }, + "flexai/parakeet-tdt-0.6b-v3": { + "input_cost_per_second": 2.5e-05, + "litellm_provider": "flexai", + "mode": "audio_transcription", + "output_cost_per_second": 0.0, + "source": "https://platform.flex.ai/models", + "supported_endpoints": [ + "/v1/audio/transcriptions" + ] + }, + "flexai/Qwen3-30B-A3B-Thinking-2507-FP8": { + "cache_read_input_token_cost": 3e-08, + "input_cost_per_token": 2e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 2.4e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Qwen3-8B-FP8": { + "cache_read_input_token_cost": 1.75e-08, + "input_cost_per_token": 1.17e-07, + "litellm_provider": "flexai", + "max_input_tokens": 40960, + "max_output_tokens": 40960, + "max_tokens": 40960, + "mode": "chat", + "output_cost_per_token": 4.55e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Qwen3-Coder-30B-A3B-Instruct-FP8": { + "cache_read_input_token_cost": 1.05e-08, + "input_cost_per_token": 7e-08, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 2.6e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Qwen3.5-9B": { + "cache_read_input_token_cost": 1.5e-08, + "input_cost_per_token": 1e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 1.5e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Qwen3.6-27B-FP8": { + "cache_read_input_token_cost": 5.85e-08, + "input_cost_per_token": 3.9e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 2.34e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Qwen3.6-35B-A3B-FP8": { + "cache_read_input_token_cost": 1.5e-08, + "input_cost_per_token": 1e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 9e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Qwen3.8-27B": { + "cache_read_input_token_cost": 2.25e-08, + "input_cost_per_token": 1.5e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 1.875e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Qwen3.8-Flash-Next": { + "cache_read_input_token_cost": 2.25e-08, + "input_cost_per_token": 1.5e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 4.7e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Step-3.7-Flash": { + "cache_read_input_token_cost": 3e-08, + "input_cost_per_token": 2e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 1.15e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/whisper-large-v3-turbo": { + "input_cost_per_second": 1.111666667e-05, + "litellm_provider": "flexai", + "mode": "audio_transcription", + "output_cost_per_second": 0.0, + "source": "https://platform.flex.ai/models", + "supported_endpoints": [ + "/v1/audio/transcriptions" + ] + }, "fallback_generalizations": { "rules": [ { diff --git a/litellm/proxy/public_endpoints/provider_create_fields.json b/litellm/proxy/public_endpoints/provider_create_fields.json index 5ded2fa5f5e..15d36711896 100644 --- a/litellm/proxy/public_endpoints/provider_create_fields.json +++ b/litellm/proxy/public_endpoints/provider_create_fields.json @@ -1701,6 +1701,34 @@ ], "default_model_placeholder": "gpt-3.5-turbo" }, + { + "provider": "FLEXAI", + "provider_display_name": "FlexAI", + "litellm_provider": "flexai", + "credential_fields": [ + { + "key": "api_key", + "label": "API Key", + "placeholder": null, + "tooltip": "Your FlexAI API key from platform.flex.ai", + "required": true, + "field_type": "password", + "options": null, + "default_value": null + }, + { + "key": "api_base", + "label": "API Base", + "placeholder": "https://api.flex.ai/v1", + "tooltip": "Defaults to https://api.flex.ai/v1", + "required": false, + "field_type": "text", + "options": null, + "default_value": null + } + ], + "default_model_placeholder": "flexai/gpt-oss-120b" + }, { "provider": "FRIENDLIAI", "provider_display_name": "Friendliai", diff --git a/litellm/types/utils.py b/litellm/types/utils.py index ba29a67a36c..adc97295c87 100644 --- a/litellm/types/utils.py +++ b/litellm/types/utils.py @@ -4781,6 +4781,7 @@ class LlmProviders(str, Enum): REKA = "reka" STREAMLAKE = "streamlake" WALLY = "wally" + FLEXAI = "flexai" 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 a5b9a5cb457..891eea5cbde 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -64728,6 +64728,385 @@ ], "supports_audio_output": true }, + "flexai/bge-m3": { + "input_cost_per_token": 1e-08, + "litellm_provider": "flexai", + "max_input_tokens": 8192, + "max_tokens": 8192, + "mode": "embedding", + "output_cost_per_token": 0.0, + "output_vector_size": 1024, + "source": "https://platform.flex.ai/models" + }, + "flexai/DeepSeek-V4-Flash-0731": { + "cache_read_input_token_cost": 9e-09, + "input_cost_per_token": 6e-08, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 1.8e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/DeepSeek-V4.1-Flash": { + "cache_read_input_token_cost": 2.1e-08, + "input_cost_per_token": 1.4e-07, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 4.2e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/FLUX.1-schnell": { + "input_cost_per_image": 0.0005, + "litellm_provider": "flexai", + "mode": "image_generation", + "source": "https://platform.flex.ai/models" + }, + "flexai/gemma-4-26B-A4B-it": { + "cache_read_input_token_cost": 9e-09, + "input_cost_per_token": 6e-08, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 3.3e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/gemma-4-31b-it": { + "cache_read_input_token_cost": 1.5e-08, + "input_cost_per_token": 1e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 3.4e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/GLM-4.5-Air-FP8": { + "cache_read_input_token_cost": 2.1e-08, + "input_cost_per_token": 1.4e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 8.6e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/GLM-5.2": { + "cache_read_input_token_cost": 8.44e-08, + "input_cost_per_token": 5.625e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 1.8e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/GLM-5.3-Flash": { + "cache_read_input_token_cost": 1.35e-08, + "input_cost_per_token": 9e-08, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 2.8e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/gpt-oss-120b": { + "cache_read_input_token_cost": 4.5e-09, + "input_cost_per_token": 3e-08, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 1.7e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/gpt-oss-20b": { + "cache_read_input_token_cost": 3e-09, + "input_cost_per_token": 2e-08, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 1e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Kokoro-82M": { + "input_cost_per_character": 6.2e-07, + "litellm_provider": "flexai", + "mode": "audio_speech", + "source": "https://platform.flex.ai/models", + "supported_endpoints": [ + "/v1/audio/speech" + ] + }, + "flexai/Llama-3.3-70B-Instruct-FP8": { + "cache_read_input_token_cost": 2.03e-08, + "input_cost_per_token": 1.35e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 4e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Meta-Llama-3.1-8B-Instruct-FP8": { + "cache_read_input_token_cost": 3e-09, + "input_cost_per_token": 2e-08, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 5e-08, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/MiniMax-M2.7": { + "cache_read_input_token_cost": 3.6e-08, + "input_cost_per_token": 2.4e-07, + "litellm_provider": "flexai", + "max_input_tokens": 204800, + "max_output_tokens": 204800, + "max_tokens": 204800, + "mode": "chat", + "output_cost_per_token": 9.6e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Mistral-Nemo-Instruct-2407-FP8": { + "cache_read_input_token_cost": 2.8e-09, + "input_cost_per_token": 1.9e-08, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 3e-08, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Muse-Glimmer-30B": { + "cache_read_input_token_cost": 4.5e-08, + "input_cost_per_token": 3e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 1.2e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/NVIDIA-Nemotron-3.5-Lightning-30B-A3B": { + "cache_read_input_token_cost": 1.2e-08, + "input_cost_per_token": 8e-08, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 2e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/PaddleOCR-VL": { + "input_cost_per_token": 1.4e-07, + "litellm_provider": "flexai", + "max_input_tokens": 131072, + "max_output_tokens": 131072, + "max_tokens": 131072, + "mode": "chat", + "output_cost_per_token": 8e-07, + "source": "https://platform.flex.ai/models", + "supports_vision": true + }, + "flexai/parakeet-tdt-0.6b-v3": { + "input_cost_per_second": 2.5e-05, + "litellm_provider": "flexai", + "mode": "audio_transcription", + "output_cost_per_second": 0.0, + "source": "https://platform.flex.ai/models", + "supported_endpoints": [ + "/v1/audio/transcriptions" + ] + }, + "flexai/Qwen3-30B-A3B-Thinking-2507-FP8": { + "cache_read_input_token_cost": 3e-08, + "input_cost_per_token": 2e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 2.4e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Qwen3-8B-FP8": { + "cache_read_input_token_cost": 1.75e-08, + "input_cost_per_token": 1.17e-07, + "litellm_provider": "flexai", + "max_input_tokens": 40960, + "max_output_tokens": 40960, + "max_tokens": 40960, + "mode": "chat", + "output_cost_per_token": 4.55e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Qwen3-Coder-30B-A3B-Instruct-FP8": { + "cache_read_input_token_cost": 1.05e-08, + "input_cost_per_token": 7e-08, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 2.6e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true + }, + "flexai/Qwen3.5-9B": { + "cache_read_input_token_cost": 1.5e-08, + "input_cost_per_token": 1e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 1.5e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Qwen3.6-27B-FP8": { + "cache_read_input_token_cost": 5.85e-08, + "input_cost_per_token": 3.9e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 2.34e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Qwen3.6-35B-A3B-FP8": { + "cache_read_input_token_cost": 1.5e-08, + "input_cost_per_token": 1e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 9e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Qwen3.8-27B": { + "cache_read_input_token_cost": 2.25e-08, + "input_cost_per_token": 1.5e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 1.875e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Qwen3.8-Flash-Next": { + "cache_read_input_token_cost": 2.25e-08, + "input_cost_per_token": 1.5e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 4.7e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/Step-3.7-Flash": { + "cache_read_input_token_cost": 3e-08, + "input_cost_per_token": 2e-07, + "litellm_provider": "flexai", + "max_input_tokens": 262144, + "max_output_tokens": 262144, + "max_tokens": 262144, + "mode": "chat", + "output_cost_per_token": 1.15e-06, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/whisper-large-v3-turbo": { + "input_cost_per_second": 1.111666667e-05, + "litellm_provider": "flexai", + "mode": "audio_transcription", + "output_cost_per_second": 0.0, + "source": "https://platform.flex.ai/models", + "supported_endpoints": [ + "/v1/audio/transcriptions" + ] + }, "fallback_generalizations": { "rules": [ { diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json index 00fee0a0d5a..efa22a6a7ad 100644 --- a/provider_endpoints_support.json +++ b/provider_endpoints_support.json @@ -5509,6 +5509,23 @@ "a2a": true, "generateContent": true } + }, + "flexai": { + "display_name": "FlexAI (`flexai`)", + "url": "https://docs.litellm.ai/docs/providers/flexai", + "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 + } } }, "endpoints": { diff --git a/tests/unit/llms/openai_like/test_flexai_provider.py b/tests/unit/llms/openai_like/test_flexai_provider.py new file mode 100644 index 00000000000..dc4c65b3ab1 --- /dev/null +++ b/tests/unit/llms/openai_like/test_flexai_provider.py @@ -0,0 +1,332 @@ +""" +Tests for FlexAI provider configuration and integration. +""" + +import json +import os + +import litellm + +# a flagship model FlexAI pins always-on; used only for provider-resolution +# assertions, which do not require the model to be reachable +FLEXAI_MODEL = "gpt-oss-120b" +FLEXAI_BASE_URL = "https://api.flex.ai/v1" + + +class TestFlexAIProviderConfig: + """Test FlexAI provider configuration""" + + def test_flexai_in_provider_list(self): + """Test that flexai is in the provider list""" + from litellm import LlmProviders + + assert hasattr(LlmProviders, "FLEXAI") + assert LlmProviders.FLEXAI.value == "flexai" + assert "flexai" in litellm.provider_list + + def test_flexai_json_config_exists(self): + """Test that flexai is configured in providers.json""" + from litellm.llms.openai_like.json_loader import JSONProviderRegistry + + assert JSONProviderRegistry.exists("flexai") + + flexai = JSONProviderRegistry.get("flexai") + assert flexai is not None + assert flexai.base_url == FLEXAI_BASE_URL + assert flexai.api_key_env == "FLEXAI_API_KEY" + assert flexai.api_base_env == "FLEXAI_API_BASE" + + def test_flexai_supports_responses_api(self): + """Test that flexai declares Responses API support""" + from litellm.llms.openai_like.json_loader import JSONProviderRegistry + + assert JSONProviderRegistry.supports_responses_api("flexai") + + def test_flexai_in_openai_compatible_providers(self): + """Test that flexai is in the openai_compatible_providers list""" + from litellm.constants import ( + openai_compatible_endpoints, + openai_compatible_providers, + ) + + assert "flexai" in openai_compatible_providers + assert FLEXAI_BASE_URL in openai_compatible_endpoints + + def test_flexai_provider_resolution(self): + """Test that provider resolution finds flexai and returns the default base URL""" + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + model, provider, api_key, api_base = get_llm_provider( + model=f"flexai/{FLEXAI_MODEL}", + custom_llm_provider=None, + api_base=None, + api_key=None, + ) + + assert model == FLEXAI_MODEL + assert provider == "flexai" + assert api_base == FLEXAI_BASE_URL + + def test_flexai_api_base_override(self): + """Test that an explicit api_base / api_key overrides the default""" + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + model, provider, api_key, api_base = get_llm_provider( + model=f"flexai/{FLEXAI_MODEL}", + custom_llm_provider=None, + api_base="https://tokens.staging.flex.ai/v1", + api_key="sk-test", + ) + + assert provider == "flexai" + assert api_base == "https://tokens.staging.flex.ai/v1" + assert api_key == "sk-test" + + def test_flexai_env_key_resolution(self, monkeypatch): + """Test that the key is read from FLEXAI_API_KEY when not passed explicitly""" + from litellm.llms.openai_like.dynamic_config import create_config_class + from litellm.llms.openai_like.json_loader import JSONProviderRegistry + + monkeypatch.setenv("FLEXAI_API_KEY", "sk-flexai-env") + + config = create_config_class(JSONProviderRegistry.get("flexai"))() + api_base, api_key = config._get_openai_compatible_provider_info(None, None) + + assert api_base == FLEXAI_BASE_URL + assert api_key == "sk-flexai-env" + + def test_flexai_url_autodetection(self): + """Test that api_base=api.flex.ai/v1 auto-sets custom_llm_provider=flexai""" + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + model, provider, api_key, api_base = get_llm_provider( + model=FLEXAI_MODEL, + custom_llm_provider=None, + api_base=FLEXAI_BASE_URL, + api_key=None, + ) + + assert provider == "flexai" + assert api_base == FLEXAI_BASE_URL + + def test_flexai_url_autodetection_prefers_caller_key(self, monkeypatch): + """An explicit api_key must win over the server's FLEXAI_API_KEY. + + `completion()` overwrites api_key with dynamic_api_key whenever it is + set, so reading the environment unconditionally here would spend the + server's credential on a caller-supplied api_base. + """ + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + monkeypatch.setenv("FLEXAI_API_KEY", "sk-server-env") + + _, provider, api_key, _ = get_llm_provider( + model=FLEXAI_MODEL, + custom_llm_provider=None, + api_base=FLEXAI_BASE_URL, + api_key="sk-caller", + ) + + assert provider == "flexai" + assert api_key == "sk-caller" + + def test_flexai_url_autodetection_falls_back_to_env_key(self, monkeypatch): + """With no explicit key, the server environment is still used""" + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + monkeypatch.setenv("FLEXAI_API_KEY", "sk-server-env") + + _, provider, api_key, _ = get_llm_provider( + model=FLEXAI_MODEL, + custom_llm_provider=None, + api_base=FLEXAI_BASE_URL, + api_key=None, + ) + + assert provider == "flexai" + assert api_key == "sk-server-env" + + def test_flexai_router_config(self): + """Test that flexai can be used in Router configuration""" + from litellm import Router + + router = Router( + model_list=[ + { + "model_name": "flexai-chat", + "litellm_params": { + "model": f"flexai/{FLEXAI_MODEL}", + "api_key": "test-key", + }, + } + ] + ) + + assert len(router.model_list) == 1 + assert router.model_list[0]["model_name"] == "flexai-chat" + + +class TestFlexAICostMap: + """Test the FlexAI entries in the model cost map""" + + @staticmethod + def _cost_map(): + repo_root = os.path.abspath( + os.path.join(os.path.dirname(__file__), "../../../..") + ) + with open(os.path.join(repo_root, "model_prices_and_context_window.json")) as f: + return json.load(f) + + @staticmethod + def _backup_cost_map(): + repo_root = os.path.abspath( + os.path.join(os.path.dirname(__file__), "../../../..") + ) + path = os.path.join( + repo_root, "litellm", "model_prices_and_context_window_backup.json" + ) + with open(path) as f: + return json.load(f) + + def test_flexai_entries_present(self): + """Test that flexai models are priced in the cost map""" + entries = { + k: v for k, v in self._cost_map().items() if k.startswith("flexai/") + } + + assert entries, "no flexai/* entries in the cost map" + for key, entry in entries.items(): + assert entry["litellm_provider"] == "flexai", key + assert entry.get("mode"), key + + def test_flexai_chat_entries_are_priced(self): + """Test that every flexai chat model carries per-token pricing + context""" + entries = { + k: v + for k, v in self._cost_map().items() + if k.startswith("flexai/") and v.get("mode") == "chat" + } + + assert entries, "no flexai/* chat entries in the cost map" + for key, entry in entries.items(): + assert entry["input_cost_per_token"] > 0, key + assert entry["output_cost_per_token"] > 0, key + assert entry["max_input_tokens"] > 0, key + assert entry["max_output_tokens"] > 0, key + + def test_flexai_entries_match_packaged_backup(self): + """Test that the packaged backup carries the same flexai entries. + + litellm loads the packaged backup when the remote cost map is + unavailable (or when LITELLM_LOCAL_MODEL_COST_MAP=True), so the two + files must not drift. + """ + root = {k: v for k, v in self._cost_map().items() if k.startswith("flexai/")} + backup = { + k: v for k, v in self._backup_cost_map().items() if k.startswith("flexai/") + } + + assert root == backup + + def test_flexai_non_chat_entries_use_calculator_readable_fields(self): + """Non-chat entries must carry the cost fields the generic calculators read. + + `default_image_cost_calculator` reads `input_cost_per_image` / + `input_cost_per_pixel`, and `select_cost_metric_for_model` requires + `input_cost_per_character` (or `input_cost_per_token`) for speech. Using + the `output_*` variants instead makes cost calculation raise rather than + return the configured cost. + """ + readable_fields = { + "image_generation": ("input_cost_per_image", "input_cost_per_pixel"), + "audio_speech": ("input_cost_per_character", "input_cost_per_token"), + "audio_transcription": ("input_cost_per_second", "input_cost_per_token"), + "embedding": ("input_cost_per_token",), + } + + entries = { + k: v + for k, v in self._cost_map().items() + if k.startswith("flexai/") and v.get("mode") != "chat" + } + assert entries, "no non-chat flexai/* entries in the cost map" + + for key, entry in entries.items(): + options = readable_fields.get(entry["mode"]) + assert options, f"{key}: unhandled mode {entry['mode']}" + assert any(field in entry for field in options), ( + f"{key} (mode={entry['mode']}) has none of {options}" + ) + + def test_flexai_image_cost_calculation(self): + """Test that image cost resolves through the generic image calculator""" + from litellm.cost_calculator import default_image_cost_calculator + + cost_map = self._cost_map() + key = next( + k + for k, v in cost_map.items() + if k.startswith("flexai/") and v.get("mode") == "image_generation" + ) + per_image = cost_map[key]["input_cost_per_image"] + + for n in (1, 3): + cost = default_image_cost_calculator( + model=key, custom_llm_provider="flexai", n=n, quality=None, size=None + ) + assert cost == per_image * n + + def test_flexai_speech_cost_calculation(self): + """Test that TTS cost resolves per input character""" + from litellm.cost_calculator import cost_per_token + from litellm.litellm_core_utils.llm_cost_calc.utils import ( + select_cost_metric_for_model, + ) + + cost_map = self._cost_map() + key = next( + k + for k, v in cost_map.items() + if k.startswith("flexai/") and v.get("mode") == "audio_speech" + ) + model = key.split("/", 1)[1] + per_character = cost_map[key]["input_cost_per_character"] + + model_info = litellm.get_model_info(model=model, custom_llm_provider="flexai") + assert select_cost_metric_for_model(model_info) == "cost_per_character" + + prompt_cost, completion_cost = cost_per_token( + model=model, + custom_llm_provider="flexai", + call_type="speech", + prompt_characters=1000, + ) + assert prompt_cost + completion_cost == per_character * 1000 + + def test_flexai_cost_calculation(self): + """Test that completion_cost resolves for a flexai chat model""" + from litellm.types.utils import Choices, Message, ModelResponse, Usage + + cost_map = self._cost_map() + key = next( + k + for k, v in cost_map.items() + if k.startswith("flexai/") and v.get("mode") == "chat" + ) + entry = cost_map[key] + + response = ModelResponse( + model=key.split("/", 1)[1], + choices=[Choices(message=Message(role="assistant", content="ok"))], + usage=Usage(prompt_tokens=1000, completion_tokens=500, total_tokens=1500), + ) + response._hidden_params = {"custom_llm_provider": "flexai"} + + cost = litellm.completion_cost( + completion_response=response, custom_llm_provider="flexai", model=key + ) + + expected = ( + 1000 * entry["input_cost_per_token"] + 500 * entry["output_cost_per_token"] + ) + assert cost == expected From eff0ca57b4ac4d15304a56f44ef6d66bdf03b061 Mon Sep 17 00:00:00 2001 From: sundar-flex Date: Thu, 22 Oct 2026 19:05:12 -0700 Subject: [PATCH 2/4] feat(flexai): sync catalog and prices to 2026-10-22 Reprices every flexai/ entry from FlexAI's current catalog (GET /v1/models, matching flex.ai/pricing), adds cache_read_input_token_cost from the cached-input rate, sets supports_reasoning where the model supports it, corrects GLM-5.2's context to 1M tokens, and adds DeepSeek-V4.1-Flash-1017. Root and packaged backup cost maps stay identical. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...odel_prices_and_context_window_backup.json | 145 +++++++++++------- model_prices_and_context_window.json | 145 +++++++++++------- 2 files changed, 180 insertions(+), 110 deletions(-) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 891eea5cbde..9a4ed727210 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -64739,29 +64739,46 @@ "source": "https://platform.flex.ai/models" }, "flexai/DeepSeek-V4-Flash-0731": { - "cache_read_input_token_cost": 9e-09, - "input_cost_per_token": 6e-08, + "cache_read_input_token_cost": 1.78e-08, + "input_cost_per_token": 1.19e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 1.8e-07, + "output_cost_per_token": 2.38e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/DeepSeek-V4.1-Flash": { - "cache_read_input_token_cost": 2.1e-08, - "input_cost_per_token": 1.4e-07, + "cache_read_input_token_cost": 1.54e-08, + "input_cost_per_token": 1.03e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 4.2e-07, + "output_cost_per_token": 7.15e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/DeepSeek-V4.1-Flash-1017": { + "cache_read_input_token_cost": 2.25e-08, + "input_cost_per_token": 1.5e-07, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 6e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -64772,30 +64789,32 @@ "source": "https://platform.flex.ai/models" }, "flexai/gemma-4-26B-A4B-it": { - "cache_read_input_token_cost": 9e-09, - "input_cost_per_token": 6e-08, + "cache_read_input_token_cost": 1.05e-08, + "input_cost_per_token": 7e-08, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 3.3e-07, + "output_cost_per_token": 2.4e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/gemma-4-31b-it": { - "cache_read_input_token_cost": 1.5e-08, - "input_cost_per_token": 1e-07, + "cache_read_input_token_cost": 2.1e-08, + "input_cost_per_token": 1.4e-07, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 3.4e-07, + "output_cost_per_token": 4e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -64810,46 +64829,50 @@ "output_cost_per_token": 8.6e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/GLM-5.2": { - "cache_read_input_token_cost": 8.44e-08, - "input_cost_per_token": 5.625e-07, - "litellm_provider": "flexai", - "max_input_tokens": 131072, - "max_output_tokens": 131072, - "max_tokens": 131072, - "mode": "chat", - "output_cost_per_token": 1.8e-06, - "source": "https://platform.flex.ai/models", - "supports_function_calling": true, - "supports_tool_choice": true - }, - "flexai/GLM-5.3-Flash": { - "cache_read_input_token_cost": 1.35e-08, - "input_cost_per_token": 9e-08, + "cache_read_input_token_cost": 1.449e-07, + "input_cost_per_token": 9.66e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 2.8e-07, + "output_cost_per_token": 3.036e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, + "supports_tool_choice": true + }, + "flexai/GLM-5.3-Flash": { + "cache_read_input_token_cost": 1.2e-08, + "input_cost_per_token": 8e-08, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 5e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/gpt-oss-120b": { - "cache_read_input_token_cost": 4.5e-09, - "input_cost_per_token": 3e-08, + "cache_read_input_token_cost": 7.5e-09, + "input_cost_per_token": 5e-08, "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, "max_tokens": 131072, "mode": "chat", - "output_cost_per_token": 1.7e-07, + "output_cost_per_token": 2.5e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/gpt-oss-20b": { @@ -64863,10 +64886,11 @@ "output_cost_per_token": 1e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/Kokoro-82M": { - "input_cost_per_character": 6.2e-07, + "input_cost_per_character": 9.9e-07, "litellm_provider": "flexai", "mode": "audio_speech", "source": "https://platform.flex.ai/models", @@ -64875,14 +64899,14 @@ ] }, "flexai/Llama-3.3-70B-Instruct-FP8": { - "cache_read_input_token_cost": 2.03e-08, - "input_cost_per_token": 1.35e-07, + "cache_read_input_token_cost": 3.3e-08, + "input_cost_per_token": 2.2e-07, "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, "max_tokens": 131072, "mode": "chat", - "output_cost_per_token": 4e-07, + "output_cost_per_token": 5e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, "supports_tool_choice": true @@ -64901,21 +64925,22 @@ "supports_tool_choice": true }, "flexai/MiniMax-M2.7": { - "cache_read_input_token_cost": 3.6e-08, - "input_cost_per_token": 2.4e-07, + "cache_read_input_token_cost": 4.5e-08, + "input_cost_per_token": 3e-07, "litellm_provider": "flexai", "max_input_tokens": 204800, "max_output_tokens": 204800, "max_tokens": 204800, "mode": "chat", - "output_cost_per_token": 9.6e-07, + "output_cost_per_token": 1.2e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/Mistral-Nemo-Instruct-2407-FP8": { - "cache_read_input_token_cost": 2.8e-09, - "input_cost_per_token": 1.9e-08, + "cache_read_input_token_cost": 3.4e-09, + "input_cost_per_token": 2.3e-08, "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, @@ -64937,20 +64962,22 @@ "output_cost_per_token": 1.2e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/NVIDIA-Nemotron-3.5-Lightning-30B-A3B": { - "cache_read_input_token_cost": 1.2e-08, - "input_cost_per_token": 8e-08, + "cache_read_input_token_cost": 9e-09, + "input_cost_per_token": 6e-08, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 2e-07, + "output_cost_per_token": 1.6e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/PaddleOCR-VL": { @@ -64985,6 +65012,7 @@ "output_cost_per_token": 2.4e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/Qwen3-8B-FP8": { @@ -64998,6 +65026,7 @@ "output_cost_per_token": 4.55e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/Qwen3-Coder-30B-A3B-Instruct-FP8": { @@ -65008,36 +65037,38 @@ "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 2.6e-07, + "output_cost_per_token": 2.8e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, "supports_tool_choice": true }, "flexai/Qwen3.5-9B": { - "cache_read_input_token_cost": 1.5e-08, - "input_cost_per_token": 1e-07, + "cache_read_input_token_cost": 1.8e-08, + "input_cost_per_token": 1.2e-07, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 1.5e-07, + "output_cost_per_token": 1.8e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/Qwen3.6-27B-FP8": { - "cache_read_input_token_cost": 5.85e-08, - "input_cost_per_token": 3.9e-07, + "cache_read_input_token_cost": 4.5e-08, + "input_cost_per_token": 3e-07, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 2.34e-06, + "output_cost_per_token": 3e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -65049,23 +65080,25 @@ "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 9e-07, + "output_cost_per_token": 9.5e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/Qwen3.8-27B": { - "cache_read_input_token_cost": 2.25e-08, - "input_cost_per_token": 1.5e-07, + "cache_read_input_token_cost": 3e-08, + "input_cost_per_token": 2e-07, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 1.875e-06, + "output_cost_per_token": 2.5e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -65080,6 +65113,7 @@ "output_cost_per_token": 4.7e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -65094,11 +65128,12 @@ "output_cost_per_token": 1.15e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/whisper-large-v3-turbo": { - "input_cost_per_second": 1.111666667e-05, + "input_cost_per_second": 3.333333333e-06, "litellm_provider": "flexai", "mode": "audio_transcription", "output_cost_per_second": 0.0, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 891eea5cbde..9a4ed727210 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -64739,29 +64739,46 @@ "source": "https://platform.flex.ai/models" }, "flexai/DeepSeek-V4-Flash-0731": { - "cache_read_input_token_cost": 9e-09, - "input_cost_per_token": 6e-08, + "cache_read_input_token_cost": 1.78e-08, + "input_cost_per_token": 1.19e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 1.8e-07, + "output_cost_per_token": 2.38e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/DeepSeek-V4.1-Flash": { - "cache_read_input_token_cost": 2.1e-08, - "input_cost_per_token": 1.4e-07, + "cache_read_input_token_cost": 1.54e-08, + "input_cost_per_token": 1.03e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 4.2e-07, + "output_cost_per_token": 7.15e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, + "supports_tool_choice": true, + "supports_vision": true + }, + "flexai/DeepSeek-V4.1-Flash-1017": { + "cache_read_input_token_cost": 2.25e-08, + "input_cost_per_token": 1.5e-07, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 6e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -64772,30 +64789,32 @@ "source": "https://platform.flex.ai/models" }, "flexai/gemma-4-26B-A4B-it": { - "cache_read_input_token_cost": 9e-09, - "input_cost_per_token": 6e-08, + "cache_read_input_token_cost": 1.05e-08, + "input_cost_per_token": 7e-08, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 3.3e-07, + "output_cost_per_token": 2.4e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/gemma-4-31b-it": { - "cache_read_input_token_cost": 1.5e-08, - "input_cost_per_token": 1e-07, + "cache_read_input_token_cost": 2.1e-08, + "input_cost_per_token": 1.4e-07, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 3.4e-07, + "output_cost_per_token": 4e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -64810,46 +64829,50 @@ "output_cost_per_token": 8.6e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/GLM-5.2": { - "cache_read_input_token_cost": 8.44e-08, - "input_cost_per_token": 5.625e-07, - "litellm_provider": "flexai", - "max_input_tokens": 131072, - "max_output_tokens": 131072, - "max_tokens": 131072, - "mode": "chat", - "output_cost_per_token": 1.8e-06, - "source": "https://platform.flex.ai/models", - "supports_function_calling": true, - "supports_tool_choice": true - }, - "flexai/GLM-5.3-Flash": { - "cache_read_input_token_cost": 1.35e-08, - "input_cost_per_token": 9e-08, + "cache_read_input_token_cost": 1.449e-07, + "input_cost_per_token": 9.66e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 2.8e-07, + "output_cost_per_token": 3.036e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, + "supports_tool_choice": true + }, + "flexai/GLM-5.3-Flash": { + "cache_read_input_token_cost": 1.2e-08, + "input_cost_per_token": 8e-08, + "litellm_provider": "flexai", + "max_input_tokens": 1048576, + "max_output_tokens": 1048576, + "max_tokens": 1048576, + "mode": "chat", + "output_cost_per_token": 5e-07, + "source": "https://platform.flex.ai/models", + "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/gpt-oss-120b": { - "cache_read_input_token_cost": 4.5e-09, - "input_cost_per_token": 3e-08, + "cache_read_input_token_cost": 7.5e-09, + "input_cost_per_token": 5e-08, "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, "max_tokens": 131072, "mode": "chat", - "output_cost_per_token": 1.7e-07, + "output_cost_per_token": 2.5e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/gpt-oss-20b": { @@ -64863,10 +64886,11 @@ "output_cost_per_token": 1e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/Kokoro-82M": { - "input_cost_per_character": 6.2e-07, + "input_cost_per_character": 9.9e-07, "litellm_provider": "flexai", "mode": "audio_speech", "source": "https://platform.flex.ai/models", @@ -64875,14 +64899,14 @@ ] }, "flexai/Llama-3.3-70B-Instruct-FP8": { - "cache_read_input_token_cost": 2.03e-08, - "input_cost_per_token": 1.35e-07, + "cache_read_input_token_cost": 3.3e-08, + "input_cost_per_token": 2.2e-07, "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, "max_tokens": 131072, "mode": "chat", - "output_cost_per_token": 4e-07, + "output_cost_per_token": 5e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, "supports_tool_choice": true @@ -64901,21 +64925,22 @@ "supports_tool_choice": true }, "flexai/MiniMax-M2.7": { - "cache_read_input_token_cost": 3.6e-08, - "input_cost_per_token": 2.4e-07, + "cache_read_input_token_cost": 4.5e-08, + "input_cost_per_token": 3e-07, "litellm_provider": "flexai", "max_input_tokens": 204800, "max_output_tokens": 204800, "max_tokens": 204800, "mode": "chat", - "output_cost_per_token": 9.6e-07, + "output_cost_per_token": 1.2e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/Mistral-Nemo-Instruct-2407-FP8": { - "cache_read_input_token_cost": 2.8e-09, - "input_cost_per_token": 1.9e-08, + "cache_read_input_token_cost": 3.4e-09, + "input_cost_per_token": 2.3e-08, "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, @@ -64937,20 +64962,22 @@ "output_cost_per_token": 1.2e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/NVIDIA-Nemotron-3.5-Lightning-30B-A3B": { - "cache_read_input_token_cost": 1.2e-08, - "input_cost_per_token": 8e-08, + "cache_read_input_token_cost": 9e-09, + "input_cost_per_token": 6e-08, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 2e-07, + "output_cost_per_token": 1.6e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/PaddleOCR-VL": { @@ -64985,6 +65012,7 @@ "output_cost_per_token": 2.4e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/Qwen3-8B-FP8": { @@ -64998,6 +65026,7 @@ "output_cost_per_token": 4.55e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true }, "flexai/Qwen3-Coder-30B-A3B-Instruct-FP8": { @@ -65008,36 +65037,38 @@ "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 2.6e-07, + "output_cost_per_token": 2.8e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, "supports_tool_choice": true }, "flexai/Qwen3.5-9B": { - "cache_read_input_token_cost": 1.5e-08, - "input_cost_per_token": 1e-07, + "cache_read_input_token_cost": 1.8e-08, + "input_cost_per_token": 1.2e-07, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 1.5e-07, + "output_cost_per_token": 1.8e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/Qwen3.6-27B-FP8": { - "cache_read_input_token_cost": 5.85e-08, - "input_cost_per_token": 3.9e-07, + "cache_read_input_token_cost": 4.5e-08, + "input_cost_per_token": 3e-07, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 2.34e-06, + "output_cost_per_token": 3e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -65049,23 +65080,25 @@ "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 9e-07, + "output_cost_per_token": 9.5e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/Qwen3.8-27B": { - "cache_read_input_token_cost": 2.25e-08, - "input_cost_per_token": 1.5e-07, + "cache_read_input_token_cost": 3e-08, + "input_cost_per_token": 2e-07, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, "max_tokens": 262144, "mode": "chat", - "output_cost_per_token": 1.875e-06, + "output_cost_per_token": 2.5e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -65080,6 +65113,7 @@ "output_cost_per_token": 4.7e-07, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, @@ -65094,11 +65128,12 @@ "output_cost_per_token": 1.15e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, + "supports_reasoning": true, "supports_tool_choice": true, "supports_vision": true }, "flexai/whisper-large-v3-turbo": { - "input_cost_per_second": 1.111666667e-05, + "input_cost_per_second": 3.333333333e-06, "litellm_provider": "flexai", "mode": "audio_transcription", "output_cost_per_second": 0.0, From bcc39f1a69d0c67cf821d0dfaf0d689a61b59428 Mon Sep 17 00:00:00 2001 From: sundar-flex Date: Thu, 29 Oct 2026 16:53:59 -0700 Subject: [PATCH 3/4] feat(flexai): sync catalog to 2026-10-29; drop retired max_tokens - Remove DeepSeek-V4.1-Flash and Qwen3-8B-FP8, which FlexAI no longer serves (absent from GET /v1/models on 2026-10-29). - GLM-5.2 prices follow the catalog: $0.70 input, $2.20 output, $0.105 cached input per 1M tokens. - Drop the legacy max_tokens field from every flexai/* row, following #48471; max_input_tokens and max_output_tokens already carry the limits. - Main and backup cost maps stay identical for flexai/* rows. Co-Authored-By: Claude Opus 5.5 (1M context) --- ...odel_prices_and_context_window_backup.json | 60 +------------------ model_prices_and_context_window.json | 60 +------------------ 2 files changed, 6 insertions(+), 114 deletions(-) diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 9a4ed727210..486a9490510 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -64732,7 +64732,6 @@ "input_cost_per_token": 1e-08, "litellm_provider": "flexai", "max_input_tokens": 8192, - "max_tokens": 8192, "mode": "embedding", "output_cost_per_token": 0.0, "output_vector_size": 1024, @@ -64744,7 +64743,6 @@ "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", "output_cost_per_token": 2.38e-07, "source": "https://platform.flex.ai/models", @@ -64752,28 +64750,12 @@ "supports_reasoning": true, "supports_tool_choice": true }, - "flexai/DeepSeek-V4.1-Flash": { - "cache_read_input_token_cost": 1.54e-08, - "input_cost_per_token": 1.03e-07, - "litellm_provider": "flexai", - "max_input_tokens": 1048576, - "max_output_tokens": 1048576, - "max_tokens": 1048576, - "mode": "chat", - "output_cost_per_token": 7.15e-07, - "source": "https://platform.flex.ai/models", - "supports_function_calling": true, - "supports_reasoning": true, - "supports_tool_choice": true, - "supports_vision": true - }, "flexai/DeepSeek-V4.1-Flash-1017": { "cache_read_input_token_cost": 2.25e-08, "input_cost_per_token": 1.5e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", "output_cost_per_token": 6e-07, "source": "https://platform.flex.ai/models", @@ -64794,7 +64776,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 2.4e-07, "source": "https://platform.flex.ai/models", @@ -64809,7 +64790,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 4e-07, "source": "https://platform.flex.ai/models", @@ -64824,7 +64804,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 8.6e-07, "source": "https://platform.flex.ai/models", @@ -64833,14 +64812,13 @@ "supports_tool_choice": true }, "flexai/GLM-5.2": { - "cache_read_input_token_cost": 1.449e-07, - "input_cost_per_token": 9.66e-07, + "cache_read_input_token_cost": 1.05e-07, + "input_cost_per_token": 7e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 3.036e-06, + "output_cost_per_token": 2.2e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, "supports_reasoning": true, @@ -64852,7 +64830,6 @@ "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", "output_cost_per_token": 5e-07, "source": "https://platform.flex.ai/models", @@ -64867,7 +64844,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 2.5e-07, "source": "https://platform.flex.ai/models", @@ -64881,7 +64857,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 1e-07, "source": "https://platform.flex.ai/models", @@ -64904,7 +64879,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 5e-07, "source": "https://platform.flex.ai/models", @@ -64917,7 +64891,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 5e-08, "source": "https://platform.flex.ai/models", @@ -64930,7 +64903,6 @@ "litellm_provider": "flexai", "max_input_tokens": 204800, "max_output_tokens": 204800, - "max_tokens": 204800, "mode": "chat", "output_cost_per_token": 1.2e-06, "source": "https://platform.flex.ai/models", @@ -64944,7 +64916,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 3e-08, "source": "https://platform.flex.ai/models", @@ -64957,7 +64928,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 1.2e-06, "source": "https://platform.flex.ai/models", @@ -64972,7 +64942,6 @@ "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", "output_cost_per_token": 1.6e-07, "source": "https://platform.flex.ai/models", @@ -64985,7 +64954,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 8e-07, "source": "https://platform.flex.ai/models", @@ -65007,7 +64975,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 2.4e-06, "source": "https://platform.flex.ai/models", @@ -65015,27 +64982,12 @@ "supports_reasoning": true, "supports_tool_choice": true }, - "flexai/Qwen3-8B-FP8": { - "cache_read_input_token_cost": 1.75e-08, - "input_cost_per_token": 1.17e-07, - "litellm_provider": "flexai", - "max_input_tokens": 40960, - "max_output_tokens": 40960, - "max_tokens": 40960, - "mode": "chat", - "output_cost_per_token": 4.55e-07, - "source": "https://platform.flex.ai/models", - "supports_function_calling": true, - "supports_reasoning": true, - "supports_tool_choice": true - }, "flexai/Qwen3-Coder-30B-A3B-Instruct-FP8": { "cache_read_input_token_cost": 1.05e-08, "input_cost_per_token": 7e-08, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 2.8e-07, "source": "https://platform.flex.ai/models", @@ -65048,7 +65000,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 1.8e-07, "source": "https://platform.flex.ai/models", @@ -65063,7 +65014,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 3e-06, "source": "https://platform.flex.ai/models", @@ -65078,7 +65028,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 9.5e-07, "source": "https://platform.flex.ai/models", @@ -65093,7 +65042,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 2.5e-06, "source": "https://platform.flex.ai/models", @@ -65108,7 +65056,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 4.7e-07, "source": "https://platform.flex.ai/models", @@ -65123,7 +65070,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 1.15e-06, "source": "https://platform.flex.ai/models", diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 9a4ed727210..486a9490510 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -64732,7 +64732,6 @@ "input_cost_per_token": 1e-08, "litellm_provider": "flexai", "max_input_tokens": 8192, - "max_tokens": 8192, "mode": "embedding", "output_cost_per_token": 0.0, "output_vector_size": 1024, @@ -64744,7 +64743,6 @@ "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", "output_cost_per_token": 2.38e-07, "source": "https://platform.flex.ai/models", @@ -64752,28 +64750,12 @@ "supports_reasoning": true, "supports_tool_choice": true }, - "flexai/DeepSeek-V4.1-Flash": { - "cache_read_input_token_cost": 1.54e-08, - "input_cost_per_token": 1.03e-07, - "litellm_provider": "flexai", - "max_input_tokens": 1048576, - "max_output_tokens": 1048576, - "max_tokens": 1048576, - "mode": "chat", - "output_cost_per_token": 7.15e-07, - "source": "https://platform.flex.ai/models", - "supports_function_calling": true, - "supports_reasoning": true, - "supports_tool_choice": true, - "supports_vision": true - }, "flexai/DeepSeek-V4.1-Flash-1017": { "cache_read_input_token_cost": 2.25e-08, "input_cost_per_token": 1.5e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", "output_cost_per_token": 6e-07, "source": "https://platform.flex.ai/models", @@ -64794,7 +64776,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 2.4e-07, "source": "https://platform.flex.ai/models", @@ -64809,7 +64790,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 4e-07, "source": "https://platform.flex.ai/models", @@ -64824,7 +64804,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 8.6e-07, "source": "https://platform.flex.ai/models", @@ -64833,14 +64812,13 @@ "supports_tool_choice": true }, "flexai/GLM-5.2": { - "cache_read_input_token_cost": 1.449e-07, - "input_cost_per_token": 9.66e-07, + "cache_read_input_token_cost": 1.05e-07, + "input_cost_per_token": 7e-07, "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", - "output_cost_per_token": 3.036e-06, + "output_cost_per_token": 2.2e-06, "source": "https://platform.flex.ai/models", "supports_function_calling": true, "supports_reasoning": true, @@ -64852,7 +64830,6 @@ "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", "output_cost_per_token": 5e-07, "source": "https://platform.flex.ai/models", @@ -64867,7 +64844,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 2.5e-07, "source": "https://platform.flex.ai/models", @@ -64881,7 +64857,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 1e-07, "source": "https://platform.flex.ai/models", @@ -64904,7 +64879,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 5e-07, "source": "https://platform.flex.ai/models", @@ -64917,7 +64891,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 5e-08, "source": "https://platform.flex.ai/models", @@ -64930,7 +64903,6 @@ "litellm_provider": "flexai", "max_input_tokens": 204800, "max_output_tokens": 204800, - "max_tokens": 204800, "mode": "chat", "output_cost_per_token": 1.2e-06, "source": "https://platform.flex.ai/models", @@ -64944,7 +64916,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 3e-08, "source": "https://platform.flex.ai/models", @@ -64957,7 +64928,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 1.2e-06, "source": "https://platform.flex.ai/models", @@ -64972,7 +64942,6 @@ "litellm_provider": "flexai", "max_input_tokens": 1048576, "max_output_tokens": 1048576, - "max_tokens": 1048576, "mode": "chat", "output_cost_per_token": 1.6e-07, "source": "https://platform.flex.ai/models", @@ -64985,7 +64954,6 @@ "litellm_provider": "flexai", "max_input_tokens": 131072, "max_output_tokens": 131072, - "max_tokens": 131072, "mode": "chat", "output_cost_per_token": 8e-07, "source": "https://platform.flex.ai/models", @@ -65007,7 +64975,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 2.4e-06, "source": "https://platform.flex.ai/models", @@ -65015,27 +64982,12 @@ "supports_reasoning": true, "supports_tool_choice": true }, - "flexai/Qwen3-8B-FP8": { - "cache_read_input_token_cost": 1.75e-08, - "input_cost_per_token": 1.17e-07, - "litellm_provider": "flexai", - "max_input_tokens": 40960, - "max_output_tokens": 40960, - "max_tokens": 40960, - "mode": "chat", - "output_cost_per_token": 4.55e-07, - "source": "https://platform.flex.ai/models", - "supports_function_calling": true, - "supports_reasoning": true, - "supports_tool_choice": true - }, "flexai/Qwen3-Coder-30B-A3B-Instruct-FP8": { "cache_read_input_token_cost": 1.05e-08, "input_cost_per_token": 7e-08, "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 2.8e-07, "source": "https://platform.flex.ai/models", @@ -65048,7 +65000,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 1.8e-07, "source": "https://platform.flex.ai/models", @@ -65063,7 +65014,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 3e-06, "source": "https://platform.flex.ai/models", @@ -65078,7 +65028,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 9.5e-07, "source": "https://platform.flex.ai/models", @@ -65093,7 +65042,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 2.5e-06, "source": "https://platform.flex.ai/models", @@ -65108,7 +65056,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 4.7e-07, "source": "https://platform.flex.ai/models", @@ -65123,7 +65070,6 @@ "litellm_provider": "flexai", "max_input_tokens": 262144, "max_output_tokens": 262144, - "max_tokens": 262144, "mode": "chat", "output_cost_per_token": 1.15e-06, "source": "https://platform.flex.ai/models", From 2d27a555ac031b2330aeb159a389acab20addd06 Mon Sep 17 00:00:00 2001 From: sundar-flex Date: Fri, 30 Oct 2026 13:50:11 -0700 Subject: [PATCH 4/4] feat(flexai): register FlexAI everywhere a JSON provider is wired Follows the ZeroGPU provider (#43874): README provider row, the Rust OPENAI_COMPATIBLE_PROVIDERS list, flexai_models in litellm/__init__.py, the dashboard provider enum, map and placeholder (with its test), the provider_endpoints_support backup row, and the current endpoints schema (messages, interactions, a2a and generateContent through the bridges). Tests: the add-model form default resolves to a priced flexai model, and FlexAI chat rows keep max_output_tokens within the context window. Co-Authored-By: Claude Opus 5.5 (1M context) --- README.md | 1 + .../src/exception_mapping_utils/original.rs | 1 + litellm/__init__.py | 5 ++++ .../provider_endpoints_support_backup.json | 26 +++++++++++++++++++ provider_endpoints_support.json | 17 +++++++++--- .../public_endpoints/test_public_endpoints.py | 19 ++++++++++++++ .../test_model_prices_and_context_window.py | 10 +++++++ .../components/provider_info_helpers.test.tsx | 5 ++++ .../src/components/provider_info_helpers.tsx | 3 +++ 9 files changed, 83 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 31a93bf8c67..6fd7aa77fec 100644 --- a/README.md +++ b/README.md @@ -404,6 +404,7 @@ Set `LITELLM_PROXY_API_BASE` and `LITELLM_PROXY_API_KEY` and every model call th | [Fal AI (`fal_ai`)](https://docs.litellm.ai/docs/providers/fal_ai) | ✅ | ✅ | ✅ | | ✅ | | | | | | | [Featherless AI (`featherless_ai`)](https://docs.litellm.ai/docs/providers/featherless_ai) | ✅ | ✅ | ✅ | | | | | | | | | [Fireworks AI (`fireworks_ai`)](https://docs.litellm.ai/docs/providers/fireworks_ai) | ✅ | ✅ | ✅ | | | | | | | | +| [FlexAI (`flexai`)](https://docs.litellm.ai/docs/providers/flexai) | ✅ | ✅ | ✅ | | | | | | | | | [FriendliAI (`friendliai`)](https://docs.litellm.ai/docs/providers/friendliai) | ✅ | ✅ | ✅ | | | | | | | | | [Galadriel (`galadriel`)](https://docs.litellm.ai/docs/providers/galadriel) | ✅ | ✅ | ✅ | | | | | | | | | [GitHub Copilot (`github_copilot`)](https://docs.litellm.ai/docs/providers/github_copilot) | ✅ | ✅ | ✅ | ✅ | | | | | | | diff --git a/litellm-rust/crates/core-utils/src/exception_mapping_utils/original.rs b/litellm-rust/crates/core-utils/src/exception_mapping_utils/original.rs index 615d530af19..9ae8de32699 100644 --- a/litellm-rust/crates/core-utils/src/exception_mapping_utils/original.rs +++ b/litellm-rust/crates/core-utils/src/exception_mapping_utils/original.rs @@ -114,6 +114,7 @@ const OPENAI_COMPATIBLE_PROVIDERS: &[&str] = &[ "cognition", "scx-ai", "zerogpu", + "flexai", ]; impl ExceptionFamily { diff --git a/litellm/__init__.py b/litellm/__init__.py index 8e5dd68a186..a7f570742e3 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -690,6 +690,7 @@ kyma_models: Final[set[str]] = set() # mutable-ok: populated when the shared mo streamlake_models: Final[Set[str]] = set() wally_models: Final[Set[str]] = set() zerogpu_models: Final[Set[str]] = set() +flexai_models: Final[Set[str]] = set() v0_models: Set = set() morph_models: Set = set() opencode_go_models: Final[set[str]] = set() # mutable-ok: populated when the shared model catalog loads @@ -989,6 +990,8 @@ def _populate_provider_model_sets(model_cost_map: Mapping[str, Mapping[str, obje wally_models.add(key) elif value.get("litellm_provider") == "zerogpu": zerogpu_models.add(key) + elif value.get("litellm_provider") == "flexai": + flexai_models.add(key) elif value.get("litellm_provider") == "v0": v0_models.add(key) elif value.get("litellm_provider") == "morph": @@ -1170,6 +1173,7 @@ model_list = list( | streamlake_models | wally_models | zerogpu_models + | flexai_models | v0_models | morph_models | opencode_go_models @@ -1304,6 +1308,7 @@ def _build_models_by_provider() -> dict: "streamlake": streamlake_models, "wally": wally_models, "zerogpu": zerogpu_models, + "flexai": flexai_models, "v0": v0_models, "morph": morph_models, "opencode_go": opencode_go_models, diff --git a/litellm/provider_endpoints_support_backup.json b/litellm/provider_endpoints_support_backup.json index 00fee0a0d5a..e15a124634d 100644 --- a/litellm/provider_endpoints_support_backup.json +++ b/litellm/provider_endpoints_support_backup.json @@ -1686,6 +1686,32 @@ "generateContent": true } }, + "flexai": { + "display_name": "FlexAI (`flexai`)", + "url": "https://docs.litellm.ai/docs/providers/flexai", + "endpoints": { + "chat_completions": true, + "responses": true, + "text_completion": true, + "embeddings": false, + "image_generations": false, + "image_edits": false, + "audio_transcriptions": false, + "audio_speech": false, + "rerank": false, + "ocr": false, + "search": false, + "moderations": false, + "realtime": false, + "video_generations": false, + "batches": false, + "messages": true, + "interactions": true, + "systemone": false, + "a2a": true, + "generateContent": true + } + }, "firecrawl": { "display_name": "Firecrawl (`firecrawl`)", "url": "https://docs.litellm.ai/docs/search/firecrawl", diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json index efa22a6a7ad..1645860c1a5 100644 --- a/provider_endpoints_support.json +++ b/provider_endpoints_support.json @@ -5515,16 +5515,25 @@ "url": "https://docs.litellm.ai/docs/providers/flexai", "endpoints": { "chat_completions": true, - "messages": false, "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 + "ocr": false, + "search": false, + "moderations": false, + "realtime": false, + "video_generations": false, + "batches": false, + "messages": true, + "interactions": true, + "systemone": false, + "a2a": true, + "generateContent": true } } }, diff --git a/tests/unit/proxy/public_endpoints/test_public_endpoints.py b/tests/unit/proxy/public_endpoints/test_public_endpoints.py index dd3ffad4727..56a72576093 100644 --- a/tests/unit/proxy/public_endpoints/test_public_endpoints.py +++ b/tests/unit/proxy/public_endpoints/test_public_endpoints.py @@ -447,6 +447,25 @@ def test_zerogpu_add_model_form_defaults_resolve_to_a_priced_zerogpu_model(): assert fields_by_key["api_key"]["field_type"] == "password" +def test_flexai_add_model_form_defaults_resolve_to_a_priced_flexai_model(): + import litellm + from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider + + app_instance: Final = FastAPI() + app_instance.include_router(router) + providers: Final = TestClient(app_instance).get("/public/providers/fields").json() + + flexai: Final = next(p for p in providers if p["litellm_provider"] == "flexai") + fields_by_key: Final = {f["key"]: f for f in flexai["credential_fields"]} + placeholder: Final = flexai["default_model_placeholder"] + _, provider, _, api_base = get_llm_provider(model=placeholder) + + assert provider == "flexai" + assert api_base == fields_by_key["api_base"]["placeholder"] + assert litellm.model_cost[placeholder]["litellm_provider"] == "flexai" + assert fields_by_key["api_key"]["required"] is True + assert fields_by_key["api_key"]["field_type"] == "password" + def test_qwen_mainland_provider_fields_carry_the_qianwen_brand(): app_instance = FastAPI() app_instance.include_router(router) diff --git a/tests/unit/test_model_prices_and_context_window.py b/tests/unit/test_model_prices_and_context_window.py index e195b970fd5..0b439b1e0b5 100644 --- a/tests/unit/test_model_prices_and_context_window.py +++ b/tests/unit/test_model_prices_and_context_window.py @@ -132,6 +132,16 @@ def test_zerogpu_rows_have_an_output_limit_that_fits_the_context_window(path: Pa assert tuple(key for key, row in rows.items() if row.max_output_tokens > row.max_input_tokens) == () +@pytest.mark.parametrize("path", (PRICES_PATH, BACKUP_PRICES_PATH), ids=("main", "backup")) +def test_flexai_chat_rows_have_an_output_limit_that_fits_the_context_window(path: Path) -> None: + prices: Final[dict[str, JsonValue]] = TypeAdapter(dict[str, JsonValue]).validate_json(path.read_bytes()) + rows: Final = MappingProxyType( + {key: _TokenLimits.model_validate(value) for key, value in prices.items() if key.startswith("flexai/") and isinstance(value, dict) and value.get("mode") == "chat"} + ) + assert rows, f"No FlexAI chat rows found in {path}" + assert tuple(key for key, row in rows.items() if row.max_output_tokens > row.max_input_tokens) == () + + def test_github_copilot_rows_resolve_through_get_model_info() -> None: rows: Final[Mapping[str, _CopilotEndpointRow]] = _copilot_endpoint_rows(PRICES_PATH) assert { 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 604d5923caa..c389480c3e5 100644 --- a/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx +++ b/ui/litellm-dashboard/src/components/provider_info_helpers.test.tsx @@ -273,6 +273,7 @@ describe("provider_info_helpers", () => { Providers.WANDB, Providers.ZAI, Providers.ZeroGPU, + Providers.FlexAI, ]; const logolessProviders = Object.values(Providers).filter((provider) => !providerLogoMap[provider]); expect([...logolessProviders].sort()).toEqual([...knownLogolessProviders].sort()); @@ -410,6 +411,10 @@ describe("provider_info_helpers", () => { expect(getPlaceholder("ZeroGPU")).toBe("zerogpu/gpt-oss-120b"); }); + it("should return flexai/gpt-oss-120b placeholder for FlexAI provider", () => { + expect(getPlaceholder("FlexAI")).toBe("flexai/gpt-oss-120b"); + }); + it("should return a chatgpt/ placeholder for the CHATGPT dropdown key", () => { expect(getPlaceholder("CHATGPT")).toBe("chatgpt/gpt-5.4"); }); diff --git a/ui/litellm-dashboard/src/components/provider_info_helpers.tsx b/ui/litellm-dashboard/src/components/provider_info_helpers.tsx index 167343fc05e..59b6f4b9ae7 100644 --- a/ui/litellm-dashboard/src/components/provider_info_helpers.tsx +++ b/ui/litellm-dashboard/src/components/provider_info_helpers.tsx @@ -209,6 +209,7 @@ export enum Providers { ZAI = "Z.AI (Zhipu AI)", BIGMODEL = "BigModel (Zhipu AI)", ZeroGPU = "ZeroGPU", + FlexAI = "FlexAI", } export const provider_map: Record = { @@ -345,6 +346,7 @@ export const provider_map: Record = { ZAI: "zai", BIGMODEL: "bigmodel", ZeroGPU: "zerogpu", + FlexAI: "flexai", }; const standaloneSubproviderSlugs = new Set(["bedrock_mantle", "meta_llama"]); @@ -530,6 +532,7 @@ const providerPlaceholderMap: Partial> = { [Providers.ZAI]: "zai/glm-4.5", [Providers.BIGMODEL]: "bigmodel/glm-5.3", [Providers.ZeroGPU]: "zerogpu/gpt-oss-120b", + [Providers.FlexAI]: "flexai/gpt-oss-120b", }; export const getPlaceholder = (selectedProvider: string): string => {