opendev_http/adapters/
mistral.rs1use serde_json::{Value, json};
10
11const DEFAULT_API_URL: &str = "https://api.mistral.ai/v1/chat/completions";
12
13#[derive(Debug, Clone)]
20pub struct MistralAdapter {
21 api_url: String,
22}
23
24impl MistralAdapter {
25 pub fn new() -> Self {
27 Self {
28 api_url: DEFAULT_API_URL.to_string(),
29 }
30 }
31
32 pub fn with_url(url: impl Into<String>) -> Self {
34 Self {
35 api_url: url.into(),
36 }
37 }
38
39 fn normalize_tool_calls(response: &mut Value) {
45 if let Some(choices) = response.get_mut("choices").and_then(|c| c.as_array_mut()) {
46 for choice in choices.iter_mut() {
47 if let Some(tool_calls) = choice
48 .get_mut("message")
49 .and_then(|m| m.get_mut("tool_calls"))
50 .and_then(|tc| tc.as_array_mut())
51 {
52 for tc in tool_calls.iter_mut() {
53 if tc.get("type").is_none() {
55 tc["type"] = json!("function");
56 }
57
58 if let Some(func) = tc.get_mut("function")
60 && let Some(args) = func.get("arguments")
61 && (args.is_object() || args.is_array())
62 {
63 let args_str = serde_json::to_string(args).unwrap_or_default();
64 func["arguments"] = Value::String(args_str);
65 }
66 }
67 }
68 }
69 }
70 }
71
72 fn clean_request(payload: &mut Value) {
76 if let Some(obj) = payload.as_object_mut() {
77 obj.remove("logprobs");
78 obj.remove("top_logprobs");
79 obj.remove("n");
80 obj.remove("seed");
81 }
82 }
83}
84
85impl Default for MistralAdapter {
86 fn default() -> Self {
87 Self::new()
88 }
89}
90
91#[async_trait::async_trait]
92impl super::base::ProviderAdapter for MistralAdapter {
93 fn provider_name(&self) -> &str {
94 "mistral"
95 }
96
97 fn convert_request(&self, mut payload: Value) -> Value {
98 Self::clean_request(&mut payload);
99 payload
101 .as_object_mut()
102 .map(|obj| obj.remove("_reasoning_effort"));
103 payload
104 }
105
106 fn convert_response(&self, mut response: Value) -> Value {
107 Self::normalize_tool_calls(&mut response);
108 response
109 }
110
111 fn api_url(&self) -> &str {
112 &self.api_url
113 }
114}
115
116#[cfg(test)]
117#[path = "mistral_tests.rs"]
118mod tests;