Skip to content

Commit c7b1dd9

Browse files
MateoTTRclaude
andcommitted
Address review findings: clean up prefixes, update stale test, add gpt-oss coverage
- Remove redundant dash-prefixes (o1-, o3-, gpt-5-) already covered by base prefixes - Replace gpt-oss-120b/gpt-oss-20b full names with gpt-oss- prefix - Rewrite test_openai_model_detection.py to use real is_reasoning_model() function instead of duplicating logic with a non-existent api_base check - Add test coverage for gpt-oss-* model family - Add comment explaining intentional omission of is_reasoning_model from shared_config Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4a0f4bd commit c7b1dd9

4 files changed

Lines changed: 49 additions & 63 deletions

File tree

openevolve/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ def __post_init__(self):
172172
self.evaluator_models = self.models.copy()
173173

174174
# Update models with shared configuration values
175+
# Note: is_reasoning_model is intentionally excluded from shared_config.
176+
# It is a per-model override, not a shared default.
175177
shared_config = {
176178
"api_base": self.api_base,
177179
"api_key": self.api_key,
@@ -226,6 +228,8 @@ def rebuild_models(self) -> None:
226228
self.evaluator_models = self.models.copy()
227229

228230
# Update models with shared configuration values
231+
# Note: is_reasoning_model is intentionally excluded from shared_config.
232+
# It is a per-model override, not a shared default.
229233
shared_config = {
230234
"api_base": self.api_base,
231235
"api_key": self.api_key,

openevolve/llm/openai.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,15 @@
2222

2323
# OpenAI reasoning models that require max_completion_tokens instead of max_tokens.
2424
# These models don't support temperature/top_p and use different parameters.
25-
OPENAI_REASONING_MODEL_PREFIXES = (
26-
# O-series reasoning models
27-
"o1-",
28-
"o1", # o1, o1-mini, o1-preview
29-
"o3-",
30-
"o3", # o3, o3-mini, o3-pro
31-
"o4-", # o4-mini
32-
# GPT-5 series are also reasoning models
33-
"gpt-5-",
34-
"gpt-5", # gpt-5, gpt-5-mini, gpt-5-nano
35-
# The GPT OSS series are also reasoning models
36-
"gpt-oss-120b",
37-
"gpt-oss-20b",
25+
OPENAI_REASONING_MODEL_PREFIXES: tuple[str, ...] = (
26+
# O-series reasoning models (o1, o1-mini, o1-preview, o3, o3-mini, o3-pro, o4-mini, etc.)
27+
"o1",
28+
"o3",
29+
"o4-",
30+
# GPT-5 series (gpt-5, gpt-5-mini, gpt-5-nano, etc.)
31+
"gpt-5",
32+
# GPT OSS series (gpt-oss-120b, gpt-oss-20b, etc.)
33+
"gpt-oss-",
3834
)
3935

4036

Lines changed: 31 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,22 @@
11
"""
22
Test OpenAI reasoning model detection logic
3+
4+
Updated to use the extracted is_reasoning_model() function instead of
5+
duplicating detection logic locally.
36
"""
47

58
import unittest
6-
from unittest.mock import MagicMock
9+
10+
from openevolve.llm.openai import OPENAI_REASONING_MODEL_PREFIXES, is_reasoning_model
711

812

913
class TestOpenAIReasoningModelDetection(unittest.TestCase):
10-
"""Test that OpenAI reasoning models are correctly identified"""
14+
"""Test that OpenAI reasoning models are correctly identified via auto-detection"""
1115

1216
def test_reasoning_model_detection(self):
1317
"""Test various model names to ensure correct reasoning model detection"""
14-
15-
# Define the same constants as in the code
16-
OPENAI_REASONING_MODEL_PREFIXES = (
17-
# O-series reasoning models
18-
"o1-",
19-
"o1", # o1, o1-mini, o1-preview
20-
"o3-",
21-
"o3", # o3, o3-mini, o3-pro
22-
"o4-", # o4-mini
23-
# GPT-5 series are also reasoning models
24-
"gpt-5-",
25-
"gpt-5", # gpt-5, gpt-5-mini, gpt-5-nano
26-
)
27-
28-
def is_reasoning_model(model_name, api_base="https://api.openai.com/v1"):
29-
"""Test function that mimics the logic in openai.py"""
30-
model_lower = str(model_name).lower()
31-
return api_base == "https://api.openai.com/v1" and model_lower.startswith(
32-
OPENAI_REASONING_MODEL_PREFIXES
33-
)
34-
35-
# Test cases: (model_name, expected_result, description)
3618
test_cases = [
37-
# Reasoning models - should return True
19+
# Reasoning models - should return True (auto-detect)
3820
("o1", True, "Base o1 model"),
3921
("o1-mini", True, "o1-mini model"),
4022
("o1-preview", True, "o1-preview model"),
@@ -46,14 +28,16 @@ def is_reasoning_model(model_name, api_base="https://api.openai.com/v1"):
4628
("gpt-5", True, "Base gpt-5 model"),
4729
("gpt-5-mini", True, "gpt-5-mini model"),
4830
("gpt-5-nano", True, "gpt-5-nano model"),
49-
# Non-reasoning models - should return False
31+
("gpt-oss-120b", True, "gpt-oss-120b model"),
32+
("gpt-oss-20b", True, "gpt-oss-20b model"),
33+
# Non-reasoning models - should return False (auto-detect)
5034
("gpt-4o-mini", False, "gpt-4o-mini (not reasoning)"),
5135
("gpt-4o", False, "gpt-4o (not reasoning)"),
5236
("gpt-4", False, "gpt-4 (not reasoning)"),
5337
("gpt-3.5-turbo", False, "gpt-3.5-turbo (not reasoning)"),
5438
("claude-3", False, "Non-OpenAI model"),
5539
("gemini-pro", False, "Non-OpenAI model"),
56-
# Edge cases
40+
# Case insensitivity
5741
("O1-MINI", True, "Uppercase o1-mini"),
5842
("GPT-5-MINI", True, "Uppercase gpt-5-mini"),
5943
]
@@ -67,32 +51,29 @@ def is_reasoning_model(model_name, api_base="https://api.openai.com/v1"):
6751
f"Model '{model_name}' ({description}): expected {expected}, got {result}",
6852
)
6953

70-
def test_non_openai_api_base(self):
71-
"""Test that non-OpenAI API bases don't trigger reasoning model logic"""
72-
OPENAI_REASONING_MODEL_PREFIXES = ("o1-", "o1", "o3-", "o3", "o4-", "gpt-5-", "gpt-5")
73-
74-
def is_reasoning_model(model_name, api_base):
75-
model_lower = str(model_name).lower()
76-
return api_base == "https://api.openai.com/v1" and model_lower.startswith(
77-
OPENAI_REASONING_MODEL_PREFIXES
78-
)
79-
80-
# Even reasoning model names should return False for non-OpenAI APIs
81-
test_cases = [
82-
("o1-mini", "https://api.anthropic.com/v1", False),
83-
("gpt-5", "https://generativelanguage.googleapis.com/v1beta/openai/", False),
84-
("o3-mini", "https://api.deepseek.com/v1", False),
54+
def test_non_openai_models_not_auto_detected(self):
55+
"""Non-OpenAI models should not be auto-detected as reasoning models"""
56+
non_openai_models = [
57+
"gemini-2.5-pro",
58+
"gemini-2.5-flash",
59+
"claude-sonnet-4-5-20250929",
60+
"claude-opus-4-5-20251101",
61+
"deepseek-r1",
8562
]
86-
87-
for model_name, api_base, expected in test_cases:
88-
with self.subTest(model=model_name, api=api_base):
89-
result = is_reasoning_model(model_name, api_base)
90-
self.assertEqual(
91-
result,
92-
expected,
93-
f"Model '{model_name}' with API '{api_base}' should return {expected}",
63+
for model_name in non_openai_models:
64+
with self.subTest(model=model_name):
65+
self.assertFalse(
66+
is_reasoning_model(model_name),
67+
f"Non-OpenAI model '{model_name}' should not be auto-detected",
9468
)
9569

70+
def test_explicit_override_ignores_api_base(self):
71+
"""Explicit config_flag overrides auto-detection regardless of model origin"""
72+
# Even non-OpenAI models can be forced to reasoning mode
73+
self.assertTrue(is_reasoning_model("gemini-2.5-flash", config_flag=True))
74+
# Even OpenAI reasoning models can be forced to standard mode
75+
self.assertFalse(is_reasoning_model("o3-mini", config_flag=False))
76+
9677

9778
if __name__ == "__main__":
9879
unittest.main()

tests/test_reasoning_model_detection.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ def test_openai_gpt5_auto_detected(self):
1919
with self.subTest(model=model):
2020
self.assertTrue(is_reasoning_model(model))
2121

22+
def test_openai_gpt_oss_auto_detected(self):
23+
for model in ["gpt-oss-120b", "gpt-oss-20b", "gpt-oss-30b"]:
24+
with self.subTest(model=model):
25+
self.assertTrue(is_reasoning_model(model))
26+
2227
def test_openai_non_reasoning_not_detected(self):
2328
for model in ["gpt-4o", "gpt-4o-mini", "gpt-4", "gpt-3.5-turbo"]:
2429
with self.subTest(model=model):

0 commit comments

Comments
 (0)