feat(tools): add MiniMax as bundled web search provider#54648
feat(tools): add MiniMax as bundled web search provider#54648steipete merged 1 commit intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR adds MiniMax as a new bundled web search provider, following the established pattern of existing providers (Brave, Kimi) with caching, credential resolution, trusted-endpoint wrapping, and Key concerns found during review:
Confidence Score: 3/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/minimax/src/minimax-web-search-provider.ts
Line: 88-93
Comment:
**`count` not forwarded to the API request**
`params.count` is resolved and passed to `runMiniMaxSearch`, but the `POST` body only ever sends `{ q: params.query }`. The result set is then trimmed client-side with `.slice(0, params.count)`.
If the MiniMax Coding Plan API supports a result-count parameter (e.g. `num` or `n`), not forwarding it means the API always returns its default page size. When the user requests more results than the API default, the slice will silently under-deliver without any error.
Consider adding `num: params.count` (or whatever the API field is called) to the request body so the API is asked for the right number of results upfront.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: extensions/minimax/src/minimax-web-search-provider.ts
Line: 173
Comment:
**Cache key missing `endpoint` (region)**
The cache key only includes `["minimax", query, resolvedCount]` but omits the `endpoint`. Because the endpoint differs between global and CN regions, two separate configurations with the same query and count will collide on the same cache entry — a global-region result would be returned for a CN-region request (and vice versa).
Kimi's implementation shows the pattern: it includes `baseUrl` in the cache key to prevent exactly this kind of cross-region collision. The fix is to add `endpoint` as a component:
```
buildSearchCacheKey(["minimax", endpoint, query, resolvedCount])
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "feat: add MiniMax as bundled web search ..." | Re-trigger Greptile |
| }, | ||
| body: JSON.stringify({ q: params.query }), | ||
| }, | ||
| }, | ||
| async (res) => { | ||
| if (!res.ok) { |
There was a problem hiding this comment.
count not forwarded to the API request
params.count is resolved and passed to runMiniMaxSearch, but the POST body only ever sends { q: params.query }. The result set is then trimmed client-side with .slice(0, params.count).
If the MiniMax Coding Plan API supports a result-count parameter (e.g. num or n), not forwarding it means the API always returns its default page size. When the user requests more results than the API default, the slice will silently under-deliver without any error.
Consider adding num: params.count (or whatever the API field is called) to the request body so the API is asked for the right number of results upfront.
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/minimax/src/minimax-web-search-provider.ts
Line: 88-93
Comment:
**`count` not forwarded to the API request**
`params.count` is resolved and passed to `runMiniMaxSearch`, but the `POST` body only ever sends `{ q: params.query }`. The result set is then trimmed client-side with `.slice(0, params.count)`.
If the MiniMax Coding Plan API supports a result-count parameter (e.g. `num` or `n`), not forwarding it means the API always returns its default page size. When the user requests more results than the API default, the slice will silently under-deliver without any error.
Consider adding `num: params.count` (or whatever the API field is called) to the request body so the API is asked for the right number of results upfront.
How can I resolve this? If you propose a fix, please make it concise.| const resolvedCount = resolveSearchCount(count, DEFAULT_SEARCH_COUNT); | ||
| const endpoint = resolveMiniMaxEndpoint(searchConfig); | ||
|
|
||
| const cacheKey = buildSearchCacheKey(["minimax", query, resolvedCount]); |
There was a problem hiding this comment.
Cache key missing
endpoint (region)
The cache key only includes ["minimax", query, resolvedCount] but omits the endpoint. Because the endpoint differs between global and CN regions, two separate configurations with the same query and count will collide on the same cache entry — a global-region result would be returned for a CN-region request (and vice versa).
Kimi's implementation shows the pattern: it includes baseUrl in the cache key to prevent exactly this kind of cross-region collision. The fix is to add endpoint as a component:
buildSearchCacheKey(["minimax", endpoint, query, resolvedCount])
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/minimax/src/minimax-web-search-provider.ts
Line: 173
Comment:
**Cache key missing `endpoint` (region)**
The cache key only includes `["minimax", query, resolvedCount]` but omits the `endpoint`. Because the endpoint differs between global and CN regions, two separate configurations with the same query and count will collide on the same cache entry — a global-region result would be returned for a CN-region request (and vice versa).
Kimi's implementation shows the pattern: it includes `baseUrl` in the cache key to prevent exactly this kind of cross-region collision. The fix is to add `endpoint` as a component:
```
buildSearchCacheKey(["minimax", endpoint, query, resolvedCount])
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Pull request overview
Adds MiniMax as a bundled/native web search provider (MiniMax Coding Plan search API), wiring it into the bundled web search registry and provider-id compatibility mapping so it can be discovered and used like existing providers (Brave/Kimi/etc.).
Changes:
- Introduces a new
minimaxweb search provider implementation with caching, credential resolution, and trusted endpoint wrapping. - Registers the MiniMax web search provider in the MiniMax extension entrypoint.
- Adds MiniMax to the bundled web search registry and provider-id compatibility map.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
src/plugins/bundled-web-search-provider-ids.ts |
Adds minimax → minimax compat provider-id mapping. |
src/bundled-web-search-registry.ts |
Adds the MiniMax extension to the bundled web search plugin registrations list. |
extensions/minimax/src/minimax-web-search-provider.ts |
Implements the MiniMax Coding Plan web search provider/tool (endpoint selection, request/response mapping, caching). |
extensions/minimax/index.ts |
Registers the new MiniMax web search provider with the plugin API. |
| { | ||
| get plugin() { | ||
| return minimaxPlugin; | ||
| }, | ||
| credentialValue: "sk-test", | ||
| }, |
There was a problem hiding this comment.
bundledWebSearchPluginRegistrations now includes the minimax plugin, but src/plugins/bundled-web-search-ids.ts (and the metadata tests that assert alignment) still omit minimax. This will break the “fast-path ids aligned with the registry” invariant and can cause resolveBundledWebSearchPluginIds to keep excluding the new bundled provider. Add minimax to BUNDLED_WEB_SEARCH_PLUGIN_IDS and update the expected bundled id lists accordingly.
| const resolvedCount = resolveSearchCount(count, DEFAULT_SEARCH_COUNT); | ||
| const endpoint = resolveMiniMaxEndpoint(searchConfig); | ||
|
|
||
| const cacheKey = buildSearchCacheKey(["minimax", query, resolvedCount]); |
There was a problem hiding this comment.
The search cache key doesn’t include the resolved endpoint/region. If a user switches between Global and CN endpoints (or if different configs run in the same process), cached results can be served for the wrong region. Include endpoint (or the region string) as part of buildSearchCacheKey inputs.
| const cacheKey = buildSearchCacheKey(["minimax", query, resolvedCount]); | |
| const cacheKey = buildSearchCacheKey(["minimax", endpoint, query, resolvedCount]); |
| function missingMiniMaxKeyPayload() { | ||
| return { | ||
| error: "missing_minimax_api_key", | ||
| message: `web_search (minimax) needs a MiniMax API key. Run \`${formatCliCommand("openclaw configure --section web")}\` to store it, or set MINIMAX_API_KEY in the Gateway environment.`, |
There was a problem hiding this comment.
The missing-credential message only mentions MINIMAX_API_KEY, but this provider also supports MINIMAX_CODE_PLAN_KEY (and advertises both in envVars). Update the guidance so users can resolve auth using either env var (and/or point at the configured secret path, consistent with other providers).
| message: `web_search (minimax) needs a MiniMax API key. Run \`${formatCliCommand("openclaw configure --section web")}\` to store it, or set MINIMAX_API_KEY in the Gateway environment.`, | |
| message: `web_search (minimax) needs a MiniMax API key. Run \`${formatCliCommand( | |
| "openclaw configure --section web", | |
| )}\` to store it, or set MINIMAX_API_KEY or MINIMAX_CODE_PLAN_KEY in the Gateway environment.`, |
| : undefined; | ||
| return region === "cn" ? MINIMAX_SEARCH_ENDPOINT_CN : MINIMAX_SEARCH_ENDPOINT_GLOBAL; | ||
| } | ||
|
|
There was a problem hiding this comment.
This new provider introduces non-trivial logic (endpoint selection, response mapping, related-search extraction, caching). Other bundled web search providers typically include a small *.test.ts plus an exported __testing surface for deterministic unit tests. Add at least a couple of unit tests for endpoint resolution (Global vs CN) and for mapping/extracting results from a representative API response shape.
| export const __testing = { | |
| MINIMAX_SEARCH_ENDPOINT_GLOBAL, | |
| MINIMAX_SEARCH_ENDPOINT_CN, | |
| resolveMiniMaxEndpoint, | |
| runMiniMaxSearch, | |
| }; |
| kimi: "moonshot", | ||
| minimax: "minimax", | ||
| perplexity: "perplexity", |
There was a problem hiding this comment.
The bundled provider-id map now includes minimax, but the alignment test in src/plugins/bundled-web-search.test.ts doesn’t assert the minimax mapping. Add a corresponding expectation there so future edits don’t accidentally break this new compat id.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 68d9f3702c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| setConfiguredCredentialValue: (configTarget, value) => { | ||
| setProviderWebSearchPluginConfigValue(configTarget, "minimax", "apiKey", value); |
There was a problem hiding this comment.
Store MiniMax web key in a schema-valid config path
This writes the credential into plugins.entries.minimax.config.webSearch.apiKey, but the MiniMax plugin manifest currently defines configSchema as an empty object with additionalProperties: false (extensions/minimax/openclaw.plugin.json), so config.webSearch is invalid for that plugin. In practice, configuring MiniMax search via onboarding/configure will produce a plugin-schema validation error instead of persisting the key (unless users only rely on environment variables).
Useful? React with 👍 / 👎.
| const resolvedCount = resolveSearchCount(count, DEFAULT_SEARCH_COUNT); | ||
| const endpoint = resolveMiniMaxEndpoint(searchConfig); | ||
|
|
||
| const cacheKey = buildSearchCacheKey(["minimax", query, resolvedCount]); |
There was a problem hiding this comment.
Include endpoint/region in MiniMax search cache key
The cache key omits endpoint/region even though requests are routed to either global or CN endpoint based on searchConfig.minimax.region. If region changes (or different sessions in one process use different regions), cached results from one endpoint can be served for the other until TTL expiry, returning stale/wrong-region data. The key should include endpoint (or normalized region) to avoid cross-region cache collisions.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 674d4a8b86
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| typeof searchConfig?.minimax === "object" && | ||
| searchConfig.minimax !== null && | ||
| !Array.isArray(searchConfig.minimax) | ||
| ? (searchConfig.minimax as Record<string, unknown>).region | ||
| : undefined; |
There was a problem hiding this comment.
Derive MiniMax search endpoint from configured CN base URL
resolveMiniMaxEndpoint only reads tools.web.search.minimax.region, so MiniMax web search defaults to the global host unless that legacy field is manually set. In the normal CN onboarding path (applyMinimaxApiConfigCn in extensions/minimax/onboard.ts), only models.providers.minimax.baseUrl is set, and the new plugin schema here only persists webSearch.apiKey, not region; as a result, users who chose the CN provider can still have web_search sent to api.minimax.io and fail in CN-only/auth-scoped environments.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2aac848fef
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| "apiKey": { | ||
| "type": "string" |
There was a problem hiding this comment.
Accept SecretRef objects for MiniMax web search key
The new MiniMax plugin schema only allows webSearch.apiKey to be a string, but OpenClaw’s secret-ref flow stores credentials as objects (for example when secret-input-mode=ref is used). That means valid MiniMax web-search credential configs are rejected as invalid config at load/validation time, so users cannot persist MiniMax search credentials in SecretRef mode even though every other bundled web-search provider accepts "string" | "object" for this field.
Useful? React with 👍 / 👎.
| const minimaxProvider = providers?.minimax as Record<string, unknown> | undefined; | ||
| const baseUrl = typeof minimaxProvider?.baseUrl === "string" ? minimaxProvider.baseUrl : ""; |
There was a problem hiding this comment.
Infer MiniMax region from OAuth provider base URL too
Region inference only reads models.providers.minimax.baseUrl, so it misses CN OAuth setups where the configured base URL lives under models.providers.minimax-portal. In that common CN OAuth path, resolveMiniMaxRegion falls back to global, causing web search calls to target api.minimax.io instead of the CN endpoint unless users manually set tools.web.search.minimax.region.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 78a1c02904
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| label: "MiniMax Search", | ||
| hint: "Structured results via MiniMax Coding Plan search API", | ||
| credentialLabel: "MiniMax API key", | ||
| envVars: ["MINIMAX_API_KEY", "MINIMAX_CODE_PLAN_KEY"], |
There was a problem hiding this comment.
Prefer MINIMAX_CODE_PLAN_KEY before MINIMAX_API_KEY
Credential fallback checks envVars in declaration order, so this provider currently picks MINIMAX_API_KEY first when both variables are set. For MiniMax coding-plan endpoints, that can make web_search fail with auth errors even though a valid MINIMAX_CODE_PLAN_KEY is present; elsewhere in the repo MiniMax auth already prefers code-plan first (src/infra/provider-usage.auth.ts). Reordering to prioritize MINIMAX_CODE_PLAN_KEY (and keeping resolution order consistent) avoids selecting the wrong credential in mixed-key environments.
Useful? React with 👍 / 👎.
|
Hey maintainers! 👋 Just wanted to add some context — I'm a MiniMax user running OpenClaw with MiniMax M2.7 as my primary model. I've been using the Since MiniMax already has a simple search API ( I know the contributing guide recommends starting with a discussion for new features — apologies for skipping that. Happy to address any further feedback! |
c4242b8 to
e273a00
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e273a003c0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const relatedSearches = Array.isArray(data.related_searches) | ||
| ? data.related_searches | ||
| .map((r) => r.query) | ||
| .filter((q): q is string => typeof q === "string" && q.length > 0) |
There was a problem hiding this comment.
Wrap related search suggestions before returning
The provider marks the payload as externalContent.wrapped: true, but related_searches strings are copied through without wrapWebContent. If MiniMax returns attacker-controlled suggestion text, that unwrapped content is passed directly to the model despite the wrapped flag, weakening the prompt-injection guardrail used for other web-search text fields. Wrap each related-search string (or omit the field) before adding it to the tool result.
Useful? React with 👍 / 👎.
e273a00 to
7993795
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 79937951a0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| "properties": { | ||
| "apiKey": { | ||
| "type": ["string", "object"] | ||
| } |
There was a problem hiding this comment.
Persist MiniMax region override in schema-backed config
resolveMiniMaxRegion now checks tools.web.search.minimax.region, but this plugin schema only allows plugins.entries.minimax.config.webSearch.apiKey and does not provide any persisted region field. In validated configs, object-valued tools.web.search.<provider> entries are normalized away unless they are in the legacy provider map, so minimax.region cannot reliably survive load/validation. That makes the explicit CN/global override path effectively unusable when endpoint inference from base URL is wrong or unavailable.
Useful? React with 👍 / 👎.
7993795 to
dfb923f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dfb923fbda
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| { | ||
| get plugin() { | ||
| return minimaxPlugin; | ||
| }, | ||
| credentialValue: "sk-test", |
There was a problem hiding this comment.
Add MiniMax web-search secret target to registry
Registering MiniMax as a bundled web-search provider here adds a new credential path (plugins.entries.minimax.config.webSearch.apiKey), but that path is not added to src/secrets/target-registry-data.ts; as a result, secret-registry consumers in src/secrets/target-registry-query.ts (for discovery/known-target checks used by openclaw secret plan/configure/audit flows) will not recognize or process MiniMax web-search SecretRefs. This leaves the new provider’s configured key unmanaged by the standard secret tooling.
Useful? React with 👍 / 👎.
dfb923f to
4c92e15
Compare
|
Maintainer review: keep open, but I would not land this yet. A few blockers against current
Non-blocking note:
If you want to refresh this toward landing, I’d suggest:
|
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 openclaw#47927 Related openclaw#11399 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4c92e15 to
cbdf56a
Compare
|
Landed via temp rebase onto main.
Thanks @JithendraNara! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cbdf56aaff
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| readConfiguredSecretString(searchConfig?.apiKey, "tools.web.search.apiKey") ?? | ||
| readProviderEnvValue([...MINIMAX_CODING_PLAN_ENV_VARS, "MINIMAX_API_KEY"]) |
There was a problem hiding this comment.
Prefer scoped MiniMax key over legacy top-level apiKey
resolveMiniMaxApiKey reads searchConfig.apiKey first, which is the shared legacy tools.web.search.apiKey slot, before checking MiniMax env vars. If a user previously configured another provider that populated this legacy field (for example Brave) and later switches to MiniMax while relying on MINIMAX_CODE_PLAN_KEY/MINIMAX_CODING_API_KEY, the stale shared key wins and MiniMax requests are sent with the wrong credential, causing auth failures until the old top-level key is manually removed.
Useful? React with 👍 / 👎.
Summary
POST /v1/coding_plan/search).api.minimax.io) and CN (api.minimaxi.com) endpoints, inferred from explicit region config, model provider base URL, orminimax-portalOAuth base URL.MINIMAX_CODE_PLAN_KEYoverMINIMAX_API_KEYin credential fallback, matching existing repo precedence.SecretRefobjects forwebSearch.apiKey, matching all other bundled web search providers.Change Type
Scope
Linked Issues
User-visible / Behavior Changes
minimaxavailable astools.web.search.provideroptionMINIMAX_CODE_PLAN_KEYorMINIMAX_API_KEYis set (priority 15)openclaw configure --section weblists MiniMax as a search providerSecurity Impact
POST /v1/coding_plan/searchviawithTrustedWebSearchEndpoint()Verification
Manual API verification:
curl -X POST https://api.minimax.io/v1/coding_plan/searchreturns structured organic results.Human Verification
openclaw configure --section webUI, auto-detection with all providers active simultaneouslyCompatibility / Migration
Failure Recovery
tools.web.search.providerto another provider, or revert 9 changed filesRisks and Mitigations
AI-assisted (Claude Code). I understand what the code does.