From 0fb7fd12e53474da494bd889a4991a9757b3c093 Mon Sep 17 00:00:00 2001 From: BlueOcean <1751259208@qq.com> Date: Mon, 18 May 2026 10:38:03 +0800 Subject: [PATCH] feat: add Xiaomi MiMo Token Plan presets (#2803) * feat: add Xiaomi MiMo token plan presets * fix: update Xiaomi MiMo provider presets * fix: align MiMo V2.5 model specs with official documentation - Update maxTokens from 32000 to 131072 (128K) for mimo-v2.5-pro and mimo-v2.5 - Update contextWindow from 262144 to 1048576 (1M) for mimo-v2.5 - Aligns with official specs from Xiaomi MiMo documentation - Ensures consistency between OpenClaw and OpenCode presets --------- Co-authored-by: Jason --- .../providers/forms/ProviderForm.tsx | 11 +- src/config/claudeDesktopProviderPresets.ts | 22 +++- src/config/claudeProviderPresets.ts | 26 ++++- src/config/hermesProviderPresets.ts | 25 ++++- src/config/openclawProviderPresets.ts | 104 +++++++++++++++++- src/config/opencodeProviderPresets.ts | 47 +++++++- tests/config/mimoTokenPlanPresets.test.ts | 51 +++++++++ tests/config/opencodeProviderPresets.test.ts | 18 +++ 8 files changed, 288 insertions(+), 16 deletions(-) create mode 100644 tests/config/mimoTokenPlanPresets.test.ts diff --git a/src/components/providers/forms/ProviderForm.tsx b/src/components/providers/forms/ProviderForm.tsx index e2da3f884..cc0b252f1 100644 --- a/src/components/providers/forms/ProviderForm.tsx +++ b/src/components/providers/forms/ProviderForm.tsx @@ -34,6 +34,7 @@ import { } from "@/config/opencodeProviderPresets"; import { openclawProviderPresets, + rebaseOpenClawSuggestedDefaults, type OpenClawProviderPreset, type OpenClawSuggestedDefaults, } from "@/config/openclawProviderPresets"; @@ -1130,9 +1131,15 @@ function ProviderFormFull({ if (activePreset.isPartner) { payload.isPartner = activePreset.isPartner; } - // OpenClaw: 传递预设的 suggestedDefaults 到提交数据 + // OpenClaw: align preset model refs with the actual submitted provider key. if (activePreset.suggestedDefaults) { - payload.suggestedDefaults = activePreset.suggestedDefaults; + payload.suggestedDefaults = + appId === "openclaw" && payload.providerKey + ? rebaseOpenClawSuggestedDefaults( + activePreset.suggestedDefaults, + payload.providerKey, + ) + : activePreset.suggestedDefaults; } } diff --git a/src/config/claudeDesktopProviderPresets.ts b/src/config/claudeDesktopProviderPresets.ts index ca3de1718..c0fc6328f 100644 --- a/src/config/claudeDesktopProviderPresets.ts +++ b/src/config/claudeDesktopProviderPresets.ts @@ -928,7 +928,27 @@ export const claudeDesktopProviderPresets: ClaudeDesktopProviderPreset[] = [ baseUrl: "https://api.xiaomimimo.com/anthropic", mode: "proxy", apiFormat: "anthropic", - modelRoutes: brandedRoutes("mimo-v2-pro", "mimo-v2-pro", "mimo-v2-pro"), + modelRoutes: brandedRoutes( + "mimo-v2.5-pro", + "mimo-v2.5-pro", + "mimo-v2.5-pro", + ), + icon: "xiaomimimo", + iconColor: "#000000", + }, + { + name: "Xiaomi MiMo Token Plan (China)", + websiteUrl: "https://platform.xiaomimimo.com/#/token-plan", + apiKeyUrl: "https://platform.xiaomimimo.com/#/console/plan-manage", + category: "cn_official", + baseUrl: "https://token-plan-cn.xiaomimimo.com/anthropic", + mode: "proxy", + apiFormat: "anthropic", + modelRoutes: brandedRoutes( + "mimo-v2.5-pro", + "mimo-v2.5-pro", + "mimo-v2.5-pro", + ), icon: "xiaomimimo", iconColor: "#000000", }, diff --git a/src/config/claudeProviderPresets.ts b/src/config/claudeProviderPresets.ts index c764b9b01..900823a05 100644 --- a/src/config/claudeProviderPresets.ts +++ b/src/config/claudeProviderPresets.ts @@ -1056,10 +1056,28 @@ export const providerPresets: ProviderPreset[] = [ env: { ANTHROPIC_BASE_URL: "https://api.xiaomimimo.com/anthropic", ANTHROPIC_AUTH_TOKEN: "", - ANTHROPIC_MODEL: "mimo-v2-pro", - ANTHROPIC_DEFAULT_HAIKU_MODEL: "mimo-v2-pro", - ANTHROPIC_DEFAULT_SONNET_MODEL: "mimo-v2-pro", - ANTHROPIC_DEFAULT_OPUS_MODEL: "mimo-v2-pro", + ANTHROPIC_MODEL: "mimo-v2.5-pro", + ANTHROPIC_DEFAULT_HAIKU_MODEL: "mimo-v2.5-pro", + ANTHROPIC_DEFAULT_SONNET_MODEL: "mimo-v2.5-pro", + ANTHROPIC_DEFAULT_OPUS_MODEL: "mimo-v2.5-pro", + }, + }, + category: "cn_official", + icon: "xiaomimimo", + iconColor: "#000000", + }, + { + name: "Xiaomi MiMo Token Plan (China)", + websiteUrl: "https://platform.xiaomimimo.com/#/token-plan", + apiKeyUrl: "https://platform.xiaomimimo.com/#/console/plan-manage", + settingsConfig: { + env: { + ANTHROPIC_BASE_URL: "https://token-plan-cn.xiaomimimo.com/anthropic", + ANTHROPIC_AUTH_TOKEN: "", + ANTHROPIC_MODEL: "mimo-v2.5-pro", + ANTHROPIC_DEFAULT_HAIKU_MODEL: "mimo-v2.5-pro", + ANTHROPIC_DEFAULT_SONNET_MODEL: "mimo-v2.5-pro", + ANTHROPIC_DEFAULT_OPUS_MODEL: "mimo-v2.5-pro", }, }, category: "cn_official", diff --git a/src/config/hermesProviderPresets.ts b/src/config/hermesProviderPresets.ts index 8a89fc99f..4f2d0278f 100644 --- a/src/config/hermesProviderPresets.ts +++ b/src/config/hermesProviderPresets.ts @@ -1221,13 +1221,34 @@ export const hermesProviderPresets: HermesProviderPreset[] = [ base_url: "https://api.xiaomimimo.com/v1", api_key: "", api_mode: "chat_completions", - models: [{ id: "mimo-v2-pro", name: "MiMo v2 Pro" }], + models: [{ id: "mimo-v2.5-pro", name: "MiMo v2.5 Pro" }], }, category: "cn_official", icon: "xiaomimimo", iconColor: "#000000", suggestedDefaults: { - model: { default: "mimo-v2-pro", provider: "xiaomi_mimo" }, + model: { default: "mimo-v2.5-pro", provider: "xiaomi_mimo" }, + }, + }, + { + name: "Xiaomi MiMo Token Plan (China)", + websiteUrl: "https://platform.xiaomimimo.com/#/token-plan", + apiKeyUrl: "https://platform.xiaomimimo.com/#/console/plan-manage", + settingsConfig: { + name: "xiaomi_mimo_token_plan", + base_url: "https://token-plan-cn.xiaomimimo.com/v1", + api_key: "", + api_mode: "chat_completions", + models: [ + { id: "mimo-v2.5-pro", name: "MiMo v2.5 Pro" }, + { id: "mimo-v2.5", name: "MiMo v2.5" }, + ], + }, + category: "cn_official", + icon: "xiaomimimo", + iconColor: "#000000", + suggestedDefaults: { + model: { default: "mimo-v2.5-pro", provider: "xiaomi_mimo_token_plan" }, }, }, ]; diff --git a/src/config/openclawProviderPresets.ts b/src/config/openclawProviderPresets.ts index 0efe70a0e..77bc7cb27 100644 --- a/src/config/openclawProviderPresets.ts +++ b/src/config/openclawProviderPresets.ts @@ -42,6 +42,46 @@ export interface OpenClawProviderPreset { suggestedDefaults?: OpenClawSuggestedDefaults; } +function rebaseOpenClawModelRef(modelRef: string, providerKey: string): string { + const slashIndex = modelRef.indexOf("/"); + return slashIndex === -1 + ? `${providerKey}/${modelRef}` + : `${providerKey}${modelRef.slice(slashIndex)}`; +} + +/** + * OpenClaw default model refs are stored as "/". + * Presets carry stable built-in keys for display/tests, but the real key is + * chosen in the add-provider form, so rewrite refs right before submission. + */ +export function rebaseOpenClawSuggestedDefaults( + defaults: OpenClawSuggestedDefaults, + providerKey: string, +): OpenClawSuggestedDefaults { + const key = providerKey.trim(); + if (!key) return defaults; + + return { + model: defaults.model + ? { + ...defaults.model, + primary: rebaseOpenClawModelRef(defaults.model.primary, key), + fallbacks: defaults.model.fallbacks?.map((modelRef) => + rebaseOpenClawModelRef(modelRef, key), + ), + } + : undefined, + modelCatalog: defaults.modelCatalog + ? Object.fromEntries( + Object.entries(defaults.modelCatalog).map(([modelRef, entry]) => [ + rebaseOpenClawModelRef(modelRef, key), + entry, + ]), + ) + : undefined, + }; +} + /** * OpenClaw API protocol options * @see https://github.com/openclaw/openclaw/blob/main/docs/gateway/configuration.md @@ -740,10 +780,13 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [ api: "openai-completions", models: [ { - id: "mimo-v2-pro", - name: "MiMo V2 Pro", - contextWindow: 128000, - cost: { input: 0.001, output: 0.004 }, + id: "mimo-v2.5-pro", + name: "MiMo V2.5 Pro", + reasoning: true, + input: ["text"], + contextWindow: 1048576, + maxTokens: 131072, + cost: { input: 1, output: 3, cacheRead: 0.2, cacheWrite: 0 }, }, ], }, @@ -758,8 +801,57 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [ }, }, suggestedDefaults: { - model: { primary: "xiaomimimo/mimo-v2-pro" }, - modelCatalog: { "xiaomimimo/mimo-v2-pro": { alias: "MiMo" } }, + model: { primary: "xiaomimimo/mimo-v2.5-pro" }, + modelCatalog: { "xiaomimimo/mimo-v2.5-pro": { alias: "MiMo" } }, + }, + }, + { + name: "Xiaomi MiMo Token Plan (China)", + websiteUrl: "https://platform.xiaomimimo.com/#/token-plan", + apiKeyUrl: "https://platform.xiaomimimo.com/#/console/plan-manage", + settingsConfig: { + baseUrl: "https://token-plan-cn.xiaomimimo.com/v1", + apiKey: "", + api: "openai-completions", + models: [ + { + id: "mimo-v2.5-pro", + name: "MiMo V2.5 Pro", + reasoning: true, + input: ["text"], + contextWindow: 1048576, + maxTokens: 131072, + }, + { + id: "mimo-v2.5", + name: "MiMo V2.5", + reasoning: true, + input: ["text", "image"], + contextWindow: 1048576, + maxTokens: 131072, + }, + ], + }, + category: "cn_official", + icon: "xiaomimimo", + iconColor: "#000000", + templateValues: { + apiKey: { + label: "Token Plan API Key", + placeholder: "tp-...", + editorValue: "", + }, + }, + suggestedDefaults: { + model: { primary: "xiaomi-mimo-token-plan/mimo-v2.5-pro" }, + modelCatalog: { + "xiaomi-mimo-token-plan/mimo-v2.5-pro": { + alias: "MiMo Token Plan (China)", + }, + "xiaomi-mimo-token-plan/mimo-v2.5": { + alias: "MiMo Token Plan (China) Multimodal", + }, + }, }, }, diff --git a/src/config/opencodeProviderPresets.ts b/src/config/opencodeProviderPresets.ts index c51a20d79..11c375395 100644 --- a/src/config/opencodeProviderPresets.ts +++ b/src/config/opencodeProviderPresets.ts @@ -919,7 +919,16 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [ setCacheKey: true, }, models: { - "mimo-v2-pro": { name: "MiMo V2 Pro" }, + "mimo-v2.5-pro": { + name: "MiMo V2.5 Pro", + limit: { context: 1048576, output: 131072 }, + modalities: { input: ["text"], output: ["text"] }, + }, + "mimo-v2.5": { + name: "MiMo V2.5", + limit: { context: 1048576, output: 131072 }, + modalities: { input: ["text", "image"], output: ["text"] }, + }, }, }, category: "cn_official", @@ -933,6 +942,42 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [ }, }, }, + { + name: "Xiaomi MiMo Token Plan (China)", + websiteUrl: "https://platform.xiaomimimo.com/#/token-plan", + apiKeyUrl: "https://platform.xiaomimimo.com/#/console/plan-manage", + settingsConfig: { + npm: "@ai-sdk/openai-compatible", + name: "Xiaomi MiMo Token Plan (China)", + options: { + baseURL: "https://token-plan-cn.xiaomimimo.com/v1", + apiKey: "", + setCacheKey: true, + }, + models: { + "mimo-v2.5-pro": { + name: "MiMo V2.5 Pro", + limit: { context: 1048576, output: 131072 }, + modalities: { input: ["text"], output: ["text"] }, + }, + "mimo-v2.5": { + name: "MiMo V2.5", + limit: { context: 1048576, output: 131072 }, + modalities: { input: ["text", "image"], output: ["text"] }, + }, + }, + }, + category: "cn_official", + icon: "xiaomimimo", + iconColor: "#000000", + templateValues: { + apiKey: { + label: "Token Plan API Key", + placeholder: "tp-...", + editorValue: "", + }, + }, + }, { name: "AiHubMix", diff --git a/tests/config/mimoTokenPlanPresets.test.ts b/tests/config/mimoTokenPlanPresets.test.ts new file mode 100644 index 000000000..90781bc00 --- /dev/null +++ b/tests/config/mimoTokenPlanPresets.test.ts @@ -0,0 +1,51 @@ +import { describe, expect, it } from "vitest"; +import { + openclawProviderPresets, + rebaseOpenClawSuggestedDefaults, +} from "@/config/openclawProviderPresets"; + +describe("Xiaomi MiMo Token Plan presets", () => { + it("uses a separate OpenClaw provider namespace from pay-as-you-go MiMo", () => { + const payAsYouGo = openclawProviderPresets.find( + (item) => item.name === "Xiaomi MiMo", + ); + const tokenPlan = openclawProviderPresets.find( + (item) => item.name === "Xiaomi MiMo Token Plan (China)", + ); + + expect(payAsYouGo?.suggestedDefaults?.model?.primary).toBe( + "xiaomimimo/mimo-v2.5-pro", + ); + expect(tokenPlan?.suggestedDefaults?.model?.primary).toBe( + "xiaomi-mimo-token-plan/mimo-v2.5-pro", + ); + expect(tokenPlan?.suggestedDefaults?.modelCatalog).toHaveProperty( + "xiaomi-mimo-token-plan/mimo-v2.5-pro", + ); + expect(tokenPlan?.suggestedDefaults?.modelCatalog).toHaveProperty( + "xiaomi-mimo-token-plan/mimo-v2.5", + ); + }); + + it("rebases OpenClaw defaults to the submitted provider key", () => { + const tokenPlan = openclawProviderPresets.find( + (item) => item.name === "Xiaomi MiMo Token Plan (China)", + ); + + expect(tokenPlan?.suggestedDefaults).toBeDefined(); + + const rebased = rebaseOpenClawSuggestedDefaults( + tokenPlan!.suggestedDefaults!, + "my-mimo-plan", + ); + + expect(rebased.model?.primary).toBe("my-mimo-plan/mimo-v2.5-pro"); + expect(rebased.modelCatalog).toHaveProperty( + "my-mimo-plan/mimo-v2.5-pro", + ); + expect(rebased.modelCatalog).toHaveProperty("my-mimo-plan/mimo-v2.5"); + expect(rebased.modelCatalog).not.toHaveProperty( + "xiaomi-mimo-token-plan/mimo-v2.5-pro", + ); + }); +}); diff --git a/tests/config/opencodeProviderPresets.test.ts b/tests/config/opencodeProviderPresets.test.ts index 0a4223be9..d033561d9 100644 --- a/tests/config/opencodeProviderPresets.test.ts +++ b/tests/config/opencodeProviderPresets.test.ts @@ -80,4 +80,22 @@ describe("AWS Bedrock OpenCode Provider Presets", () => { "https://api.kimi.com/coding/v1", ); }); + + it("Xiaomi MiMo presets should include official OpenCode model metadata", () => { + const presets = ["Xiaomi MiMo", "Xiaomi MiMo Token Plan (China)"].map( + (name) => opencodeProviderPresets.find((preset) => preset.name === name), + ); + + for (const preset of presets) { + expect(preset).toBeDefined(); + expect(preset!.settingsConfig.models["mimo-v2.5-pro"]).toMatchObject({ + limit: { context: 1048576, output: 131072 }, + modalities: { input: ["text"], output: ["text"] }, + }); + expect(preset!.settingsConfig.models["mimo-v2.5"]).toMatchObject({ + limit: { context: 1048576, output: 131072 }, + modalities: { input: ["text", "image"], output: ["text"] }, + }); + } + }); });