diff --git a/.gitignore b/.gitignore index 72f3b1761..b869ecc33 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,9 @@ build/ # Secrets & Config (keep templates, ignore actual secrets) .env config/config.json +.security.yml +onboard + # Test coverage.txt diff --git a/docs/providers.md b/docs/providers.md index 3a740d3b8..42d46189a 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -27,6 +27,7 @@ | `mistral` | LLM (Mistral direct) | [console.mistral.ai](https://console.mistral.ai) | | `longcat` | LLM (Longcat direct) | [longcat.ai](https://longcat.ai) | | `modelscope` | LLM (ModelScope direct) | [modelscope.cn](https://modelscope.cn) | +| `mimo` | LLM (Xiaomi MiMo direct) | [platform.xiaomimimo.com](https://platform.xiaomimimo.com) | ### Model Configuration (model_list) @@ -63,6 +64,7 @@ This design also enables **multi-agent support** with flexible provider selectio | **Vivgrid** | `vivgrid/` | `https://api.vivgrid.com/v1` | OpenAI | [Get Key](https://vivgrid.com) | | **LongCat** | `longcat/` | `https://api.longcat.chat/openai` | OpenAI | [Get Key](https://longcat.chat/platform) | | **ModelScope (魔搭)**| `modelscope/` | `https://api-inference.modelscope.cn/v1` | OpenAI | [Get Token](https://modelscope.cn/my/tokens) | +| **Xiaomi MiMo** | `mimo/` | `https://api.xiaomimimo.com/v1` | OpenAI | [Get Key](https://platform.xiaomimimo.com) | | **Azure OpenAI** | `azure/` | `https://{resource}.openai.azure.com` | Azure | [Get Key](https://portal.azure.com) | | **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth only | | **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | diff --git a/docs/zh/providers.md b/docs/zh/providers.md index e7b323ebf..057e7d3d5 100644 --- a/docs/zh/providers.md +++ b/docs/zh/providers.md @@ -26,6 +26,7 @@ | `mistral` | LLM (Mistral 直连) | [console.mistral.ai](https://console.mistral.ai) | | `longcat` | LLM (Longcat 直连) | [longcat.ai](https://longcat.ai) | | `modelscope` | LLM (ModelScope 直连) | [modelscope.cn](https://modelscope.cn) | +| `mimo` | LLM (小米 MiMo 直连) | [platform.xiaomimimo.com](https://platform.xiaomimimo.com) | ### 模型配置 (model_list) @@ -62,6 +63,7 @@ | **Vivgrid** | `vivgrid/` | `https://api.vivgrid.com/v1` | OpenAI | [获取密钥](https://vivgrid.com) | | **LongCat** | `longcat/` | `https://api.longcat.chat/openai` | OpenAI | [获取密钥](https://longcat.chat/platform) | | **ModelScope (魔搭)**| `modelscope/` | `https://api-inference.modelscope.cn/v1` | OpenAI | [获取 Token](https://modelscope.cn/my/tokens) | +| **小米 MiMo** | `mimo/` | `https://api.xiaomimimo.com/v1` | OpenAI | [获取密钥](https://platform.xiaomimimo.com) | | **Antigravity** | `antigravity/` | Google Cloud | 自定义 | 仅 OAuth | | **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | diff --git a/pkg/providers/factory_provider.go b/pkg/providers/factory_provider.go index 1128fc042..962e6ae19 100644 --- a/pkg/providers/factory_provider.go +++ b/pkg/providers/factory_provider.go @@ -158,7 +158,7 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err "ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras", "vivgrid", "volcengine", "vllm", "qwen", "qwen-intl", "qwen-international", "dashscope-intl", "qwen-us", "dashscope-us", "mistral", "avian", "longcat", "modelscope", "novita", - "coding-plan", "alibaba-coding", "qwen-coding": + "coding-plan", "alibaba-coding", "qwen-coding", "mimo": // All other OpenAI-compatible HTTP providers if cfg.APIKey() == "" && cfg.APIBase == "" { return nil, "", fmt.Errorf("api_key or api_base is required for HTTP-based protocol %q", protocol) @@ -349,6 +349,8 @@ func getDefaultAPIBase(protocol string) string { return "https://api.longcat.chat/openai" case "modelscope": return "https://api-inference.modelscope.cn/v1" + case "mimo": + return "https://api.xiaomimimo.com/v1" default: return "" } diff --git a/pkg/providers/factory_provider_test.go b/pkg/providers/factory_provider_test.go index 2fed18c35..f1fe02cc2 100644 --- a/pkg/providers/factory_provider_test.go +++ b/pkg/providers/factory_provider_test.go @@ -123,6 +123,7 @@ func TestCreateProviderFromConfig_DefaultAPIBase(t *testing.T) { {"ollama", "ollama"}, {"longcat", "longcat"}, {"modelscope", "modelscope"}, + {"mimo", "mimo"}, } for _, tt := range tests { @@ -252,6 +253,35 @@ func TestGetDefaultAPIBase_Novita(t *testing.T) { } } +func TestCreateProviderFromConfig_Mimo(t *testing.T) { + cfg := &config.ModelConfig{ + ModelName: "test-mimo", + Model: "mimo/mimo-v2-pro", + APIBase: "https://api.xiaomimimo.com/v1", + } + cfg.SetAPIKey("test-key") + + provider, modelID, err := CreateProviderFromConfig(cfg) + if err != nil { + t.Fatalf("CreateProviderFromConfig() error = %v", err) + } + if provider == nil { + t.Fatal("CreateProviderFromConfig() returned nil provider") + } + if modelID != "mimo-v2-pro" { + t.Errorf("modelID = %q, want %q", modelID, "mimo-v2-pro") + } + if _, ok := provider.(*HTTPProvider); !ok { + t.Fatalf("expected *HTTPProvider, got %T", provider) + } +} + +func TestGetDefaultAPIBase_Mimo(t *testing.T) { + if got := getDefaultAPIBase("mimo"); got != "https://api.xiaomimimo.com/v1" { + t.Fatalf("getDefaultAPIBase(%q) = %q, want %q", "mimo", got, "https://api.xiaomimimo.com/v1") + } +} + func TestCreateProviderFromConfig_Anthropic(t *testing.T) { cfg := &config.ModelConfig{ ModelName: "test-anthropic", diff --git a/web/frontend/src/components/models/models-page.tsx b/web/frontend/src/components/models/models-page.tsx index 6776e5ca8..a6747c5e0 100644 --- a/web/frontend/src/components/models/models-page.tsx +++ b/web/frontend/src/components/models/models-page.tsx @@ -32,6 +32,7 @@ const PROVIDER_PRIORITY: Record = { vllm: 16, mistral: 17, avian: 18, + mimo: 19, } interface ProviderGroup { diff --git a/web/frontend/src/components/models/provider-icon.tsx b/web/frontend/src/components/models/provider-icon.tsx index 5e2151e2d..814a59834 100644 --- a/web/frontend/src/components/models/provider-icon.tsx +++ b/web/frontend/src/components/models/provider-icon.tsx @@ -37,6 +37,7 @@ const PROVIDER_DOMAINS: Record = { avian: "avian.io", vllm: "vllm.ai", zhipu: "zhipuai.cn", + mimo: "xiaomi.com", } interface ProviderIconProps { diff --git a/web/frontend/src/components/models/provider-label.ts b/web/frontend/src/components/models/provider-label.ts index 923cd9506..82600a96f 100644 --- a/web/frontend/src/components/models/provider-label.ts +++ b/web/frontend/src/components/models/provider-label.ts @@ -18,6 +18,7 @@ const PROVIDER_LABELS: Record = { avian: "Avian", vllm: "VLLM (local)", zhipu: "Zhipu AI (智谱)", + mimo: "Xiaomi MiMo", } export function getProviderKey(model: string): string {