From c4ee34185265601cec8e519ff5c521e8429424f4 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Tue, 5 May 2026 17:11:24 +0200 Subject: [PATCH] fix: discover xiaomi live models --- .../src/core/model-discovery.test.ts | 72 ++++++++++++++++++- .../src/core/model-discovery.ts | 7 ++ src/cli.ts | 2 +- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/packages/pi-coding-agent/src/core/model-discovery.test.ts b/packages/pi-coding-agent/src/core/model-discovery.test.ts index 6852f160f..8c835267b 100644 --- a/packages/pi-coding-agent/src/core/model-discovery.test.ts +++ b/packages/pi-coding-agent/src/core/model-discovery.test.ts @@ -95,7 +95,7 @@ describe("getDiscoverableProviders", () => { "openrouter", "zai", "minimax", - + "xiaomi", "mistral", ]); assert.ok(!providers.includes("ollama")); @@ -147,7 +147,13 @@ describe("getDefaultTTL", () => { }); it("returns 1 hour for direct live-listed providers", () => { - for (const provider of ["zai", "minimax", "kimi-coding", "mistral"]) { + for (const provider of [ + "zai", + "minimax", + "kimi-coding", + "xiaomi", + "mistral", + ]) { assert.equal(getDefaultTTL(provider), 60 * 60 * 1000); } }); @@ -169,6 +175,7 @@ describe("DISCOVERY_TTLS", () => { assert.ok("zai" in DISCOVERY_TTLS); assert.ok("minimax" in DISCOVERY_TTLS); assert.ok("kimi-coding" in DISCOVERY_TTLS); + assert.ok("xiaomi" in DISCOVERY_TTLS); assert.ok("mistral" in DISCOVERY_TTLS); assert.ok("singularity-memory" in DISCOVERY_TTLS); assert.ok("default" in DISCOVERY_TTLS); @@ -324,6 +331,67 @@ describe("ollama-cloud discovery", () => { }); }); +// ─── Xiaomi Adapter ───────────────────────────────────────────────────────── + +describe("xiaomi discovery", () => { + it("uses the live Xiaomi token-plan /v1/models endpoint and keeps the Anthropic execution endpoint", async () => { + const originalFetch = globalThis.fetch; + const calls: Array<{ url: string; headers?: RequestInit["headers"] }> = []; + globalThis.fetch = (async ( + input: string | URL | Request, + init?: RequestInit, + ) => { + calls.push({ url: String(input), headers: init?.headers }); + return new Response( + JSON.stringify({ + data: [ + { + id: "mimo-v2.5", + name: "MiMo V2.5", + context_length: 1048576, + max_output_tokens: 131072, + }, + { + id: "mimo-v2.5-pro", + capabilities: { reasoning: true, vision: true }, + }, + ], + }), + { status: 200 }, + ); + }) as typeof fetch; + + try { + const adapter = getDiscoveryAdapter("xiaomi"); + const models = await adapter.fetchModels("test-key"); + + assert.equal( + calls[0]?.url, + "https://token-plan-ams.xiaomimimo.com/v1/models", + ); + assert.deepEqual(calls[0]?.headers, { + Authorization: "Bearer test-key", + }); + assert.deepEqual( + models.map((m) => m.id), + ["mimo-v2.5", "mimo-v2.5-pro"], + ); + assert.ok(models.every((m) => m.provider === "xiaomi")); + assert.ok(models.every((m) => m.api === "anthropic-messages")); + assert.ok( + models.every( + (m) => + m.baseUrl === "https://token-plan-ams.xiaomimimo.com/anthropic", + ), + ); + assert.equal(models[1]?.reasoning, true); + assert.deepEqual(models[1]?.input, ["text", "image"]); + } finally { + globalThis.fetch = originalFetch; + } + }); +}); + // ─── OpenRouter Adapter ───────────────────────────────────────────────────── describe("openrouter discovery", () => { diff --git a/packages/pi-coding-agent/src/core/model-discovery.ts b/packages/pi-coding-agent/src/core/model-discovery.ts index c47bb0612..b8e6fd244 100644 --- a/packages/pi-coding-agent/src/core/model-discovery.ts +++ b/packages/pi-coding-agent/src/core/model-discovery.ts @@ -47,6 +47,7 @@ export const DISCOVERY_TTLS: Record = { zai: 60 * 60 * 1000, // 1 hour minimax: 60 * 60 * 1000, // 1 hour "kimi-coding": 60 * 60 * 1000, // 1 hour + xiaomi: 60 * 60 * 1000, // 1 hour mistral: 60 * 60 * 1000, // 1 hour "singularity-memory": 5 * 60 * 1000, // 5 minutes (local daemon catalog) default: 24 * 60 * 60 * 1000, // 24 hours @@ -528,6 +529,12 @@ const adapters: Record = { api: "anthropic-messages", }), "kimi-coding": new StaticDiscoveryAdapter("kimi-coding"), + xiaomi: new ProviderModelListAdapter({ + provider: "xiaomi", + discoveryBaseUrl: "https://token-plan-ams.xiaomimimo.com", + executionBaseUrl: "https://token-plan-ams.xiaomimimo.com/anthropic", + api: "anthropic-messages", + }), mistral: new ProviderModelListAdapter({ provider: "mistral", discoveryBaseUrl: "https://api.mistral.ai/v1", diff --git a/src/cli.ts b/src/cli.ts index a269952c1..b3a2ce3e5 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -72,7 +72,7 @@ function exitIfManagedResourcesAreNewer(currentAgentDir: string): void { async function warmDiscoveryBackedProviders( modelRegistry: ModelRegistry, ): Promise { - const providers = ["ollama-cloud"].filter((provider) => + const providers = ["ollama-cloud", "xiaomi"].filter((provider) => modelRegistry.isProviderRequestReady(provider), ); if (providers.length === 0) return;