diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index 24313e50a..835280d9f 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -291,6 +291,7 @@ free-experimentation model. | SiliconFlow | `https://api.siliconflow.cn/v1` | | Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | +| Xiaomi MiMo (OpenAI Chat) | `https://api.xiaomimimo.com/v1` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitLab Duo | `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | | Cloudflare AI Gateway | `https://gateway.ai.cloudflare.com/v1/{account-id}/{gateway}/anthropic` | diff --git a/docs-site/src/content/docs/ja/guides/providers.md b/docs-site/src/content/docs/ja/guides/providers.md index 7a44f3a70..988bbfab7 100644 --- a/docs-site/src/content/docs/ja/guides/providers.md +++ b/docs-site/src/content/docs/ja/guides/providers.md @@ -218,6 +218,7 @@ Cline IDE/CLI のみで API からは使えません。`minimax/minimax-m2.5` | SiliconFlow | `https://api.siliconflow.cn/v1` | | Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | +| Xiaomi MiMo (OpenAI Chat) | `https://api.xiaomimimo.com/v1` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitLab Duo | `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | | Cloudflare AI Gateway | `https://gateway.ai.cloudflare.com/v1/{account-id}/{gateway}/anthropic` | diff --git a/docs-site/src/content/docs/ko/guides/providers.md b/docs-site/src/content/docs/ko/guides/providers.md index 0911820da..4d0e033d5 100644 --- a/docs-site/src/content/docs/ko/guides/providers.md +++ b/docs-site/src/content/docs/ko/guides/providers.md @@ -218,6 +218,7 @@ Cline IDE/CLI에서만 제공되며 API로는 사용할 수 없습니다. `minim | SiliconFlow | `https://api.siliconflow.cn/v1` | | Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | +| Xiaomi MiMo (OpenAI Chat) | `https://api.xiaomimimo.com/v1` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitLab Duo | `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | | Cloudflare AI Gateway | `https://gateway.ai.cloudflare.com/v1/{account-id}/{gateway}/anthropic` | diff --git a/docs-site/src/content/docs/ru/guides/providers.md b/docs-site/src/content/docs/ru/guides/providers.md index 5b2e67a45..e2cb648c3 100644 --- a/docs-site/src/content/docs/ru/guides/providers.md +++ b/docs-site/src/content/docs/ru/guides/providers.md @@ -229,6 +229,7 @@ opencodex поставляется с 79 встроенными пресетам | SiliconFlow | `https://api.siliconflow.cn/v1` | | Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | +| Xiaomi MiMo (OpenAI Chat) | `https://api.xiaomimimo.com/v1` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitLab Duo | `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | | Cloudflare AI Gateway | `https://gateway.ai.cloudflare.com/v1/{account-id}/{gateway}/anthropic` | diff --git a/docs-site/src/content/docs/zh-cn/guides/providers.md b/docs-site/src/content/docs/zh-cn/guides/providers.md index 1740e66e1..9537da4b4 100644 --- a/docs-site/src/content/docs/zh-cn/guides/providers.md +++ b/docs-site/src/content/docs/zh-cn/guides/providers.md @@ -206,6 +206,7 @@ Cline IDE/CLI 中提供,不能通过 API 使用;`minimax/minimax-m2.5` 是 | SiliconFlow | `https://api.siliconflow.cn/v1` | | 火山方舟 · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | +| Xiaomi MiMo (OpenAI Chat) | `https://api.xiaomimimo.com/v1` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitLab Duo | `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | | Cloudflare AI Gateway | `https://gateway.ai.cloudflare.com/v1/{account-id}/{gateway}/anthropic` | diff --git a/docs-site/src/content/docs/zh-tw/guides/providers.md b/docs-site/src/content/docs/zh-tw/guides/providers.md index b21bc6e98..cbbe1d38f 100644 --- a/docs-site/src/content/docs/zh-tw/guides/providers.md +++ b/docs-site/src/content/docs/zh-tw/guides/providers.md @@ -272,6 +272,7 @@ IDE/CLI,不透過 API;`minimax/minimax-m2.5` 是文件列出的 API 免費 | SiliconFlow | `https://api.siliconflow.cn/v1` | | Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | +| Xiaomi MiMo (OpenAI Chat) | `https://api.xiaomimimo.com/v1` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitLab Duo | `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | | Cloudflare AI Gateway | `https://gateway.ai.cloudflare.com/v1/{account-id}/{gateway}/anthropic` | @@ -507,4 +508,4 @@ refresh 的即時 utilization bar。bar 代表特定 window(5 小時、weekly 具有 live probe 的 provider:OpenAI/Codex、Anthropic、xAI、Cursor、Kimi、Google Antigravity、 OpenRouter、DeepSeek、ClinePass、Z.AI、MiniMax、Moonshot、Venice、Synthetic、DeepInfra、Neuralwatt, -以及任何由 a6api 支援的 custom provider。 \ No newline at end of file +以及任何由 a6api 支援的 custom provider。 diff --git a/src/providers/registry.ts b/src/providers/registry.ts index 54c623027..5f2f5c2ae 100644 --- a/src/providers/registry.ts +++ b/src/providers/registry.ts @@ -2303,6 +2303,24 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ noVisionModels: OPENCODE_ZEN_TEXT_ONLY_MODELS, }, { id: "xiaomi", label: "Xiaomi MiMo", baseUrl: "https://api.xiaomimimo.com/anthropic", adapter: "anthropic", authKind: "key", dashboardUrl: "https://xiaomimimo.com", defaultModel: "mimo-v2.5-pro" }, + // Xiaomi's public OpenAI-compatible endpoint is a distinct transport from both the Anthropic + // preset above and the paid token-plan host below. Keep a separate fixed-destination contract + // so existing custom providers are never retargeted while the official route receives the + // strict reasoning ladder its validator enforces (#1483). + { + id: "xiaomi-mimo", + label: "Xiaomi MiMo (OpenAI Chat)", + baseUrl: "https://api.xiaomimimo.com/v1", + adapter: "openai-chat", + authKind: "key", + dashboardUrl: "https://platform.xiaomimimo.com/console/balance", + defaultModel: "mimo-v2.5", + models: ["mimo-v2.5"], + reasoningEfforts: ["low", "medium", "high"], + reasoningEffortMap: { xhigh: "high", max: "high", ultra: "high" }, + preserveCustomDestination: true, + note: "Official Xiaomi MiMo OpenAI-compatible Chat endpoint. The upstream validator accepts reasoning_effort none/low/medium/high; higher Codex tiers are clamped to high.", + }, { id: "kilo", label: "Kilo", baseUrl: "https://api.kilo.ai/api/gateway", adapter: "openai-chat", authKind: "key", dashboardUrl: "https://kilo.ai" }, { id: "mimo-free", diff --git a/structure/03_catalog-and-subagents.md b/structure/03_catalog-and-subagents.md index d35f29272..5de606df0 100644 --- a/structure/03_catalog-and-subagents.md +++ b/structure/03_catalog-and-subagents.md @@ -150,6 +150,21 @@ wire-clamps ultra/max to each model's real top rung (e.g. gpt-5.5 ultra → xhig (`src/server/effort-policy.ts`): they lower or preserve the requested effort rather than rejecting the request, and they never raise it. +[Decision Log] +- 목적과 의도: Xiaomi MiMo의 공식 OpenAI Chat endpoint가 실제로 받지 않는 `max`/ + `ultra` reasoning tier를 catalog에 노출하지 않도록 한다. +- 기존 구현 및 제약 조건: `xiaomi`는 Anthropic endpoint, `mimo`는 token-plan endpoint를 + 소유하며, 공식 `https://api.xiaomimimo.com/v1`은 generic custom provider로 처리됐다. +- 검토한 주요 대안: 기존 `xiaomi`/`mimo` contract를 확장하기, 모든 custom provider의 ladder를 + 일괄 축소하기, 공식 public endpoint만을 별도 registry row로 소유하기. +- 선택한 방식: `xiaomi-mimo`를 고정 목적지의 `openai-chat` preset으로 등록하고 + `low`/`medium`/`high`만 노출하며 높은 direct request는 `high`로 clamp한다. +- 다른 대안 대신 이 방식을 선택한 이유: 서로 다른 auth/wire/host를 하나의 preset으로 + 합치지 않으면서 upstream error로 확인된 계약만 적용할 수 있다. +- 장점, 단점 및 영향: 공식 endpoint에서 안전한 picker/wire 계약을 제공하고, + `preserveCustomDestination`으로 같은 이름의 다른 host/key를 보호한다. 대신 새 preset 표면을 + 문서와 registry parity에서 함께 유지해야 한다. + [Decision Log] - 목적과 의도: bare `defaultModel` selectors that route into third-party providers must keep their adapter-owned effort ladder; only true ChatGPT-native requests should receive the mock-max repair. diff --git a/tests/mimo-token-plan-provider.test.ts b/tests/mimo-token-plan-provider.test.ts index 17314d6e7..83dfc0877 100644 --- a/tests/mimo-token-plan-provider.test.ts +++ b/tests/mimo-token-plan-provider.test.ts @@ -1,9 +1,74 @@ import { describe, expect, test } from "bun:test"; +import { applyProviderConfigHints } from "../src/codex/catalog"; import { KEY_LOGIN_PROVIDERS } from "../src/oauth/key-providers"; import { PROVIDER_REGISTRY } from "../src/providers/registry"; +import { mapReasoningEffort } from "../src/reasoning-effort"; import { routeModel } from "../src/router"; import type { OcxConfig } from "../src/types"; +describe("Xiaomi MiMo public OpenAI Chat endpoint (#1483)", () => { + const baseUrl = "https://api.xiaomimimo.com/v1"; + const entry = PROVIDER_REGISTRY.find(row => row.id === "xiaomi-mimo"); + + test("owns the official destination and advertises only its validated ladder", () => { + expect(entry).toMatchObject({ + adapter: "openai-chat", + baseUrl, + dashboardUrl: "https://platform.xiaomimimo.com/console/balance", + defaultModel: "mimo-v2.5", + models: ["mimo-v2.5"], + preserveCustomDestination: true, + reasoningEfforts: ["low", "medium", "high"], + }); + expect(KEY_LOGIN_PROVIDERS["xiaomi-mimo"]?.baseUrl).toBe(baseUrl); + + const config: OcxConfig = { + port: 10100, + defaultProvider: "xiaomi-mimo", + providers: { + "xiaomi-mimo": { + adapter: "openai-chat", + baseUrl, + authMode: "key", + apiKey: "test-key", + liveModels: true, + }, + }, + }; + const route = routeModel(config, "xiaomi-mimo/mimo-v2.5"); + const catalogModel = applyProviderConfigHints("xiaomi-mimo", route.provider, { + provider: "xiaomi-mimo", + id: route.modelId, + }); + + expect(catalogModel.reasoningEfforts).toEqual(["low", "medium", "high"]); + for (const tier of ["xhigh", "max", "ultra"]) { + expect(mapReasoningEffort(route.provider, route.modelId, tier)).toBe("high"); + } + }); + + test("does not claim a same-named provider at another destination", () => { + const config: OcxConfig = { + port: 10100, + defaultProvider: "xiaomi-mimo", + providers: { + "xiaomi-mimo": { + adapter: "openai-chat", + baseUrl: "https://private.example/v1", + authMode: "key", + apiKey: "private-key", + }, + }, + }; + + const route = routeModel(config, "xiaomi-mimo/mimo-v2.5"); + expect(route.provider.baseUrl).toBe("https://private.example/v1"); + expect(route.provider.apiKey).toBe("private-key"); + expect(route.provider.reasoningEfforts).toBeUndefined(); + expect(route.provider.reasoningEffortMap).toBeUndefined(); + }); +}); + describe("Xiaomi MiMo token plan (#1158)", () => { const entry = PROVIDER_REGISTRY.find(row => row.id === "mimo"); diff --git a/tests/provider-registry-parity.test.ts b/tests/provider-registry-parity.test.ts index f5ab05f11..1c08074ae 100644 --- a/tests/provider-registry-parity.test.ts +++ b/tests/provider-registry-parity.test.ts @@ -35,7 +35,7 @@ const EXPECTED_KEY_PROVIDER_IDS = [ "huggingface", "nvidia", "venice", "zai", "zhipu-bigmodel", "zhipu-bigmodel-coding", "nanogpt", "synthetic", "siliconflow", "qwen-cloud", "tencent-coding-plan", "volcengine", "volcengine-coding-plan", "volcengine-agent-plan", "qianfan", "alibaba", "alibaba-token-plan", "alibaba-token-plan-intl", "parallel", "zenmux", "litellm", "ollama-cloud", "mistral", "minimax", "minimax-cn", "kimi-code", "opencode-zen", "vercel-ai-gateway", - "opencode-free", "xiaomi", "kilo", "mimo-free", "mimo", "cloudflare-ai-gateway", "cloudflare-workers-ai", "gitlab-duo", + "opencode-free", "xiaomi", "xiaomi-mimo", "kilo", "mimo-free", "mimo", "cloudflare-ai-gateway", "cloudflare-workers-ai", "gitlab-duo", ]; describe("provider registry parity", () => {