From 47a9c1a8934209281f0f10b13c81b5f5cd0d33da Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 16 Mar 2026 02:26:11 +0000 Subject: [PATCH] refactor: merge minimax bundled plugins --- CHANGELOG.md | 1 + docs/providers/minimax.md | 4 +- docs/tools/plugin.md | 5 +- extensions/minimax-portal-auth/README.md | 33 --- extensions/minimax-portal-auth/index.ts | 163 --------------- .../minimax-portal-auth/openclaw.plugin.json | 9 - extensions/minimax-portal-auth/package.json | 12 -- extensions/minimax/README.md | 37 ++++ extensions/minimax/index.ts | 195 ++++++++++++++++-- .../{minimax-portal-auth => minimax}/oauth.ts | 20 +- extensions/minimax/openclaw.plugin.json | 2 +- extensions/minimax/package.json | 2 +- scripts/check-no-raw-channel-fetch.mjs | 4 +- src/commands/auth-choice.apply.minimax.ts | 4 +- src/config/plugin-auto-enable.test.ts | 19 ++ src/config/plugin-auto-enable.ts | 2 +- src/plugin-sdk/minimax-portal-auth.ts | 4 +- src/plugins/config-state.test.ts | 12 +- src/plugins/config-state.ts | 2 +- src/plugins/providers.ts | 1 - 20 files changed, 258 insertions(+), 273 deletions(-) delete mode 100644 extensions/minimax-portal-auth/README.md delete mode 100644 extensions/minimax-portal-auth/index.ts delete mode 100644 extensions/minimax-portal-auth/openclaw.plugin.json delete mode 100644 extensions/minimax-portal-auth/package.json create mode 100644 extensions/minimax/README.md rename extensions/{minimax-portal-auth => minimax}/oauth.ts (90%) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca1d5cf8998..20d0b32ae92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Docs: https://docs.openclaw.ai - Docs/Zalo: clarify the Marketplace-bot support matrix and config guidance so the Zalo channel docs match current Bot Creator behavior more closely. (#47552) Thanks @No898. - Install/update: allow package-manager installs from GitHub `main` via `openclaw update --tag main`, installer `--version main`, or direct npm/pnpm git specs. - Plugins/providers: move OpenRouter, GitHub Copilot, and OpenAI Codex provider/runtime logic into bundled plugins, including dynamic model fallback, runtime auth exchange, stream wrappers, capability hints, and cache-TTL policy. +- Plugins/MiniMax: merge the bundled MiniMax API and MiniMax OAuth plugin surfaces into a single default-on `minimax` plugin, while keeping legacy `minimax-portal-auth` config ids aliased for compatibility. - Plugins/bundles: add compatible Codex, Claude, and Cursor bundle discovery/install support, map bundle skills into OpenClaw skills, and apply Claude bundle `settings.json` defaults to embedded Pi with shell overrides sanitized. - Plugins/agent integrations: broaden the plugin surface for app-server integrations with channel-aware commands, interactive callbacks, inbound claims, and Discord/Telegram conversation binding support. (#45318) Thanks @huntharo and @vincentkoc. diff --git a/docs/providers/minimax.md b/docs/providers/minimax.md index 8cdc5b028f6..0d3635352cc 100644 --- a/docs/providers/minimax.md +++ b/docs/providers/minimax.md @@ -42,7 +42,7 @@ MiniMax highlights these improvements in M2.5: Enable the bundled OAuth plugin and authenticate: ```bash -openclaw plugins enable minimax-portal-auth # skip if already loaded. +openclaw plugins enable minimax # skip if already loaded. openclaw gateway restart # restart if gateway is already running openclaw onboard --auth-choice minimax-portal ``` @@ -52,7 +52,7 @@ You will be prompted to select an endpoint: - **Global** - International users (`api.minimax.io`) - **CN** - Users in China (`api.minimaxi.com`) -See [MiniMax OAuth plugin README](https://github.com/openclaw/openclaw/tree/main/extensions/minimax-portal-auth) for details. +See [MiniMax plugin README](https://github.com/openclaw/openclaw/tree/main/extensions/minimax) for details. ### MiniMax M2.5 (API key) diff --git a/docs/tools/plugin.md b/docs/tools/plugin.md index 2a5b5d37006..91613cbe731 100644 --- a/docs/tools/plugin.md +++ b/docs/tools/plugin.md @@ -172,8 +172,7 @@ Important trust note: - Hugging Face provider catalog — bundled as `huggingface` (enabled by default) - Kilo Gateway provider runtime — bundled as `kilocode` (enabled by default) - Kimi Coding provider catalog — bundled as `kimi-coding` (enabled by default) -- MiniMax provider catalog + usage — bundled as `minimax` (enabled by default) -- MiniMax OAuth (provider auth + catalog) — bundled as `minimax-portal-auth` (enabled by default) +- MiniMax provider catalog + usage + OAuth — bundled as `minimax` (enabled by default; owns `minimax` and `minimax-portal`) - Mistral provider capabilities — bundled as `mistral` (enabled by default) - Model Studio provider catalog — bundled as `modelstudio` (enabled by default) - Moonshot provider runtime — bundled as `moonshot` (enabled by default) @@ -664,7 +663,7 @@ Default-on bundled plugin examples: - `kilocode` - `kimi-coding` - `minimax` -- `minimax-portal-auth` +- `minimax` - `modelstudio` - `moonshot` - `nvidia` diff --git a/extensions/minimax-portal-auth/README.md b/extensions/minimax-portal-auth/README.md deleted file mode 100644 index 3c29ab8ac22..00000000000 --- a/extensions/minimax-portal-auth/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# MiniMax OAuth (OpenClaw plugin) - -OAuth provider plugin for **MiniMax** (OAuth). - -## Enable - -Bundled plugins are disabled by default. Enable this one: - -```bash -openclaw plugins enable minimax-portal-auth -``` - -Restart the Gateway after enabling. - -```bash -openclaw gateway restart -``` - -## Authenticate - -```bash -openclaw models auth login --provider minimax-portal --set-default -``` - -You will be prompted to select an endpoint: - -- **Global** - International users, optimized for overseas access (`api.minimax.io`) -- **China** - Optimized for users in China (`api.minimaxi.com`) - -## Notes - -- MiniMax OAuth uses a user-code login flow. -- Currently, OAuth login is supported only for the Coding plan diff --git a/extensions/minimax-portal-auth/index.ts b/extensions/minimax-portal-auth/index.ts deleted file mode 100644 index eda0b72227c..00000000000 --- a/extensions/minimax-portal-auth/index.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { - buildOauthProviderAuthResult, - emptyPluginConfigSchema, - type OpenClawPluginApi, - type ProviderAuthContext, - type ProviderAuthResult, - type ProviderCatalogContext, -} from "openclaw/plugin-sdk/minimax-portal-auth"; -import { ensureAuthProfileStore, listProfilesForProvider } from "../../src/agents/auth-profiles.js"; -import { MINIMAX_OAUTH_MARKER } from "../../src/agents/model-auth-markers.js"; -import { buildMinimaxPortalProvider } from "../../src/agents/models-config.providers.static.js"; -import { loginMiniMaxPortalOAuth, type MiniMaxRegion } from "./oauth.js"; - -const PROVIDER_ID = "minimax-portal"; -const PROVIDER_LABEL = "MiniMax"; -const DEFAULT_MODEL = "MiniMax-M2.5"; -const DEFAULT_BASE_URL_CN = "https://api.minimaxi.com/anthropic"; -const DEFAULT_BASE_URL_GLOBAL = "https://api.minimax.io/anthropic"; - -function getDefaultBaseUrl(region: MiniMaxRegion): string { - return region === "cn" ? DEFAULT_BASE_URL_CN : DEFAULT_BASE_URL_GLOBAL; -} - -function modelRef(modelId: string): string { - return `${PROVIDER_ID}/${modelId}`; -} - -function buildProviderCatalog(params: { baseUrl: string; apiKey: string }) { - return { - ...buildMinimaxPortalProvider(), - baseUrl: params.baseUrl, - apiKey: params.apiKey, - }; -} - -function resolveCatalog(ctx: ProviderCatalogContext) { - const explicitProvider = ctx.config.models?.providers?.[PROVIDER_ID]; - const envApiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; - const authStore = ensureAuthProfileStore(ctx.agentDir, { - allowKeychainPrompt: false, - }); - const hasProfiles = listProfilesForProvider(authStore, PROVIDER_ID).length > 0; - const explicitApiKey = - typeof explicitProvider?.apiKey === "string" ? explicitProvider.apiKey.trim() : undefined; - const apiKey = envApiKey ?? explicitApiKey ?? (hasProfiles ? MINIMAX_OAUTH_MARKER : undefined); - if (!apiKey) { - return null; - } - - const explicitBaseUrl = - typeof explicitProvider?.baseUrl === "string" ? explicitProvider.baseUrl.trim() : undefined; - - return { - provider: buildProviderCatalog({ - baseUrl: explicitBaseUrl || DEFAULT_BASE_URL_GLOBAL, - apiKey, - }), - }; -} - -function createOAuthHandler(region: MiniMaxRegion) { - const defaultBaseUrl = getDefaultBaseUrl(region); - const regionLabel = region === "cn" ? "CN" : "Global"; - - return async (ctx: ProviderAuthContext): Promise => { - const progress = ctx.prompter.progress(`Starting MiniMax OAuth (${regionLabel})…`); - try { - const result = await loginMiniMaxPortalOAuth({ - openUrl: ctx.openUrl, - note: ctx.prompter.note, - progress, - region, - }); - - progress.stop("MiniMax OAuth complete"); - - if (result.notification_message) { - await ctx.prompter.note(result.notification_message, "MiniMax OAuth"); - } - - const baseUrl = result.resourceUrl || defaultBaseUrl; - - return buildOauthProviderAuthResult({ - providerId: PROVIDER_ID, - defaultModel: modelRef(DEFAULT_MODEL), - access: result.access, - refresh: result.refresh, - expires: result.expires, - configPatch: { - models: { - providers: { - [PROVIDER_ID]: { - baseUrl, - models: [], - }, - }, - }, - agents: { - defaults: { - models: { - [modelRef("MiniMax-M2.5")]: { alias: "minimax-m2.5" }, - [modelRef("MiniMax-M2.5-highspeed")]: { - alias: "minimax-m2.5-highspeed", - }, - [modelRef("MiniMax-M2.5-Lightning")]: { - alias: "minimax-m2.5-lightning", - }, - }, - }, - }, - }, - notes: [ - "MiniMax OAuth tokens auto-refresh. Re-run login if refresh fails or access is revoked.", - `Base URL defaults to ${defaultBaseUrl}. Override models.providers.${PROVIDER_ID}.baseUrl if needed.`, - ...(result.notification_message ? [result.notification_message] : []), - ], - }); - } catch (err) { - const errorMsg = err instanceof Error ? err.message : String(err); - progress.stop(`MiniMax OAuth failed: ${errorMsg}`); - await ctx.prompter.note( - "If OAuth fails, verify your MiniMax account has portal access and try again.", - "MiniMax OAuth", - ); - throw err; - } - }; -} - -const minimaxPortalPlugin = { - id: "minimax-portal-auth", - name: "MiniMax OAuth", - description: "OAuth flow for MiniMax models", - configSchema: emptyPluginConfigSchema(), - register(api: OpenClawPluginApi) { - api.registerProvider({ - id: PROVIDER_ID, - label: PROVIDER_LABEL, - docsPath: "/providers/minimax", - catalog: { - run: async (ctx: ProviderCatalogContext) => resolveCatalog(ctx), - }, - auth: [ - { - id: "oauth", - label: "MiniMax OAuth (Global)", - hint: "Global endpoint - api.minimax.io", - kind: "device_code", - run: createOAuthHandler("global"), - }, - { - id: "oauth-cn", - label: "MiniMax OAuth (CN)", - hint: "CN endpoint - api.minimaxi.com", - kind: "device_code", - run: createOAuthHandler("cn"), - }, - ], - }); - }, -}; - -export default minimaxPortalPlugin; diff --git a/extensions/minimax-portal-auth/openclaw.plugin.json b/extensions/minimax-portal-auth/openclaw.plugin.json deleted file mode 100644 index 4645b6907eb..00000000000 --- a/extensions/minimax-portal-auth/openclaw.plugin.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "minimax-portal-auth", - "providers": ["minimax-portal"], - "configSchema": { - "type": "object", - "additionalProperties": false, - "properties": {} - } -} diff --git a/extensions/minimax-portal-auth/package.json b/extensions/minimax-portal-auth/package.json deleted file mode 100644 index 093d42dad1d..00000000000 --- a/extensions/minimax-portal-auth/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@openclaw/minimax-portal-auth", - "version": "2026.3.14", - "private": true, - "description": "OpenClaw MiniMax Portal OAuth provider plugin", - "type": "module", - "openclaw": { - "extensions": [ - "./index.ts" - ] - } -} diff --git a/extensions/minimax/README.md b/extensions/minimax/README.md new file mode 100644 index 00000000000..e38b7c16c68 --- /dev/null +++ b/extensions/minimax/README.md @@ -0,0 +1,37 @@ +# MiniMax (OpenClaw plugin) + +Bundled MiniMax plugin for both: + +- API-key provider setup (`minimax`) +- Coding Plan OAuth setup (`minimax-portal`) + +## Enable + +```bash +openclaw plugins enable minimax +``` + +Restart the Gateway after enabling. + +```bash +openclaw gateway restart +``` + +## Authenticate + +OAuth: + +```bash +openclaw models auth login --provider minimax-portal --set-default +``` + +API key: + +```bash +openclaw onboard --auth-choice minimax-global-api +``` + +## Notes + +- MiniMax OAuth uses a user-code login flow. +- OAuth currently targets the Coding Plan path. diff --git a/extensions/minimax/index.ts b/extensions/minimax/index.ts index 6585e27d7cf..969868986f0 100644 --- a/extensions/minimax/index.ts +++ b/extensions/minimax/index.ts @@ -1,35 +1,165 @@ -import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core"; -import { buildMinimaxProvider } from "../../src/agents/models-config.providers.static.js"; +import { + buildOauthProviderAuthResult, + emptyPluginConfigSchema, + type OpenClawPluginApi, + type ProviderAuthContext, + type ProviderAuthResult, + type ProviderCatalogContext, +} from "openclaw/plugin-sdk/minimax-portal-auth"; +import { ensureAuthProfileStore, listProfilesForProvider } from "../../src/agents/auth-profiles.js"; +import { MINIMAX_OAUTH_MARKER } from "../../src/agents/model-auth-markers.js"; +import { + buildMinimaxPortalProvider, + buildMinimaxProvider, +} from "../../src/agents/models-config.providers.static.js"; import { fetchMinimaxUsage } from "../../src/infra/provider-usage.fetch.js"; +import { loginMiniMaxPortalOAuth, type MiniMaxRegion } from "./oauth.js"; -const PROVIDER_ID = "minimax"; +const API_PROVIDER_ID = "minimax"; +const PORTAL_PROVIDER_ID = "minimax-portal"; +const PROVIDER_LABEL = "MiniMax"; +const DEFAULT_MODEL = "MiniMax-M2.5"; +const DEFAULT_BASE_URL_CN = "https://api.minimaxi.com/anthropic"; +const DEFAULT_BASE_URL_GLOBAL = "https://api.minimax.io/anthropic"; + +function getDefaultBaseUrl(region: MiniMaxRegion): string { + return region === "cn" ? DEFAULT_BASE_URL_CN : DEFAULT_BASE_URL_GLOBAL; +} + +function modelRef(modelId: string): string { + return `${PORTAL_PROVIDER_ID}/${modelId}`; +} + +function buildPortalProviderCatalog(params: { baseUrl: string; apiKey: string }) { + return { + ...buildMinimaxPortalProvider(), + baseUrl: params.baseUrl, + apiKey: params.apiKey, + }; +} + +function resolveApiCatalog(ctx: ProviderCatalogContext) { + const apiKey = ctx.resolveProviderApiKey(API_PROVIDER_ID).apiKey; + if (!apiKey) { + return null; + } + return { + provider: { + ...buildMinimaxProvider(), + apiKey, + }, + }; +} + +function resolvePortalCatalog(ctx: ProviderCatalogContext) { + const explicitProvider = ctx.config.models?.providers?.[PORTAL_PROVIDER_ID]; + const envApiKey = ctx.resolveProviderApiKey(PORTAL_PROVIDER_ID).apiKey; + const authStore = ensureAuthProfileStore(ctx.agentDir, { + allowKeychainPrompt: false, + }); + const hasProfiles = listProfilesForProvider(authStore, PORTAL_PROVIDER_ID).length > 0; + const explicitApiKey = + typeof explicitProvider?.apiKey === "string" ? explicitProvider.apiKey.trim() : undefined; + const apiKey = envApiKey ?? explicitApiKey ?? (hasProfiles ? MINIMAX_OAUTH_MARKER : undefined); + if (!apiKey) { + return null; + } + + const explicitBaseUrl = + typeof explicitProvider?.baseUrl === "string" ? explicitProvider.baseUrl.trim() : undefined; + + return { + provider: buildPortalProviderCatalog({ + baseUrl: explicitBaseUrl || DEFAULT_BASE_URL_GLOBAL, + apiKey, + }), + }; +} + +function createOAuthHandler(region: MiniMaxRegion) { + const defaultBaseUrl = getDefaultBaseUrl(region); + const regionLabel = region === "cn" ? "CN" : "Global"; + + return async (ctx: ProviderAuthContext): Promise => { + const progress = ctx.prompter.progress(`Starting MiniMax OAuth (${regionLabel})…`); + try { + const result = await loginMiniMaxPortalOAuth({ + openUrl: ctx.openUrl, + note: ctx.prompter.note, + progress, + region, + }); + + progress.stop("MiniMax OAuth complete"); + + if (result.notification_message) { + await ctx.prompter.note(result.notification_message, "MiniMax OAuth"); + } + + const baseUrl = result.resourceUrl || defaultBaseUrl; + + return buildOauthProviderAuthResult({ + providerId: PORTAL_PROVIDER_ID, + defaultModel: modelRef(DEFAULT_MODEL), + access: result.access, + refresh: result.refresh, + expires: result.expires, + configPatch: { + models: { + providers: { + [PORTAL_PROVIDER_ID]: { + baseUrl, + models: [], + }, + }, + }, + agents: { + defaults: { + models: { + [modelRef("MiniMax-M2.5")]: { alias: "minimax-m2.5" }, + [modelRef("MiniMax-M2.5-highspeed")]: { + alias: "minimax-m2.5-highspeed", + }, + [modelRef("MiniMax-M2.5-Lightning")]: { + alias: "minimax-m2.5-lightning", + }, + }, + }, + }, + }, + notes: [ + "MiniMax OAuth tokens auto-refresh. Re-run login if refresh fails or access is revoked.", + `Base URL defaults to ${defaultBaseUrl}. Override models.providers.${PORTAL_PROVIDER_ID}.baseUrl if needed.`, + ...(result.notification_message ? [result.notification_message] : []), + ], + }); + } catch (err) { + const errorMsg = err instanceof Error ? err.message : String(err); + progress.stop(`MiniMax OAuth failed: ${errorMsg}`); + await ctx.prompter.note( + "If OAuth fails, verify your MiniMax account has portal access and try again.", + "MiniMax OAuth", + ); + throw err; + } + }; +} const minimaxPlugin = { - id: PROVIDER_ID, - name: "MiniMax Provider", - description: "Bundled MiniMax provider plugin", + id: API_PROVIDER_ID, + name: "MiniMax", + description: "Bundled MiniMax API-key and OAuth provider plugin", configSchema: emptyPluginConfigSchema(), register(api: OpenClawPluginApi) { api.registerProvider({ - id: PROVIDER_ID, - label: "MiniMax", + id: API_PROVIDER_ID, + label: PROVIDER_LABEL, docsPath: "/providers/minimax", envVars: ["MINIMAX_API_KEY"], auth: [], catalog: { order: "simple", - run: async (ctx) => { - const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey; - if (!apiKey) { - return null; - } - return { - provider: { - ...buildMinimaxProvider(), - apiKey, - }, - }; - }, + run: async (ctx) => resolveApiCatalog(ctx), }, resolveUsageAuth: async (ctx) => { const apiKey = ctx.resolveApiKeyFromConfigAndStore({ @@ -40,6 +170,31 @@ const minimaxPlugin = { fetchUsageSnapshot: async (ctx) => await fetchMinimaxUsage(ctx.token, ctx.timeoutMs, ctx.fetchFn), }); + + api.registerProvider({ + id: PORTAL_PROVIDER_ID, + label: PROVIDER_LABEL, + docsPath: "/providers/minimax", + catalog: { + run: async (ctx) => resolvePortalCatalog(ctx), + }, + auth: [ + { + id: "oauth", + label: "MiniMax OAuth (Global)", + hint: "Global endpoint - api.minimax.io", + kind: "device_code", + run: createOAuthHandler("global"), + }, + { + id: "oauth-cn", + label: "MiniMax OAuth (CN)", + hint: "CN endpoint - api.minimaxi.com", + kind: "device_code", + run: createOAuthHandler("cn"), + }, + ], + }); }, }; diff --git a/extensions/minimax-portal-auth/oauth.ts b/extensions/minimax/oauth.ts similarity index 90% rename from extensions/minimax-portal-auth/oauth.ts rename to extensions/minimax/oauth.ts index 5b18c13d3a4..fb405cd5559 100644 --- a/extensions/minimax-portal-auth/oauth.ts +++ b/extensions/minimax/oauth.ts @@ -161,7 +161,7 @@ async function pollOAuthToken(params: { return { status: "error", message: "An error occurred. Please try again later" }; } - if (tokenPayload.status != "success") { + if (tokenPayload.status !== "success") { return { status: "pending", message: "current user code is not authorized" }; } @@ -216,29 +216,17 @@ export async function loginMiniMaxPortalOAuth(params: { region, }); - // // Debug: print poll result - // await params.note( - // `status: ${result.status}` + - // (result.status === "success" ? `\ntoken: ${JSON.stringify(result.token, null, 2)}` : "") + - // (result.status === "error" ? `\nmessage: ${result.message}` : "") + - // (result.status === "pending" && result.message ? `\nmessage: ${result.message}` : ""), - // "MiniMax OAuth Poll Result", - // ); - if (result.status === "success") { return result.token; } if (result.status === "error") { - throw new Error(`MiniMax OAuth failed: ${result.message}`); - } - - if (result.status === "pending") { - pollIntervalMs = Math.min(pollIntervalMs * 1.5, 10000); + throw new Error(result.message); } await new Promise((resolve) => setTimeout(resolve, pollIntervalMs)); + pollIntervalMs = Math.max(pollIntervalMs, 2000); } - throw new Error("MiniMax OAuth timed out waiting for authorization."); + throw new Error("MiniMax OAuth timed out before authorization completed."); } diff --git a/extensions/minimax/openclaw.plugin.json b/extensions/minimax/openclaw.plugin.json index 01f3e5efbea..32d8be58bf5 100644 --- a/extensions/minimax/openclaw.plugin.json +++ b/extensions/minimax/openclaw.plugin.json @@ -1,6 +1,6 @@ { "id": "minimax", - "providers": ["minimax"], + "providers": ["minimax", "minimax-portal"], "configSchema": { "type": "object", "additionalProperties": false, diff --git a/extensions/minimax/package.json b/extensions/minimax/package.json index 6650cf1e456..f6c99e0e756 100644 --- a/extensions/minimax/package.json +++ b/extensions/minimax/package.json @@ -2,7 +2,7 @@ "name": "@openclaw/minimax-provider", "version": "2026.3.14", "private": true, - "description": "OpenClaw MiniMax provider plugin", + "description": "OpenClaw MiniMax provider and OAuth plugin", "type": "module", "openclaw": { "extensions": [ diff --git a/scripts/check-no-raw-channel-fetch.mjs b/scripts/check-no-raw-channel-fetch.mjs index 7b935d183e5..57adb600c81 100644 --- a/scripts/check-no-raw-channel-fetch.mjs +++ b/scripts/check-no-raw-channel-fetch.mjs @@ -24,8 +24,8 @@ const allowedRawFetchCallsites = new Set([ "extensions/mattermost/src/mattermost/client.ts:211", "extensions/mattermost/src/mattermost/monitor.ts:230", "extensions/mattermost/src/mattermost/probe.ts:27", - "extensions/minimax-portal-auth/oauth.ts:71", - "extensions/minimax-portal-auth/oauth.ts:112", + "extensions/minimax/oauth.ts:62", + "extensions/minimax/oauth.ts:93", "extensions/msteams/src/graph.ts:39", "extensions/nextcloud-talk/src/room-info.ts:92", "extensions/nextcloud-talk/src/send.ts:107", diff --git a/src/commands/auth-choice.apply.minimax.ts b/src/commands/auth-choice.apply.minimax.ts index 1a381b908b8..6438b94c043 100644 --- a/src/commands/auth-choice.apply.minimax.ts +++ b/src/commands/auth-choice.apply.minimax.ts @@ -22,7 +22,7 @@ export async function applyAuthChoiceMiniMax( if (params.authChoice === "minimax-global-oauth") { return await applyAuthChoicePluginProvider(params, { authChoice: "minimax-global-oauth", - pluginId: "minimax-portal-auth", + pluginId: "minimax", providerId: "minimax-portal", methodId: "oauth", label: "MiniMax", @@ -32,7 +32,7 @@ export async function applyAuthChoiceMiniMax( if (params.authChoice === "minimax-cn-oauth") { return await applyAuthChoicePluginProvider(params, { authChoice: "minimax-cn-oauth", - pluginId: "minimax-portal-auth", + pluginId: "minimax", providerId: "minimax-portal", methodId: "oauth-cn", label: "MiniMax CN", diff --git a/src/config/plugin-auto-enable.test.ts b/src/config/plugin-auto-enable.test.ts index cae9b4e5c18..8439a2768ec 100644 --- a/src/config/plugin-auto-enable.test.ts +++ b/src/config/plugin-auto-enable.test.ts @@ -310,6 +310,25 @@ describe("applyPluginAutoEnable", () => { expect(result.config.plugins?.entries?.google?.enabled).toBe(true); }); + it("auto-enables minimax when minimax-portal profiles exist", () => { + const result = applyPluginAutoEnable({ + config: { + auth: { + profiles: { + "minimax-portal:default": { + provider: "minimax-portal", + mode: "oauth", + }, + }, + }, + }, + env: {}, + }); + + expect(result.config.plugins?.entries?.minimax?.enabled).toBe(true); + expect(result.config.plugins?.entries?.["minimax-portal-auth"]).toBeUndefined(); + }); + it("auto-enables acpx plugin when ACP is configured", () => { const result = applyPluginAutoEnable({ config: { diff --git a/src/config/plugin-auto-enable.ts b/src/config/plugin-auto-enable.ts index 72e1dede1ef..2a7524b2558 100644 --- a/src/config/plugin-auto-enable.ts +++ b/src/config/plugin-auto-enable.ts @@ -31,7 +31,7 @@ const PROVIDER_PLUGIN_IDS: Array<{ pluginId: string; providerId: string }> = [ { pluginId: "google", providerId: "google-gemini-cli" }, { pluginId: "qwen-portal-auth", providerId: "qwen-portal" }, { pluginId: "copilot-proxy", providerId: "copilot-proxy" }, - { pluginId: "minimax-portal-auth", providerId: "minimax-portal" }, + { pluginId: "minimax", providerId: "minimax-portal" }, ]; function hasNonEmptyString(value: unknown): boolean { diff --git a/src/plugin-sdk/minimax-portal-auth.ts b/src/plugin-sdk/minimax-portal-auth.ts index cc41b2cc80d..07aefa0aafa 100644 --- a/src/plugin-sdk/minimax-portal-auth.ts +++ b/src/plugin-sdk/minimax-portal-auth.ts @@ -1,5 +1,5 @@ -// Narrow plugin-sdk surface for the bundled minimax-portal-auth plugin. -// Keep this list additive and scoped to symbols used under extensions/minimax-portal-auth. +// Narrow plugin-sdk surface for MiniMax OAuth helpers used by the bundled minimax plugin. +// Keep this list additive and scoped to MiniMax OAuth support code. export { emptyPluginConfigSchema } from "../plugins/config-schema.js"; export { buildOauthProviderAuthResult } from "./provider-auth-result.js"; diff --git a/src/plugins/config-state.test.ts b/src/plugins/config-state.test.ts index 37db8a6efae..c4195a5e6e3 100644 --- a/src/plugins/config-state.test.ts +++ b/src/plugins/config-state.test.ts @@ -80,18 +80,22 @@ describe("normalizePluginsConfig", () => { it("normalizes legacy plugin ids to their merged bundled plugin id", () => { const result = normalizePluginsConfig({ - allow: ["openai-codex"], - deny: ["openai-codex"], + allow: ["openai-codex", "minimax-portal-auth"], + deny: ["openai-codex", "minimax-portal-auth"], entries: { "openai-codex": { enabled: true, }, + "minimax-portal-auth": { + enabled: false, + }, }, }); - expect(result.allow).toEqual(["openai"]); - expect(result.deny).toEqual(["openai"]); + expect(result.allow).toEqual(["openai", "minimax"]); + expect(result.deny).toEqual(["openai", "minimax"]); expect(result.entries.openai?.enabled).toBe(true); + expect(result.entries.minimax?.enabled).toBe(false); }); }); diff --git a/src/plugins/config-state.ts b/src/plugins/config-state.ts index a5860b606e3..493ad885f51 100644 --- a/src/plugins/config-state.ts +++ b/src/plugins/config-state.ts @@ -33,7 +33,6 @@ export const BUNDLED_ENABLED_BY_DEFAULT = new Set([ "kilocode", "kimi-coding", "minimax", - "minimax-portal-auth", "mistral", "modelstudio", "moonshot", @@ -60,6 +59,7 @@ export const BUNDLED_ENABLED_BY_DEFAULT = new Set([ const PLUGIN_ID_ALIASES: Readonly> = { "openai-codex": "openai", + "minimax-portal-auth": "minimax", }; function normalizePluginId(id: string): string { diff --git a/src/plugins/providers.ts b/src/plugins/providers.ts index 4f4216730cf..c1de0680359 100644 --- a/src/plugins/providers.ts +++ b/src/plugins/providers.ts @@ -16,7 +16,6 @@ const BUNDLED_PROVIDER_ALLOWLIST_COMPAT_PLUGIN_IDS = [ "kilocode", "kimi-coding", "minimax", - "minimax-portal-auth", "mistral", "modelstudio", "moonshot",