From f26942335551831ef5b87841b934b293ca347f32 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 2 May 2026 05:58:37 +0100 Subject: [PATCH] fix(web-search): include MiniMax in setup detection --- CHANGELOG.md | 1 + docs/tools/minimax-search.md | 11 ++++++----- docs/tools/web.md | 2 +- extensions/minimax/index.test.ts | 8 +++++++- .../minimax/src/minimax-web-search-provider.ts | 4 +++- extensions/minimax/web-search-contract-api.ts | 4 +++- src/commands/onboard-search.test.ts | 18 +++++++++++++++++- src/config/config.web-search-provider.test.ts | 12 +++++++++++- .../contracts/providers.contract.test.ts | 1 + 9 files changed, 50 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc0c3567aab..6632c7ca19b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Docs: https://docs.openclaw.ai - Feishu: preserve Feishu/Lark HTTP error bodies for message sends, media sends, and chat member lookups, so HTTP 400 failures include vendor code, message, log id, and troubleshooter details. Fixes #73860. Thanks @desksk. - Agents/transcripts: avoid reopening large Pi transcript files through the synchronous session manager for maintenance rewrites, persisted tool-result truncation, manual compaction boundary hardening, and queued compaction rotation. Thanks @mariozechner. +- Web search/MiniMax: include MiniMax Search in the web-search setup flow and let `MINIMAX_API_KEY` participate in MiniMax Search auto-detection. Supersedes #65828. Thanks @Jah-yee. - Telegram: inherit the process DNS result order for Bot API transport and downgrade recovered sticky IPv4 fallback promotions to debug logs, while keeping pinned-IP escalation warnings visible. Fixes #75904. Thanks @highfly-hi and @neeravmakwana. - Web search/MiniMax: allow `MINIMAX_OAUTH_TOKEN` to satisfy MiniMax Search credentials, so OAuth-authorized MiniMax Token Plan setups do not need a separate web-search key. Fixes #65768. Thanks @kikibrian and @zhouhe-xydt. - Providers/MiniMax: derive Coding Plan usage polling from the configured MiniMax base URL, so global setups no longer query the CN usage host. Fixes #65054. Thanks @sixone74 and @Yanhu007. diff --git a/docs/tools/minimax-search.md b/docs/tools/minimax-search.md index d2b4f83b2aa..4ef9206f6cc 100644 --- a/docs/tools/minimax-search.md +++ b/docs/tools/minimax-search.md @@ -29,9 +29,10 @@ snippets, and related queries. -OpenClaw also accepts `MINIMAX_CODING_API_KEY` and `MINIMAX_OAUTH_TOKEN` as env -aliases. `MINIMAX_API_KEY` is still read as a compatibility fallback when it -already points at a token-plan credential. +OpenClaw also accepts `MINIMAX_CODING_API_KEY`, `MINIMAX_OAUTH_TOKEN`, and +`MINIMAX_API_KEY` as env aliases. `MINIMAX_API_KEY` should point at a +search-enabled Token Plan credential; ordinary MiniMax model API keys may not +be accepted by the Token Plan search endpoint. ## Config @@ -59,8 +60,8 @@ already points at a token-plan credential. } ``` -**Environment alternative:** set `MINIMAX_CODE_PLAN_KEY` or `MINIMAX_OAUTH_TOKEN` -in the Gateway environment. +**Environment alternative:** set `MINIMAX_CODE_PLAN_KEY`, `MINIMAX_CODING_API_KEY`, +`MINIMAX_OAUTH_TOKEN`, or `MINIMAX_API_KEY` in the Gateway environment. For a gateway install, put it in `~/.openclaw/.env`. ## Region selection diff --git a/docs/tools/web.md b/docs/tools/web.md index ad45c0dc40d..af9ddb300f2 100644 --- a/docs/tools/web.md +++ b/docs/tools/web.md @@ -164,7 +164,7 @@ first one that is ready: API-backed providers first: 1. **Brave** -- `BRAVE_API_KEY` or `plugins.entries.brave.config.webSearch.apiKey` (order 10) -2. **MiniMax Search** -- `MINIMAX_CODE_PLAN_KEY` / `MINIMAX_CODING_API_KEY` / `MINIMAX_OAUTH_TOKEN` or `plugins.entries.minimax.config.webSearch.apiKey` (order 15) +2. **MiniMax Search** -- `MINIMAX_CODE_PLAN_KEY` / `MINIMAX_CODING_API_KEY` / `MINIMAX_OAUTH_TOKEN` / `MINIMAX_API_KEY` or `plugins.entries.minimax.config.webSearch.apiKey` (order 15) 3. **Gemini** -- `plugins.entries.google.config.webSearch.apiKey`, `GEMINI_API_KEY`, or `models.providers.google.apiKey` (order 20) 4. **Grok** -- `XAI_API_KEY` or `plugins.entries.xai.config.webSearch.apiKey` (order 30) 5. **Kimi** -- `KIMI_API_KEY` / `MOONSHOT_API_KEY` or `plugins.entries.moonshot.config.webSearch.apiKey` (order 40) diff --git a/extensions/minimax/index.test.ts b/extensions/minimax/index.test.ts index b18bb5c7873..5a70666ed27 100644 --- a/extensions/minimax/index.test.ts +++ b/extensions/minimax/index.test.ts @@ -246,7 +246,13 @@ describe("minimax provider hooks", () => { expect(webSearchProviders[0]).toMatchObject({ id: "minimax", label: "MiniMax Search", - envVars: ["MINIMAX_CODE_PLAN_KEY", "MINIMAX_CODING_API_KEY", "MINIMAX_OAUTH_TOKEN"], + onboardingScopes: ["text-inference"], + envVars: [ + "MINIMAX_CODE_PLAN_KEY", + "MINIMAX_CODING_API_KEY", + "MINIMAX_OAUTH_TOKEN", + "MINIMAX_API_KEY", + ], }); }); diff --git a/extensions/minimax/src/minimax-web-search-provider.ts b/extensions/minimax/src/minimax-web-search-provider.ts index 7ebe983d76c..032f9236cb7 100644 --- a/extensions/minimax/src/minimax-web-search-provider.ts +++ b/extensions/minimax/src/minimax-web-search-provider.ts @@ -9,6 +9,7 @@ const MINIMAX_TOKEN_PLAN_ENV_VARS = [ "MINIMAX_CODING_API_KEY", "MINIMAX_OAUTH_TOKEN", ] as const; +const MINIMAX_WEB_SEARCH_ENV_VARS = [...MINIMAX_TOKEN_PLAN_ENV_VARS, "MINIMAX_API_KEY"] as const; type MiniMaxWebSearchRuntime = typeof import("./minimax-web-search-provider.runtime.js"); @@ -37,8 +38,9 @@ export function createMiniMaxWebSearchProvider(): WebSearchProviderPlugin { id: "minimax", label: "MiniMax Search", hint: "Structured results via MiniMax Token Plan search API", + onboardingScopes: ["text-inference"], credentialLabel: "MiniMax Token Plan key or OAuth token", - envVars: [...MINIMAX_TOKEN_PLAN_ENV_VARS], + envVars: [...MINIMAX_WEB_SEARCH_ENV_VARS], placeholder: "sk-cp-...", signupUrl: "https://platform.minimax.io/user-center/basic-information/interface-key", docsUrl: "https://docs.openclaw.ai/tools/minimax-search", diff --git a/extensions/minimax/web-search-contract-api.ts b/extensions/minimax/web-search-contract-api.ts index 15d0b5749a7..d772f030236 100644 --- a/extensions/minimax/web-search-contract-api.ts +++ b/extensions/minimax/web-search-contract-api.ts @@ -8,6 +8,7 @@ const MINIMAX_TOKEN_PLAN_ENV_VARS = [ "MINIMAX_CODING_API_KEY", "MINIMAX_OAUTH_TOKEN", ] as const; +const MINIMAX_WEB_SEARCH_ENV_VARS = [...MINIMAX_TOKEN_PLAN_ENV_VARS, "MINIMAX_API_KEY"] as const; export function createMiniMaxWebSearchProvider(): WebSearchProviderPlugin { const credentialPath = "plugins.entries.minimax.config.webSearch.apiKey"; @@ -16,8 +17,9 @@ export function createMiniMaxWebSearchProvider(): WebSearchProviderPlugin { id: "minimax", label: "MiniMax Search", hint: "Structured results via MiniMax Token Plan search API", + onboardingScopes: ["text-inference"], credentialLabel: "MiniMax Token Plan key or OAuth token", - envVars: [...MINIMAX_TOKEN_PLAN_ENV_VARS], + envVars: [...MINIMAX_WEB_SEARCH_ENV_VARS], placeholder: "sk-cp-...", signupUrl: "https://platform.minimax.io/user-center/basic-information/interface-key", docsUrl: "https://docs.openclaw.ai/tools/minimax-search", diff --git a/src/commands/onboard-search.test.ts b/src/commands/onboard-search.test.ts index ad7d9eb1b5e..de8465edba3 100644 --- a/src/commands/onboard-search.test.ts +++ b/src/commands/onboard-search.test.ts @@ -28,6 +28,17 @@ const SEARCH_PROVIDER_PLUGINS: Record< label: "Kimi", credentialLabel: "Moonshot / Kimi API key", }, + minimax: { + pluginId: "minimax", + envVars: [ + "MINIMAX_CODE_PLAN_KEY", + "MINIMAX_CODING_API_KEY", + "MINIMAX_OAUTH_TOKEN", + "MINIMAX_API_KEY", + ], + label: "MiniMax Search", + credentialLabel: "MiniMax Token Plan key or OAuth token", + }, perplexity: { pluginId: "perplexity", envVars: ["PERPLEXITY_API_KEY", "OPENROUTER_API_KEY"], @@ -110,7 +121,7 @@ function createSearchProviderEntry(id: string): PluginWebSearchProviderEntry { const searchProviderFixture = vi.hoisted(() => ({ resolvePluginWebSearchProviders: vi.fn(() => - ["brave", "firecrawl", "gemini", "grok", "kimi", "perplexity", "tavily"].map((id) => + ["brave", "firecrawl", "gemini", "grok", "kimi", "minimax", "perplexity", "tavily"].map((id) => createSearchProviderEntry(id), ), ), @@ -135,6 +146,10 @@ const SEARCH_PROVIDER_ENV_VARS = [ "GOOGLE_API_KEY", "KIMI_API_KEY", "MOONSHOT_API_KEY", + "MINIMAX_API_KEY", + "MINIMAX_CODE_PLAN_KEY", + "MINIMAX_CODING_API_KEY", + "MINIMAX_OAUTH_TOKEN", "OPENROUTER_API_KEY", "PERPLEXITY_API_KEY", "TAVILY_API_KEY", @@ -652,6 +667,7 @@ describe("setupSearch", () => { "gemini", "grok", "kimi", + "minimax", "perplexity", "tavily", ]), diff --git a/src/config/config.web-search-provider.test.ts b/src/config/config.web-search-provider.test.ts index 082eaf3eea3..87399a42007 100644 --- a/src/config/config.web-search-provider.test.ts +++ b/src/config/config.web-search-provider.test.ts @@ -76,7 +76,12 @@ const mockWebSearchProviders = [ { id: "minimax", pluginId: "minimax", - envVars: ["MINIMAX_CODE_PLAN_KEY", "MINIMAX_CODING_API_KEY", "MINIMAX_OAUTH_TOKEN"], + envVars: [ + "MINIMAX_CODE_PLAN_KEY", + "MINIMAX_CODING_API_KEY", + "MINIMAX_OAUTH_TOKEN", + "MINIMAX_API_KEY", + ], credentialPath: "plugins.entries.minimax.config.webSearch.apiKey", getCredentialValue: getScopedWebSearchCredential("minimax"), getConfiguredCredentialValue: getConfiguredPluginWebSearchCredential("minimax"), @@ -456,6 +461,11 @@ describe("web search provider auto-detection", () => { expect(resolveSearchProvider({})).toBe("tavily"); }); + it("auto-detects minimax when only MINIMAX_API_KEY is set", () => { + process.env.MINIMAX_API_KEY = "test-minimax-key"; // pragma: allowlist secret + expect(resolveSearchProvider({})).toBe("minimax"); + }); + it("auto-detects firecrawl when only FIRECRAWL_API_KEY is set", () => { process.env.FIRECRAWL_API_KEY = "fc-test-key"; // pragma: allowlist secret expect(resolveSearchProvider({})).toBe("firecrawl"); diff --git a/src/plugins/contracts/providers.contract.test.ts b/src/plugins/contracts/providers.contract.test.ts index a92331b7cd7..d285e30cca5 100644 --- a/src/plugins/contracts/providers.contract.test.ts +++ b/src/plugins/contracts/providers.contract.test.ts @@ -20,6 +20,7 @@ for (const providerId of [ "exa", "firecrawl", "google", + "minimax", "moonshot", "perplexity", "tavily",