Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions mem0/llms/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,19 @@ def _is_reasoning_model(self, model: str) -> bool:
"o1", "o1-preview", "o3-mini", "o3",
"gpt-5", "gpt-5o", "gpt-5o-mini", "gpt-5o-micro",
}

if model.lower() in reasoning_models:
return True


model_lower = model.lower()
if any(reasoning_model in model_lower for reasoning_model in ["gpt-5", "o1", "o3"]):
# Strip provider prefixes (e.g. "openai/o3-mini" -> "o3-mini")
base_model = model_lower.rsplit("/", 1)[-1]

if base_model in reasoning_models:
return True


# Match o1/o3 family with prefixes (o1-2024-12-17, o3-2025-04-16)
# but NOT gpt-5.x variants (gpt-5.4-mini supports temperature)
if any(base_model.startswith(prefix) for prefix in ["o1-", "o1.", "o3-", "o3."]):
return True

return False

def _get_supported_params(self, **kwargs) -> Dict:
Expand Down
43 changes: 43 additions & 0 deletions tests/llms/test_openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,49 @@ def test_reasoning_effort_config_values():
assert config.reasoning_effort is None


def test_gpt5_mini_not_classified_as_reasoning(mock_openai_client):
"""Test that gpt-5.4-mini is NOT treated as a reasoning model.

gpt-5.4-mini supports temperature and other standard params.
The previous substring match on "gpt-5" incorrectly stripped these.
Regression test for https://github.com/mem0ai/mem0/issues/4738
"""
config = OpenAIConfig(model="gpt-5.4-mini", temperature=0.1)
llm = OpenAILLM(config)
messages = [{"role": "user", "content": "Hello"}]

mock_response = Mock()
mock_response.choices = [Mock(message=Mock(content="Response"))]
mock_openai_client.chat.completions.create.return_value = mock_response

llm.generate_response(messages)

call_kwargs = mock_openai_client.chat.completions.create.call_args
# gpt-5.4-mini should pass through temperature, not strip it
assert call_kwargs[1].get("temperature") == 0.1


def test_is_reasoning_model_classification():
"""Test _is_reasoning_model correctly classifies known models."""
config = OpenAIConfig(model="gpt-4.1")
llm = OpenAILLM(config)

# Reasoning models — should return True
assert llm._is_reasoning_model("o1") is True
assert llm._is_reasoning_model("o3-mini") is True
assert llm._is_reasoning_model("o3") is True
assert llm._is_reasoning_model("gpt-5") is True
assert llm._is_reasoning_model("o1-preview") is True
assert llm._is_reasoning_model("o1-2024-12-17") is True
assert llm._is_reasoning_model("openai/o3-mini") is True

# Non-reasoning models — should return False
assert llm._is_reasoning_model("gpt-5.4-mini") is False
assert llm._is_reasoning_model("gpt-5.4") is False
assert llm._is_reasoning_model("gpt-4.1") is False
assert llm._is_reasoning_model("gpt-4.1-nano-2025-04-14") is False


def test_callback_with_tools(mock_openai_client):
mock_callback = Mock()
config = OpenAIConfig(model="gpt-4.1-nano-2025-04-14", response_callback=mock_callback)
Expand Down
Loading