diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index 032c262cbfa..240a6f8dc57 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -31293,6 +31293,42 @@ "video" ] }, + "github_copilot/claude-fable-5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": true + }, + "github_copilot/claude-fable-5.1": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": true + }, "github_copilot/claude-haiku-4.5": { "cache_creation_input_token_cost": 1.25e-06, "cache_read_input_token_cost": 1e-07, @@ -31308,76 +31344,166 @@ ], "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_vision": true }, - "github_copilot/claude-opus-4.5": { + "github_copilot/claude-haiku-5.5": { + "cache_creation_input_token_cost": 1.25e-07, + "cache_creation_input_token_cost_above_100k_tokens": 6.25e-07, + "cache_read_input_token_cost": 1e-08, + "cache_read_input_token_cost_above_100k_tokens": 5e-08, + "input_cost_per_token": 1e-07, + "input_cost_per_token_above_100k_tokens": 5e-07, "litellm_provider": "github_copilot", "max_input_tokens": 128000, "max_output_tokens": 16000, "max_tokens": 16000, "mode": "chat", + "output_cost_per_token": 5e-07, + "output_cost_per_token_above_100k_tokens": 2.5e-06, + "source": "https://raw.githubusercontent.com/github/docs/main/data/tables/copilot/models-and-pricing.yml", "supported_endpoints": [ - "/v1/chat/completions" + "/v1/chat/completions", + "/v1/messages" ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_vision": true, - "supports_output_config": true - }, - "github_copilot/claude-opus-4.6-fast": { "supports_adaptive_thinking": true, - "supports_legacy_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": false + }, + "github_copilot/claude-opus-4.8": { "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 16000, - "max_tokens": 16000, + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/claude-opus-4.8-fast": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/claude-opus-5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/claude-opus-5.5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": true + }, + "github_copilot/claude-sonnet-5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/claude-sonnet-5.5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": true + }, + "github_copilot/gemini-3.7-flash": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, "mode": "chat", "supported_endpoints": [ "/v1/chat/completions" ], "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_vision": true }, - "github_copilot/claude-opus-41": { + "github_copilot/gemini-3.8-flash": { "litellm_provider": "github_copilot", - "max_input_tokens": 80000, - "max_output_tokens": 16000, - "max_tokens": 16000, - "mode": "chat", - "supported_endpoints": [ - "/v1/chat/completions" - ], - "supports_vision": true - }, - "github_copilot/claude-sonnet-4": { - "cache_creation_input_token_cost": 3.75e-06, - "cache_read_input_token_cost": 3e-07, - "input_cost_per_token": 3e-06, - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 16000, - "max_tokens": 16000, - "mode": "chat", - "output_cost_per_token": 1.5e-05, - "supported_endpoints": [ - "/v1/chat/completions" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_vision": true - }, - "github_copilot/claude-sonnet-4.5": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 16000, - "max_tokens": 16000, + "max_input_tokens": 200000, + "max_output_tokens": 65536, + "max_tokens": 65536, "mode": "chat", "supported_endpoints": [ "/v1/chat/completions" ], "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_vision": true }, "github_copilot/gpt-3.5-turbo": { @@ -31504,21 +31630,6 @@ "supports_function_calling": true, "supports_parallel_function_calling": true }, - "github_copilot/gpt-5": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "chat", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/responses" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_response_schema": true, - "supports_vision": true - }, "github_copilot/gpt-5-mini": { "cache_read_input_token_cost": 2.5e-08, "input_cost_per_token": 2.5e-07, @@ -31533,50 +31644,6 @@ "supports_response_schema": true, "supports_vision": true }, - "github_copilot/gpt-5.1": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 64000, - "max_tokens": 64000, - "mode": "chat", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/responses" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_response_schema": true, - "supports_vision": true - }, - "github_copilot/gpt-5.1-codex-max": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "responses", - "supported_endpoints": [ - "/v1/responses" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_response_schema": true, - "supports_vision": true - }, - "github_copilot/gpt-5.2": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 64000, - "max_tokens": 64000, - "mode": "chat", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/responses" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_response_schema": true, - "supports_vision": true - }, "github_copilot/gpt-5.3-codex": { "cache_read_input_token_cost": 1.75e-07, "input_cost_per_token": 1.75e-06, @@ -31591,40 +31658,188 @@ ], "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_vision": true }, - "github_copilot/mai-code-1-flash": { - "cache_read_input_token_cost": 7.5e-08, - "input_cost_per_token": 7.5e-07, + "github_copilot/gpt-5.4": { "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 64000, - "max_tokens": 64000, + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, "mode": "chat", - "output_cost_per_token": 4.5e-06, "supported_endpoints": [ - "/v1/chat/completions" + "/v1/chat/completions", + "/v1/responses" ], "supports_function_calling": true, "supports_parallel_function_calling": true, - "supports_response_schema": true + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true }, - "github_copilot/mai-code-1-flash-internal": { - "cache_read_input_token_cost": 7.5e-08, - "input_cost_per_token": 7.5e-07, + "github_copilot/gpt-5.4-mini": { "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 64000, - "max_tokens": 64000, + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.6-luna": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.6-sol": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.6-terra": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-6-astra": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-6-luna": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-6-sol": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-6.1-sol": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/kimi-k3": { + "litellm_provider": "github_copilot", + "max_input_tokens": 917504, + "max_output_tokens": 131072, + "max_tokens": 131072, "mode": "chat", - "output_cost_per_token": 4.5e-06, "supported_endpoints": [ "/v1/chat/completions" ], "supports_function_calling": true, "supports_parallel_function_calling": true, - "supports_response_schema": true + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/mai-code-1.1-flash": { + "litellm_provider": "github_copilot", + "max_input_tokens": 128000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_response_schema": true, + "supports_vision": true }, "github_copilot/text-embedding-3-small": { "litellm_provider": "github_copilot", @@ -78959,27 +79174,5 @@ "supported_endpoints": [ "/v1/responses" ] - }, - "github_copilot/claude-haiku-5.5": { - "cache_creation_input_token_cost": 1.25e-07, - "cache_creation_input_token_cost_above_100k_tokens": 6.25e-07, - "cache_read_input_token_cost": 1e-08, - "cache_read_input_token_cost_above_100k_tokens": 5e-08, - "input_cost_per_token": 1e-07, - "input_cost_per_token_above_100k_tokens": 5e-07, - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 16000, - "max_tokens": 16000, - "mode": "chat", - "output_cost_per_token": 5e-07, - "output_cost_per_token_above_100k_tokens": 2.5e-06, - "source": "https://raw.githubusercontent.com/github/docs/main/data/tables/copilot/models-and-pricing.yml", - "supported_endpoints": [ - "/v1/chat/completions" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_vision": true } } diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 032c262cbfa..240a6f8dc57 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -31293,6 +31293,42 @@ "video" ] }, + "github_copilot/claude-fable-5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": true + }, + "github_copilot/claude-fable-5.1": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": true + }, "github_copilot/claude-haiku-4.5": { "cache_creation_input_token_cost": 1.25e-06, "cache_read_input_token_cost": 1e-07, @@ -31308,76 +31344,166 @@ ], "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_vision": true }, - "github_copilot/claude-opus-4.5": { + "github_copilot/claude-haiku-5.5": { + "cache_creation_input_token_cost": 1.25e-07, + "cache_creation_input_token_cost_above_100k_tokens": 6.25e-07, + "cache_read_input_token_cost": 1e-08, + "cache_read_input_token_cost_above_100k_tokens": 5e-08, + "input_cost_per_token": 1e-07, + "input_cost_per_token_above_100k_tokens": 5e-07, "litellm_provider": "github_copilot", "max_input_tokens": 128000, "max_output_tokens": 16000, "max_tokens": 16000, "mode": "chat", + "output_cost_per_token": 5e-07, + "output_cost_per_token_above_100k_tokens": 2.5e-06, + "source": "https://raw.githubusercontent.com/github/docs/main/data/tables/copilot/models-and-pricing.yml", "supported_endpoints": [ - "/v1/chat/completions" + "/v1/chat/completions", + "/v1/messages" ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_vision": true, - "supports_output_config": true - }, - "github_copilot/claude-opus-4.6-fast": { "supports_adaptive_thinking": true, - "supports_legacy_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": false + }, + "github_copilot/claude-opus-4.8": { "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 16000, - "max_tokens": 16000, + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/claude-opus-4.8-fast": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/claude-opus-5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/claude-opus-5.5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": true + }, + "github_copilot/claude-sonnet-5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/claude-sonnet-5.5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/messages" + ], + "supports_adaptive_thinking": true, + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true, + "thinking_always_on": true + }, + "github_copilot/gemini-3.7-flash": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, "mode": "chat", "supported_endpoints": [ "/v1/chat/completions" ], "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_vision": true }, - "github_copilot/claude-opus-41": { + "github_copilot/gemini-3.8-flash": { "litellm_provider": "github_copilot", - "max_input_tokens": 80000, - "max_output_tokens": 16000, - "max_tokens": 16000, - "mode": "chat", - "supported_endpoints": [ - "/v1/chat/completions" - ], - "supports_vision": true - }, - "github_copilot/claude-sonnet-4": { - "cache_creation_input_token_cost": 3.75e-06, - "cache_read_input_token_cost": 3e-07, - "input_cost_per_token": 3e-06, - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 16000, - "max_tokens": 16000, - "mode": "chat", - "output_cost_per_token": 1.5e-05, - "supported_endpoints": [ - "/v1/chat/completions" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_vision": true - }, - "github_copilot/claude-sonnet-4.5": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 16000, - "max_tokens": 16000, + "max_input_tokens": 200000, + "max_output_tokens": 65536, + "max_tokens": 65536, "mode": "chat", "supported_endpoints": [ "/v1/chat/completions" ], "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_vision": true }, "github_copilot/gpt-3.5-turbo": { @@ -31504,21 +31630,6 @@ "supports_function_calling": true, "supports_parallel_function_calling": true }, - "github_copilot/gpt-5": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "chat", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/responses" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_response_schema": true, - "supports_vision": true - }, "github_copilot/gpt-5-mini": { "cache_read_input_token_cost": 2.5e-08, "input_cost_per_token": 2.5e-07, @@ -31533,50 +31644,6 @@ "supports_response_schema": true, "supports_vision": true }, - "github_copilot/gpt-5.1": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 64000, - "max_tokens": 64000, - "mode": "chat", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/responses" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_response_schema": true, - "supports_vision": true - }, - "github_copilot/gpt-5.1-codex-max": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 128000, - "max_tokens": 128000, - "mode": "responses", - "supported_endpoints": [ - "/v1/responses" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_response_schema": true, - "supports_vision": true - }, - "github_copilot/gpt-5.2": { - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 64000, - "max_tokens": 64000, - "mode": "chat", - "supported_endpoints": [ - "/v1/chat/completions", - "/v1/responses" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_response_schema": true, - "supports_vision": true - }, "github_copilot/gpt-5.3-codex": { "cache_read_input_token_cost": 1.75e-07, "input_cost_per_token": 1.75e-06, @@ -31591,40 +31658,188 @@ ], "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_vision": true }, - "github_copilot/mai-code-1-flash": { - "cache_read_input_token_cost": 7.5e-08, - "input_cost_per_token": 7.5e-07, + "github_copilot/gpt-5.4": { "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 64000, - "max_tokens": 64000, + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, "mode": "chat", - "output_cost_per_token": 4.5e-06, "supported_endpoints": [ - "/v1/chat/completions" + "/v1/chat/completions", + "/v1/responses" ], "supports_function_calling": true, "supports_parallel_function_calling": true, - "supports_response_schema": true + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true }, - "github_copilot/mai-code-1-flash-internal": { - "cache_read_input_token_cost": 7.5e-08, - "input_cost_per_token": 7.5e-07, + "github_copilot/gpt-5.4-mini": { "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 64000, - "max_tokens": 64000, + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.6-luna": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.6-sol": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.6-terra": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-6-astra": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-6-luna": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-6-sol": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-6.1-sol": { + "litellm_provider": "github_copilot", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/kimi-k3": { + "litellm_provider": "github_copilot", + "max_input_tokens": 917504, + "max_output_tokens": 131072, + "max_tokens": 131072, "mode": "chat", - "output_cost_per_token": 4.5e-06, "supported_endpoints": [ "/v1/chat/completions" ], "supports_function_calling": true, "supports_parallel_function_calling": true, - "supports_response_schema": true + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/mai-code-1.1-flash": { + "litellm_provider": "github_copilot", + "max_input_tokens": 128000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_response_schema": true, + "supports_vision": true }, "github_copilot/text-embedding-3-small": { "litellm_provider": "github_copilot", @@ -78959,27 +79174,5 @@ "supported_endpoints": [ "/v1/responses" ] - }, - "github_copilot/claude-haiku-5.5": { - "cache_creation_input_token_cost": 1.25e-07, - "cache_creation_input_token_cost_above_100k_tokens": 6.25e-07, - "cache_read_input_token_cost": 1e-08, - "cache_read_input_token_cost_above_100k_tokens": 5e-08, - "input_cost_per_token": 1e-07, - "input_cost_per_token_above_100k_tokens": 5e-07, - "litellm_provider": "github_copilot", - "max_input_tokens": 128000, - "max_output_tokens": 16000, - "max_tokens": 16000, - "mode": "chat", - "output_cost_per_token": 5e-07, - "output_cost_per_token_above_100k_tokens": 2.5e-06, - "source": "https://raw.githubusercontent.com/github/docs/main/data/tables/copilot/models-and-pricing.yml", - "supported_endpoints": [ - "/v1/chat/completions" - ], - "supports_function_calling": true, - "supports_parallel_function_calling": true, - "supports_vision": true } } diff --git a/tests/integration/providers/test_device_code_login_guard_boot.py b/tests/integration/providers/test_device_code_login_guard_boot.py index 0c5b2615d6f..7bf15ac2e1c 100644 --- a/tests/integration/providers/test_device_code_login_guard_boot.py +++ b/tests/integration/providers/test_device_code_login_guard_boot.py @@ -31,10 +31,10 @@ pytestmark: Final = pytest.mark.timeout(900) _STARTED_WORKER: Final = re.compile(r"Started server process \[(\d+)\]") _DROPPED: Final = re.compile(r"original model: (\S+), ignoring and continuing") _FIXED: Final[Mapping[str, str]] = MappingProxyType( - {"chatgpt-fixed": "chatgpt/gpt-5.6-terra", "copilot-fixed": "github_copilot/gpt-5.2"} + {"chatgpt-fixed": "chatgpt/gpt-5.6-terra", "copilot-fixed": "github_copilot/gpt-5.4"} ) _WILDCARDS: Final[Mapping[str, str]] = MappingProxyType( - {"chatgpt/*": "chatgpt/gpt-5.6-terra", "github_copilot/*": "github_copilot/gpt-5.2"} + {"chatgpt/*": "chatgpt/gpt-5.6-terra", "github_copilot/*": "github_copilot/gpt-5.4"} ) _LOGIN_PREFIXES: Final = ("chatgpt/", "github_copilot/") _LOGIN_NAMES: Final = (*_FIXED, *_FIXED.values()) @@ -424,7 +424,7 @@ async def test_worker_sigkill_mid_burst_leaves_the_sibling_refusing_logins_and_s for item in served: assert item.status == 200, item.text refusals: Final = await _burst( - _base_url(owned), key, ("chatgpt/gpt-5.6-terra", "github_copilot/gpt-5.2") * 10 + _base_url(owned), key, ("chatgpt/gpt-5.6-terra", "github_copilot/gpt-5.4") * 10 ) for index, answer in enumerate(refusals): assert answer is not None and answer.status == 400, answer diff --git a/tests/integration/providers/test_device_code_login_guard_wire.py b/tests/integration/providers/test_device_code_login_guard_wire.py index 8ec41ac6ac2..072de4f3782 100644 --- a/tests/integration/providers/test_device_code_login_guard_wire.py +++ b/tests/integration/providers/test_device_code_login_guard_wire.py @@ -41,9 +41,9 @@ _MODELS: Final[Mapping[tuple[Provider, Endpoint], str]] = MappingProxyType( ("chatgpt", "chat"): "chatgpt/gpt-5.6-terra", ("chatgpt", "responses"): "chatgpt/gpt-5.6-terra", ("chatgpt", "messages"): "chatgpt/gpt-5.6-terra", - ("copilot", "chat"): "github_copilot/gpt-5.2", - ("copilot", "responses"): "github_copilot/gpt-5.2", - ("copilot", "messages"): "github_copilot/claude-sonnet-4.5", + ("copilot", "chat"): "github_copilot/gpt-5.4", + ("copilot", "responses"): "github_copilot/gpt-5.4", + ("copilot", "messages"): "github_copilot/claude-sonnet-5.5", } ) _REFUSALS: Final[Mapping[Provider, str]] = MappingProxyType( @@ -469,9 +469,9 @@ _ROUTES: Final = ( "/v1/embeddings", {"model": "github_copilot/text-embedding-3-small", "input": "login"}, ), - _Route("copilot-completions", "copilot", "/v1/completions", {"model": "github_copilot/gpt-5.2", "prompt": "login"}), + _Route("copilot-completions", "copilot", "/v1/completions", {"model": "github_copilot/gpt-5.4", "prompt": "login"}), _Route( - "copilot-images", "copilot", "/v1/images/generations", {"model": "github_copilot/gpt-5.2", "prompt": "login"} + "copilot-images", "copilot", "/v1/images/generations", {"model": "github_copilot/gpt-5.4", "prompt": "login"} ), ) diff --git a/tests/integration/sdk/test_device_code_login_guard_sdk.py b/tests/integration/sdk/test_device_code_login_guard_sdk.py index d579fbef237..51e955ea6ec 100644 --- a/tests/integration/sdk/test_device_code_login_guard_sdk.py +++ b/tests/integration/sdk/test_device_code_login_guard_sdk.py @@ -19,7 +19,7 @@ pytestmark: Final = pytest.mark.timeout(300) Provider: TypeAlias = Literal["chatgpt", "copilot"] _MODELS: Final[Mapping[Provider, str]] = MappingProxyType( - {"chatgpt": "chatgpt/gpt-5.6-terra", "copilot": "github_copilot/gpt-5.2"} + {"chatgpt": "chatgpt/gpt-5.6-terra", "copilot": "github_copilot/gpt-5.4"} ) _REFUSALS: Final[Mapping[Provider, str]] = MappingProxyType( {"chatgpt": dl.CHATGPT_REFUSAL, "copilot": dl.COPILOT_REFUSAL} diff --git a/tests/unit/integrations/websearch_interception/test_websearch_native_blocks.py b/tests/unit/integrations/websearch_interception/test_websearch_native_blocks.py index 068a60e1fff..92feab86dc0 100644 --- a/tests/unit/integrations/websearch_interception/test_websearch_native_blocks.py +++ b/tests/unit/integrations/websearch_interception/test_websearch_native_blocks.py @@ -531,7 +531,7 @@ class TestShortCircuitEmitsNativeBlocks: new=AsyncMock(return_value=("Title: x\nURL: y", _make_search_response())), ): result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "search query"}], tools=[ { @@ -569,7 +569,7 @@ class TestShortCircuitEmitsNativeBlocks: new=AsyncMock(return_value=("Title: x\nURL: y", _make_search_response())), ): result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "search query"}], tools=[ { @@ -601,7 +601,7 @@ class TestShortCircuitEmitsNativeBlocks: side_effect=RateLimitError("slow down", llm_provider="tavily", model="tavily"), ): result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "search query"}], tools=[{"type": "web_search_20250305", "name": "web_search"}], custom_llm_provider="github_copilot", diff --git a/tests/unit/integrations/websearch_interception/test_websearch_short_circuit.py b/tests/unit/integrations/websearch_interception/test_websearch_short_circuit.py index 8294add60c7..ea1ebe6b654 100644 --- a/tests/unit/integrations/websearch_interception/test_websearch_short_circuit.py +++ b/tests/unit/integrations/websearch_interception/test_websearch_short_circuit.py @@ -35,7 +35,7 @@ class TestTryShortCircuitSearch: ) result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[ {"role": "user", "content": "Search for Claude Code releases"} ], @@ -66,7 +66,7 @@ class TestTryShortCircuitSearch: logger = WebSearchInterceptionLogger(enabled_providers=["github_copilot"]) result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "Do something"}], tools=[ {"type": "web_search_20250305", "name": "web_search", "max_uses": 8}, @@ -83,7 +83,7 @@ class TestTryShortCircuitSearch: logger = WebSearchInterceptionLogger(enabled_providers=["github_copilot"]) result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "Hello"}], tools=None, custom_llm_provider="github_copilot", @@ -97,7 +97,7 @@ class TestTryShortCircuitSearch: logger = WebSearchInterceptionLogger(enabled_providers=["github_copilot"]) result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "Hello"}], tools=[], custom_llm_provider="github_copilot", @@ -111,7 +111,7 @@ class TestTryShortCircuitSearch: logger = WebSearchInterceptionLogger(enabled_providers=["bedrock"]) result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "Search for something"}], tools=[ {"type": "web_search_20250305", "name": "web_search", "max_uses": 8} @@ -150,7 +150,7 @@ class TestTryShortCircuitSearch: logger = WebSearchInterceptionLogger(enabled_providers=["github_copilot"]) result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[], tools=[ {"type": "web_search_20250305", "name": "web_search", "max_uses": 8} @@ -171,7 +171,7 @@ class TestTryShortCircuitSearch: mock_search.side_effect = RuntimeError("Tavily API error") result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "Search for something"}], tools=[ {"type": "web_search_20250305", "name": "web_search", "max_uses": 8} @@ -194,7 +194,7 @@ class TestTryShortCircuitSearch: mock_search.return_value = ("search results here", None) result = await logger.try_short_circuit_search( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "Search query"}], tools=[{"type": "web_search_20250305", "name": "web_search"}], custom_llm_provider="github_copilot", @@ -206,7 +206,7 @@ class TestTryShortCircuitSearch: assert result["id"].startswith("msg_") assert result["type"] == "message" assert result["role"] == "assistant" - assert result["model"] == "github_copilot/claude-sonnet-4" + assert result["model"] == "github_copilot/claude-sonnet-5.5" assert result["stop_reason"] == "end_turn" assert result["stop_sequence"] is None assert "usage" in result @@ -257,7 +257,7 @@ class TestShortCircuitEntryPoint: mock_search.return_value = ("results", None) with patch("litellm.callbacks", [logger]): result = await _try_websearch_short_circuit( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "search query"}], tools=[{"type": "web_search_20250305", "name": "web_search"}], custom_llm_provider="github_copilot", @@ -285,7 +285,7 @@ class TestShortCircuitEntryPoint: mock_search.return_value = ("streaming results", None) with patch("litellm.callbacks", [logger]): result = await _try_websearch_short_circuit( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "search query"}], tools=[{"type": "web_search_20250305", "name": "web_search"}], custom_llm_provider="github_copilot", @@ -353,7 +353,7 @@ class TestShortCircuitEntryPoint: # is passed to the short-circuit, even though the hook would have # already converted stream to False in request_kwargs. result = await _try_websearch_short_circuit( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "search query"}], tools=[{"type": "web_search_20250305", "name": "web_search"}], custom_llm_provider="github_copilot", @@ -382,7 +382,7 @@ class TestShortCircuitEntryPoint: # Simulate the caller having derived custom_llm_provider from # the model string before calling _try_websearch_short_circuit result = await _try_websearch_short_circuit( - model="github_copilot/claude-sonnet-4", + model="github_copilot/claude-sonnet-5.5", messages=[{"role": "user", "content": "search query"}], tools=[{"type": "web_search_20250305", "name": "web_search"}], custom_llm_provider="github_copilot", diff --git a/tests/unit/litellm_core_utils/test_fallback_generalizations.py b/tests/unit/litellm_core_utils/test_fallback_generalizations.py index e10751b2c71..31db7d6f30c 100644 --- a/tests/unit/litellm_core_utils/test_fallback_generalizations.py +++ b/tests/unit/litellm_core_utils/test_fallback_generalizations.py @@ -625,8 +625,8 @@ def test_shipped_version_boundaries(shipped_cost_map, model, provider, adaptive, assert info.get("supports_mid_conversation_system") is mid_conversation, model -def test_shipped_claude_version_regex_excludes_undelimited_41(shipped_cost_map): - unmatched = match_capability_generalizations("github_copilot/claude-opus-41") +def test_shipped_claude_version_regex_excludes_two_digit_major(shipped_cost_map): + unmatched = match_capability_generalizations("github_copilot/claude-opus-42") assert unmatched is None or "supports_adaptive_thinking" not in unmatched assert unmatched is None or "supports_mid_conversation_system" not in unmatched diff --git a/tests/unit/llms/github_copilot/messages/test_github_copilot_messages_transformation.py b/tests/unit/llms/github_copilot/messages/test_github_copilot_messages_transformation.py index b029e5aba0b..5cbb9a0a7b4 100644 --- a/tests/unit/llms/github_copilot/messages/test_github_copilot_messages_transformation.py +++ b/tests/unit/llms/github_copilot/messages/test_github_copilot_messages_transformation.py @@ -336,7 +336,7 @@ def test_validate_environment_uses_per_user_session_and_skips_authenticator(): session = GithubCopilotUserSession(token="user-copilot-token", api_base="https://tenant.githubcopilot.com/") headers, api_base = config.validate_anthropic_messages_environment( headers={}, - model="github_copilot/claude-sonnet-4.5", + model="github_copilot/claude-sonnet-5.5", messages=[], optional_params={}, litellm_params={"github_copilot_user_session": session}, @@ -371,14 +371,14 @@ def test_transform_response_carries_upstream_usage(): "id": "msg_1", "type": "message", "role": "assistant", - "model": "github_copilot/claude-sonnet-4.5", + "model": "github_copilot/claude-sonnet-5.5", "content": [{"type": "text", "text": "hi"}], "stop_reason": "end_turn", "usage": {"input_tokens": 14, "output_tokens": 3}, }, ) result = config.transform_anthropic_messages_response( - model="github_copilot/claude-sonnet-4.5", + model="github_copilot/claude-sonnet-5.5", raw_response=raw, logging_obj=MagicMock(), ) diff --git a/tests/unit/llms/github_copilot/responses/test_github_copilot_responses_transformation.py b/tests/unit/llms/github_copilot/responses/test_github_copilot_responses_transformation.py index 12fdc374123..c3a62592039 100644 --- a/tests/unit/llms/github_copilot/responses/test_github_copilot_responses_transformation.py +++ b/tests/unit/llms/github_copilot/responses/test_github_copilot_responses_transformation.py @@ -765,7 +765,7 @@ def test_validate_environment_uses_per_user_session_and_skips_authenticator(): session = GithubCopilotUserSession(token="user-copilot-token", api_base="https://api.githubcopilot.com") headers = config.validate_environment( headers={}, - model="github_copilot/gpt-5.1", + model="github_copilot/gpt-5.4", litellm_params={"github_copilot_user_session": session}, ) assert headers["Authorization"] == "Bearer user-copilot-token" @@ -811,7 +811,7 @@ def test_transform_response_carries_upstream_usage(): "object": "response", "created_at": 1, "status": "completed", - "model": "github_copilot/gpt-5.1", + "model": "github_copilot/gpt-5.4", "output": [ { "type": "message", @@ -825,7 +825,7 @@ def test_transform_response_carries_upstream_usage(): }, ) result = config.transform_response_api_response( - model="github_copilot/gpt-5.1", + model="github_copilot/gpt-5.4", raw_response=raw, logging_obj=MagicMock(), ) diff --git a/tests/unit/llms/github_copilot/test_github_copilot_transformation.py b/tests/unit/llms/github_copilot/test_github_copilot_transformation.py index c775beeae24..2dbfae07526 100644 --- a/tests/unit/llms/github_copilot/test_github_copilot_transformation.py +++ b/tests/unit/llms/github_copilot/test_github_copilot_transformation.py @@ -500,7 +500,7 @@ class TestGithubCopilotTransformResponse: "id": "chatcmpl-123", "object": "chat.completion", "created": 1700000000, - "model": "github_copilot/claude-opus-4.5", + "model": "github_copilot/claude-opus-4.8", "choices": [ { "index": 0, @@ -519,7 +519,7 @@ class TestGithubCopilotTransformResponse: model_response = ModelResponse() result = config.transform_response( - model="github_copilot/claude-opus-4.5", + model="github_copilot/claude-opus-4.8", raw_response=raw_response, model_response=model_response, logging_obj=self._make_logging_obj(), diff --git a/tests/unit/test_model_prices_schema.py b/tests/unit/test_model_prices_schema.py index d0a5676e333..37df91d22af 100644 --- a/tests/unit/test_model_prices_schema.py +++ b/tests/unit/test_model_prices_schema.py @@ -10,8 +10,10 @@ from typing import Final import jsonschema import pytest +from pydantic import BaseModel, ConfigDict, JsonValue, TypeAdapter import litellm +from litellm.litellm_core_utils.fallback_generalizations import match_capability_generalizations from litellm.llms.openai.chat.gpt_5_transformation import is_gpt_reasoning_series_name from litellm.llms.openai_like.json_loader import JSONProviderRegistry from litellm.router_utils.reasoning_effort_capability import resolve_supported_reasoning_efforts @@ -45,6 +47,127 @@ def prices() -> dict: return json.loads(PRICES_PATH.read_text()) +class _CopilotEndpointRow(BaseModel): + model_config = ConfigDict(frozen=True, extra="ignore") + + mode: str + max_input_tokens: int + max_output_tokens: int + max_tokens: int + supported_endpoints: tuple[str, ...] + + +class _CopilotThinkingCapabilities(BaseModel): + model_config = ConfigDict(frozen=True, extra="ignore") + + supports_reasoning: bool | None = None + supports_adaptive_thinking: bool | None = None + supports_legacy_thinking: bool | None = None + thinking_always_on: bool | None = None + + +def _copilot_endpoint_rows(path: Path) -> Mapping[str, _CopilotEndpointRow]: + prices: Final[dict[str, JsonValue]] = TypeAdapter(dict[str, JsonValue]).validate_json(path.read_bytes()) + return MappingProxyType( + { + key: _CopilotEndpointRow.model_validate(value) + for key, value in prices.items() + if key.startswith("github_copilot/") and isinstance(value, dict) and "supported_endpoints" in value + } + ) + + +def _thinking_capabilities(prices: Mapping[str, JsonValue], key: str) -> _CopilotThinkingCapabilities: + return _CopilotThinkingCapabilities.model_validate(prices[key]) + + +def _github_copilot_catalog_rows(path: Path) -> Mapping[str, JsonValue]: + prices: Final[dict[str, JsonValue]] = TypeAdapter(dict[str, JsonValue]).validate_json(path.read_bytes()) + return MappingProxyType({key: value for key, value in prices.items() if key.startswith("github_copilot/")}) + + +_THINKING_KEYS: Final[tuple[str, ...]] = ( + "supports_reasoning", + "supports_adaptive_thinking", + "supports_legacy_thinking", + "thinking_always_on", +) + + +def _anthropic_counterpart(key: str) -> str: + return key.removeprefix("github_copilot/").removesuffix("-fast").replace(".", "-") + + +@pytest.mark.parametrize(("path",), [(PRICES_PATH,), (BACKUP_PRICES_PATH,)], ids=("main", "backup")) +def test_github_copilot_rows_derive_mode_and_max_tokens_from_their_endpoints(path: Path) -> None: + rows: Final[Mapping[str, _CopilotEndpointRow]] = _copilot_endpoint_rows(path) + assert rows, f"No GitHub Copilot endpoint rows found in {path}" + assert {key: (row.mode, row.max_tokens) for key, row in rows.items()} == { + key: ( + "chat" if "/v1/chat/completions" in row.supported_endpoints else "responses", + row.max_output_tokens, + ) + for key, row in rows.items() + } + + +def test_github_copilot_backup_rows_match_the_main_catalog() -> None: + assert _github_copilot_catalog_rows(PRICES_PATH) == _github_copilot_catalog_rows(BACKUP_PRICES_PATH) + + +def test_github_copilot_rows_resolve_through_get_model_info() -> None: + rows: Final[Mapping[str, _CopilotEndpointRow]] = _copilot_endpoint_rows(PRICES_PATH) + assert { + key: (litellm.get_model_info(key)["mode"], litellm.get_model_info(key)["max_input_tokens"]) for key in rows + } == {key: (row.mode, row.max_input_tokens) for key, row in rows.items()} + + +def test_github_copilot_rows_keep_the_reasoning_flag_their_family_fallback_supplies() -> None: + reasoning_rows: Final = tuple( + key + for key in _copilot_endpoint_rows(PRICES_PATH) + if (match_capability_generalizations(key) or {}).get("supports_reasoning") is True + ) + prices: Final[dict[str, JsonValue]] = TypeAdapter(dict[str, JsonValue]).validate_json(PRICES_PATH.read_bytes()) + assert reasoning_rows + assert {key: _thinking_capabilities(prices, key).supports_reasoning for key in reasoning_rows} == dict.fromkeys( + reasoning_rows, True + ) + assert {key: litellm.get_model_info(key).get("supports_reasoning") for key in reasoning_rows} == dict.fromkeys( + reasoning_rows, True + ) + assert { + key: resolve_supported_reasoning_efforts( + litellm.get_model_info(key), + deployment_is_mapped=True, + ) + != () + for key in reasoning_rows + } == dict.fromkeys(reasoning_rows, True) + + +def test_github_copilot_messages_claude_rows_keep_their_anthropic_thinking_capabilities() -> None: + prices: Final[dict[str, JsonValue]] = TypeAdapter(dict[str, JsonValue]).validate_json(PRICES_PATH.read_bytes()) + claude_rows: Final = tuple( + key + for key, row in _copilot_endpoint_rows(PRICES_PATH).items() + if key.startswith("github_copilot/claude-") and "/v1/messages" in row.supported_endpoints + ) + assert claude_rows + assert {key: _thinking_capabilities(prices, key) for key in claude_rows} == { + key: _thinking_capabilities(prices, _anthropic_counterpart(key)) for key in claude_rows + } + assert { + key: tuple(litellm.get_model_info(key).get(thinking_key) for thinking_key in _THINKING_KEYS) + for key in claude_rows + } == { + key: tuple( + litellm.get_model_info(_anthropic_counterpart(key)).get(thinking_key) for thinking_key in _THINKING_KEYS + ) + for key in claude_rows + } + + def test_committed_schema_matches_generator_output(prices: dict, committed_schema: dict): generator = load_generator() regenerated = json.loads(generator.render(generator.build_schema(prices)))