From 32575a65fc2b70cf5359557cb75b1319cf78a890 Mon Sep 17 00:00:00 2001 From: ly-wang19 <94427531+ly-wang19@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:06:15 +0800 Subject: [PATCH] fix(llms): honor reasoning-model params in OpenAIStructuredLLM (#5458) Co-authored-by: ly-wang19 Co-authored-by: kartik-mem0 --- mem0/llms/openai_structured.py | 7 ++-- tests/llms/test_openai_structured.py | 51 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 tests/llms/test_openai_structured.py diff --git a/mem0/llms/openai_structured.py b/mem0/llms/openai_structured.py index 6a9a14c36..2d5104039 100644 --- a/mem0/llms/openai_structured.py +++ b/mem0/llms/openai_structured.py @@ -36,11 +36,8 @@ class OpenAIStructuredLLM(LLMBase): Returns: str: The generated response. """ - params = { - "model": self.config.model, - "messages": messages, - "temperature": self.config.temperature, - } + params = self._get_supported_params(messages=messages) + params["model"] = self.config.model if response_format: params["response_format"] = response_format diff --git a/tests/llms/test_openai_structured.py b/tests/llms/test_openai_structured.py new file mode 100644 index 000000000..4881d4b35 --- /dev/null +++ b/tests/llms/test_openai_structured.py @@ -0,0 +1,51 @@ +from unittest.mock import Mock, patch + +import pytest + +from mem0.configs.llms.openai import OpenAIConfig +from mem0.llms.openai_structured import OpenAIStructuredLLM + + +@pytest.fixture +def mock_openai_client(): + with patch("mem0.llms.openai_structured.OpenAI") as mock_openai: + mock_client = Mock() + mock_openai.return_value = mock_client + yield mock_client + + +def _mock_parse(mock_client, content="ok"): + mock_response = Mock() + mock_response.choices = [Mock(message=Mock(content=content))] + mock_client.beta.chat.completions.parse.return_value = mock_response + + +def test_reasoning_model_drops_temperature(mock_openai_client): + """Reasoning models reject `temperature`; structured output must not send it.""" + config = OpenAIConfig(model="o3-mini", reasoning_effort="low") + llm = OpenAIStructuredLLM(config) + _mock_parse(mock_openai_client) + + llm.generate_response([{"role": "user", "content": "Hello"}]) + + call_kwargs = mock_openai_client.beta.chat.completions.parse.call_args[1] + assert "temperature" not in call_kwargs # reasoning models don't accept temperature + assert "max_tokens" not in call_kwargs # also dropped for reasoning models + assert "top_p" not in call_kwargs # also dropped for reasoning models + assert call_kwargs["reasoning_effort"] == "low" + assert call_kwargs["model"] == "o3-mini" + + +def test_regular_model_sends_sampling_params(mock_openai_client): + """Regular models still receive the standard sampling params.""" + config = OpenAIConfig(model="gpt-4o", temperature=0.3) + llm = OpenAIStructuredLLM(config) + _mock_parse(mock_openai_client) + + llm.generate_response([{"role": "user", "content": "Hello"}]) + + call_kwargs = mock_openai_client.beta.chat.completions.parse.call_args[1] + assert call_kwargs["temperature"] == 0.3 + assert "max_tokens" in call_kwargs # standard sampling params still forwarded + assert "top_p" in call_kwargs + assert call_kwargs["model"] == "gpt-4o"