diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 33314368b..e5eae4d0d 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -4,6 +4,7 @@ ### 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 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. diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index 04b3deb40..f262b7b5c 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -1534,38 +1534,50 @@ async function loadModelsDevData(): Promise[]> { thinkingFormat: "deepseek", }; const xiaomiVariants = [ - { 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" }, - { provider: "xiaomi-token-plan-sgp", baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1" }, + { source: "xiaomi", provider: "xiaomi", baseUrl: "https://api.xiaomimimo.com/v1" }, + { + source: "xiaomi-token-plan-cn", + 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; - if (data.xiaomi?.models) { - for (const { provider, baseUrl } of xiaomiVariants) { - for (const [modelId, model] of Object.entries(data.xiaomi.models)) { - const m = model as ModelsDevModel; - if (m.tool_call !== true) continue; - if (provider.startsWith("xiaomi-token-plan-") && modelId === "mimo-v2-flash") continue; + for (const { source, provider, baseUrl } of xiaomiVariants) { + const providerModels = data[source]?.models; + if (!providerModels) continue; - models.push({ - id: modelId, - name: m.name || modelId, - api: "openai-completions", - provider, - baseUrl, - compat: xiaomiCompat, - reasoning: m.reasoning === true, - input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"], - cost: { - input: m.cost?.input || 0, - output: m.cost?.output || 0, - cacheRead: m.cost?.cache_read || 0, - cacheWrite: m.cost?.cache_write || 0, - }, - contextWindow: m.limit?.context || 4096, - maxTokens: m.limit?.output || 4096, - }); - } + for (const [modelId, model] of Object.entries(providerModels)) { + const m = model as ModelsDevModel; + if (m.tool_call !== true) continue; + + models.push({ + id: modelId, + name: m.name || modelId, + api: "openai-completions", + provider, + baseUrl, + compat: xiaomiCompat, + reasoning: m.reasoning === true, + input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"], + cost: { + input: m.cost?.input || 0, + output: m.cost?.output || 0, + cacheRead: m.cost?.cache_read || 0, + cacheWrite: m.cost?.cache_write || 0, + }, + contextWindow: m.limit?.context || 4096, + maxTokens: m.limit?.output || 4096, + }); } } diff --git a/packages/ai/src/providers/amazon-bedrock.models.ts b/packages/ai/src/providers/amazon-bedrock.models.ts index 6a8ca04a1..e154c08e6 100644 --- a/packages/ai/src/providers/amazon-bedrock.models.ts +++ b/packages/ai/src/providers/amazon-bedrock.models.ts @@ -749,6 +749,23 @@ export const AMAZON_BEDROCK_MODELS = { contextWindow: 128000, maxTokens: 4096, } 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": { id: "jp.anthropic.claude-opus-4-7", name: "Claude Opus 4.7 (JP)", diff --git a/packages/ai/src/providers/anthropic.models.ts b/packages/ai/src/providers/anthropic.models.ts index e4b19d6b5..bebe482d1 100644 --- a/packages/ai/src/providers/anthropic.models.ts +++ b/packages/ai/src/providers/anthropic.models.ts @@ -4,108 +4,6 @@ import type { Model } from "../types.ts"; 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": { id: "claude-fable-5", name: "Claude Fable 5", @@ -159,23 +57,6 @@ export const ANTHROPIC_MODELS = { contextWindow: 200000, maxTokens: 64000, } 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": { id: "claude-opus-4-1", name: "Claude Opus 4.1 (latest)", @@ -210,23 +91,6 @@ export const ANTHROPIC_MODELS = { contextWindow: 200000, maxTokens: 32000, } 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": { id: "claude-opus-4-5", name: "Claude Opus 4.5 (latest)", @@ -318,40 +182,6 @@ export const ANTHROPIC_MODELS = { contextWindow: 1000000, maxTokens: 128000, } 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": { id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5 (latest)", @@ -366,7 +196,7 @@ export const ANTHROPIC_MODELS = { cacheRead: 0.3, cacheWrite: 3.75, }, - contextWindow: 200000, + contextWindow: 1000000, maxTokens: 64000, } satisfies Model<"anthropic-messages">, "claude-sonnet-4-5-20250929": { @@ -383,7 +213,7 @@ export const ANTHROPIC_MODELS = { cacheRead: 0.3, cacheWrite: 3.75, }, - contextWindow: 200000, + contextWindow: 1000000, maxTokens: 64000, } satisfies Model<"anthropic-messages">, "claude-sonnet-4-6": { @@ -402,7 +232,7 @@ export const ANTHROPIC_MODELS = { cacheWrite: 3.75, }, contextWindow: 1000000, - maxTokens: 64000, + maxTokens: 128000, } satisfies Model<"anthropic-messages">, "claude-sonnet-5": { id: "claude-sonnet-5", diff --git a/packages/ai/src/providers/fireworks.models.ts b/packages/ai/src/providers/fireworks.models.ts index 93336dab7..fc0ea1ce0 100644 --- a/packages/ai/src/providers/fireworks.models.ts +++ b/packages/ai/src/providers/fireworks.models.ts @@ -71,7 +71,7 @@ export const FIREWORKS_MODELS = { cost: { input: 1.4, output: 4.4, - cacheRead: 0.26, + cacheRead: 0.14, cacheWrite: 0, }, contextWindow: 1048575, diff --git a/packages/ai/src/providers/huggingface.models.ts b/packages/ai/src/providers/huggingface.models.ts index 4c4b66284..f38b38f3e 100644 --- a/packages/ai/src/providers/huggingface.models.ts +++ b/packages/ai/src/providers/huggingface.models.ts @@ -670,6 +670,24 @@ export const HUGGINGFACE_MODELS = { contextWindow: 131072, maxTokens: 32768, } 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": { id: "stepfun-ai/Step-3.5-Flash", name: "Step 3.5 Flash", diff --git a/packages/ai/src/providers/mistral.models.ts b/packages/ai/src/providers/mistral.models.ts index 7060772b8..439517aad 100644 --- a/packages/ai/src/providers/mistral.models.ts +++ b/packages/ai/src/providers/mistral.models.ts @@ -333,12 +333,12 @@ export const MISTRAL_MODELS = { api: "mistral-conversations", provider: "mistral", baseUrl: "https://api.mistral.ai", - reasoning: false, + reasoning: true, input: ["text", "image"], cost: { - input: 0.4, - output: 2, - cacheRead: 0.04, + input: 1.5, + output: 7.5, + cacheRead: 0.15, cacheWrite: 0, }, contextWindow: 262144, diff --git a/packages/ai/src/providers/opencode.models.ts b/packages/ai/src/providers/opencode.models.ts index b4963e55d..48740316d 100644 --- a/packages/ai/src/providers/opencode.models.ts +++ b/packages/ai/src/providers/opencode.models.ts @@ -691,6 +691,24 @@ export const OPENCODE_MODELS = { contextWindow: 256000, maxTokens: 256000, } 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": { id: "kimi-k2.5", name: "Kimi K2.5", diff --git a/packages/ai/src/providers/openrouter.models.ts b/packages/ai/src/providers/openrouter.models.ts index 9fa4a8a8e..d2a377d8a 100644 --- a/packages/ai/src/providers/openrouter.models.ts +++ b/packages/ai/src/providers/openrouter.models.ts @@ -22,6 +22,60 @@ export const OPENROUTER_MODELS = { contextWindow: 256000, maxTokens: 4096, } 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": { id: "amazon/nova-2-lite-v1", name: "Amazon: Nova 2 Lite", @@ -746,7 +800,7 @@ export const OPENROUTER_MODELS = { cacheWrite: 0, }, contextWindow: 1048576, - maxTokens: 16384, + maxTokens: 65536, } satisfies Model<"openai-completions">, "deepseek/deepseek-v4-pro": { id: "deepseek/deepseek-v4-pro", @@ -1866,6 +1920,42 @@ export const OPENROUTER_MODELS = { contextWindow: 262144, maxTokens: 16384, } 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": { id: "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: { input: 0.385, output: 2.45, - cacheRead: 0, + cacheRead: 0.111, cacheWrite: 0, }, contextWindow: 256000, @@ -4146,6 +4236,24 @@ export const OPENROUTER_MODELS = { contextWindow: 256000, maxTokens: 256000, } 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": { id: "tencent/hy3-preview", name: "Tencent: Hy3 preview", @@ -4164,6 +4272,24 @@ export const OPENROUTER_MODELS = { contextWindow: 262144, maxTokens: 4096, } 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": { id: "thedrummer/unslopnemo-12b", name: "TheDrummer: UnslopNemo 12B", @@ -4266,7 +4392,7 @@ export const OPENROUTER_MODELS = { cost: { input: 0.105, output: 0.28, - cacheRead: 0, + cacheRead: 0.028, cacheWrite: 0, }, contextWindow: 1048576, @@ -4481,13 +4607,13 @@ export const OPENROUTER_MODELS = { thinkingLevelMap: {"xhigh":"xhigh"}, input: ["text"], cost: { - input: 0.91, - output: 2.86, - cacheRead: 0.169, + input: 0.93, + output: 3, + cacheRead: 0.18, cacheWrite: 0, }, contextWindow: 1048576, - maxTokens: 128000, + maxTokens: 32768, } satisfies Model<"openai-completions">, "z-ai/glm-5v-turbo": { id: "z-ai/glm-5v-turbo", diff --git a/packages/ai/src/providers/xiaomi-token-plan-ams.models.ts b/packages/ai/src/providers/xiaomi-token-plan-ams.models.ts index fad90ac4a..05f245613 100644 --- a/packages/ai/src/providers/xiaomi-token-plan-ams.models.ts +++ b/packages/ai/src/providers/xiaomi-token-plan-ams.models.ts @@ -4,24 +4,6 @@ import type { Model } from "../types.ts"; 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": { id: "mimo-v2-pro", name: "MiMo-V2-Pro", @@ -32,9 +14,9 @@ export const XIAOMI_TOKEN_PLAN_AMS_MODELS = { reasoning: true, input: ["text"], cost: { - input: 0.435, - output: 0.87, - cacheRead: 0.0036, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, @@ -50,9 +32,9 @@ export const XIAOMI_TOKEN_PLAN_AMS_MODELS = { reasoning: true, input: ["text", "image"], cost: { - input: 0.14, - output: 0.28, - cacheRead: 0.0028, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, @@ -68,27 +50,9 @@ export const XIAOMI_TOKEN_PLAN_AMS_MODELS = { reasoning: true, input: ["text"], cost: { - input: 0.435, - output: 0.87, - cacheRead: 0.0036, - 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, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, diff --git a/packages/ai/src/providers/xiaomi-token-plan-cn.models.ts b/packages/ai/src/providers/xiaomi-token-plan-cn.models.ts index a3a357da9..3a5c6fc38 100644 --- a/packages/ai/src/providers/xiaomi-token-plan-cn.models.ts +++ b/packages/ai/src/providers/xiaomi-token-plan-cn.models.ts @@ -4,24 +4,6 @@ import type { Model } from "../types.ts"; 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": { id: "mimo-v2-pro", name: "MiMo-V2-Pro", @@ -32,9 +14,9 @@ export const XIAOMI_TOKEN_PLAN_CN_MODELS = { reasoning: true, input: ["text"], cost: { - input: 0.435, - output: 0.87, - cacheRead: 0.0036, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, @@ -50,9 +32,9 @@ export const XIAOMI_TOKEN_PLAN_CN_MODELS = { reasoning: true, input: ["text", "image"], cost: { - input: 0.14, - output: 0.28, - cacheRead: 0.0028, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, @@ -68,27 +50,9 @@ export const XIAOMI_TOKEN_PLAN_CN_MODELS = { reasoning: true, input: ["text"], cost: { - input: 0.435, - output: 0.87, - cacheRead: 0.0036, - 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, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, diff --git a/packages/ai/src/providers/xiaomi-token-plan-sgp.models.ts b/packages/ai/src/providers/xiaomi-token-plan-sgp.models.ts index 3f2d378cc..391f4c540 100644 --- a/packages/ai/src/providers/xiaomi-token-plan-sgp.models.ts +++ b/packages/ai/src/providers/xiaomi-token-plan-sgp.models.ts @@ -4,24 +4,6 @@ import type { Model } from "../types.ts"; 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": { id: "mimo-v2-pro", name: "MiMo-V2-Pro", @@ -32,9 +14,9 @@ export const XIAOMI_TOKEN_PLAN_SGP_MODELS = { reasoning: true, input: ["text"], cost: { - input: 0.435, - output: 0.87, - cacheRead: 0.0036, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, @@ -50,9 +32,9 @@ export const XIAOMI_TOKEN_PLAN_SGP_MODELS = { reasoning: true, input: ["text", "image"], cost: { - input: 0.14, - output: 0.28, - cacheRead: 0.0028, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, @@ -68,27 +50,9 @@ export const XIAOMI_TOKEN_PLAN_SGP_MODELS = { reasoning: true, input: ["text"], cost: { - input: 0.435, - output: 0.87, - cacheRead: 0.0036, - 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, + input: 0, + output: 0, + cacheRead: 0, cacheWrite: 0, }, contextWindow: 1048576, diff --git a/packages/ai/test/xiaomi-models.test.ts b/packages/ai/test/xiaomi-models.test.ts index 277b84957..d39cf8718 100644 --- a/packages/ai/test/xiaomi-models.test.ts +++ b/packages/ai/test/xiaomi-models.test.ts @@ -2,14 +2,16 @@ import { describe, expect, it } from "vitest"; import { getModel, getModels } from "../src/compat.ts"; describe("Xiaomi MiMo models", () => { - it("keeps mimo-v2-flash on the API billing provider", () => { - expect(getModel("xiaomi", "mimo-v2-flash")).toBeDefined(); + it.each(["mimo-v2-flash", "mimo-v2-omni"] as const)("keeps %s on the API billing provider", (modelId) => { + expect(getModel("xiaomi", modelId)).toBeDefined(); }); 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) => { - 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"); }, ); }); diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 82c4ec5a3..0752db171 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -9,6 +9,7 @@ ### 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 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)).