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.
Reuse the startup runtime plugin registry across provider/tool helper paths while preserving standalone CLI/MCP fallback loading.
Includes follow-up fixes for migration/provider/tool registry bootstrap and regression coverage for compatible registry reuse.
Co-authored-by: DmitryPogodaev <pogodaev.dm@gmail.com>