From ab24e93573749d5551b1e85667e1ca2e5236c4a7 Mon Sep 17 00:00:00 2001 From: Joey Krug Date: Mon, 4 May 2026 00:00:01 -0400 Subject: [PATCH] fix(web-search): preserve runtime auto-detect fallback --- CHANGELOG.md | 1 + src/agents/tools/web-search.late-bind.test.ts | 10 +++++----- src/agents/tools/web-search.ts | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 836a56e8f50..440bebe5903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ Docs: https://docs.openclaw.ai - Agents/session status: keep semantic `session_status({ sessionKey: "current" })` on the live run session even before that run has a persisted session-store entry, instead of falling back to the sandbox policy key. Thanks @vincentkoc. - QA/Slack: resolve bundled official plugin public-surface package aliases during source-mode QA runs, so release Slack live validation can load `@openclaw/slack/api.js` without workspace symlinks. Thanks @vincentkoc. - Codex: pass the live run session key into app-server dynamic tools when sandbox policy uses a separate session key, so `session_status({ sessionKey: "current" })` reports the active run instead of the sandbox policy key. Thanks @vincentkoc. +- Web search: keep first-class assistant `web_search` auto-detect and configured runtime providers visible when active runtime metadata or the active plugin registry is incomplete. Fixes #77073. - Plugins/tools: mark manifest-optional sibling tools as optional even when they come from a shared non-optional factory, so cached/status/MCP metadata keeps opt-in tool policy accurate. Thanks @vincentkoc. - Matrix: keep `streaming.progress.toolProgress` scoped to progress draft mode, so partial and quiet Matrix previews do not lose tool progress unless `streaming.preview.toolProgress` is disabled. Thanks @vincentkoc. - Channels/streaming: keep `streaming.progress.toolProgress` scoped to progress draft mode, so disabling compact progress lines does not silence partial/block preview tool updates. Thanks @vincentkoc. diff --git a/src/agents/tools/web-search.late-bind.test.ts b/src/agents/tools/web-search.late-bind.test.ts index b5fc3fd3798..aa10fd94ecf 100644 --- a/src/agents/tools/web-search.late-bind.test.ts +++ b/src/agents/tools/web-search.late-bind.test.ts @@ -47,7 +47,7 @@ describe("web_search late-bound runtime fallback", () => { runtimeWebSearch: { selectedProvider: "brave", providerConfigured: "brave", - providerSource: "plugin", + providerSource: "configured", diagnostics: [], }, }); @@ -100,7 +100,7 @@ describe("web_search late-bound runtime fallback", () => { ); }); - it("does not prefer runtime providers when no provider id is selected anywhere", async () => { + it("keeps runtime provider discovery enabled when no provider id is selected anywhere", async () => { const { createWebSearchTool } = await import("./web-search.js"); const tool = createWebSearchTool({ config: {}, @@ -111,7 +111,7 @@ describe("web_search late-bound runtime fallback", () => { expect(mocks.resolveManifestContractOwnerPluginId).not.toHaveBeenCalled(); expect(mocks.runWebSearch).toHaveBeenCalledWith( - expect.objectContaining({ preferRuntimeProviders: false }), + expect.objectContaining({ preferRuntimeProviders: true }), ); }); @@ -138,7 +138,7 @@ describe("web_search late-bound runtime fallback", () => { search: { selectedProvider: "perplexity", providerConfigured: "perplexity", - providerSource: "plugin", + providerSource: "configured", diagnostics: [], }, }); @@ -149,7 +149,7 @@ describe("web_search late-bound runtime fallback", () => { runtimeWebSearch: { selectedProvider: "brave", providerConfigured: "brave", - providerSource: "plugin", + providerSource: "configured", diagnostics: [], }, }); diff --git a/src/agents/tools/web-search.ts b/src/agents/tools/web-search.ts index 4a948ca725a..a6f64ef7729 100644 --- a/src/agents/tools/web-search.ts +++ b/src/agents/tools/web-search.ts @@ -107,7 +107,7 @@ export function createWebSearchTool(options?: { : ""; const providerSelectionId = runtimeProviderId || configuredProviderId; const preferRuntimeProviders = - Boolean(providerSelectionId) && + !providerSelectionId || !resolveManifestContractOwnerPluginId({ contract: "webSearchProviders", value: providerSelectionId,