rig_core/providers/minimax/
extension.rs1use serde::ser::SerializeMap;
16use serde::{Serialize, Serializer};
17use serde_json::Value;
18
19use crate::completion::provider_options::reply_field;
20use crate::completion::{ExtensionOptions, ProviderExtension, ReplyExtras};
21use crate::message::Api;
22use crate::providers::anthropic::extension::{MessagesStop, Nested};
23use crate::providers::anthropic::wire::MESSAGES_API;
24
25#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
27pub struct MiniMaxExt;
28
29impl ProviderExtension for MiniMaxExt {
30 const PROVIDER: &'static str = super::PROVIDER_NAME;
31 type Options = MiniMaxOptions;
32 type Extras = MiniMaxExtras;
33}
34
35#[non_exhaustive]
39#[derive(Clone, Debug, Default, PartialEq, Serialize)]
40pub struct MiniMaxOptions {
41 #[serde(rename = "openai.chat")]
43 pub chat: MiniMaxChat,
44 #[serde(rename = "anthropic.messages")]
46 pub messages: MiniMaxMessages,
47}
48
49impl MiniMaxOptions {
50 pub fn new() -> Self {
52 Self::default()
53 }
54
55 pub fn chat(mut self, chat: MiniMaxChat) -> Self {
57 self.chat = chat;
58 self
59 }
60
61 pub fn messages(mut self, messages: MiniMaxMessages) -> Self {
63 self.messages = messages;
64 self
65 }
66
67 pub fn reasoning_split(mut self, split: bool) -> Self {
70 self.chat = std::mem::take(&mut self.chat).reasoning_split(split);
71 self
72 }
73
74 pub fn metadata_user_id(mut self, user_id: impl Into<String>) -> Self {
77 self.messages = std::mem::take(&mut self.messages).metadata_user_id(user_id);
78 self
79 }
80}
81
82impl ExtensionOptions for MiniMaxOptions {
83 type Ext = MiniMaxExt;
84}
85
86#[non_exhaustive]
88#[derive(Clone, Debug, Default, PartialEq, Serialize)]
89pub struct MiniMaxChat {
90 #[serde(skip_serializing_if = "Option::is_none")]
93 pub reasoning_split: Option<bool>,
94}
95
96impl MiniMaxChat {
97 pub fn new() -> Self {
99 Self::default()
100 }
101
102 pub fn reasoning_split(mut self, split: bool) -> Self {
104 self.reasoning_split = Some(split);
105 self
106 }
107}
108
109#[non_exhaustive]
112#[derive(Clone, Debug, Default, PartialEq)]
113pub struct MiniMaxMessages {
114 pub metadata_user_id: Option<String>,
116}
117
118impl MiniMaxMessages {
119 pub fn new() -> Self {
121 Self::default()
122 }
123
124 pub fn metadata_user_id(mut self, user_id: impl Into<String>) -> Self {
126 self.metadata_user_id = Some(user_id.into());
127 self
128 }
129}
130
131impl Serialize for MiniMaxMessages {
132 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
133 let Self { metadata_user_id } = self;
134 let mut map = serializer.serialize_map(None)?;
135 if let Some(user_id) = metadata_user_id {
136 map.serialize_entry("metadata", &Nested("user_id", user_id))?;
137 }
138 map.end()
139 }
140}
141
142#[non_exhaustive]
144#[derive(Clone, Debug, Default, PartialEq)]
145pub struct MiniMaxExtras {
146 pub reasoning_details: Option<Vec<Value>>,
149 pub base_resp: Option<Value>,
151 pub stop_reason: Option<String>,
153 pub stop_sequence: Option<String>,
155}
156
157impl ReplyExtras for MiniMaxExtras {
158 fn from_reply(api: &Api, raw: &Value) -> Result<Self, serde_json::Error> {
159 if api.as_str() == MESSAGES_API {
160 let MessagesStop {
161 stop_reason,
162 stop_sequence,
163 } = MessagesStop::read("MiniMax", api, raw)?;
164 return Ok(Self {
165 stop_reason,
166 stop_sequence,
167 ..Self::default()
168 });
169 }
170 if api.as_str() != "openai.chat" {
171 return Ok(Self::default());
172 }
173 Ok(Self {
174 reasoning_details: reply_field(raw, "/choices/0/message/reasoning_details")?,
175 base_resp: reply_field(raw, "/base_resp")?,
176 ..Self::default()
177 })
178 }
179}
180
181#[cfg(test)]
182mod tests;