From 493082405237e66a2f033481a5f8bf8293b0d553 Mon Sep 17 00:00:00 2001 From: David Knedlik Date: Thu, 21 Aug 2025 14:27:00 -0500 Subject: [PATCH 1/7] feat: Add comprehensive GPT-5 series model support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add GPT-5, GPT-5-mini, and GPT-5-nano models to unified configuration - Implement proper thinking mode support via dynamic capability checking - Add OpenAI provider model enumeration methods for registry integration - Update tests to cover all GPT-5 models and their aliases - Fix critical bug where thinking mode was hardcoded instead of using model capabilities Breaking Changes: - None (backward compatible) New Models Available: - gpt-5 (400K context, 128K output, reasoning support) - gpt-5-mini (400K context, 128K output, efficient variant) - gpt-5-nano (400K context, fastest/cheapest variant) Aliases: - gpt5, gpt5-mini, gpt5mini, gpt5-nano, gpt5nano, nano All models support: - Extended thinking mode (reasoning tokens) - Vision capabilities - JSON mode - Function calling 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- conf/custom_models.json | 42 +++++++++++++++++++++++++++++++++++ providers/openai_provider.py | 26 +++++++++++++++++----- tests/test_openai_provider.py | 18 +++++++++++---- 3 files changed, 76 insertions(+), 10 deletions(-) diff --git a/conf/custom_models.json b/conf/custom_models.json index 8d83e00..2bda899 100644 --- a/conf/custom_models.json +++ b/conf/custom_models.json @@ -228,6 +228,48 @@ "temperature_constraint": "fixed", "description": "OpenAI's o4-mini model - optimized for shorter contexts with rapid reasoning and vision" }, + { + "model_name": "gpt-5", + "aliases": ["gpt5", "gpt-5"], + "context_window": 400000, + "max_output_tokens": 128000, + "supports_extended_thinking": true, + "supports_json_mode": true, + "supports_function_calling": true, + "supports_images": true, + "max_image_size_mb": 20.0, + "supports_temperature": true, + "temperature_constraint": "fixed", + "description": "GPT-5 (400K context, 128K output) - Advanced model with reasoning support" + }, + { + "model_name": "gpt-5-mini", + "aliases": ["gpt5-mini", "gpt5mini", "mini"], + "context_window": 400000, + "max_output_tokens": 128000, + "supports_extended_thinking": true, + "supports_json_mode": true, + "supports_function_calling": true, + "supports_images": true, + "max_image_size_mb": 20.0, + "supports_temperature": true, + "temperature_constraint": "fixed", + "description": "GPT-5-mini (400K context, 128K output) - Efficient variant with reasoning support" + }, + { + "model_name": "gpt-5-nano", + "aliases": ["gpt5nano", "gpt5-nano", "nano"], + "context_window": 400000, + "max_output_tokens": 128000, + "supports_extended_thinking": true, + "supports_json_mode": true, + "supports_function_calling": true, + "supports_images": true, + "max_image_size_mb": 20.0, + "supports_temperature": true, + "temperature_constraint": "fixed", + "description": "GPT-5 nano (400K context) - Fastest, cheapest version of GPT-5 for summarization and classification tasks" + }, { "model_name": "llama3.2", "aliases": ["local-llama", "local", "llama3.2", "ollama-llama"], diff --git a/providers/openai_provider.py b/providers/openai_provider.py index 2d3c0cd..a7f5898 100644 --- a/providers/openai_provider.py +++ b/providers/openai_provider.py @@ -259,12 +259,10 @@ class OpenAIModelProvider(OpenAICompatibleProvider): def supports_thinking_mode(self, model_name: str) -> bool: """Check if the model supports extended thinking mode.""" - # GPT-5 models support reasoning tokens (extended thinking) - resolved_name = self._resolve_model_name(model_name) - if resolved_name in ["gpt-5", "gpt-5-mini"]: - return True - # O3 models don't support extended thinking yet - return False + try: + return self.get_capabilities(model_name).supports_extended_thinking + except ValueError: + return False def get_preferred_model(self, category: "ToolModelCategory", allowed_models: list[str]) -> Optional[str]: """Get OpenAI's preferred model for a given category from allowed models. @@ -303,3 +301,19 @@ class OpenAIModelProvider(OpenAICompatibleProvider): # Prefer balanced performance/cost models preferred = find_first(["gpt-5", "gpt-5-mini", "o4-mini", "o3-mini"]) return preferred if preferred else allowed_models[0] + + def get_model_configurations(self) -> dict[str, ModelCapabilities]: + """Get model configurations supported by this provider. + + Returns: + Dict mapping model names to their ModelCapabilities + """ + return self.SUPPORTED_MODELS.copy() + + def get_all_model_aliases(self) -> dict[str, list[str]]: + """Get all model aliases supported by this provider. + + Returns: + Dict mapping model names to their alias lists + """ + return {model_name: caps.aliases for model_name, caps in self.SUPPORTED_MODELS.items()} diff --git a/tests/test_openai_provider.py b/tests/test_openai_provider.py index 3a00faa..5278ff5 100644 --- a/tests/test_openai_provider.py +++ b/tests/test_openai_provider.py @@ -253,14 +253,21 @@ class TestOpenAIProvider: assert call_kwargs["model"] == "o3-mini" # Should be unchanged def test_supports_thinking_mode(self): - """Test thinking mode support.""" + """Test thinking mode support based on model capabilities.""" provider = OpenAIModelProvider("test-key") - # GPT-5 models support thinking mode (reasoning tokens) + # GPT-5 models support thinking mode (reasoning tokens) - all variants assert provider.supports_thinking_mode("gpt-5") is True assert provider.supports_thinking_mode("gpt-5-mini") is True - assert provider.supports_thinking_mode("gpt5") is True # Test with alias - assert provider.supports_thinking_mode("gpt5mini") is True # Test with alias + assert provider.supports_thinking_mode("gpt-5-nano") is True # Now included + + # Test GPT-5 aliases + assert provider.supports_thinking_mode("gpt5") is True + assert provider.supports_thinking_mode("gpt5-mini") is True + assert provider.supports_thinking_mode("gpt5mini") is True + assert provider.supports_thinking_mode("gpt5-nano") is True + assert provider.supports_thinking_mode("gpt5nano") is True + assert provider.supports_thinking_mode("nano") is True # New alias for gpt-5-nano # O3/O4 models don't support thinking mode assert provider.supports_thinking_mode("o3") is False @@ -270,6 +277,9 @@ class TestOpenAIProvider: provider.supports_thinking_mode("mini") is True ) # "mini" now resolves to gpt-5-mini which supports thinking + # Test invalid model name + assert provider.supports_thinking_mode("invalid-model") is False + @patch("providers.openai_compatible.OpenAI") def test_o3_pro_routes_to_responses_endpoint(self, mock_openai_class): """Test that o3-pro model routes to the /v1/responses endpoint (mock test).""" From d9b5c77dd8793c509adf04fc21c7c5197b60644e Mon Sep 17 00:00:00 2001 From: dknedlik Date: Thu, 21 Aug 2025 14:44:54 -0500 Subject: [PATCH 2/7] Update conf/custom_models.json Updating per code review comments. Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- conf/custom_models.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/custom_models.json b/conf/custom_models.json index 2bda899..aa178ba 100644 --- a/conf/custom_models.json +++ b/conf/custom_models.json @@ -239,7 +239,7 @@ "supports_images": true, "max_image_size_mb": 20.0, "supports_temperature": true, - "temperature_constraint": "fixed", + "temperature_constraint": "range", "description": "GPT-5 (400K context, 128K output) - Advanced model with reasoning support" }, { From 09d6ba4eac61b1df4fff833098f604512f9558b0 Mon Sep 17 00:00:00 2001 From: dknedlik Date: Thu, 21 Aug 2025 14:45:28 -0500 Subject: [PATCH 3/7] Update conf/custom_models.json Adding max token for consistency per review comment Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- conf/custom_models.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/custom_models.json b/conf/custom_models.json index aa178ba..686f4e6 100644 --- a/conf/custom_models.json +++ b/conf/custom_models.json @@ -268,7 +268,7 @@ "max_image_size_mb": 20.0, "supports_temperature": true, "temperature_constraint": "fixed", - "description": "GPT-5 nano (400K context) - Fastest, cheapest version of GPT-5 for summarization and classification tasks" + "description": "GPT-5 nano (400K context, 128K output) - Fastest, cheapest version of GPT-5 for summarization and classification tasks" }, { "model_name": "llama3.2", From 7371ed6487b7d90a1b225a67dca2a38c1a52f2ad Mon Sep 17 00:00:00 2001 From: Fahad Date: Wed, 1 Oct 2025 19:41:17 +0400 Subject: [PATCH 4/7] fix: missing "optenai/" in name --- conf/custom_models.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/conf/custom_models.json b/conf/custom_models.json index 686f4e6..3b10deb 100644 --- a/conf/custom_models.json +++ b/conf/custom_models.json @@ -52,7 +52,7 @@ "models": [ { "model_name": "anthropic/claude-opus-4.1", - "aliases": ["opus", "claude-opus", "claude-opus-4.1", "claude-4.1-opus"], + "aliases": ["opus", "claude-opus"], "context_window": 200000, "max_output_tokens": 64000, "supports_extended_thinking": false, @@ -64,7 +64,7 @@ }, { "model_name": "anthropic/claude-sonnet-4.1", - "aliases": ["sonnet", "claude-sonnet", "claude-sonnet-4.1", "claude-4.1-sonnet", "claude"], + "aliases": ["sonnet4.1"], "context_window": 200000, "max_output_tokens": 64000, "supports_extended_thinking": false, @@ -76,7 +76,7 @@ }, { "model_name": "anthropic/claude-3.5-haiku", - "aliases": ["haiku", "claude-haiku", "claude3-haiku", "claude-3-haiku"], + "aliases": ["haiku"], "context_window": 200000, "max_output_tokens": 64000, "supports_extended_thinking": false, @@ -100,7 +100,7 @@ }, { "model_name": "google/gemini-2.5-flash", - "aliases": ["flash","gemini-flash", "flash-openrouter", "flash-2.5"], + "aliases": ["flash","gemini-flash"], "context_window": 1048576, "max_output_tokens": 65536, "supports_extended_thinking": false, @@ -202,7 +202,7 @@ }, { "model_name": "openai/o3-pro", - "aliases": ["o3-pro", "o3pro"], + "aliases": ["o3pro"], "context_window": 200000, "max_output_tokens": 100000, "supports_extended_thinking": false, @@ -229,8 +229,8 @@ "description": "OpenAI's o4-mini model - optimized for shorter contexts with rapid reasoning and vision" }, { - "model_name": "gpt-5", - "aliases": ["gpt5", "gpt-5"], + "model_name": "openai/gpt-5", + "aliases": ["gpt5"], "context_window": 400000, "max_output_tokens": 128000, "supports_extended_thinking": true, @@ -243,8 +243,8 @@ "description": "GPT-5 (400K context, 128K output) - Advanced model with reasoning support" }, { - "model_name": "gpt-5-mini", - "aliases": ["gpt5-mini", "gpt5mini", "mini"], + "model_name": "openai/gpt-5-mini", + "aliases": ["gpt5mini"], "context_window": 400000, "max_output_tokens": 128000, "supports_extended_thinking": true, @@ -257,8 +257,8 @@ "description": "GPT-5-mini (400K context, 128K output) - Efficient variant with reasoning support" }, { - "model_name": "gpt-5-nano", - "aliases": ["gpt5nano", "gpt5-nano", "nano"], + "model_name": "openai/gpt-5-nano", + "aliases": ["gpt5nano"], "context_window": 400000, "max_output_tokens": 128000, "supports_extended_thinking": true, @@ -272,7 +272,7 @@ }, { "model_name": "llama3.2", - "aliases": ["local-llama", "local", "llama3.2", "ollama-llama"], + "aliases": ["local-llama", "ollama-llama"], "context_window": 128000, "max_output_tokens": 64000, "supports_extended_thinking": false, From 484d78d96b4f5ded1a476152b806ae31724822ff Mon Sep 17 00:00:00 2001 From: Fahad Date: Wed, 1 Oct 2025 19:46:43 +0400 Subject: [PATCH 5/7] Cleanup --- providers/openai_provider.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/providers/openai_provider.py b/providers/openai_provider.py index a7f5898..2a927ef 100644 --- a/providers/openai_provider.py +++ b/providers/openai_provider.py @@ -300,20 +300,4 @@ class OpenAIModelProvider(OpenAICompatibleProvider): else: # BALANCED or default # Prefer balanced performance/cost models preferred = find_first(["gpt-5", "gpt-5-mini", "o4-mini", "o3-mini"]) - return preferred if preferred else allowed_models[0] - - def get_model_configurations(self) -> dict[str, ModelCapabilities]: - """Get model configurations supported by this provider. - - Returns: - Dict mapping model names to their ModelCapabilities - """ - return self.SUPPORTED_MODELS.copy() - - def get_all_model_aliases(self) -> dict[str, list[str]]: - """Get all model aliases supported by this provider. - - Returns: - Dict mapping model names to their alias lists - """ - return {model_name: caps.aliases for model_name, caps in self.SUPPORTED_MODELS.items()} + return preferred if preferred else allowed_models[0] \ No newline at end of file From dc96344db043e087ee4f8bf264a79c51dc2e0b7a Mon Sep 17 00:00:00 2001 From: Fahad Date: Wed, 1 Oct 2025 19:50:01 +0400 Subject: [PATCH 6/7] fix: add sonnet alias for Claude Sonnet 4.1 to match opus/haiku pattern --- conf/custom_models.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/custom_models.json b/conf/custom_models.json index 3b10deb..04dce42 100644 --- a/conf/custom_models.json +++ b/conf/custom_models.json @@ -64,7 +64,7 @@ }, { "model_name": "anthropic/claude-sonnet-4.1", - "aliases": ["sonnet4.1"], + "aliases": ["claude", "sonnet", "sonnet4.1", "claude-sonnet", "claude-4.1-sonnet", "claude-sonnet-4.1"], "context_window": 200000, "max_output_tokens": 64000, "supports_extended_thinking": false, From acef7da93c95dca070782f99cc90de68a6266769 Mon Sep 17 00:00:00 2001 From: Fahad Date: Wed, 1 Oct 2025 19:51:24 +0400 Subject: [PATCH 7/7] Cleanup --- providers/openai_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/openai_provider.py b/providers/openai_provider.py index 2a927ef..14843b4 100644 --- a/providers/openai_provider.py +++ b/providers/openai_provider.py @@ -300,4 +300,4 @@ class OpenAIModelProvider(OpenAICompatibleProvider): else: # BALANCED or default # Prefer balanced performance/cost models preferred = find_first(["gpt-5", "gpt-5-mini", "o4-mini", "o3-mini"]) - return preferred if preferred else allowed_models[0] \ No newline at end of file + return preferred if preferred else allowed_models[0]