mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-09-01 17:10:24 +08:00
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:
@@ -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 ||
|
||||||
|
|||||||
@@ -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>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
## 服务端多模型配置
|
## 服务端多模型配置
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
## サーバーサイドマルチモデル設定
|
## サーバーサイドマルチモデル設定
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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": "すべて追加済み",
|
||||||
|
|||||||
@@ -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": "已全部新增",
|
||||||
|
|||||||
@@ -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": "已全部添加",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user