diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 2b10ce11b..d5d5617d0 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -105,6 +105,10 @@ - Removed the dead `iterateUntilAbort` helper (superseded by `iterateWithIdleTimeout`); it leaked the upstream iterator when the consumer abandoned mid-yield and had no production call sites. +### Changed + +- Updated MiniMax and MiniMax Token Plan defaults to `MiniMax-M3` and refreshed Token Plan login copy/links ([#1725](https://github.com/can1357/oh-my-pi/issues/1725)). + ## [15.10.9] - 2026-06-09 ### Added diff --git a/packages/ai/src/registry/minimax-code-cn.ts b/packages/ai/src/registry/minimax-code-cn.ts index 05c0c786d..4f5bef489 100644 --- a/packages/ai/src/registry/minimax-code-cn.ts +++ b/packages/ai/src/registry/minimax-code-cn.ts @@ -3,7 +3,7 @@ import type { ProviderDefinition } from "./types"; export const minimaxCodeCnProvider = { id: "minimax-code-cn", - name: "MiniMax Coding Plan (China)", + name: "MiniMax Token Plan (China)", login: async (cb: OAuthLoginCallbacks) => { // Lazy import: keep heavy OAuth flow modules out of the eager registry graph. const { loginMiniMaxCodeCn } = await import("./oauth/minimax-code"); diff --git a/packages/ai/src/registry/minimax-code.ts b/packages/ai/src/registry/minimax-code.ts index ead92a77d..9a2b77d21 100644 --- a/packages/ai/src/registry/minimax-code.ts +++ b/packages/ai/src/registry/minimax-code.ts @@ -3,7 +3,7 @@ import type { ProviderDefinition } from "./types"; export const minimaxCodeProvider = { id: "minimax-code", - name: "MiniMax Coding Plan (International)", + name: "MiniMax Token Plan (International)", login: async (cb: OAuthLoginCallbacks) => { // Lazy import: keep heavy OAuth flow modules out of the eager registry graph. const { loginMiniMaxCode } = await import("./oauth/minimax-code"); diff --git a/packages/ai/src/registry/minimax.ts b/packages/ai/src/registry/minimax.ts index 0215a6b8e..ce10b25e7 100644 --- a/packages/ai/src/registry/minimax.ts +++ b/packages/ai/src/registry/minimax.ts @@ -3,4 +3,5 @@ import type { ProviderDefinition } from "./types"; export const minimaxProvider = { id: "minimax", name: "MiniMax", + } as const satisfies ProviderDefinition; diff --git a/packages/ai/src/registry/oauth/minimax-code.ts b/packages/ai/src/registry/oauth/minimax-code.ts index 0101712ce..c130dddd6 100644 --- a/packages/ai/src/registry/oauth/minimax-code.ts +++ b/packages/ai/src/registry/oauth/minimax-code.ts @@ -1,8 +1,8 @@ /** - * MiniMax Coding Plan login flow. + * MiniMax Token Plan login flow. * - * MiniMax Coding Plan is a subscription service that provides access to - * MiniMax models (M2, M2.1) through an OpenAI-compatible API. + * MiniMax Token Plan is a subscription service that provides access to + * MiniMax models (M2 and newer) through an OpenAI-compatible API. * * This is not OAuth - it's a simple API key flow: * 1. Open browser to the matching regional MiniMax subscription page @@ -16,20 +16,20 @@ import { validateOpenAICompatibleApiKey } from "../api-key-validation"; import type { OAuthController } from "./types"; -const AUTH_URL_INTL = "https://platform.minimax.io/subscribe/coding-plan"; -const AUTH_URL_CN = "https://platform.minimaxi.com/subscribe/coding-plan"; +const AUTH_URL_INTL = "https://platform.minimax.io/subscribe/token-plan"; +const AUTH_URL_CN = "https://platform.minimaxi.com/subscribe/token-plan"; const API_BASE_URL_INTL = "https://api.minimax.io/v1"; const API_BASE_URL_CN = "https://api.minimaxi.com/v1"; -const VALIDATION_MODEL = "MiniMax-M2"; +const VALIDATION_MODEL = "MiniMax-M3"; /** - * Login to MiniMax Coding Plan (international). + * Login to MiniMax Token Plan (international). * * Opens browser to subscription page, prompts user to paste their API key. * Returns the API key directly (not OAuthCredentials - this isn't OAuth). */ export async function loginMiniMaxCode(options: OAuthController): Promise { - return loginMiniMaxCodeWithBaseUrl(options, AUTH_URL_INTL, API_BASE_URL_INTL, "MiniMax Coding Plan"); + return loginMiniMaxCodeWithBaseUrl(options, AUTH_URL_INTL, API_BASE_URL_INTL, "MiniMax Token Plan"); } async function loginMiniMaxCodeWithBaseUrl( @@ -40,16 +40,16 @@ async function loginMiniMaxCodeWithBaseUrl( ): Promise { const fetchImpl = options.fetch ?? fetch; if (!options.onPrompt) { - throw new Error("MiniMax Coding Plan login requires onPrompt callback"); + throw new Error("MiniMax Token Plan login requires onPrompt callback"); } // Open browser to subscription page options.onAuth?.({ url: authUrl, - instructions: "Subscribe to Coding Plan and copy your API key", + instructions: "Subscribe to Token Plan and copy your API key", }); // Prompt user to paste their API key const apiKey = await options.onPrompt({ - message: "Paste your MiniMax Coding Plan API key", + message: "Paste your MiniMax Token Plan API key", placeholder: "sk-...", }); if (options.signal?.aborted) { @@ -73,10 +73,10 @@ async function loginMiniMaxCodeWithBaseUrl( } /** - * Login to MiniMax Coding Plan (China). + * Login to MiniMax Token Plan (China). * * Same flow as international but uses China endpoint. */ export async function loginMiniMaxCodeCn(options: OAuthController): Promise { - return loginMiniMaxCodeWithBaseUrl(options, AUTH_URL_CN, API_BASE_URL_CN, "MiniMax Coding Plan (China)"); + return loginMiniMaxCodeWithBaseUrl(options, AUTH_URL_CN, API_BASE_URL_CN, "MiniMax Token Plan (China)"); } diff --git a/packages/ai/src/usage/minimax-code.ts b/packages/ai/src/usage/minimax-code.ts index 501c1daaa..dfec0f07a 100644 --- a/packages/ai/src/usage/minimax-code.ts +++ b/packages/ai/src/usage/minimax-code.ts @@ -1,13 +1,12 @@ import type { UsageFetchContext, UsageFetchParams, UsageProvider, UsageReport } from "../usage"; /** - * MiniMax Coding Plan usage provider. + * MiniMax Token Plan usage provider. * - * MiniMax Coding Plan is a subscription-based service with a 5-hour rolling window - * quota system. The quota resets automatically based on a rolling window. + * MiniMax Token Plan is a subscription-based service with a rolling quota system. * - * Currently, MiniMax does not expose a usage/quota API endpoint for the Coding Plan. - * Usage is tracked via the web dashboard at https://platform.minimax.io/user-center/payment/coding-plan + * Currently, MiniMax does not expose a usage/quota API endpoint for the Token Plan. + * Usage is tracked via the web dashboard at https://platform.minimax.io/subscribe/token-plan * * This provider exists to register support for the minimax-code provider in the * usage system. When MiniMax adds a usage API, this can be implemented. @@ -17,7 +16,7 @@ async function fetchMiniMaxCodeUsage(params: UsageFetchParams, _ctx: UsageFetchC return null; } - // MiniMax Coding Plan does not currently expose a usage API + // MiniMax Token Plan does not currently expose a usage API // Users can check their usage via the web dashboard return null; } diff --git a/packages/ai/test/minimax-code-login.test.ts b/packages/ai/test/minimax-code-login.test.ts index efcf9b0b0..fa6997580 100644 --- a/packages/ai/test/minimax-code-login.test.ts +++ b/packages/ai/test/minimax-code-login.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "bun:test"; import { loginMiniMaxCode, loginMiniMaxCodeCn } from "@oh-my-pi/pi-ai/registry/oauth/minimax-code"; import type { FetchImpl } from "@oh-my-pi/pi-ai/types"; -describe("MiniMax Coding Plan login", () => { +describe("MiniMax Token Plan login", () => { it("opens the international platform and validates against the international API", async () => { const authUrls: string[] = []; const validationUrls: string[] = []; @@ -19,7 +19,7 @@ describe("MiniMax Coding Plan login", () => { }); expect(apiKey).toBe("sk-intl"); - expect(authUrls).toEqual(["https://platform.minimax.io/subscribe/coding-plan"]); + expect(authUrls).toEqual(["https://platform.minimax.io/subscribe/token-plan"]); expect(validationUrls).toEqual(["https://api.minimax.io/v1/chat/completions"]); }); @@ -39,7 +39,7 @@ describe("MiniMax Coding Plan login", () => { }); expect(apiKey).toBe("sk-cn"); - expect(authUrls).toEqual(["https://platform.minimaxi.com/subscribe/coding-plan"]); + expect(authUrls).toEqual(["https://platform.minimaxi.com/subscribe/token-plan"]); expect(validationUrls).toEqual(["https://api.minimaxi.com/v1/chat/completions"]); }); }); diff --git a/packages/catalog/src/provider-models/descriptors.ts b/packages/catalog/src/provider-models/descriptors.ts index b4d32b462..69c83de83 100644 --- a/packages/catalog/src/provider-models/descriptors.ts +++ b/packages/catalog/src/provider-models/descriptors.ts @@ -191,17 +191,17 @@ export const CATALOG_PROVIDERS = [ }, { id: "minimax", - defaultModel: "MiniMax-M2.5", + defaultModel: "MiniMax-M3", envVars: ["MINIMAX_API_KEY"], }, { id: "minimax-code", - defaultModel: "MiniMax-M2.5", + defaultModel: "MiniMax-M3", envVars: ["MINIMAX_CODE_API_KEY"], }, { id: "minimax-code-cn", - defaultModel: "MiniMax-M2.5", + defaultModel: "MiniMax-M3", envVars: ["MINIMAX_CODE_CN_API_KEY"], }, { diff --git a/packages/catalog/test/descriptors.test.ts b/packages/catalog/test/descriptors.test.ts index 12b9c7636..8ff6632e0 100644 --- a/packages/catalog/test/descriptors.test.ts +++ b/packages/catalog/test/descriptors.test.ts @@ -13,6 +13,9 @@ describe("catalog provider descriptors", () => { // but still a known model provider with a default. expect(PROVIDER_DESCRIPTORS.some(descriptor => descriptor.providerId === "openai-codex")).toBe(false); expect(DEFAULT_MODEL_PER_PROVIDER["openai-codex"]).toBe("gpt-5.4"); + expect(DEFAULT_MODEL_PER_PROVIDER.minimax).toBe("MiniMax-M3"); + expect(DEFAULT_MODEL_PER_PROVIDER["minimax-code"]).toBe("MiniMax-M3"); + expect(DEFAULT_MODEL_PER_PROVIDER["minimax-code-cn"]).toBe("MiniMax-M3"); // Login-only tools have no default model. expect(DEFAULT_MODEL_PER_PROVIDER).not.toHaveProperty("kagi"); });