use crate::protocol::LLMProtocol;
use crate::stream::AssistantMessageEventStream;
use crate::types::*;
use async_trait::async_trait;
use std::collections::HashMap;
const DEFAULT_BASE_URL: &str = "https://api.xiaomimimo.com/v1";
pub struct XiaomiMIMOProvider {
default_api_key: Option<String>,
}
impl XiaomiMIMOProvider {
pub fn new() -> Self {
Self {
default_api_key: None,
}
}
pub fn with_api_key(api_key: impl Into<String>) -> Self {
Self {
default_api_key: Some(api_key.into()),
}
}
pub fn default_compat() -> OpenAICompletionsCompat {
let mut effort_map = HashMap::new();
effort_map.insert("xhigh".to_string(), "high".to_string());
OpenAICompletionsCompat {
thinking: CompatThinking {
effort_map,
..Default::default()
},
..Default::default()
}
}
fn resolve_api_key(&self, options: &StreamOptions) -> Option<String> {
if let Some(ref key) = options.api_key {
return Some(key.clone());
}
if let Some(ref key) = self.default_api_key {
return Some(key.clone());
}
std::env::var("XIAOMI_MIMO_API_KEY").ok()
}
}
impl Default for XiaomiMIMOProvider {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl LLMProtocol for XiaomiMIMOProvider {
fn provider_type(&self) -> Provider {
Provider::XiaomiMIMO
}
fn stream(
&self,
model: &Model,
context: &Context,
options: StreamOptions,
) -> AssistantMessageEventStream {
let mut opts = options;
if opts.api_key.is_none() {
opts.api_key = self.resolve_api_key(&opts);
}
let mut m = model.clone();
if m.base_url.is_none() && opts.base_url.is_none() {
m.base_url = Some(DEFAULT_BASE_URL.to_string());
}
if m.compat.is_none() {
m.compat = Some(Self::default_compat());
}
let provider = crate::protocol::openai_completions::OpenAICompletionsProtocol::new();
provider.stream(&m, context, opts)
}
fn stream_simple(
&self,
model: &Model,
context: &Context,
options: SimpleStreamOptions,
) -> AssistantMessageEventStream {
let mut opts = options;
if opts.base.api_key.is_none() {
opts.base.api_key = self.resolve_api_key(&opts.base);
}
let mut m = model.clone();
if m.base_url.is_none() && opts.base.base_url.is_none() {
m.base_url = Some(DEFAULT_BASE_URL.to_string());
}
if m.compat.is_none() {
m.compat = Some(Self::default_compat());
}
let provider = crate::protocol::openai_completions::OpenAICompletionsProtocol::new();
provider.stream_simple(&m, context, opts)
}
}