Skip to content

fix(onboard): write current web-search schema so the brave plugin install validates - #5318

Merged
cv merged 6 commits into
NVIDIA:mainfrom
zhiyanliu:fix/web-search-config-schema
Jun 13, 2026
Merged

fix(onboard): write current web-search schema so the brave plugin install validates#5318
cv merged 6 commits into
NVIDIA:mainfrom
zhiyanliu:fix/web-search-config-schema

Conversation

@zhiyanliu

@zhiyanliu zhiyanliu commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Enabling Brave Web Search at onboarding still aborts the sandbox image build at the OpenClaw plugin-install step. scripts/generate-openclaw-config.mts writes the legacy tools.web.search shape (inline apiKey), which OpenClaw 2026.5.x rejects — and because openclaw plugins install validates the existing config before installing, it exits non-zero while the brave plugin is not yet installed, aborting the build under set -eu before openclaw doctor --fix can migrate it. This PR emits the current schema directly so the build-time install validates cleanly.

Related Issue

Fixes #5266 (follow-up to #4955 / #3948)

Changes

  • scripts/generate-openclaw-config.mts: when NEMOCLAW_WEB_SEARCH_ENABLED=1, write tools.web.search = { enabled, provider: "brave" } and move the provider-owned apiKey placeholder to plugins.entries.brave.config.webSearch — the same shape doctor --fix produces after a successful install.
  • test/generate-openclaw-config.test.ts: update the existing web-search case to assert the current schema (no inline apiKey) and the plugins.entries.brave entry.

Why this is the fix

#4955 pinned/installed @openclaw/brave-plugin at build time and threaded BRAVE_API_KEY into the doctor env, assuming doctor --fix would migrate the legacy block. But plugins install runs config validation up front, so on the legacy shape it fails (exit 1) before the plugin exists — an ordering deadlock the migration step never gets to resolve.

Verified inside ghcr.io/nvidia/nemoclaw/sandbox-base:v0.0.55 (OpenClaw 2026.5.27):

legacy schema (inline apiKey)         → openclaw plugins install EXIT=1   # current behavior, breaks build
current schema (plugins.entries.brave) → openclaw plugins install EXIT=0  # this PR

End-to-end: a real nemoclaw onboard --recreate-sandbox with Brave Web Search and Slack both enabled now builds cleanly, and web_search works in the running sandbox alongside Slack.

Type of Change

  • Code change (feature, bug fix, or refactor)

Verification

  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • test/generate-openclaw-config.test.ts passes (128/128) — covers the changed code
  • npm run typecheck:cli passes; npx biome lint clean on changed files
  • Full npm test — relevant subset verified; the full local run had unrelated timeouts under heavy parallelism (spawn/docker suites), none in the changed files. Deferring to CI for the authoritative full run.

Signed-off-by: Zhi Yan Liu lzy.dev@gmail.com

Summary by CodeRabbit

  • Chores

    • Web-search config updated to the new OpenClaw schema: provider-only tools entry and Brave API key moved into plugin config; CI test-size budget adjusted.
  • Tests

    • Updated tests to assert the new schema and added coverage to accept legacy inline API-key placements.
  • Bug Fixes

    • Web-search verification now resolves and validates the Brave API key from both new plugin config and legacy inline locations.

…tall validates

Enabling Brave Web Search at onboarding still aborts the sandbox image
build at the OpenClaw plugin-install step. `generate-openclaw-config.mts`
writes the legacy `tools.web.search` shape with an inline `apiKey`, which
OpenClaw 2026.5.x rejects. `openclaw plugins install` validates the
existing config before installing, so it exits non-zero on the legacy
shape while the brave plugin is not yet installed — aborting the build
under `set -eu` before `openclaw doctor --fix` can migrate the schema.

Emit the current schema directly: `tools.web.search` carries only
`enabled` + `provider`, and the provider-owned apiKey placeholder moves
to `plugins.entries.brave.config.webSearch`. This is exactly what
`doctor --fix` produces after a successful install, so the build-time
install validates cleanly (exit 0), doctor completes, and web search
works alongside other channels (e.g. Slack) enabled in the same onboard.

Follow-up to #4955 / #3948. Update the existing generate-config test to
assert the current schema and the brave plugin entry.

Fixes #5266

Signed-off-by: Zhi Yan Liu <lzy.dev@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 104e87bd-6fb5-4b6c-bd26-eaa9a681a5e7

📥 Commits

Reviewing files that changed from the base of the PR and between b34484f and 93605c7.

📒 Files selected for processing (1)
  • src/lib/onboard/web-search-verify.ts

📝 Walkthrough

Walkthrough

Generator now emits provider-only tools.web.search and a Brave plugin entry with config.webSearch.apiKey resolved from BRAVE_API_KEY. Verifier reads the API key from the plugin entry with legacy fallback and uses the resolved key for the egress probe. Tests and CI budget updated accordingly.

Changes

Web Search Configuration Schema Migration

Layer / File(s) Summary
Config emission: provider-only tools.web.search and plugin entry
scripts/generate-openclaw-config.mts
buildConfig emits tools.web.search as { enabled, provider } and writes config.plugins.entries.brave.config.webSearch.apiKey resolved from BRAVE_API_KEY.
Verifier: resolve API key from plugin with legacy fallback
src/lib/onboard/web-search-verify.ts
verifyWebSearchInsideSandbox reads Brave API key from plugins.entries.<provider>.config.webSearch.apiKey with fallback to tools.web.search.apiKey, validates placeholders, and uses the resolved key in the egress curl probe.
Tests updated to new schema; CI budget tweak
test/generate-openclaw-config.test.ts, src/lib/onboard/web-search-verify.test.ts, ci/test-file-size-budget.json
Tests now assert provider-only tools.web.search, Brave plugin entry key at plugins.entries.brave.config.webSearch.apiKey, add a legacy-inline-key probe test, and adjust the test file size budget by -1.

Sequence Diagram

sequenceDiagram
  participant Generator as buildConfig
  participant OpenClawConfig as OpenClaw JSON
  participant Verifier as verifyWebSearchInsideSandbox
  participant Curl as egress probe (curl)

  Generator->>OpenClawConfig: write tools.web.search { enabled, provider: "brave" }
  Generator->>OpenClawConfig: write plugins.entries.brave.config.webSearch.apiKey (resolve BRAVE_API_KEY)
  Verifier->>OpenClawConfig: read plugins.entries.brave.config.webSearch.apiKey
  alt missing
    Verifier->>OpenClawConfig: fallback read tools.web.search.apiKey
  end
  Verifier->>Curl: run probe using resolved apiKey
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

  • NVIDIA/NemoClaw#4955 — Related adjustments to Brave web-search onboarding and how BRAVE_API_KEY is handled and preserved across tooling flows.

Suggested reviewers

  • prekshivyas

Poem

🐇 I hop and push the config through,

Keys tucked in plugins, neat and new,
The verifier sniffs both old and right,
Tests give a hop at morning light,
A tiny rabbit cheers the view.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating the web-search configuration schema so the Brave plugin install validates during the onboard process.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/generate-openclaw-config.test.ts (1)

799-819: ⚠️ Potential issue | 🟠 Major | ⚖️ Poor tradeoff

Test file size exceeds legacy budget (policy violation).

The test file has grown to 1998 lines, exceeding its legacy budget of 1990 lines. This is flagged as a policy failure in CI. While the added assertions are necessary to validate the new schema correctly, the test file is already at capacity.

Consider one of these remediation options:

  1. Extract some unrelated test cases into a separate test file to bring this file back under budget
  2. Request an exception to increase the budget for this file, given the critical nature of web-search configuration validation
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/generate-openclaw-config.test.ts` around lines 799 - 819, The test file
test/generate-openclaw-config.test.ts exceeded the legacy size budget after
adding assertions to the "enables web search when env is '1' using the current
plugin schema" test (the block using runConfigScript and assertions on
config.tools/web and config.plugins.entries.brave). Fix by splitting this file:
move unrelated or older test cases out of generate-openclaw-config.test.ts into
a new test file (keeping the new web-search test intact) and update any shared
imports/fixtures so runConfigScript remains available; alternatively, if
splitting is not desired, open a request to increase the file budget for
generate-openclaw-config.test.ts so CI policy accepts the added assertions.
Ensure the new file preserves the test suite structure and that the web-search
test continues to assert config.tools?.web?.search,
config.plugins?.entries?.brave, and related expectations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/generate-openclaw-config.mts`:
- Around line 959-973: Update src/lib/onboard/web-search-verify.ts so the Brave
egress verifier looks up the apiKey from the new plugin config location as well
as the legacy inline location: check parsed.tools.web.search.apiKey (legacy) and
parsed.config?.plugins?.entries?.[provider]?.config?.webSearch?.apiKey (new
schema) where provider comes from parsed.tools.web.search.provider, and preserve
the existing validation that the apiKey is an openshell:resolve:env:*
placeholder; then update src/lib/onboard/web-search-verify.test.ts to build
fixtures using the new shape
(config.plugins.entries.brave.config.webSearch.apiKey) in tests and add a test
that verifies backward compatibility when tools.web.search.apiKey is present.

---

Outside diff comments:
In `@test/generate-openclaw-config.test.ts`:
- Around line 799-819: The test file test/generate-openclaw-config.test.ts
exceeded the legacy size budget after adding assertions to the "enables web
search when env is '1' using the current plugin schema" test (the block using
runConfigScript and assertions on config.tools/web and
config.plugins.entries.brave). Fix by splitting this file: move unrelated or
older test cases out of generate-openclaw-config.test.ts into a new test file
(keeping the new web-search test intact) and update any shared imports/fixtures
so runConfigScript remains available; alternatively, if splitting is not
desired, open a request to increase the file budget for
generate-openclaw-config.test.ts so CI policy accepts the added assertions.
Ensure the new file preserves the test suite structure and that the web-search
test continues to assert config.tools?.web?.search,
config.plugins?.entries?.brave, and related expectations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 78ca62dc-9a0f-43ae-9c0c-3af63396a48c

📥 Commits

Reviewing files that changed from the base of the PR and between b3500bf and ef5cf61.

📒 Files selected for processing (2)
  • scripts/generate-openclaw-config.mts
  • test/generate-openclaw-config.test.ts

Comment thread scripts/generate-openclaw-config.mts
…g in the egress verifier

Address CodeRabbit review on #5318:

- web-search-verify.ts read the apiKey only from the legacy inline
  tools.web.search.apiKey location, so with the current plugin schema it
  warned "no API key placeholder" and silently skipped the Brave egress
  probe. Resolve the placeholder from
  plugins.entries.<provider>.config.webSearch.apiKey first and fall back
  to the legacy inline field so both schema generations stay probed.
- Add a verifier test for the plugin-config location and keep a legacy
  inline-apiKey test for backward compatibility.
- Tighten the new web-search assertions in
  test/generate-openclaw-config.test.ts (toEqual is already exact, so
  the separate apiKey-undefined assertion was redundant) to bring the
  file back under its legacy size budget, and ratchet the budget down
  to the new line count as the checker requires.

Signed-off-by: Zhi Yan Liu <lzy.dev@gmail.com>
@zhiyanliu

Copy link
Copy Markdown
Contributor Author

Addressed both CodeRabbit findings in 351beed:

  • Verifier schema mismatch: web-search-verify.ts now resolves the apiKey placeholder from plugins.entries.<provider>.config.webSearch.apiKey (current schema) with fallback to the legacy inline tools.web.search.apiKey, so the Brave egress probe runs for both schema generations instead of silently skipping. Added a plugin-config fixture test plus a legacy-compat test.
  • Test file size budget: tightened the new assertions (the toEqual exact match already covers the no-inline-apiKey case) bringing test/generate-openclaw-config.test.ts to 1989 lines, and ratcheted the legacy budget entry down to 1989 as the checker requires.

Verified locally: budget check passes, web-search-verify.test.ts 8/8, generate-openclaw-config.test.ts 128/128, typecheck:cli clean.

@wscurran wscurran added area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression integration: brave Brave integration behavior labels Jun 12, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for updating the generate-openclaw-config script to emit the current web-search schema with the Brave provider config. This proposes a way to write the provider-owned apiKey placeholder to plugins.entries.brave.config.webSearch so the build-time plugin install validates cleanly.


Related open PRs:


Related open issues:

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 27458771824
Target ref: 93605c7c4ce2c22ee5a74a1dcc7045ce42dace5a
Workflow ref: main
Requested jobs: brave-search-e2e
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
brave-search-e2e ✅ success

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is green on the current head. I verified the CodeRabbit web-search schema and file-size findings were addressed: the verifier supports the plugin config apiKey path with legacy fallback, generate-openclaw-config stays within the ratcheted budget, and the targeted brave-search-e2e run 27458771824 passed for head 93605c7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression integration: brave Brave integration behavior

Projects

None yet

3 participants