!refactor(xai): move x_search config behind plugin boundary#59674
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 91f131571c
ℹ️ 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".
Greptile SummaryThis PR moves Confidence Score: 5/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/xai/x-search.ts
Line: 114-118
Comment:
**Dead code: unused variables after refactor**
`sourceXSearchConfig` and `runtimeXSearchConfig` are computed but never referenced in the return expression. The refactor removed the old `readConfiguredSecretString(runtimeXSearchConfig?.apiKey, …)` calls but left the variable assignments behind.
```suggestion
return (
resolveFallbackXaiApiKey(params.runtimeConfig) ??
resolveFallbackXaiApiKey(params.sourceConfig) ??
readLegacyXSearchApiKey(params.runtimeConfig) ??
readLegacyXSearchApiKey(params.sourceConfig) ??
readProviderEnvValue(["XAI_API_KEY"])
);
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: src/config/legacy-x-search.ts
Line: 82-85
Comment:
**Silent plugin auto-enable not surfaced in changes log**
When the xAI plugin entry did not previously have an `enabled` field, the migration unconditionally sets `entry.enabled = true` but never pushes a corresponding entry into `changes`. Users running `openclaw doctor --fix` with a legacy `tools.web.x_search` config will see the config moved, but will not be told that the xAI plugin was also auto-enabled. Consider adding a change line such as `"Enabled plugins.entries.xai (auto-enabled by x_search migration)."` when `!hadEnabled` so the side effect is visible in the doctor output.
How can I resolve this? If you propose a fix, please make it concise.Reviews (2): Last reviewed commit: "Merge branch 'main' into chore/x-search-..." | Re-trigger Greptile |
🔒 Aisle Security AnalysisWe found 1 potential security issue(s) in this PR:
1. 🟡 Legacy x_search migration can unintentionally enable xAI code_execution tool via shared API key and forced plugin enablement
Description
Because the xAI plugin registers multiple tools ( Impact:
Vulnerable code: const hadEnabled = entry.enabled !== undefined;
if (!hadEnabled) {
entry.enabled = true;
}
...
config.webSearch = { apiKey: auth };RecommendationAvoid implicitly broad-enabling the plugin or any higher-privilege tools during migration. Safer options:
if (!hadEnabled) {
entry.enabled = true;
}
const config = ensureRecord(entry, "config");
// Ensure legacy x_search migration does not also enable code_execution
if (!isRecord(config.codeExecution) || (config.codeExecution as any).enabled === undefined) {
config.codeExecution = { ...(isRecord(config.codeExecution) ? config.codeExecution : {}), enabled: false };
}
// Optionally set xSearch.enabled = true to scope intent
config.xSearch = { ...(isRecord(config.xSearch) ? config.xSearch : {}), enabled: true };
Analyzed PR: #59674 at commit Last updated on: 2026-04-02T13:39:47Z |
|
@greptileai review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5050e1713d
ℹ️ 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".
| }); | ||
| return value !== undefined; | ||
| }); | ||
| const searchEnabled = hasConfiguredSearchSurface && search?.enabled !== false; |
There was a problem hiding this comment.
Resolve x_search SecretRefs even when web search is disabled
x_search now reads plugins.entries.xai.config.webSearch.apiKey, but this function only resolves web-search credentials inside if (searchEnabled), and searchEnabled is forced false when tools.web.search.enabled is false. In that configuration, the xAI SecretRef is left unresolved in the runtime snapshot, and createXSearchTool later throws on that unresolved SecretRef (plugins.entries.xai.config.webSearch.apiKey) instead of running x_search; this regresses configs that intentionally disable tools.web.search while keeping x_search enabled via SecretRef-backed auth.
Useful? React with 👍 / 👎.
* refactor(xai): move x_search config behind plugin boundary * chore(changelog): note x_search config migration * fix(xai): include x_search migration helpers
…#59674) * refactor(xai): move x_search config behind plugin boundary * chore(changelog): note x_search config migration * fix(xai): include x_search migration helpers
…#59674) * refactor(xai): move x_search config behind plugin boundary * chore(changelog): note x_search config migration * fix(xai): include x_search migration helpers
…#59674) * refactor(xai): move x_search config behind plugin boundary * chore(changelog): note x_search config migration * fix(xai): include x_search migration helpers
…#59674) * refactor(xai): move x_search config behind plugin boundary * chore(changelog): note x_search config migration * fix(xai): include x_search migration helpers
…#59674) * refactor(xai): move x_search config behind plugin boundary * chore(changelog): note x_search config migration * fix(xai): include x_search migration helpers
Summary
x_searchsettings out of coretools.web.x_search.*and into plugin-ownedplugins.entries.xai.config.xSearch.*x_searchauth on shared xAI web-search auth (plugins.entries.xai.config.webSearch.apiKey/XAI_API_KEY), with legacytools.web.x_search.apiKeytreated as migration compatx_searchruntime secret/status plumbing and let generic plugin-owned web-search auth resolution carry the runtime pathWhat changed
xSearchconfig schema/ui hints inextensions/xai/openclaw.plugin.jsonextensions/xai/x-search.tsandextensions/xai/web-search.tsto read/write plugin-ownedxSearchconfigsrc/config/legacy-x-search.tsand doctor migration wiring fortools.web.x_search.*tools.web.x_search.apiKeyfrom core secret target/status handling and runtime-web-tools special casestools.web.searchis absentWhy
x_searchexecution was already plugin-owned, but config, secret activation, and secret-gateway UX still lived in core. This keeps recreating the same mixed boundary we just cleaned up forweb_fetch/Firecrawl. This PR makes the XAI plugin the real owner ofx_searchsettings while keeping a compat window for legacy config.Compatibility
plugins.entries.xai.config.xSearch.*x_searchisplugins.entries.xai.config.webSearch.apiKeytools.web.x_search.*is still loadable and migrated byopenclaw doctor --fixtools.web.x_search.apiKeyinto the plugin-owned path before resolution so old SecretRef-based configs keep working during the migration windowTesting
pnpm test -- src/secrets/runtime-web-tools.test.ts src/secrets/runtime.test.ts src/config/legacy-x-search.test.tspnpm test -- extensions/xai/x-search.test.ts extensions/xai/web-search.test.ts extensions/xai/x-search.live.test.ts src/config/legacy-x-search.test.ts src/commands/doctor-legacy-config.migrations.test.ts src/secrets/runtime.test.ts src/secrets/runtime-web-tools.test.ts src/flows/search-setup.test.ts src/config/plugin-auto-enable.test.ts src/cli/command-secret-targets.test.ts src/web-search/runtime.test.tspnpm tsgopnpm config:docs:gennode --import tsx scripts/generate-base-config-schema.ts --writepnpm buildAI-assisted. Fully tested on the touched surface.