feat: add MiMo (Xiaomi) as AI provider (#887)

* feat: add MiMo (Xiaomi) as AI provider

* fix: correct MiMo default base URL, suggested models, and reasoning support

- Default base URL was the China Token Plan endpoint (tp- keys only);
  switch to https://api.xiaomimimo.com/v1 which works with standard
  pay-as-you-go sk- keys. Token Plan users can override in settings.
- Replace deprecated mimo-v2-flash suggestion with mimo-v2.5
  (v2 series was deprecated on 2026-06-30).
- Use createDeepSeek instead of createOpenAI so reasoning_content is
  passed back during multi-turn tool calls (MiMo returns 400 without
  it), matching the existing Kimi implementation.
- Add mimo to SINGLE_SYSTEM_PROVIDERS so system messages are merged.
- Fold validate-model case into the shared OpenAI-compatible group.
- Drop the Bot icon special case; models.dev serves a real xiaomi logo
  via PROVIDER_LOGO_MAP.
- Document MIMO_API_KEY/MIMO_BASE_URL in env.example and
  docs/{en,cn,ja}/ai-providers.md.

* feat: show base URL hint for MiMo in provider settings

MiMo has two endpoints tied to key type: pay-as-you-go keys (sk-...)
use the default api.xiaomimimo.com/v1, while Token Plan keys (tp-...)
require token-plan-cn.xiaomimimo.com/v1. Surface this under the Base
URL field like the existing MiniMax hint, in all four locales.

---------

Co-authored-by: mapengfei <mapengfei@srsj.com>
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
This commit is contained in:
CharlesJay01
2026-07-12 08:10:12 +08:00
committed by GitHub
parent 5bfd7b2468
commit 4984be82a1
12 changed files with 97 additions and 11 deletions

View File

@@ -372,12 +372,13 @@ export async function POST(req: Request) {
break break
} }
// GLM, Qwen, Kimi, Qiniu, Novita - OpenAI compatible // GLM, Qwen, Kimi, Qiniu, Novita, MiMo - OpenAI compatible
case "glm": case "glm":
case "qwen": case "qwen":
case "kimi": case "kimi":
case "qiniu": case "qiniu":
case "novita": { case "novita":
case "mimo": {
const baseURL = const baseURL =
baseUrl || baseUrl ||
PROVIDER_INFO[provider as ProviderName]?.defaultBaseUrl || PROVIDER_INFO[provider as ProviderName]?.defaultBaseUrl ||

View File

@@ -249,6 +249,11 @@ export function ProviderCredentialsFields({
{dict.modelConfig.minimaxBaseUrlHint} {dict.modelConfig.minimaxBaseUrlHint}
</p> </p>
)} )}
{provider === "mimo" && (
<p className="text-xs text-muted-foreground">
{dict.modelConfig.mimoBaseUrlHint}
</p>
)}
</div> </div>
</> </>
)} )}

View File

@@ -308,6 +308,19 @@ AI_MODEL=your_model_id
QINIU_BASE_URL=https://your-custom-endpoint QINIU_BASE_URL=https://your-custom-endpoint
``` ```
### MiMo (小米)
```bash
MIMO_API_KEY=your_api_key
AI_MODEL=mimo-v2.5-pro
```
可选的自定义端点Token Plan 订阅用户请设置专属 Base URL
```bash
MIMO_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
```
## 自动检测 ## 自动检测
如果您只配置了**一个**提供商的 API 密钥,系统将自动检测并使用该提供商。无需设置 `AI_PROVIDER` 如果您只配置了**一个**提供商的 API 密钥,系统将自动检测并使用该提供商。无需设置 `AI_PROVIDER`
@@ -315,7 +328,7 @@ QINIU_BASE_URL=https://your-custom-endpoint
如果您配置了**多个** API 密钥,则必须显式设置 `AI_PROVIDER` 如果您配置了**多个** API 密钥,则必须显式设置 `AI_PROVIDER`
```bash ```bash
AI_PROVIDER=google # 或openai, anthropic, aihubmix, deepseek, siliconflow, doubao, azure, bedrock, openrouter, ollama, gateway, sglang, modelscope, minimax, glm, qwen, kimi, qiniu AI_PROVIDER=google # 或openai, anthropic, aihubmix, deepseek, siliconflow, doubao, azure, bedrock, openrouter, ollama, gateway, sglang, modelscope, minimax, glm, qwen, kimi, qiniu, mimo
``` ```
## 服务端多模型配置 ## 服务端多模型配置

View File

@@ -323,6 +323,19 @@ Optional custom endpoint:
QINIU_BASE_URL=https://your-custom-endpoint QINIU_BASE_URL=https://your-custom-endpoint
``` ```
### MiMo (Xiaomi)
```bash
MIMO_API_KEY=your_api_key
AI_MODEL=mimo-v2.5-pro
```
Optional custom endpoint (Token Plan subscribers should set their dedicated Base URL):
```bash
MIMO_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
```
## Auto-Detection ## Auto-Detection
If you only configure **one** provider's API key, the system will automatically detect and use that provider. No need to set `AI_PROVIDER`. If you only configure **one** provider's API key, the system will automatically detect and use that provider. No need to set `AI_PROVIDER`.
@@ -330,7 +343,7 @@ If you only configure **one** provider's API key, the system will automatically
If you configure **multiple** API keys, you must explicitly set `AI_PROVIDER`: If you configure **multiple** API keys, you must explicitly set `AI_PROVIDER`:
```bash ```bash
AI_PROVIDER=google # or: openai, anthropic, aihubmix, deepseek, siliconflow, doubao, azure, bedrock, openrouter, ollama, gateway, sglang, modelscope, minimax, glm, qwen, kimi, qiniu AI_PROVIDER=google # or: openai, anthropic, aihubmix, deepseek, siliconflow, doubao, azure, bedrock, openrouter, ollama, gateway, sglang, modelscope, minimax, glm, qwen, kimi, qiniu, mimo
``` ```
## Server-Side Multi-Model Configuration ## Server-Side Multi-Model Configuration

View File

@@ -308,6 +308,19 @@ AI_MODEL=your_model_id
QINIU_BASE_URL=https://your-custom-endpoint QINIU_BASE_URL=https://your-custom-endpoint
``` ```
### MiMo (Xiaomi)
```bash
MIMO_API_KEY=your_api_key
AI_MODEL=mimo-v2.5-pro
```
オプションのカスタムエンドポイントToken Plan 加入者は専用の Base URL を設定してください):
```bash
MIMO_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
```
## 自動検出 ## 自動検出
**1つ**のプロバイダーの API キーのみを設定した場合、システムはそのプロバイダーを自動的に検出して使用します。`AI_PROVIDER` を設定する必要はありません。 **1つ**のプロバイダーの API キーのみを設定した場合、システムはそのプロバイダーを自動的に検出して使用します。`AI_PROVIDER` を設定する必要はありません。
@@ -315,7 +328,7 @@ QINIU_BASE_URL=https://your-custom-endpoint
**複数**の API キーを設定する場合は、`AI_PROVIDER` を明示的に設定する必要があります: **複数**の API キーを設定する場合は、`AI_PROVIDER` を明示的に設定する必要があります:
```bash ```bash
AI_PROVIDER=google # または: openai, anthropic, aihubmix, deepseek, siliconflow, doubao, azure, bedrock, openrouter, ollama, gateway, sglang, modelscope, minimax, glm, qwen, kimi, qiniu AI_PROVIDER=google # または: openai, anthropic, aihubmix, deepseek, siliconflow, doubao, azure, bedrock, openrouter, ollama, gateway, sglang, modelscope, minimax, glm, qwen, kimi, qiniu, mimo
``` ```
## サーバーサイドマルチモデル設定 ## サーバーサイドマルチモデル設定

View File

@@ -189,3 +189,8 @@ AI_MODEL=global.anthropic.claude-sonnet-4-5-20250929-v1:0
# Get your API key from: https://novita.ai/dashboard/key # Get your API key from: https://novita.ai/dashboard/key
# NOVITA_API_KEY=your_novita_api_key # NOVITA_API_KEY=your_novita_api_key
# NOVITA_BASE_URL=https://api.novita.ai/openai # Optional, default # NOVITA_BASE_URL=https://api.novita.ai/openai # Optional, default
# MiMo (Xiaomi) Configuration (Optional)
# Get your API key from: https://platform.xiaomimimo.com/
# MIMO_API_KEY=your_mimo_api_key
# MIMO_BASE_URL=https://api.xiaomimimo.com/v1 # Optional, default. Token Plan users: https://token-plan-cn.xiaomimimo.com/v1

View File

@@ -32,6 +32,7 @@ export const SINGLE_SYSTEM_PROVIDERS = new Set<ProviderName>([
"kimi", "kimi",
"qiniu", "qiniu",
"novita", "novita",
"mimo",
]) ])
/** /**
@@ -116,6 +117,7 @@ const ALLOWED_CLIENT_PROVIDERS: ProviderName[] = [
"kimi", "kimi",
"minimax", "minimax",
"novita", "novita",
"mimo",
] ]
// Bedrock provider options for Anthropic beta features // Bedrock provider options for Anthropic beta features
@@ -540,7 +542,8 @@ function buildProviderOptions(
case "qwen": case "qwen":
case "kimi": case "kimi":
case "qiniu": case "qiniu":
case "novita": { case "novita":
case "mimo": {
// These providers don't have reasoning configs in AI SDK yet // These providers don't have reasoning configs in AI SDK yet
// Gateway passes through to underlying providers which handle their own configs // Gateway passes through to underlying providers which handle their own configs
break break
@@ -577,6 +580,7 @@ export const PROVIDER_ENV_VARS: Record<ProviderName, string | null> = {
kimi: "KIMI_API_KEY", kimi: "KIMI_API_KEY",
minimax: "MINIMAX_API_KEY", minimax: "MINIMAX_API_KEY",
novita: "NOVITA_API_KEY", novita: "NOVITA_API_KEY",
mimo: "MIMO_API_KEY",
} }
/** /**
@@ -1346,6 +1350,23 @@ export function getAIModel(overrides?: ClientOverrides): ModelConfig {
break break
} }
case "mimo": {
const apiKey = resolveApiKey(overrides, "MIMO_API_KEY")
const baseURL = resolveBaseURL(
overrides?.apiKey,
overrides?.baseUrl,
resolveBaseUrlEnv(overrides, "MIMO_BASE_URL"),
PROVIDER_INFO.mimo?.defaultBaseUrl,
)
// Use createDeepSeek to properly handle reasoning_content for MiMo
// thinking models (e.g., mimo-v2.5-pro). MiMo's API requires
// reasoning_content to be passed back during multi-turn tool calls
// (returns 400 otherwise), same convention as DeepSeek and Kimi.
const mimoProvider = createDeepSeek({ apiKey, baseURL })
model = mimoProvider(modelId)
break
}
case "glm": case "glm":
case "qwen": case "qwen":
case "qiniu": case "qiniu":
@@ -1393,7 +1414,7 @@ export function getAIModel(overrides?: ClientOverrides): ModelConfig {
default: default:
throw new Error( throw new Error(
`Unknown AI provider: ${provider}. Supported providers: bedrock, openai, anthropic, google, azure, ollama, openrouter, aihubmix, deepseek, siliconflow, sglang, gateway, edgeone, doubao, modelscope, glm, qwen, qiniu, kimi, minimax, novita`, `Unknown AI provider: ${provider}. Supported providers: bedrock, openai, anthropic, google, azure, ollama, openrouter, aihubmix, deepseek, siliconflow, sglang, gateway, edgeone, doubao, modelscope, glm, qwen, qiniu, kimi, minimax, novita, mimo`,
) )
} }

View File

@@ -34,7 +34,8 @@
"glm": "GLM", "glm": "GLM",
"qwen": "Qwen", "qwen": "Qwen",
"kimi": "Kimi", "kimi": "Kimi",
"qiniu": "Qiniu" "qiniu": "Qiniu",
"mimo": "MiMo (Xiaomi)"
}, },
"chat": { "chat": {
"placeholder": "Describe your diagram or upload a file...", "placeholder": "Describe your diagram or upload a file...",
@@ -371,6 +372,7 @@
"baseUrlWithExample": "Base URL (optional, e.g. {example})", "baseUrlWithExample": "Base URL (optional, e.g. {example})",
"customEndpoint": "Custom endpoint URL", "customEndpoint": "Custom endpoint URL",
"minimaxBaseUrlHint": "Use /anthropic for Anthropic-compatible API (recommended), or /v1 for OpenAI-compatible API", "minimaxBaseUrlHint": "Use /anthropic for Anthropic-compatible API (recommended), or /v1 for OpenAI-compatible API",
"mimoBaseUrlHint": "Default works with pay-as-you-go keys (sk-...). Token Plan subscribers (tp-... keys) must set https://token-plan-cn.xiaomimimo.com/v1",
"models": "Models", "models": "Models",
"customModelId": "Custom model ID...", "customModelId": "Custom model ID...",
"allAdded": "All added", "allAdded": "All added",

View File

@@ -34,7 +34,8 @@
"glm": "GLM", "glm": "GLM",
"qwen": "Qwen", "qwen": "Qwen",
"kimi": "Kimi", "kimi": "Kimi",
"qiniu": "Qiniu" "qiniu": "Qiniu",
"mimo": "MiMo (Xiaomi)"
}, },
"chat": { "chat": {
"placeholder": "ダイアグラムを説明するか、ファイルをアップロード...", "placeholder": "ダイアグラムを説明するか、ファイルをアップロード...",
@@ -325,6 +326,7 @@
"baseUrlWithExample": "ベース URLオプション、例: {example}", "baseUrlWithExample": "ベース URLオプション、例: {example}",
"customEndpoint": "カスタムエンドポイント URL", "customEndpoint": "カスタムエンドポイント URL",
"minimaxBaseUrlHint": "/anthropic で Anthropic 互換 API推奨、または /v1 で OpenAI 互換 API を使用", "minimaxBaseUrlHint": "/anthropic で Anthropic 互換 API推奨、または /v1 で OpenAI 互換 API を使用",
"mimoBaseUrlHint": "デフォルトは従量課金キーsk-...用です。Token Plan 加入者tp-... キー)は https://token-plan-cn.xiaomimimo.com/v1 を設定してください",
"models": "モデル", "models": "モデル",
"customModelId": "カスタムモデル ID...", "customModelId": "カスタムモデル ID...",
"allAdded": "すべて追加済み", "allAdded": "すべて追加済み",

View File

@@ -34,7 +34,8 @@
"glm": "GLM", "glm": "GLM",
"qwen": "Qwen", "qwen": "Qwen",
"kimi": "Kimi", "kimi": "Kimi",
"qiniu": "Qiniu" "qiniu": "Qiniu",
"mimo": "MiMo (小米)"
}, },
"chat": { "chat": {
"placeholder": "描述您的圖表或上傳檔案...", "placeholder": "描述您的圖表或上傳檔案...",
@@ -371,6 +372,7 @@
"baseUrlWithExample": "基礎 URL可選例如 {example}", "baseUrlWithExample": "基礎 URL可選例如 {example}",
"customEndpoint": "自訂端點 URL", "customEndpoint": "自訂端點 URL",
"minimaxBaseUrlHint": "使用 /anthropic 端點為 Anthropic 相容 API推薦或使用 /v1 端點為 OpenAI 相容 API", "minimaxBaseUrlHint": "使用 /anthropic 端點為 Anthropic 相容 API推薦或使用 /v1 端點為 OpenAI 相容 API",
"mimoBaseUrlHint": "預設地址適用於按量付費金鑰sk-...。Token Plan 訂閱用戶tp-... 金鑰)請設定為 https://token-plan-cn.xiaomimimo.com/v1",
"models": "模型", "models": "模型",
"customModelId": "自訂模型 ID...", "customModelId": "自訂模型 ID...",
"allAdded": "已全部新增", "allAdded": "已全部新增",

View File

@@ -34,7 +34,8 @@
"glm": "GLM", "glm": "GLM",
"qwen": "Qwen", "qwen": "Qwen",
"kimi": "Kimi", "kimi": "Kimi",
"qiniu": "Qiniu" "qiniu": "Qiniu",
"mimo": "MiMo (小米)"
}, },
"chat": { "chat": {
"placeholder": "描述您的图表或上传文件...", "placeholder": "描述您的图表或上传文件...",
@@ -371,6 +372,7 @@
"baseUrlWithExample": "基础 URL可选例如 {example}", "baseUrlWithExample": "基础 URL可选例如 {example}",
"customEndpoint": "自定义端点 URL", "customEndpoint": "自定义端点 URL",
"minimaxBaseUrlHint": "使用 /anthropic 端点为 Anthropic 兼容 API推荐或使用 /v1 端点为 OpenAI 兼容 API", "minimaxBaseUrlHint": "使用 /anthropic 端点为 Anthropic 兼容 API推荐或使用 /v1 端点为 OpenAI 兼容 API",
"mimoBaseUrlHint": "默认地址适用于按量付费密钥sk-...。Token Plan 订阅用户tp-... 密钥)请设置为 https://token-plan-cn.xiaomimimo.com/v1",
"models": "模型", "models": "模型",
"customModelId": "自定义模型 ID...", "customModelId": "自定义模型 ID...",
"allAdded": "已全部添加", "allAdded": "已全部添加",

View File

@@ -23,6 +23,7 @@ export type ProviderName =
| "kimi" | "kimi"
| "minimax" | "minimax"
| "novita" | "novita"
| "mimo"
// Individual model configuration // Individual model configuration
export interface ModelConfig { export interface ModelConfig {
@@ -114,6 +115,7 @@ export const PROVIDER_LOGO_MAP: Record<string, string> = {
modelscope: "modelscope", modelscope: "modelscope",
minimax: "minimax", minimax: "minimax",
novita: "novita", novita: "novita",
mimo: "xiaomi",
} }
// Provider metadata // Provider metadata
@@ -200,6 +202,10 @@ export const PROVIDER_INFO: Record<
label: "Novita AI", label: "Novita AI",
defaultBaseUrl: "https://api.novita.ai/openai", defaultBaseUrl: "https://api.novita.ai/openai",
}, },
mimo: {
label: "MiMo (Xiaomi)",
defaultBaseUrl: "https://api.xiaomimimo.com/v1",
},
} }
// Suggested models per provider for quick add // Suggested models per provider for quick add
@@ -437,6 +443,7 @@ export const SUGGESTED_MODELS: Partial<Record<ProviderName, string[]>> = {
"moonshotai/kimi-k2.6", "moonshotai/kimi-k2.6",
"deepseek/deepseek-v4-flash", "deepseek/deepseek-v4-flash",
], ],
mimo: ["mimo-v2.5-pro", "mimo-v2.5"],
} }
// Helper to generate UUID // Helper to generate UUID