fix(ai): refresh Xiaomi token plan model catalogs

Use the new provider-specific Xiaomi Token Plan catalogs from models.dev instead of cloning the API-billing Xiaomi catalog into every token-plan region. This removes API-billing-only models such as mimo-v2-omni from xiaomi-token-plan-{cn,ams,sgp}.
This commit is contained in:
Vegard Stikbakke
2026-07-08 09:39:44 +02:00
parent 4ea062f9f3
commit cc2db98002
14 changed files with 270 additions and 353 deletions
+1
View File
@@ -4,6 +4,7 @@
### Fixed ### Fixed
- Fixed Xiaomi Token Plan model metadata to follow the upstream models.dev token-plan catalogs, removing unsupported `mimo-v2-omni` variants ([#6204](https://github.com/earendil-works/pi/issues/6204)).
- Fixed GitHub Copilot device-code login polling to wait before the first token poll, avoiding incorrect device-code failures for some users after browser authorization ([#6187](https://github.com/earendil-works/pi/issues/6187)). - Fixed GitHub Copilot device-code login polling to wait before the first token poll, avoiding incorrect device-code failures for some users after browser authorization ([#6187](https://github.com/earendil-works/pi/issues/6187)).
- Fixed OAuth device-code polling to honor the server-provided `slow_down` interval instead of only applying the RFC 8628 5-second increment, so GitHub Copilot login recovers instead of appearing to hang when polls arrive early (e.g. WSL/VM clock drift) ([#6187](https://github.com/earendil-works/pi/issues/6187)). - Fixed OAuth device-code polling to honor the server-provided `slow_down` interval instead of only applying the RFC 8628 5-second increment, so GitHub Copilot login recovers instead of appearing to hang when polls arrive early (e.g. WSL/VM clock drift) ([#6187](https://github.com/earendil-works/pi/issues/6187)).
- Fixed OpenAI Codex user-agent construction to synchronously load Node OS metadata, avoiding a startup race that could report `pi (browser)` in Node/Bun. - Fixed OpenAI Codex user-agent construction to synchronously load Node OS metadata, avoiding a startup race that could report `pi (browser)` in Node/Bun.
+41 -29
View File
@@ -1534,38 +1534,50 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
thinkingFormat: "deepseek", thinkingFormat: "deepseek",
}; };
const xiaomiVariants = [ const xiaomiVariants = [
{ provider: "xiaomi", baseUrl: "https://api.xiaomimimo.com/v1" }, { source: "xiaomi", provider: "xiaomi", baseUrl: "https://api.xiaomimimo.com/v1" },
{ provider: "xiaomi-token-plan-cn", baseUrl: "https://token-plan-cn.xiaomimimo.com/v1" }, {
{ provider: "xiaomi-token-plan-ams", baseUrl: "https://token-plan-ams.xiaomimimo.com/v1" }, source: "xiaomi-token-plan-cn",
{ provider: "xiaomi-token-plan-sgp", baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1" }, provider: "xiaomi-token-plan-cn",
baseUrl: "https://token-plan-cn.xiaomimimo.com/v1",
},
{
source: "xiaomi-token-plan-ams",
provider: "xiaomi-token-plan-ams",
baseUrl: "https://token-plan-ams.xiaomimimo.com/v1",
},
{
source: "xiaomi-token-plan-sgp",
provider: "xiaomi-token-plan-sgp",
baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1",
},
] as const; ] as const;
if (data.xiaomi?.models) { for (const { source, provider, baseUrl } of xiaomiVariants) {
for (const { provider, baseUrl } of xiaomiVariants) { const providerModels = data[source]?.models;
for (const [modelId, model] of Object.entries(data.xiaomi.models)) { if (!providerModels) continue;
const m = model as ModelsDevModel;
if (m.tool_call !== true) continue;
if (provider.startsWith("xiaomi-token-plan-") && modelId === "mimo-v2-flash") continue;
models.push({ for (const [modelId, model] of Object.entries(providerModels)) {
id: modelId, const m = model as ModelsDevModel;
name: m.name || modelId, if (m.tool_call !== true) continue;
api: "openai-completions",
provider, models.push({
baseUrl, id: modelId,
compat: xiaomiCompat, name: m.name || modelId,
reasoning: m.reasoning === true, api: "openai-completions",
input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"], provider,
cost: { baseUrl,
input: m.cost?.input || 0, compat: xiaomiCompat,
output: m.cost?.output || 0, reasoning: m.reasoning === true,
cacheRead: m.cost?.cache_read || 0, input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"],
cacheWrite: m.cost?.cache_write || 0, cost: {
}, input: m.cost?.input || 0,
contextWindow: m.limit?.context || 4096, output: m.cost?.output || 0,
maxTokens: m.limit?.output || 4096, cacheRead: m.cost?.cache_read || 0,
}); cacheWrite: m.cost?.cache_write || 0,
} },
contextWindow: m.limit?.context || 4096,
maxTokens: m.limit?.output || 4096,
});
} }
} }
@@ -749,6 +749,23 @@ export const AMAZON_BEDROCK_MODELS = {
contextWindow: 128000, contextWindow: 128000,
maxTokens: 4096, maxTokens: 4096,
} satisfies Model<"bedrock-converse-stream">, } satisfies Model<"bedrock-converse-stream">,
"jp.anthropic.claude-haiku-4-5-20251001-v1:0": {
id: "jp.anthropic.claude-haiku-4-5-20251001-v1:0",
name: "Claude Haiku 4.5 (JP)",
api: "bedrock-converse-stream",
provider: "amazon-bedrock",
baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
reasoning: true,
input: ["text", "image"],
cost: {
input: 1,
output: 5,
cacheRead: 0.1,
cacheWrite: 1.25,
},
contextWindow: 200000,
maxTokens: 64000,
} satisfies Model<"bedrock-converse-stream">,
"jp.anthropic.claude-opus-4-7": { "jp.anthropic.claude-opus-4-7": {
id: "jp.anthropic.claude-opus-4-7", id: "jp.anthropic.claude-opus-4-7",
name: "Claude Opus 4.7 (JP)", name: "Claude Opus 4.7 (JP)",
+3 -173
View File
@@ -4,108 +4,6 @@
import type { Model } from "../types.ts"; import type { Model } from "../types.ts";
export const ANTHROPIC_MODELS = { export const ANTHROPIC_MODELS = {
"claude-3-5-sonnet-20240620": {
id: "claude-3-5-sonnet-20240620",
name: "Claude Sonnet 3.5",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 3,
output: 15,
cacheRead: 0.3,
cacheWrite: 3.75,
},
contextWindow: 200000,
maxTokens: 8192,
} satisfies Model<"anthropic-messages">,
"claude-3-5-sonnet-20241022": {
id: "claude-3-5-sonnet-20241022",
name: "Claude Sonnet 3.5 v2",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 3,
output: 15,
cacheRead: 0.3,
cacheWrite: 3.75,
},
contextWindow: 200000,
maxTokens: 8192,
} satisfies Model<"anthropic-messages">,
"claude-3-7-sonnet-20250219": {
id: "claude-3-7-sonnet-20250219",
name: "Claude Sonnet 3.7",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: true,
input: ["text", "image"],
cost: {
input: 3,
output: 15,
cacheRead: 0.3,
cacheWrite: 3.75,
},
contextWindow: 200000,
maxTokens: 64000,
} satisfies Model<"anthropic-messages">,
"claude-3-haiku-20240307": {
id: "claude-3-haiku-20240307",
name: "Claude Haiku 3",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0.25,
output: 1.25,
cacheRead: 0.03,
cacheWrite: 0.3,
},
contextWindow: 200000,
maxTokens: 4096,
} satisfies Model<"anthropic-messages">,
"claude-3-opus-20240229": {
id: "claude-3-opus-20240229",
name: "Claude Opus 3",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 15,
output: 75,
cacheRead: 1.5,
cacheWrite: 18.75,
},
contextWindow: 200000,
maxTokens: 4096,
} satisfies Model<"anthropic-messages">,
"claude-3-sonnet-20240229": {
id: "claude-3-sonnet-20240229",
name: "Claude Sonnet 3",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: false,
input: ["text", "image"],
cost: {
input: 3,
output: 15,
cacheRead: 0.3,
cacheWrite: 0.3,
},
contextWindow: 200000,
maxTokens: 4096,
} satisfies Model<"anthropic-messages">,
"claude-fable-5": { "claude-fable-5": {
id: "claude-fable-5", id: "claude-fable-5",
name: "Claude Fable 5", name: "Claude Fable 5",
@@ -159,23 +57,6 @@ export const ANTHROPIC_MODELS = {
contextWindow: 200000, contextWindow: 200000,
maxTokens: 64000, maxTokens: 64000,
} satisfies Model<"anthropic-messages">, } satisfies Model<"anthropic-messages">,
"claude-opus-4-0": {
id: "claude-opus-4-0",
name: "Claude Opus 4 (latest)",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: true,
input: ["text", "image"],
cost: {
input: 15,
output: 75,
cacheRead: 1.5,
cacheWrite: 18.75,
},
contextWindow: 200000,
maxTokens: 32000,
} satisfies Model<"anthropic-messages">,
"claude-opus-4-1": { "claude-opus-4-1": {
id: "claude-opus-4-1", id: "claude-opus-4-1",
name: "Claude Opus 4.1 (latest)", name: "Claude Opus 4.1 (latest)",
@@ -210,23 +91,6 @@ export const ANTHROPIC_MODELS = {
contextWindow: 200000, contextWindow: 200000,
maxTokens: 32000, maxTokens: 32000,
} satisfies Model<"anthropic-messages">, } satisfies Model<"anthropic-messages">,
"claude-opus-4-20250514": {
id: "claude-opus-4-20250514",
name: "Claude Opus 4",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: true,
input: ["text", "image"],
cost: {
input: 15,
output: 75,
cacheRead: 1.5,
cacheWrite: 18.75,
},
contextWindow: 200000,
maxTokens: 32000,
} satisfies Model<"anthropic-messages">,
"claude-opus-4-5": { "claude-opus-4-5": {
id: "claude-opus-4-5", id: "claude-opus-4-5",
name: "Claude Opus 4.5 (latest)", name: "Claude Opus 4.5 (latest)",
@@ -318,40 +182,6 @@ export const ANTHROPIC_MODELS = {
contextWindow: 1000000, contextWindow: 1000000,
maxTokens: 128000, maxTokens: 128000,
} satisfies Model<"anthropic-messages">, } satisfies Model<"anthropic-messages">,
"claude-sonnet-4-0": {
id: "claude-sonnet-4-0",
name: "Claude Sonnet 4 (latest)",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: true,
input: ["text", "image"],
cost: {
input: 3,
output: 15,
cacheRead: 0.3,
cacheWrite: 3.75,
},
contextWindow: 200000,
maxTokens: 64000,
} satisfies Model<"anthropic-messages">,
"claude-sonnet-4-20250514": {
id: "claude-sonnet-4-20250514",
name: "Claude Sonnet 4",
api: "anthropic-messages",
provider: "anthropic",
baseUrl: "https://api.anthropic.com",
reasoning: true,
input: ["text", "image"],
cost: {
input: 3,
output: 15,
cacheRead: 0.3,
cacheWrite: 3.75,
},
contextWindow: 200000,
maxTokens: 64000,
} satisfies Model<"anthropic-messages">,
"claude-sonnet-4-5": { "claude-sonnet-4-5": {
id: "claude-sonnet-4-5", id: "claude-sonnet-4-5",
name: "Claude Sonnet 4.5 (latest)", name: "Claude Sonnet 4.5 (latest)",
@@ -366,7 +196,7 @@ export const ANTHROPIC_MODELS = {
cacheRead: 0.3, cacheRead: 0.3,
cacheWrite: 3.75, cacheWrite: 3.75,
}, },
contextWindow: 200000, contextWindow: 1000000,
maxTokens: 64000, maxTokens: 64000,
} satisfies Model<"anthropic-messages">, } satisfies Model<"anthropic-messages">,
"claude-sonnet-4-5-20250929": { "claude-sonnet-4-5-20250929": {
@@ -383,7 +213,7 @@ export const ANTHROPIC_MODELS = {
cacheRead: 0.3, cacheRead: 0.3,
cacheWrite: 3.75, cacheWrite: 3.75,
}, },
contextWindow: 200000, contextWindow: 1000000,
maxTokens: 64000, maxTokens: 64000,
} satisfies Model<"anthropic-messages">, } satisfies Model<"anthropic-messages">,
"claude-sonnet-4-6": { "claude-sonnet-4-6": {
@@ -402,7 +232,7 @@ export const ANTHROPIC_MODELS = {
cacheWrite: 3.75, cacheWrite: 3.75,
}, },
contextWindow: 1000000, contextWindow: 1000000,
maxTokens: 64000, maxTokens: 128000,
} satisfies Model<"anthropic-messages">, } satisfies Model<"anthropic-messages">,
"claude-sonnet-5": { "claude-sonnet-5": {
id: "claude-sonnet-5", id: "claude-sonnet-5",
@@ -71,7 +71,7 @@ export const FIREWORKS_MODELS = {
cost: { cost: {
input: 1.4, input: 1.4,
output: 4.4, output: 4.4,
cacheRead: 0.26, cacheRead: 0.14,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048575, contextWindow: 1048575,
@@ -670,6 +670,24 @@ export const HUGGINGFACE_MODELS = {
contextWindow: 131072, contextWindow: 131072,
maxTokens: 32768, maxTokens: 32768,
} satisfies Model<"openai-completions">, } satisfies Model<"openai-completions">,
"openai/gpt-oss-20b": {
id: "openai/gpt-oss-20b",
name: "GPT OSS 20B",
api: "openai-completions",
provider: "huggingface",
baseUrl: "https://router.huggingface.co/v1",
compat: {"supportsDeveloperRole":false},
reasoning: true,
input: ["text"],
cost: {
input: 0.1,
output: 0.5,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 32768,
} satisfies Model<"openai-completions">,
"stepfun-ai/Step-3.5-Flash": { "stepfun-ai/Step-3.5-Flash": {
id: "stepfun-ai/Step-3.5-Flash", id: "stepfun-ai/Step-3.5-Flash",
name: "Step 3.5 Flash", name: "Step 3.5 Flash",
+4 -4
View File
@@ -333,12 +333,12 @@ export const MISTRAL_MODELS = {
api: "mistral-conversations", api: "mistral-conversations",
provider: "mistral", provider: "mistral",
baseUrl: "https://api.mistral.ai", baseUrl: "https://api.mistral.ai",
reasoning: false, reasoning: true,
input: ["text", "image"], input: ["text", "image"],
cost: { cost: {
input: 0.4, input: 1.5,
output: 2, output: 7.5,
cacheRead: 0.04, cacheRead: 0.15,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 262144, contextWindow: 262144,
@@ -691,6 +691,24 @@ export const OPENCODE_MODELS = {
contextWindow: 256000, contextWindow: 256000,
maxTokens: 256000, maxTokens: 256000,
} satisfies Model<"openai-completions">, } satisfies Model<"openai-completions">,
"hy3-free": {
id: "hy3-free",
name: "Hy3 Free",
api: "openai-completions",
provider: "opencode",
baseUrl: "https://opencode.ai/zen/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"maxTokensField":"max_tokens"},
reasoning: true,
input: ["text"],
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 256000,
maxTokens: 64000,
} satisfies Model<"openai-completions">,
"kimi-k2.5": { "kimi-k2.5": {
id: "kimi-k2.5", id: "kimi-k2.5",
name: "Kimi K2.5", name: "Kimi K2.5",
+133 -7
View File
@@ -22,6 +22,60 @@ export const OPENROUTER_MODELS = {
contextWindow: 256000, contextWindow: 256000,
maxTokens: 4096, maxTokens: 4096,
} satisfies Model<"openai-completions">, } satisfies Model<"openai-completions">,
"aion-labs/aion-2.0": {
id: "aion-labs/aion-2.0",
name: "AionLabs: Aion-2.0",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter"},
reasoning: true,
input: ["text"],
cost: {
input: 0.8,
output: 1.6,
cacheRead: 0.2,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 32768,
} satisfies Model<"openai-completions">,
"aion-labs/aion-3.0": {
id: "aion-labs/aion-3.0",
name: "AionLabs: Aion-3.0",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter"},
reasoning: true,
input: ["text"],
cost: {
input: 3,
output: 6,
cacheRead: 0.75,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 32768,
} satisfies Model<"openai-completions">,
"aion-labs/aion-3.0-mini": {
id: "aion-labs/aion-3.0-mini",
name: "AionLabs: Aion-3.0-Mini",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter"},
reasoning: true,
input: ["text"],
cost: {
input: 0.7,
output: 1.4,
cacheRead: 0.18,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 32768,
} satisfies Model<"openai-completions">,
"amazon/nova-2-lite-v1": { "amazon/nova-2-lite-v1": {
id: "amazon/nova-2-lite-v1", id: "amazon/nova-2-lite-v1",
name: "Amazon: Nova 2 Lite", name: "Amazon: Nova 2 Lite",
@@ -746,7 +800,7 @@ export const OPENROUTER_MODELS = {
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
maxTokens: 16384, maxTokens: 65536,
} satisfies Model<"openai-completions">, } satisfies Model<"openai-completions">,
"deepseek/deepseek-v4-pro": { "deepseek/deepseek-v4-pro": {
id: "deepseek/deepseek-v4-pro", id: "deepseek/deepseek-v4-pro",
@@ -1866,6 +1920,42 @@ export const OPENROUTER_MODELS = {
contextWindow: 262144, contextWindow: 262144,
maxTokens: 16384, maxTokens: 16384,
} satisfies Model<"openai-completions">, } satisfies Model<"openai-completions">,
"nex-agi/nex-n2-mini": {
id: "nex-agi/nex-n2-mini",
name: "Nex AGI: Nex-N2-Mini",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter"},
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.025,
output: 0.1,
cacheRead: 0.0025,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 262144,
} satisfies Model<"openai-completions">,
"nex-agi/nex-n2-pro": {
id: "nex-agi/nex-n2-pro",
name: "Nex AGI: Nex-N2-Pro",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter"},
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.25,
output: 1,
cacheRead: 0.025,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 262144,
} satisfies Model<"openai-completions">,
"nvidia/llama-3.3-nemotron-super-49b-v1.5": { "nvidia/llama-3.3-nemotron-super-49b-v1.5": {
id: "nvidia/llama-3.3-nemotron-super-49b-v1.5", id: "nvidia/llama-3.3-nemotron-super-49b-v1.5",
name: "NVIDIA: Llama 3.3 Nemotron Super 49B V1.5", name: "NVIDIA: Llama 3.3 Nemotron Super 49B V1.5",
@@ -3834,7 +3924,7 @@ export const OPENROUTER_MODELS = {
cost: { cost: {
input: 0.385, input: 0.385,
output: 2.45, output: 2.45,
cacheRead: 0, cacheRead: 0.111,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 256000, contextWindow: 256000,
@@ -4146,6 +4236,24 @@ export const OPENROUTER_MODELS = {
contextWindow: 256000, contextWindow: 256000,
maxTokens: 256000, maxTokens: 256000,
} satisfies Model<"openai-completions">, } satisfies Model<"openai-completions">,
"tencent/hy3": {
id: "tencent/hy3",
name: "Tencent: Hy3",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter"},
reasoning: true,
input: ["text"],
cost: {
input: 0.2,
output: 0.8,
cacheRead: 0.5,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"tencent/hy3-preview": { "tencent/hy3-preview": {
id: "tencent/hy3-preview", id: "tencent/hy3-preview",
name: "Tencent: Hy3 preview", name: "Tencent: Hy3 preview",
@@ -4164,6 +4272,24 @@ export const OPENROUTER_MODELS = {
contextWindow: 262144, contextWindow: 262144,
maxTokens: 4096, maxTokens: 4096,
} satisfies Model<"openai-completions">, } satisfies Model<"openai-completions">,
"tencent/hy3:free": {
id: "tencent/hy3:free",
name: "Tencent: Hy3 (free)",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
compat: {"supportsDeveloperRole":false,"thinkingFormat":"openrouter"},
reasoning: true,
input: ["text"],
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 262144,
} satisfies Model<"openai-completions">,
"thedrummer/unslopnemo-12b": { "thedrummer/unslopnemo-12b": {
id: "thedrummer/unslopnemo-12b", id: "thedrummer/unslopnemo-12b",
name: "TheDrummer: UnslopNemo 12B", name: "TheDrummer: UnslopNemo 12B",
@@ -4266,7 +4392,7 @@ export const OPENROUTER_MODELS = {
cost: { cost: {
input: 0.105, input: 0.105,
output: 0.28, output: 0.28,
cacheRead: 0, cacheRead: 0.028,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -4481,13 +4607,13 @@ export const OPENROUTER_MODELS = {
thinkingLevelMap: {"xhigh":"xhigh"}, thinkingLevelMap: {"xhigh":"xhigh"},
input: ["text"], input: ["text"],
cost: { cost: {
input: 0.91, input: 0.93,
output: 2.86, output: 3,
cacheRead: 0.169, cacheRead: 0.18,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
maxTokens: 128000, maxTokens: 32768,
} satisfies Model<"openai-completions">, } satisfies Model<"openai-completions">,
"z-ai/glm-5v-turbo": { "z-ai/glm-5v-turbo": {
id: "z-ai/glm-5v-turbo", id: "z-ai/glm-5v-turbo",
@@ -4,24 +4,6 @@
import type { Model } from "../types.ts"; import type { Model } from "../types.ts";
export const XIAOMI_TOKEN_PLAN_AMS_MODELS = { export const XIAOMI_TOKEN_PLAN_AMS_MODELS = {
"mimo-v2-omni": {
id: "mimo-v2-omni",
name: "MiMo-V2-Omni",
api: "openai-completions",
provider: "xiaomi-token-plan-ams",
baseUrl: "https://token-plan-ams.xiaomimimo.com/v1",
compat: {"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.14,
output: 0.28,
cacheRead: 0.0028,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"mimo-v2-pro": { "mimo-v2-pro": {
id: "mimo-v2-pro", id: "mimo-v2-pro",
name: "MiMo-V2-Pro", name: "MiMo-V2-Pro",
@@ -32,9 +14,9 @@ export const XIAOMI_TOKEN_PLAN_AMS_MODELS = {
reasoning: true, reasoning: true,
input: ["text"], input: ["text"],
cost: { cost: {
input: 0.435, input: 0,
output: 0.87, output: 0,
cacheRead: 0.0036, cacheRead: 0,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -50,9 +32,9 @@ export const XIAOMI_TOKEN_PLAN_AMS_MODELS = {
reasoning: true, reasoning: true,
input: ["text", "image"], input: ["text", "image"],
cost: { cost: {
input: 0.14, input: 0,
output: 0.28, output: 0,
cacheRead: 0.0028, cacheRead: 0,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -68,27 +50,9 @@ export const XIAOMI_TOKEN_PLAN_AMS_MODELS = {
reasoning: true, reasoning: true,
input: ["text"], input: ["text"],
cost: { cost: {
input: 0.435, input: 0,
output: 0.87, output: 0,
cacheRead: 0.0036, cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"mimo-v2.5-pro-ultraspeed": {
id: "mimo-v2.5-pro-ultraspeed",
name: "MiMo-V2.5-Pro-UltraSpeed",
api: "openai-completions",
provider: "xiaomi-token-plan-ams",
baseUrl: "https://token-plan-ams.xiaomimimo.com/v1",
compat: {"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
input: ["text"],
cost: {
input: 1.305,
output: 2.61,
cacheRead: 0.0108,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -4,24 +4,6 @@
import type { Model } from "../types.ts"; import type { Model } from "../types.ts";
export const XIAOMI_TOKEN_PLAN_CN_MODELS = { export const XIAOMI_TOKEN_PLAN_CN_MODELS = {
"mimo-v2-omni": {
id: "mimo-v2-omni",
name: "MiMo-V2-Omni",
api: "openai-completions",
provider: "xiaomi-token-plan-cn",
baseUrl: "https://token-plan-cn.xiaomimimo.com/v1",
compat: {"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.14,
output: 0.28,
cacheRead: 0.0028,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"mimo-v2-pro": { "mimo-v2-pro": {
id: "mimo-v2-pro", id: "mimo-v2-pro",
name: "MiMo-V2-Pro", name: "MiMo-V2-Pro",
@@ -32,9 +14,9 @@ export const XIAOMI_TOKEN_PLAN_CN_MODELS = {
reasoning: true, reasoning: true,
input: ["text"], input: ["text"],
cost: { cost: {
input: 0.435, input: 0,
output: 0.87, output: 0,
cacheRead: 0.0036, cacheRead: 0,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -50,9 +32,9 @@ export const XIAOMI_TOKEN_PLAN_CN_MODELS = {
reasoning: true, reasoning: true,
input: ["text", "image"], input: ["text", "image"],
cost: { cost: {
input: 0.14, input: 0,
output: 0.28, output: 0,
cacheRead: 0.0028, cacheRead: 0,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -68,27 +50,9 @@ export const XIAOMI_TOKEN_PLAN_CN_MODELS = {
reasoning: true, reasoning: true,
input: ["text"], input: ["text"],
cost: { cost: {
input: 0.435, input: 0,
output: 0.87, output: 0,
cacheRead: 0.0036, cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"mimo-v2.5-pro-ultraspeed": {
id: "mimo-v2.5-pro-ultraspeed",
name: "MiMo-V2.5-Pro-UltraSpeed",
api: "openai-completions",
provider: "xiaomi-token-plan-cn",
baseUrl: "https://token-plan-cn.xiaomimimo.com/v1",
compat: {"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
input: ["text"],
cost: {
input: 1.305,
output: 2.61,
cacheRead: 0.0108,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -4,24 +4,6 @@
import type { Model } from "../types.ts"; import type { Model } from "../types.ts";
export const XIAOMI_TOKEN_PLAN_SGP_MODELS = { export const XIAOMI_TOKEN_PLAN_SGP_MODELS = {
"mimo-v2-omni": {
id: "mimo-v2-omni",
name: "MiMo-V2-Omni",
api: "openai-completions",
provider: "xiaomi-token-plan-sgp",
baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1",
compat: {"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.14,
output: 0.28,
cacheRead: 0.0028,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"mimo-v2-pro": { "mimo-v2-pro": {
id: "mimo-v2-pro", id: "mimo-v2-pro",
name: "MiMo-V2-Pro", name: "MiMo-V2-Pro",
@@ -32,9 +14,9 @@ export const XIAOMI_TOKEN_PLAN_SGP_MODELS = {
reasoning: true, reasoning: true,
input: ["text"], input: ["text"],
cost: { cost: {
input: 0.435, input: 0,
output: 0.87, output: 0,
cacheRead: 0.0036, cacheRead: 0,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -50,9 +32,9 @@ export const XIAOMI_TOKEN_PLAN_SGP_MODELS = {
reasoning: true, reasoning: true,
input: ["text", "image"], input: ["text", "image"],
cost: { cost: {
input: 0.14, input: 0,
output: 0.28, output: 0,
cacheRead: 0.0028, cacheRead: 0,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
@@ -68,27 +50,9 @@ export const XIAOMI_TOKEN_PLAN_SGP_MODELS = {
reasoning: true, reasoning: true,
input: ["text"], input: ["text"],
cost: { cost: {
input: 0.435, input: 0,
output: 0.87, output: 0,
cacheRead: 0.0036, cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 1048576,
maxTokens: 131072,
} satisfies Model<"openai-completions">,
"mimo-v2.5-pro-ultraspeed": {
id: "mimo-v2.5-pro-ultraspeed",
name: "MiMo-V2.5-Pro-UltraSpeed",
api: "openai-completions",
provider: "xiaomi-token-plan-sgp",
baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1",
compat: {"requiresReasoningContentOnAssistantMessages":true,"thinkingFormat":"deepseek"},
reasoning: true,
input: ["text"],
cost: {
input: 1.305,
output: 2.61,
cacheRead: 0.0108,
cacheWrite: 0, cacheWrite: 0,
}, },
contextWindow: 1048576, contextWindow: 1048576,
+6 -4
View File
@@ -2,14 +2,16 @@ import { describe, expect, it } from "vitest";
import { getModel, getModels } from "../src/compat.ts"; import { getModel, getModels } from "../src/compat.ts";
describe("Xiaomi MiMo models", () => { describe("Xiaomi MiMo models", () => {
it("keeps mimo-v2-flash on the API billing provider", () => { it.each(["mimo-v2-flash", "mimo-v2-omni"] as const)("keeps %s on the API billing provider", (modelId) => {
expect(getModel("xiaomi", "mimo-v2-flash")).toBeDefined(); expect(getModel("xiaomi", modelId)).toBeDefined();
}); });
it.each(["xiaomi-token-plan-cn", "xiaomi-token-plan-ams", "xiaomi-token-plan-sgp"] as const)( it.each(["xiaomi-token-plan-cn", "xiaomi-token-plan-ams", "xiaomi-token-plan-sgp"] as const)(
"omits mimo-v2-flash from %s", "omits API-billing-only models from %s",
(provider) => { (provider) => {
expect(getModels(provider).some((model) => model.id === "mimo-v2-flash")).toBe(false); const modelIds = getModels(provider).map((model) => model.id);
expect(modelIds).not.toContain("mimo-v2-flash");
expect(modelIds).not.toContain("mimo-v2-omni");
}, },
); );
}); });
+1
View File
@@ -9,6 +9,7 @@
### Fixed ### Fixed
- Fixed Xiaomi Token Plan model metadata to follow the upstream models.dev token-plan catalogs, removing unsupported `mimo-v2-omni` variants ([#6204](https://github.com/earendil-works/pi/issues/6204)).
- Fixed startup model selection to skip unauthenticated saved defaults so configured local custom models can be selected instead ([#6231](https://github.com/earendil-works/pi/issues/6231)). - Fixed startup model selection to skip unauthenticated saved defaults so configured local custom models can be selected instead ([#6231](https://github.com/earendil-works/pi/issues/6231)).
- Fixed the question extension example to run question tool calls sequentially so multiple questions in one assistant turn remain answerable ([#6189](https://github.com/earendil-works/pi/issues/6189)). - Fixed the question extension example to run question tool calls sequentially so multiple questions in one assistant turn remain answerable ([#6189](https://github.com/earendil-works/pi/issues/6189)).
- Fixed `/login` to report auth storage persistence failures instead of claiming credentials were saved when `auth.json` is locked ([#6223](https://github.com/earendil-works/pi/issues/6223)). - Fixed `/login` to report auth storage persistence failures instead of claiming credentials were saved when `auth.json` is locked ([#6223](https://github.com/earendil-works/pi/issues/6223)).