From 1e81a1bd7c13116d2dfc8429192f7cf38ece823f Mon Sep 17 00:00:00 2001 From: Tim Elfrink Date: Sun, 17 Aug 2025 17:13:29 +0200 Subject: [PATCH] feat: Add thinking and reasoning_effort parameter support for GitHub Copilot provider - Add github_copilot case to get_supported_openai_params function - Implement get_supported_openai_params method in GithubCopilotConfig - Dynamically add thinking and reasoning_effort params for Anthropic models - Add comprehensive tests for parameter support validation - Ensure case-insensitive model detection for parameter inclusion Fixes UnsupportedParamsError when using advanced reasoning parameters with Anthropic models through GitHub Copilot proxy. --- .../get_supported_openai_params.py | 2 + .../github_copilot/chat/transformation.py | 16 ++++++++ .../test_github_copilot_transformation.py | 40 +++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/litellm/litellm_core_utils/get_supported_openai_params.py b/litellm/litellm_core_utils/get_supported_openai_params.py index 5fcd2ddb70a..e17a0a88a0e 100644 --- a/litellm/litellm_core_utils/get_supported_openai_params.py +++ b/litellm/litellm_core_utils/get_supported_openai_params.py @@ -271,6 +271,8 @@ def get_supported_openai_params( # noqa: PLR0915 model=model ) ) + elif custom_llm_provider == "github_copilot": + return litellm.GithubCopilotConfig().get_supported_openai_params(model=model) elif custom_llm_provider in litellm._custom_providers: if request_type == "chat_completion": provider_config = litellm.ProviderConfigManager.get_provider_chat_config( diff --git a/litellm/llms/github_copilot/chat/transformation.py b/litellm/llms/github_copilot/chat/transformation.py index 4526e6247b4..de363654feb 100644 --- a/litellm/llms/github_copilot/chat/transformation.py +++ b/litellm/llms/github_copilot/chat/transformation.py @@ -77,6 +77,22 @@ class GithubCopilotConfig(OpenAIConfig): return validated_headers + def get_supported_openai_params(self, model: str) -> list: + """ + Get supported OpenAI parameters for GitHub Copilot. + + For Anthropic models (like claude-sonnet-4), includes thinking and reasoning parameters. + For other models, returns standard OpenAI parameters. + """ + # Get base OpenAI parameters + base_params = super().get_supported_openai_params(model) + + # Add thinking and reasoning parameters for Anthropic Claude models + if "claude" in model.lower(): + base_params.extend(["thinking", "reasoning_effort"]) + + return base_params + def _determine_initiator(self, messages: List[AllMessageValues]) -> str: """ Determine if request is user or agent initiated based on message roles. diff --git a/tests/test_litellm/llms/github_copilot/test_github_copilot_transformation.py b/tests/test_litellm/llms/github_copilot/test_github_copilot_transformation.py index f21c123579d..ac7046f8ced 100644 --- a/tests/test_litellm/llms/github_copilot/test_github_copilot_transformation.py +++ b/tests/test_litellm/llms/github_copilot/test_github_copilot_transformation.py @@ -362,3 +362,43 @@ def test_x_initiator_header_system_only_messages(): ) assert headers["X-Initiator"] == "user" + + +def test_get_supported_openai_params_claude_model(): + """Test that Claude models support thinking and reasoning parameters.""" + config = GithubCopilotConfig() + + # Test Claude model supports thinking and reasoning_effort parameters + supported_params = config.get_supported_openai_params("claude-sonnet-4") + assert "thinking" in supported_params + assert "reasoning_effort" in supported_params + + # Test Claude model with different naming + supported_params_claude = config.get_supported_openai_params("claude-3.5-sonnet") + assert "thinking" in supported_params_claude + assert "reasoning_effort" in supported_params_claude + + # Test non-Claude model doesn't include thinking/reasoning parameters + supported_params_gpt = config.get_supported_openai_params("gpt-4o") + assert "thinking" not in supported_params_gpt + assert "reasoning_effort" not in supported_params_gpt + + # Test with other non-Claude models + supported_params_o3 = config.get_supported_openai_params("o3-mini") + assert "thinking" not in supported_params_o3 + assert "reasoning_effort" not in supported_params_o3 + + +def test_get_supported_openai_params_case_insensitive(): + """Test that Claude model detection is case-insensitive.""" + config = GithubCopilotConfig() + + # Test uppercase + supported_params_upper = config.get_supported_openai_params("CLAUDE-SONNET-4") + assert "thinking" in supported_params_upper + assert "reasoning_effort" in supported_params_upper + + # Test mixed case + supported_params_mixed = config.get_supported_openai_params("Claude-3.5-Sonnet") + assert "thinking" in supported_params_mixed + assert "reasoning_effort" in supported_params_mixed