fix: strip extra fields from messages for Mistral chat

Mistral API enforces additionalProperties: false on its message
schema, rejecting extra fields like metadata, provider_specific_fields,
thinking_blocks, and cache_control. Strip these before sending.

Fixes #30882
This commit is contained in:
factnn 2026-06-21 15:48:17 +08:00
parent 906897bebf
commit d19d83925c
2 changed files with 37 additions and 0 deletions

View file

@ -265,6 +265,13 @@ class MistralConfig(OpenAIGPTConfig):
if MistralConfig._is_empty_assistant_message(m):
continue
m = strip_none_values_from_message(m) # prevents 'extra_forbidden' error
# GH#30882: strip fields not permitted by Mistral
# (additionalProperties: false on their message schema)
if isinstance(m, dict):
m.pop("metadata", None)
m.pop("provider_specific_fields", None)
m.pop("thinking_blocks", None)
m.pop("cache_control", None)
new_messages.append(m)
if is_async:

View file

@ -249,6 +249,36 @@ class TestMistralReasoningSupport:
assert result == messages
assert len(result) == 1
def test_transform_messages_strips_extra_fields(self):
"""GH#30882: extra fields like metadata should be stripped
from messages before sending to Mistral API."""
mistral_config = MistralConfig()
messages: List[AllMessageValues] = [
cast(
AllMessageValues,
{
"role": "assistant",
"content": "hello",
"metadata": {
"tool_outputs_trimmed": True,
"trimmed_by": "async_context_compression",
},
"provider_specific_fields": {"foo": "bar"},
"thinking_blocks": [],
"cache_control": {"type": "ephemeral"},
},
)
]
result = mistral_config._transform_messages(messages, "mistral/mistral-large-latest")
assert len(result) == 1
msg = cast(dict, result[0])
assert msg["role"] == "assistant"
assert msg["content"] == "hello"
assert "metadata" not in msg
assert "provider_specific_fields" not in msg
assert "thinking_blocks" not in msg
assert "cache_control" not in msg
def test_transform_request_magistral_with_reasoning(self):
"""Test transform_request method for magistral model with reasoning."""
mistral_config = MistralConfig()