fix(mistral): accept reasoning_effort on all models and drop client_metadata for Codex compatibility

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Devin AI 2026-09-14 09:50:11 +00:00
parent 30f33a949b
commit cd8887d72c
2 changed files with 39 additions and 8 deletions

View file

@ -99,11 +99,11 @@ class MistralConfig(OpenAIGPTConfig):
"stop",
"response_format",
"parallel_tool_calls",
"reasoning_effort",
]
# Add reasoning support for magistral models
if "magistral" in model.lower():
supported_params.extend(["thinking", "reasoning_effort"])
supported_params.append("thinking")
return supported_params
@ -171,9 +171,11 @@ class MistralConfig(OpenAIGPTConfig):
optional_params["extra_body"] = {"random_seed": value}
if param == "response_format":
optional_params["response_format"] = value
if param == "reasoning_effort" and "magistral" in model.lower():
# Flag that we need to add reasoning system prompt
optional_params["_add_reasoning_prompt"] = True
if param == "reasoning_effort":
if "magistral" in model.lower():
optional_params["_add_reasoning_prompt"] = True
else:
optional_params["reasoning_effort"] = value
if param == "thinking" and "magistral" in model.lower():
# Flag that we need to add reasoning system prompt
optional_params["_add_reasoning_prompt"] = True
@ -534,6 +536,8 @@ class MistralConfig(OpenAIGPTConfig):
if "magistral" in model.lower() and optional_params.get("_add_reasoning_prompt", False):
messages = self._add_reasoning_system_prompt_if_needed(messages, optional_params)
optional_params.pop("client_metadata", None)
# Call parent transform_request which handles _transform_messages
return super().transform_request(
model=model,

View file

@ -51,11 +51,11 @@ class TestMistralReasoningSupport:
assert "reasoning_effort" in supported_params
assert "thinking" in supported_params
# Test non-magistral model doesn't include reasoning parameters
# Non-magistral models accept reasoning_effort (forwarded verbatim) but not thinking
supported_params_normal = mistral_config.get_supported_openai_params(
"mistral/mistral-large-latest"
)
assert "reasoning_effort" not in supported_params_normal
assert "reasoning_effort" in supported_params_normal
assert "thinking" not in supported_params_normal
def test_map_openai_params_reasoning_effort(self):
@ -73,7 +73,7 @@ class TestMistralReasoningSupport:
assert result.get("_add_reasoning_prompt") is True
# Test reasoning_effort ignored for non-magistral model
# Test reasoning_effort forwarded verbatim for non-magistral model
optional_params_normal = {}
result_normal = mistral_config.map_openai_params(
non_default_params={"reasoning_effort": "low"},
@ -83,6 +83,33 @@ class TestMistralReasoningSupport:
)
assert "_add_reasoning_prompt" not in result_normal
assert result_normal["reasoning_effort"] == "low"
def test_reasoning_effort_not_unsupported_for_non_magistral(self):
"""Codex sends reasoning_effort to every model; Mistral must not raise UnsupportedParamsError."""
import litellm
optional_params = litellm.get_optional_params(
model="mistral-medium-latest",
custom_llm_provider="mistral",
reasoning_effort="medium",
)
assert optional_params["reasoning_effort"] == "medium"
def test_client_metadata_stripped_from_request(self):
"""client_metadata passed by Codex must not reach Mistral, whose schema rejects unknown fields."""
mistral_config = MistralConfig()
request = mistral_config.transform_request(
model="mistral-medium-latest",
messages=[{"role": "user", "content": "hi"}],
optional_params={"client_metadata": {"originator": "codex_cli_rs"}, "temperature": 0.2},
litellm_params={},
headers={},
)
assert "client_metadata" not in request
assert request["temperature"] == 0.2
def test_map_openai_params_thinking(self):
"""Test that thinking parameter is properly mapped for magistral models."""