fix(web-search): keep first-class web_search runtime providers visible#77074
fix(web-search): keep first-class web_search runtime providers visible#77074steipete merged 3 commits intoopenclaw:mainfrom
Conversation
|
Codex review: needs maintainer review before merge. Summary Reproducibility: yes. at source level: current main can drop captured runtime metadata in late-bound web_search and can treat an empty active runtime registry as authoritative. I did not establish a live Gateway reproduction in this read-only pass. Next step before merge Security Review detailsBest possible solution: Land this narrow source/test/changelog fix after normal maintainer validation so first-class web_search can use configured runtime providers in late-bound agent contexts. Do we have a high-confidence way to reproduce the issue? Yes, at source level: current main can drop captured runtime metadata in late-bound web_search and can treat an empty active runtime registry as authoritative. I did not establish a live Gateway reproduction in this read-only pass. Is this the best way to solve the issue? Yes. The PR keeps active runtime state precedence, adds captured runtime/config fallback, and falls through only from empty active registries while preserving explicit empty scopes. What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against dadf0005ec3a. Re-review progress:
|
df83c20 to
961adda
Compare
8850f56 to
b37c319
Compare
When createWebSearchTool is wired with lateBindRuntimeConfig: true, the first-class assistant tool now lives off whatever runtime is active at execute time. That works in the gateway process where runtime metadata and the active secrets snapshot are populated, but in agent contexts that do not share that in-process state, both fall through to undefined and the tool returned "web_search is disabled or no provider is available" even though `openclaw capability web search` and direct provider runtime execution succeeded. Two fixes: - src/agents/tools/web-search.ts: when late-binding, fall back to options.runtimeWebSearch when the active runtime web tools metadata is null, and fall back to options.config when getActiveSecretsRuntimeSnapshot is null. Derive a configured provider id from config.tools.web.search.provider and use it together with the runtime selection when deciding preferRuntimeProviders, so an explicit Brave/ Perplexity selection still discovers the configured plugin even when no runtime provider id is bound. - src/plugins/web-provider-runtime-shared.ts: the active gateway plugin registry may be otherwise compatible with the active config while contributing zero web providers (channels, memory, harnesses, and sidecars without Brave/web). Treating that empty active registry as authoritative meant first-class tools resolved to "no provider". Fall through to the scoped provider plugin load when the active registry returns no providers. Explicit `onlyPluginIds: []` still short-circuits to [] to preserve the empty-scope contract. Adds regression tests for both seams.
b37c319 to
d0cdd05
Compare
This comment was marked as low quality.
This comment was marked as low quality.
|
Landed via GitHub rebase merge onto main.
Thanks @joeykrug! |
Summary
Fixes #77073 — first-class assistant
web_searchreportedweb_search is disabled or no provider is availableeven whenopenclaw capability web searchand direct runtime provider execution succeeded against the same configured Brave plugin.Two source-only fixes:
src/agents/tools/web-search.ts— whenlateBindRuntimeConfig: true:runtimeWebSearchfalls back tooptions?.runtimeWebSearchwhengetActiveRuntimeWebToolsMetadata()?.searchisnull(in agent contexts that do not share the gateway in-process runtime snapshot).configfalls back tooptions?.configwhengetActiveSecretsRuntimeSnapshot()isnull.configuredProviderIdfromconfig.tools.web.search.providerand usesruntimeProviderId || configuredProviderIdto decidepreferRuntimeProviders, so an explicit Brave/Perplexity selection still routes through runtime provider discovery when the runtime metadata is unbound.src/plugins/web-provider-runtime-shared.ts— whengetLoadedRuntimePluginRegistry(...)returns a registry that maps to zero web providers, fall through to a scoped plugin load instead of treating that empty active registry as authoritative. ExplicitonlyPluginIds: []still short-circuits to[]to preserve the empty-scope contract for bothresolvePluginWebProvidersandresolveRuntimeWebProviders.Why
The active gateway plugin registry is intentionally scoped to channels, memory, harnesses, and sidecars on startup. It can be otherwise compatible with the active OpenClaw config while contributing zero web-provider entries (e.g. when Brave/web providers live in a separately-loaded plugin set). Without a fall-through, the assistant's first-class
web_searchtool sees that empty active result as authoritative and reports "no provider available" — even thoughopenclaw capability web searchand the direct runtime path use a scoped load and find the configured provider just fine.Late-binding compounded the problem: in agent contexts where the active-runtime/active-secrets globals are not set, the late-bound execute lambda lost both
runtimeWebSearchandconfig, leavingpreferRuntimeProvidersunable to route to the configured plugin.Test plan
node scripts/run-vitest.mjs run --config test/vitest/vitest.plugins.config.ts src/plugins/web-provider-runtime-shared.test.ts— 13 / 13 passed (4 new fall-through cases added).node scripts/run-vitest.mjs run --config test/vitest/vitest.agents-tools.config.ts src/agents/tools/web-search.late-bind.test.ts— 6 / 6 passed (new file, covers both??fallbacks, configured-provider routing, no-selection guard, bundled manifest owner precedence, and active-runtime priority).web-search.test.tsandweb-search.signal.test.tsto confirm no regression.pnpm exec oxfmt --check --threads=1on the four touched files — clean.Notes
plugins/web-provider*test files were observed identically with and without this branch (manifest-registry mock and source-checkout-runtime fixture issues). They are not affected by this change.🤖 Generated with Claude Code