codex_convert_proxy/providers/
minimax.rs1use crate::providers::trait_::Provider;
4use crate::types::chat_api::{ChatRequest, ChatResponse, ChatStreamChunk, Content, MessageRole};
5
6pub struct MiniMaxProvider;
12
13impl Default for MiniMaxProvider {
14 fn default() -> Self {
15 Self
16 }
17}
18
19impl MiniMaxProvider {
20 pub fn new() -> Self {
21 Self
22 }
23}
24
25impl Provider for MiniMaxProvider {
26 fn name(&self) -> &'static str {
27 "minimax"
28 }
29
30 fn chat_completions_path(&self) -> String {
31 "/chat/completions".to_string()
34 }
35
36 fn transform_request(&self, request: &mut ChatRequest) {
37 for message in &mut request.messages {
39 if matches!(message.content, Content::Array(_)) {
40 let text = message.content.as_text();
41 message.content = Content::String(text);
42 }
43 if message.role == MessageRole::Developer {
45 message.role = MessageRole::User;
46 }
47 }
48 }
49
50 fn transform_response(&self, response: &mut ChatResponse) {
51 for choice in &mut response.choices {
53 if matches!(choice.message.content, Content::Array(_)) {
54 let text = choice.message.content.as_text();
55 choice.message.content = Content::String(text);
56 }
57 }
58 }
59
60 fn transform_stream_chunk(&self, chunk: &mut ChatStreamChunk) {
61 for choice in &mut chunk.choices {
63 if let Some(delta) = &mut choice.delta
64 && matches!(delta.content, Some(Content::Array(_)))
65 && let Some(content) = delta.content.take() {
66 let text = content.as_text();
67 if !text.is_empty() {
68 delta.content = Some(Content::String(text));
69 }
70 }
71 }
72 }
73
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79 use crate::types::chat_api::{ChatMessage, Content, MessageRole};
80
81 #[test]
82 fn test_minimax_flattens_content() {
83 let mut request = ChatRequest {
84 model: "ab-01".to_string(),
85 messages: vec![ChatMessage {
86 role: MessageRole::User,
87 content: Content::Array(vec![crate::types::chat_api::ContentBlock {
88 block_type: "text".to_string(),
89 text: Some("Hello".to_string()),
90 image_url: None,
91 input_audio: None,
92 file: None,
93 refusal: None,
94 }]),
95 name: None,
96 annotations: None,
97 tool_calls: None,
98 tool_call_id: None,
99 function_call: None,
100 refusal: None,
101 }],
102 tools: None,
103 tool_choice: None,
104 stream: Some(false),
105 temperature: None,
106 max_tokens: None,
107 top_p: None,
108 user: None,
109 stream_options: None,
110 frequency_penalty: None,
111 presence_penalty: None,
112 logit_bias: None,
113 logprobs: None,
114 top_logprobs: None,
115 n: None,
116 stop: None,
117 response_format: None,
118 reasoning_effort: None,
119 parallel_tool_calls: None,
120 seed: None,
121 service_tier: None,
122 web_search_options: None,
123 modalities: None,
124 prediction: None,
125 audio: None,
126 };
127
128 let provider = MiniMaxProvider;
129 provider.transform_request(&mut request);
130
131 let msg = request.messages.first().unwrap();
132 assert!(matches!(msg.content, Content::String(_)));
133 assert_eq!(msg.content.as_text(), "Hello");
134 }
135}