language_models: Add tool use support for Mistral models (#29994)

Closes https://github.com/zed-industries/zed/issues/29855

Implement tool use handling in Mistral provider, including mapping tool
call events and updating request construction. Add support for
tool_choice and parallel_tool_calls in Mistral API requests.

This works fine with all the existing models. Didn't touched anything
else but for future. Fetching models using their models api, deducting
tool call support, parallel tool calls etc should be done from model
data from api response.

<img width="547" alt="Screenshot 2025-05-06 at 4 52 37 PM"
src="https://github.com/user-attachments/assets/4c08b544-1174-40cc-a40d-522989953448"
/>

Tasks:

- [x] Add tool call support
- [x] Auto Fetch models using mistral api
- [x] Add tests for mistral crates.
- [x] Fix mistral configurations for llm providers.

Release Notes:

- agent: Add tool call support for existing mistral models

---------

Co-authored-by: Peter Tripp <peter@zed.dev>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
This commit is contained in:
Umesh Yadav 2025-05-19 22:06:59 +05:30 committed by GitHub
parent 26a8cac0d8
commit 926f377c6c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 347 additions and 50 deletions

View file

@ -67,6 +67,7 @@ pub enum Model {
max_tokens: usize,
max_output_tokens: Option<u32>,
max_completion_tokens: Option<u32>,
supports_tools: Option<bool>,
},
}
@ -133,6 +134,18 @@ impl Model {
_ => None,
}
}
pub fn supports_tools(&self) -> bool {
match self {
Self::CodestralLatest
| Self::MistralLargeLatest
| Self::MistralMediumLatest
| Self::MistralSmallLatest
| Self::OpenMistralNemo
| Self::OpenCodestralMamba => true,
Self::Custom { supports_tools, .. } => supports_tools.unwrap_or(false),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
@ -146,6 +159,10 @@ pub struct Request {
pub temperature: Option<f32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub response_format: Option<ResponseFormat>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<ToolChoice>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parallel_tool_calls: Option<bool>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tools: Vec<ToolDefinition>,
}
@ -190,12 +207,13 @@ pub enum Prediction {
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
#[serde(rename_all = "snake_case")]
pub enum ToolChoice {
Auto,
Required,
None,
Other(ToolDefinition),
Any,
Function(ToolDefinition),
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]