diff --git a/crates/language_models/src/provider/mistral.rs b/crates/language_models/src/provider/mistral.rs index e739ccd99d..87c23e49e7 100644 --- a/crates/language_models/src/provider/mistral.rs +++ b/crates/language_models/src/provider/mistral.rs @@ -444,6 +444,35 @@ pub fn into_mistral( } } + // The Mistral API requires that tool messages be followed by assistant messages, + // not user messages. When we have a tool->user sequence in the conversation, + // we need to insert a placeholder assistant message to maintain proper conversation + // flow and prevent API errors. This is a Mistral-specific requirement that differs + // from other language model APIs. + let messages = { + let mut fixed_messages = Vec::with_capacity(messages.len()); + let mut messages_iter = messages.into_iter().peekable(); + + while let Some(message) = messages_iter.next() { + let is_tool_message = matches!(message, mistral::RequestMessage::Tool { .. }); + fixed_messages.push(message); + + // Insert assistant message between tool and user messages + if is_tool_message { + if let Some(next_msg) = messages_iter.peek() { + if matches!(next_msg, mistral::RequestMessage::User { .. }) { + fixed_messages.push(mistral::RequestMessage::Assistant { + content: Some(" ".to_string()), + tool_calls: Vec::new(), + }); + } + } + } + } + + fixed_messages + }; + mistral::Request { model, messages,