feat(tools): add MiniMax as bundled web search provider

Add native MiniMax Search integration via their Coding Plan search API
(POST /v1/coding_plan/search). This brings MiniMax in line with Brave,
Kimi, Grok, Gemini, and other providers that already have bundled web
search support.

- Implement WebSearchProviderPlugin with caching, credential resolution,
  and trusted endpoint wrapping
- Support both global (api.minimax.io) and CN (api.minimaxi.com)
  endpoints, inferred from explicit region config, model provider base
  URL, or minimax-portal OAuth base URL
- Prefer MINIMAX_CODE_PLAN_KEY over MINIMAX_API_KEY in credential
  fallback, matching existing repo precedence
- Accept SecretRef objects for webSearch.apiKey (type: [string, object])
- Register in bundled registry, provider-id compat map, and fast-path
  plugin id list with full alignment test coverage
- Add unit tests for endpoint/region resolution and edge cases

Closes #47927
Related #11399

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jithendra
2026-03-25 18:41:35 -04:00
committed by Peter Steinberger
parent a722719720
commit d204be80af
18 changed files with 798 additions and 66 deletions

View File

@@ -42,7 +42,7 @@ vi.mock("../plugins/web-fetch-providers.runtime.js", () => ({
}));
function createTestProvider(params: {
id: "brave" | "gemini" | "grok" | "kimi" | "perplexity" | "firecrawl" | "tavily";
id: "brave" | "gemini" | "grok" | "kimi" | "minimax" | "perplexity" | "firecrawl" | "tavily";
pluginId: string;
order: number;
}): PluginWebSearchProviderEntry {
@@ -100,6 +100,7 @@ function buildTestWebSearchProviders(): PluginWebSearchProviderEntry[] {
createTestProvider({ id: "gemini", pluginId: "google", order: 20 }),
createTestProvider({ id: "grok", pluginId: "xai", order: 30 }),
createTestProvider({ id: "kimi", pluginId: "moonshot", order: 40 }),
createTestProvider({ id: "minimax", pluginId: "minimax", order: 15 }),
createTestProvider({ id: "perplexity", pluginId: "perplexity", order: 50 }),
createTestProvider({ id: "firecrawl", pluginId: "firecrawl", order: 60 }),
createTestProvider({ id: "tavily", pluginId: "tavily", order: 70 }),
@@ -260,6 +261,9 @@ function buildConfigForOpenClawTarget(entry: SecretRegistryEntry, envId: string)
if (entry.id === "plugins.entries.firecrawl.config.webSearch.apiKey") {
setPathCreateStrict(config, ["tools", "web", "search", "provider"], "firecrawl");
}
if (entry.id === "plugins.entries.minimax.config.webSearch.apiKey") {
setPathCreateStrict(config, ["tools", "web", "search", "provider"], "minimax");
}
if (entry.id === "plugins.entries.tavily.config.webSearch.apiKey") {
setPathCreateStrict(config, ["tools", "web", "search", "provider"], "tavily");
}