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