rig_core/providers/
minimax.rs1use crate::client;
25use crate::providers::internal::anthropic_compatible::{
26 AnthropicBaseUrl, impl_dual_dialect_provider,
27};
28
29pub const GLOBAL_API_BASE_URL: &str = "https://api.minimax.io/v1";
31pub const CHINA_API_BASE_URL: &str = "https://api.minimaxi.com/v1";
33pub const GLOBAL_ANTHROPIC_API_BASE_URL: &str = "https://api.minimax.io/anthropic";
35pub const CHINA_ANTHROPIC_API_BASE_URL: &str = "https://api.minimaxi.com/anthropic";
37
38pub const MINIMAX_M2_7: &str = "MiniMax-M2.7";
40pub const MINIMAX_M2_7_HIGHSPEED: &str = "MiniMax-M2.7-highspeed";
42pub const MINIMAX_M2_5: &str = "MiniMax-M2.5";
44pub const MINIMAX_M2_5_HIGHSPEED: &str = "MiniMax-M2.5-highspeed";
46pub const MINIMAX_M2_1: &str = "MiniMax-M2.1";
48pub const MINIMAX_M2_1_HIGHSPEED: &str = "MiniMax-M2.1-highspeed";
50pub const MINIMAX_M2: &str = "MiniMax-M2";
52
53impl_dual_dialect_provider!(
54 ext = MiniMaxExt,
55 builder = MiniMaxBuilder,
56 anthropic_ext = MiniMaxAnthropicExt,
57 anthropic_builder = MiniMaxAnthropicBuilder,
58 client_input = client::BearerAuth,
59 api_key_env = "MINIMAX_API_KEY",
60 base_url = GLOBAL_API_BASE_URL,
61 base_url_env = "MINIMAX_API_BASE",
62 anthropic_provider_name = "minimax",
63 anthropic_base_url = GLOBAL_ANTHROPIC_API_BASE_URL,
64 anthropic_base_url_env = "MINIMAX_ANTHROPIC_API_BASE",
65);
66
67client::impl_capabilities!(
68 MiniMaxExt,
69 completion = super::openai::completion::GenericCompletionModel<MiniMaxExt, H>,
70 model_listing = MiniMaxModelLister<H>,
71);
72
73crate::providers::internal::model_listing::impl_model_lister!(
74 MiniMaxModelLister,
80 Client<H>,
81 crate::providers::internal::model_listing::ListModelEntry,
82 "MiniMax",
83 "/models"
84);
85
86impl super::openai::completion::OpenAICompatibleProvider for MiniMaxExt {
87 const PROVIDER_NAME: &'static str = "minimax";
88
89 type StreamingUsage = super::openai::Usage;
90
91 type Response = super::openai::CompletionResponse;
92}
93
94const ANTHROPIC_BASE_URLS: AnthropicBaseUrl = AnthropicBaseUrl::new(
95 &[
96 (GLOBAL_API_BASE_URL, GLOBAL_ANTHROPIC_API_BASE_URL),
97 (CHINA_API_BASE_URL, CHINA_ANTHROPIC_API_BASE_URL),
98 ],
99 &["/v1", "/v1/"],
100 "/anthropic",
101);
102
103impl<H> ClientBuilder<H> {
104 pub fn global(self) -> Self {
105 self.base_url(GLOBAL_API_BASE_URL)
106 }
107
108 pub fn china(self) -> Self {
109 self.base_url(CHINA_API_BASE_URL)
110 }
111}
112
113impl<H> AnthropicClientBuilder<H> {
114 pub fn global(self) -> Self {
115 self.base_url(GLOBAL_ANTHROPIC_API_BASE_URL)
116 }
117
118 pub fn china(self) -> Self {
119 self.base_url(CHINA_ANTHROPIC_API_BASE_URL)
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::{
126 ANTHROPIC_BASE_URLS, CHINA_ANTHROPIC_API_BASE_URL, CHINA_API_BASE_URL,
127 GLOBAL_ANTHROPIC_API_BASE_URL, GLOBAL_API_BASE_URL,
128 };
129
130 #[test]
131 fn test_client_initialization() {
132 let _client = crate::providers::minimax::Client::new("dummy-key").expect("Client::new()");
133 let _client_from_builder = crate::providers::minimax::Client::builder()
134 .api_key("dummy-key")
135 .build()
136 .expect("Client::builder()");
137 let _anthropic_client = crate::providers::minimax::AnthropicClient::new("dummy-key")
138 .expect("AnthropicClient::new()");
139 let _anthropic_client_from_builder = crate::providers::minimax::AnthropicClient::builder()
140 .api_key("dummy-key")
141 .build()
142 .expect("AnthropicClient::builder()");
143 }
144
145 #[test]
146 fn normalize_openai_bases_to_anthropic_bases() {
147 assert_eq!(
148 ANTHROPIC_BASE_URLS
149 .normalize(GLOBAL_API_BASE_URL)
150 .as_deref(),
151 Some(GLOBAL_ANTHROPIC_API_BASE_URL)
152 );
153 assert_eq!(
154 ANTHROPIC_BASE_URLS.normalize(CHINA_API_BASE_URL).as_deref(),
155 Some(CHINA_ANTHROPIC_API_BASE_URL)
156 );
157 assert_eq!(
158 ANTHROPIC_BASE_URLS
159 .normalize("https://proxy.example.com/v1")
160 .as_deref(),
161 Some("https://proxy.example.com/anthropic")
162 );
163 }
164
165 #[test]
166 fn normalize_preserves_existing_anthropic_base() {
167 assert_eq!(
168 ANTHROPIC_BASE_URLS
169 .normalize(CHINA_ANTHROPIC_API_BASE_URL)
170 .as_deref(),
171 Some(CHINA_ANTHROPIC_API_BASE_URL)
172 );
173 }
174
175 #[test]
176 fn anthropic_primary_override_wins() {
177 let override_url = ANTHROPIC_BASE_URLS.resolve(
178 Some("https://primary.example.com/anthropic"),
179 Some(CHINA_API_BASE_URL),
180 );
181
182 assert_eq!(
183 override_url.as_deref(),
184 Some("https://primary.example.com/anthropic")
185 );
186 }
187}