feat(onboard): extend web search onboarding to Gemini and Tavily - #2721
feat(onboard): extend web search onboarding to Gemini and Tavily#2721jyaunches wants to merge 3 commits into
Conversation
📝 WalkthroughWalkthroughAdds provider-aware web-search support (Brave, Gemini, Tavily): provider model/metadata, onboarding/provider selection and validation, session persistence of provider choice, provider-specific OpenClaw/Docker config generation, two policy presets, and corresponding tests and Docker ARG/ENV export. Changes
Sequence DiagramsequenceDiagram
actor User
participant Onboard as Onboard
participant Provider as ProviderValidator
participant Config as ConfigGenerator
participant Docker as DockerBuild
participant Session as SessionStore
User->>Onboard: run "nemoclaw onboard" (or set NEMOCLAW_WEB_SEARCH_PROVIDER)
Onboard->>User: prompt provider / read env
User->>Onboard: select provider + provide API key (or skip)
Onboard->>Provider: validate API key for provider
Provider-->>Onboard: validation result
Onboard->>Config: build OpenClaw fragment (plugin entry, cred env ref, model)
Config-->>Onboard: config fragment
Onboard->>Docker: pass NEMOCLAW_WEB_SEARCH_PROVIDER arg + encoded config
Docker-->>Onboard: image with ENV injected
Onboard->>Session: persist webSearchConfig { provider, fetchEnabled }
Session-->>Onboard: saved
Onboard-->>User: onboarding complete
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Review rate limit: 8/10 reviews remaining, refill in 7 minutes and 55 seconds. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib/onboard.ts (1)
7833-7835:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winResume output still says “Brave Search” for every provider.
Gemini/Tavily rebuilds will log the wrong provider here, which makes resume/debug output misleading.
Suggested fix
if (webSearchConfig) { - note(" [resume] Reusing Brave Search configuration already baked into the sandbox."); + const meta = webSearch.getWebSearchProvider(webSearchConfig.provider); + note(` [resume] Reusing ${meta.label} configuration already baked into the sandbox.`); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard.ts` around lines 7833 - 7835, The resume message currently hardcodes "Brave Search" which mislabels other providers; update the note call to derive the provider name from the webSearchConfig object (e.g., webSearchConfig.provider or webSearchConfig.name) instead of the literal string, and fall back to a generic label like "web search" if that field is missing; modify the note invocation where webSearchConfig is checked so it logs the actual provider value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/onboard.ts`:
- Around line 1571-1584: The validateWebSearchApiKey function currently only
checks for emptiness for non-Brave providers; update the non-Brave branch
(inside validateWebSearchApiKey) to perform format-only validation for "gemini"
and "tavily" instead of accepting any non-empty string: add provider-specific
simple regex/format checks (e.g., a known prefix/character set or length
constraints) for "gemini" and "tavily", return { ok: false, message: "<clear
format error>" } on mismatch, and fall back to { ok: true } only when the key
matches the expected format; keep validateBraveSearchApiKey usage for provider
=== "brave".
- Around line 5893-5896: computeSetupPresetSuggestions() still hardcodes
add("brave"), causing the Brave policy preset to be applied even when a
different web-search provider is chosen; update computeSetupPresetSuggestions()
to be provider-aware by reading the selected web-search provider (use
webSearch.getWebSearchProvider(...) / wsMeta.policyPreset or the same source
used where you push wsMeta.policyPreset) and push that provider's policy preset
instead of add("brave"), so the suggestions array consistently uses
wsMeta.policyPreset when a webSearchConfig exists.
---
Outside diff comments:
In `@src/lib/onboard.ts`:
- Around line 7833-7835: The resume message currently hardcodes "Brave Search"
which mislabels other providers; update the note call to derive the provider
name from the webSearchConfig object (e.g., webSearchConfig.provider or
webSearchConfig.name) instead of the literal string, and fall back to a generic
label like "web search" if that field is missing; modify the note invocation
where webSearchConfig is checked so it logs the actual provider value.
🪄 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: 4924c413-3c97-45fb-9eee-8e8fd7a765b9
📒 Files selected for processing (11)
Dockerfilenemoclaw-blueprint/policies/presets/gemini.yamlnemoclaw-blueprint/policies/presets/tavily.yamlscripts/generate-openclaw-config.pysrc/lib/onboard-session.test.tssrc/lib/onboard-session.tssrc/lib/onboard.tssrc/lib/web-search.test.tssrc/lib/web-search.tstest/onboard-brave-validation.test.tstest/policies.test.ts
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
src/lib/onboard.ts (1)
1659-1711: Please run the onboarding E2E matrix for this path.These changes touch provider selection, credential handling, sandbox creation, and policy suggestion inside
src/lib/onboard.ts, socloud-e2e,sandbox-operations-e2e, andrebuild-openclaw-e2eare the best regression check before merge.As per coding guidelines,
src/lib/onboard.ts: "This file contains core onboarding logic. Changes here affect the full sandbox creation and configuration flow."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard.ts` around lines 1659 - 1711, Run the onboarding end-to-end regression matrix covering cloud-e2e, sandbox-operations-e2e, and rebuild-openclaw-e2e because this diff changes web search provider selection, credential handling, sandbox creation, and policy suggestion in src/lib/onboard.ts; specifically exercise both non-interactive and interactive flows that touch agentSupportsWebSearch, resolveNonInteractiveWebSearchProvider(), webSearch.getWebSearchProvider(), getCredential/normalizeCredentialValue/saveCredential, validateWebSearchApiKey/ensureValidatedWebSearchCredential, and promptWebSearchProviderSelection to confirm API key validation, environment variable propagation (process.env[meta.credentialEnv]), credential persistence, and that sandbox creation and policy suggestion behave correctly after enabling/disabling web-search.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/onboard.ts`:
- Around line 1647-1652: The recovery prompt currently calls
promptBraveSearchRecovery(...) which hardcodes "Brave Search" in the interactive
retry flow; replace that call with a provider-agnostic recovery prompt (e.g.,
promptProviderRecovery or promptGenericRecovery) that accepts the validation and
the provider label (use meta.label or a providerIdentifier passed into this
scope) and update the implementation of promptBraveSearchRecovery (or create a
new promptProviderRecovery) to use the provided label instead of "Brave Search"
so Gemini/Tavily failures display the correct provider name; ensure you update
the call site here (where action is assigned) to pass the provider label and
keep the same return semantics ("skip" handling).
- Around line 1934-1939: The staged Dockerfile replacement for
NEMOCLAW_WEB_SEARCH_PROVIDER can be a silent no-op if the Dockerfile lacks that
ARG, causing a mismatch between the selected provider and the built image;
update the onboarding logic in src/lib/onboard.ts so that when webSearchConfig
is set you verify the Dockerfile contains the provider ARG (match /^ARG
NEMOCLAW_WEB_SEARCH_PROVIDER=.*$/m) and throw a clear error if it is missing (or
alternatively tighten agentSupportsWebSearch() to require the provider ARG),
ensuring the code path that performs the replace on the dockerfile variable
fails fast when the ARG is absent.
- Around line 1520-1530: resolveNonInteractiveWebSearchProvider currently warns
then silently falls back to "brave" when webSearch.parseWebSearchProvider
returns falsy; instead fail fast to avoid accidentally using BRAVE_API_KEY.
Update resolveNonInteractiveWebSearchProvider (and keep use of
webSearch.WEB_SEARCH_PROVIDER_ENV and webSearch.parseWebSearchProvider) to throw
a clear Error when envValue is present but parseWebSearchProvider(envValue)
returns falsy — include the invalid value and acceptable provider names in the
message — OR, if you prefer disabling over throwing, return an explicit
"disabled" sentinel instead of "brave" so callers won't construct a Brave
backend silently.
---
Nitpick comments:
In `@src/lib/onboard.ts`:
- Around line 1659-1711: Run the onboarding end-to-end regression matrix
covering cloud-e2e, sandbox-operations-e2e, and rebuild-openclaw-e2e because
this diff changes web search provider selection, credential handling, sandbox
creation, and policy suggestion in src/lib/onboard.ts; specifically exercise
both non-interactive and interactive flows that touch agentSupportsWebSearch,
resolveNonInteractiveWebSearchProvider(), webSearch.getWebSearchProvider(),
getCredential/normalizeCredentialValue/saveCredential,
validateWebSearchApiKey/ensureValidatedWebSearchCredential, and
promptWebSearchProviderSelection to confirm API key validation, environment
variable propagation (process.env[meta.credentialEnv]), credential persistence,
and that sandbox creation and policy suggestion behave correctly after
enabling/disabling web-search.
🪄 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: d75d3c95-89a0-471a-a6d6-9a3b7af343c2
📒 Files selected for processing (1)
src/lib/onboard.ts
ebff645 to
9324355
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
Dockerfile (1)
283-309: Run the Dockerfile E2E matrix before merge to validate container-layer behavior.Given this is a Dockerfile config-path change, I recommend running
cloud-e2e,sandbox-survival-e2e,hermes-e2e, andrebuild-openclaw-e2eon this branch.As per coding guidelines, "This file affects the sandbox container image. Layer ordering, permissions, and baked config changes are only testable with a real container build."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Dockerfile` around lines 283 - 309, This change touches the Dockerfile ENV block (e.g., NEMOCLAW_WEB_SEARCH_PROVIDER and the promoted ENV variables) which affects the sandbox image and must be validated by container builds; run the full Dockerfile E2E matrix on this branch—at minimum execute cloud-e2e, sandbox-survival-e2e, hermes-e2e, and rebuild-openclaw-e2e—to confirm layer ordering, permissions, and baked config behavior before merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/onboard.ts`:
- Around line 7722-7725: When resuming, the code currently unconditionally
restores session.webSearchConfig into webSearchConfig, which causes an explicit
web-search provider override (e.g., NEMOCLAW_WEB_SEARCH_PROVIDER or the
CLI/webSearchProvider param) to be ignored; modify the resume logic around
webSearchConfig and the later revalidation to detect an explicit override and
treat mismatches as a resume conflict: if an override value exists and
session.webSearchConfig?.provider is present and differs, throw/return the same
conflict error used for model/provider mismatches (mirror the existing
resume-check behavior), otherwise proceed to use the override or session value
as appropriate; update both places where webSearchConfig is restored/revalidated
(the webSearchConfig initialization and the later revalidation block) to apply
this same check.
- Around line 1958-1972: The code only rewrites ARG NEMOCLAW_WEB_SEARCH_PROVIDER
for non-Brave providers; change it to always patch the ARG whenever
webSearchConfig is present so a Dockerfile that defaults to a non-Brave provider
doesn't remain stale when Brave is selected. In the block referencing
webSearchConfig and dockerfile, remove the provider !== "brave" guard, ensure
you check that the Dockerfile declares ARG NEMOCLAW_WEB_SEARCH_PROVIDER with
/^\s*ARG\s+NEMOCLAW_WEB_SEARCH_PROVIDER=/m, throw the same error if missing, and
replace the line with `ARG
NEMOCLAW_WEB_SEARCH_PROVIDER=${webSearchConfig.provider ?? "brave"}` (use
webSearchConfig.provider or "brave" as fallback) so the ARG is always updated
when webSearchConfig is set.
---
Nitpick comments:
In `@Dockerfile`:
- Around line 283-309: This change touches the Dockerfile ENV block (e.g.,
NEMOCLAW_WEB_SEARCH_PROVIDER and the promoted ENV variables) which affects the
sandbox image and must be validated by container builds; run the full Dockerfile
E2E matrix on this branch—at minimum execute cloud-e2e, sandbox-survival-e2e,
hermes-e2e, and rebuild-openclaw-e2e—to confirm layer ordering, permissions, and
baked config behavior before merging.
🪄 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: 49c26ffc-b9ca-4b7a-9296-778a4fd6a64e
📒 Files selected for processing (12)
Dockerfilenemoclaw-blueprint/policies/presets/gemini.yamlnemoclaw-blueprint/policies/presets/tavily.yamlscripts/generate-openclaw-config.pysrc/lib/onboard-session.test.tssrc/lib/onboard-session.tssrc/lib/onboard.tssrc/lib/web-search.test.tssrc/lib/web-search.tstest/onboard-brave-validation.test.tstest/onboard.test.tstest/policies.test.ts
✅ Files skipped from review due to trivial changes (4)
- test/onboard-brave-validation.test.ts
- nemoclaw-blueprint/policies/presets/gemini.yaml
- test/policies.test.ts
- test/onboard.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/lib/onboard-session.test.ts
- nemoclaw-blueprint/policies/presets/tavily.yaml
- scripts/generate-openclaw-config.py
- src/lib/onboard-session.ts
…DIA#2718) Extend the web search onboarding flow from Brave-only to support Brave, Gemini, and Tavily as selectable providers. Changes: - Expand src/lib/web-search.ts with provider registry, types, config fragment builder, and Docker arg encoder - Add NEMOCLAW_WEB_SEARCH_PROVIDER build-arg to Dockerfile and ENV promotion block - Update scripts/generate-openclaw-config.py to generate provider-aware config (plugin entry, credential env, Gemini model) - Refactor configureWebSearch() in onboard.ts to present provider selection prompt (interactive) or read NEMOCLAW_WEB_SEARCH_PROVIDER env (non-interactive) - Update credential injection, policy preset suggestion, and config summary to be provider-aware - Add gemini.yaml and tavily.yaml policy presets - Update onboard-session.ts to persist PersistedWebSearchConfig with provider field (backward-compat: missing provider defaults to brave) - Update tests: web-search.test.ts (36 new tests), policies.test.ts, onboard-session.test.ts, onboard-brave-validation.test.ts Closes NVIDIA#2718 Prior art: PR NVIDIA#1497 (closed)
- Add minimum length validation for Gemini/Tavily API keys (reject < 10 chars) - Non-interactive path now checks saved credentials (getCredential) before falling back to process.env, matching interactive behavior - Fix computeSetupPresetSuggestions() to use provider-aware policy preset instead of hardcoded 'brave'
- Fail fast on invalid NEMOCLAW_WEB_SEARCH_PROVIDER instead of silently defaulting to brave (throws Error with valid values) - Add provider-agnostic promptWebSearchRecovery() that shows the correct provider label instead of hardcoded 'Brave Search' - Fail fast when Dockerfile lacks ARG NEMOCLAW_WEB_SEARCH_PROVIDER for non-Brave providers (prevents silent config divergence) - Fix resume output to show correct provider label instead of 'Brave Search' - Update onboard.test.ts Dockerfile patching test to use new WebSearchConfig format with provider field
9324355 to
85680b4
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/onboard.ts (1)
7886-8591: Please run the onboarding E2Es for this path before merge.These changes touch provider selection, sandbox recreate/reuse, and policy application in the core onboarding flow, so I’d run the recommended
cloud-e2e,sandbox-operations-e2e, andrebuild-openclaw-e2ejobs on this branch before landing it.As per coding guidelines
src/lib/onboard.ts: "This file contains core onboarding logic. Changes here affect the full sandbox creation and configuration flow. E2E test recommendation:cloud-e2e— full onboard + cloud inference;sandbox-operations-e2e— multi-sandbox lifecycle;rebuild-openclaw-e2e— workspace state survives rebuild."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard.ts` around lines 7886 - 8591, The change touches core onboarding flow (function onboard) affecting provider selection (setupNim/setupInference), sandbox recreate/reuse logic (getSandboxReuseState/createSandbox/registry.updateSandbox), and policy application (setupPoliciesWithSelection/arePolicyPresetsApplied), so before merging run the E2E suites: cloud-e2e, sandbox-operations-e2e, and rebuild-openclaw-e2e on this branch; verify resume vs fresh flows, --from Dockerfile + non-interactive name guards, gateway reuse/recreate paths, webSearchConfig changes, messaging channel selection, migration of staged legacy credentials, and that policy presets are applied/recorded and survive sandbox rebuilds.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/lib/onboard.ts`:
- Around line 7886-8591: The change touches core onboarding flow (function
onboard) affecting provider selection (setupNim/setupInference), sandbox
recreate/reuse logic
(getSandboxReuseState/createSandbox/registry.updateSandbox), and policy
application (setupPoliciesWithSelection/arePolicyPresetsApplied), so before
merging run the E2E suites: cloud-e2e, sandbox-operations-e2e, and
rebuild-openclaw-e2e on this branch; verify resume vs fresh flows, --from
Dockerfile + non-interactive name guards, gateway reuse/recreate paths,
webSearchConfig changes, messaging channel selection, migration of staged legacy
credentials, and that policy presets are applied/recorded and survive sandbox
rebuilds.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 2197f8d6-b037-4ca3-9b4c-f3d922c260ed
📒 Files selected for processing (12)
Dockerfilenemoclaw-blueprint/policies/presets/gemini.yamlnemoclaw-blueprint/policies/presets/tavily.yamlscripts/generate-openclaw-config.pysrc/lib/onboard-session.test.tssrc/lib/onboard-session.tssrc/lib/onboard.tssrc/lib/web-search.test.tssrc/lib/web-search.tstest/onboard-brave-validation.test.tstest/onboard.test.tstest/policies.test.ts
✅ Files skipped from review due to trivial changes (4)
- test/policies.test.ts
- nemoclaw-blueprint/policies/presets/gemini.yaml
- src/lib/onboard-session.test.ts
- nemoclaw-blueprint/policies/presets/tavily.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
- test/onboard-brave-validation.test.ts
- scripts/generate-openclaw-config.py
Summary
Extend the web search onboarding flow from Brave-only to support Brave, Gemini, and Tavily as selectable providers during
nemoclaw onboard.Linked Issues
Changes
Provider Model (
src/lib/web-search.ts)WebSearchProvidertype:"brave" | "gemini" | "tavily"buildWebSearchConfigFragment()— generates provider-appropriate OpenClaw confignormalizePersistedWebSearchConfig()— handles backward compat (missing provider defaults to brave)Config Generation (
scripts/generate-openclaw-config.py,Dockerfile)NEMOCLAW_WEB_SEARCH_PROVIDERbuild-arg + env (default:brave)Onboarding Flow (
src/lib/onboard.ts)NEMOCLAW_WEB_SEARCH_PROVIDERenv varSession & Resume (
src/lib/onboard-session.ts)webSearchConfignow persistsproviderfieldPolicy Presets
nemoclaw-blueprint/policies/presets/gemini.yamlnemoclaw-blueprint/policies/presets/tavily.yamlValidation
Type of Change
Risks / Notes
ensureValidatedBraveSearchCredentialfunction is preserved (exported) for backward compat but is no longer in the main onboard flow.Summary by CodeRabbit
New Features
Bug Fixes / Improvements
Tests