From 09a4643966f790e76e647c4be560e7387f0221c7 Mon Sep 17 00:00:00 2001 From: felipeborgaco Date: Tue, 14 Apr 2026 15:35:12 -0300 Subject: [PATCH] feat: add Xiaomi MiMo provider support Add Xiaomi MiMo as a new AI provider with support for: - MiMo V2 Pro (1T+ params, 1M context) - MiMo V2 Omni (multi-modal) - MiMo V2 TTS Includes provider configuration, API endpoints, and tests. --- crates/forge_domain/src/provider.rs | 22 +++++++++++ crates/forge_repo/src/provider/provider.json | 41 ++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/crates/forge_domain/src/provider.rs b/crates/forge_domain/src/provider.rs index 02b69a913b..ba317bb5fd 100644 --- a/crates/forge_domain/src/provider.rs +++ b/crates/forge_domain/src/provider.rs @@ -75,6 +75,7 @@ impl ProviderId { pub const NOVITA: ProviderId = ProviderId(Cow::Borrowed("novita")); pub const GOOGLE_AI_STUDIO: ProviderId = ProviderId(Cow::Borrowed("google_ai_studio")); pub const MODAL: ProviderId = ProviderId(Cow::Borrowed("modal")); + pub const XIAOMI_MIMO: ProviderId = ProviderId(Cow::Borrowed("xiaomi_mimo")); /// Returns all built-in provider IDs /// @@ -110,6 +111,7 @@ impl ProviderId { ProviderId::NOVITA, ProviderId::GOOGLE_AI_STUDIO, ProviderId::MODAL, + ProviderId::XIAOMI_MIMO, ] } @@ -139,6 +141,7 @@ impl ProviderId { "novita" => "Novita".to_string(), "google_ai_studio" => "GoogleAIStudio".to_string(), "modal" => "Modal".to_string(), + "xiaomi_mimo" => "XiaomiMimo".to_string(), _ => { // For other providers, use UpperCamelCase conversion use convert_case::{Case, Casing}; @@ -186,6 +189,7 @@ impl std::str::FromStr for ProviderId { "novita" => ProviderId::NOVITA, "google_ai_studio" => ProviderId::GOOGLE_AI_STUDIO, "modal" => ProviderId::MODAL, + "xiaomi_mimo" => ProviderId::XIAOMI_MIMO, // For custom providers, use Cow::Owned to avoid memory leaks custom => ProviderId(Cow::Owned(custom.to_string())), }; @@ -618,6 +622,24 @@ mod tests { assert!(built_in.contains(&ProviderId::MODAL)); } + #[test] + fn test_xiaomi_mimo_from_str() { + let actual = ProviderId::from_str("xiaomi_mimo").unwrap(); + let expected = ProviderId::XIAOMI_MIMO; + assert_eq!(actual, expected); + } + + #[test] + fn test_xiaomi_mimo_display_name() { + assert_eq!(ProviderId::XIAOMI_MIMO.to_string(), "XiaomiMimo"); + } + + #[test] + fn test_xiaomi_mimo_in_built_in_providers() { + let built_in = ProviderId::built_in_providers(); + assert!(built_in.contains(&ProviderId::XIAOMI_MIMO)); + } + #[test] fn test_io_intelligence() { let fixture = "test_key"; diff --git a/crates/forge_repo/src/provider/provider.json b/crates/forge_repo/src/provider/provider.json index ef1bebb607..6f1223b752 100644 --- a/crates/forge_repo/src/provider/provider.json +++ b/crates/forge_repo/src/provider/provider.json @@ -3229,5 +3229,46 @@ } ], "auth_methods": ["api_key"] + }, + { + "id": "xiaomi_mimo", + "api_key_vars": "XIAOMI_MIMO_API_KEY", + "url_param_vars": [ + { "name": "CLUSTER", "options": ["token-plan-sgp.xiaomimimo.com", "token-plan-cn.xiaomimimo.com", "token-plan-ams.xiaomimimo.com"] } + ], + "response_type": "OpenAI", + "url": "https://{{#if CLUSTER}}{{CLUSTER}}{{else}}token-plan-sgp.xiaomimimo.com{{/if}}/v1/chat/completions", + "models": [ + { + "id": "mimo-v2-pro", + "name": "MiMo V2 Pro", + "description": "Xiaomi's flagship foundation model with 1T+ parameters and 1M context length", + "context_length": 1000000, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text"] + }, + { + "id": "mimo-v2-omni", + "name": "MiMo V2 Omni", + "description": "Xiaomi's omni-modal model that natively processes image, video, and audio inputs", + "context_length": 262100, + "tools_supported": true, + "supports_parallel_tool_calls": true, + "supports_reasoning": true, + "input_modalities": ["text", "image"] + }, + { + "id": "mimo-v2-tts", + "name": "MiMo V2 TTS", + "description": "Xiaomi's text-to-speech model", + "context_length": 8192, + "tools_supported": false, + "supports_parallel_tool_calls": false, + "input_modalities": ["text"] + } + ], + "auth_methods": ["api_key"] } ]