diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 926672b19a2..50cbcf3b4b8 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -30217,6 +30217,7 @@ "mode": "chat", "supports_function_calling": true, "supports_parallel_function_calling": true, + "supports_reasoning": true, "supports_response_schema": true, "supports_vision": true }, @@ -30278,6 +30279,95 @@ "supports_response_schema": true, "supports_vision": true }, + "github_copilot/claude-3-5-haiku": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 8192, + "max_tokens": 8192, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_vision": true + }, + "github_copilot/claude-3-5-sonnet": { + "litellm_provider": "github_copilot", + "max_input_tokens": 200000, + "max_output_tokens": 8192, + "max_tokens": 8192, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_vision": true + }, + "github_copilot/gemini-1-5-pro": { + "litellm_provider": "github_copilot", + "max_input_tokens": 2000000, + "max_output_tokens": 8192, + "max_tokens": 8192, + "mode": "chat", + "supported_endpoints": [ + "/v1/chat/completions" + ], + "supports_function_calling": true, + "supports_parallel_function_calling": true, + "supports_vision": true + }, + "github_copilot/gpt-5.4": { + "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_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.4-mini": { + "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_reasoning": true, + "supports_response_schema": true, + "supports_vision": true + }, + "github_copilot/gpt-5.5": { + "litellm_provider": "github_copilot", + "max_input_tokens": 922000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "responses", + "supported_endpoints": [ + "/v1/responses" + ], + "supports_function_calling": true, + "supports_none_reasoning_effort": true, + "supports_parallel_function_calling": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "supports_vision": true, + "supports_xhigh_reasoning_effort": true + }, "github_copilot/mai-code-1-flash": { "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 7.5e-07, diff --git a/tests/test_litellm/test_github_copilot.py b/tests/test_litellm/test_github_copilot.py new file mode 100644 index 00000000000..a8a939a0e56 --- /dev/null +++ b/tests/test_litellm/test_github_copilot.py @@ -0,0 +1,84 @@ +""" +Unit tests for GitHub Copilot model registration in LiteLLM. +Validates that models listed in the GitHub Copilot API are correctly +registered in the model_prices_and_context_window.json registry. +""" + +import pytest +import litellm + + +# Models newly added by this PR (gpt-4o was already registered) +EXPECTED_MODELS = [ + "github_copilot/claude-3-5-sonnet", + "github_copilot/claude-3-5-haiku", + "github_copilot/gemini-1-5-pro", + "github_copilot/gpt-5.4", + "github_copilot/gpt-5.4-mini", +] + +REASONING_MODELS = [ + "github_copilot/gpt-5-mini", + "github_copilot/gpt-5.4", + "github_copilot/gpt-5.4-mini", + "github_copilot/gpt-5.5", +] + + +@pytest.mark.parametrize("model", EXPECTED_MODELS) +def test_github_copilot_model_registered(model): + """Each GitHub Copilot model should be resolvable via get_model_info.""" + model_info = litellm.get_model_info(model) + assert model_info is not None, f"Model '{model}' not found in registry" + assert model_info["litellm_provider"] == "github_copilot", ( + f"Expected litellm_provider='github_copilot' for '{model}', " + f"got '{model_info['litellm_provider']}'" + ) + assert model_info["mode"] == "chat", ( + f"Expected mode='chat' for '{model}', got '{model_info['mode']}'" + ) + + +@pytest.mark.parametrize("model", EXPECTED_MODELS) +def test_github_copilot_model_has_token_limits(model): + """Each model should define max_tokens.""" + model_info = litellm.get_model_info(model) + assert model_info is not None + assert "max_tokens" in model_info, f"'{model}' is missing max_tokens" + assert model_info["max_tokens"] > 0, ( + f"'{model}' has invalid max_tokens={model_info['max_tokens']}" + ) + + +def test_github_copilot_claude_3_5_sonnet_context_window(): + """claude-3-5-sonnet should reflect the 200k context window.""" + model_info = litellm.get_model_info("github_copilot/claude-3-5-sonnet") + assert model_info is not None + assert model_info["max_input_tokens"] == 200000 + + +def test_github_copilot_claude_3_5_haiku_context_window(): + """claude-3-5-haiku should reflect the 200k context window.""" + model_info = litellm.get_model_info("github_copilot/claude-3-5-haiku") + assert model_info is not None + assert model_info["max_input_tokens"] == 200000 + + +@pytest.mark.parametrize("model", EXPECTED_MODELS) +def test_github_copilot_models_support_function_calling(model): + """Each newly added model should support function calling.""" + model_info = litellm.get_model_info(model) + assert model_info is not None + assert model_info.get("supports_function_calling") is True, ( + f"'{model}' should support function calling" + ) + + +@pytest.mark.parametrize("model", REASONING_MODELS) +def test_github_copilot_reasoning_models(model): + """gpt-5-mini, gpt-5.4, and gpt-5.4-mini should have supports_reasoning=True.""" + model_info = litellm.get_model_info(model) + assert model_info is not None, f"Model '{model}' not found in registry" + assert model_info.get("supports_reasoning") is True, ( + f"'{model}' should have supports_reasoning=True" + )