From ab26781b139f360220fbdb71cbbf040e61ea3f30 Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Sun, 15 Mar 2026 14:58:11 -0500 Subject: [PATCH] fix: reopen configured search provider setup --- src/commands/onboard-search.test.ts | 89 ++++++++++++++++++++++++++++- src/commands/onboard-search.ts | 2 +- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/commands/onboard-search.test.ts b/src/commands/onboard-search.test.ts index c42da7639c9..1c0be9a48e5 100644 --- a/src/commands/onboard-search.test.ts +++ b/src/commands/onboard-search.test.ts @@ -31,7 +31,7 @@ vi.mock("./onboarding/plugin-install.js", () => ({ reloadOnboardingPluginRegistry, })); -import { setupSearch } from "./onboard-search.js"; +import { configureSearchProviderSelection, setupSearch } from "./onboard-search.js"; const runtime: RuntimeEnv = { log: vi.fn(), @@ -552,6 +552,93 @@ describe("setupSearch", () => { ); }); + it("reopens config when selecting an already configured provider in configure flow", async () => { + loadOpenClawPlugins.mockReturnValue({ + searchProviders: [ + { + pluginId: "tavily-search", + provider: { + id: "tavily", + name: "Tavily Search", + description: "Search the web using Tavily.", + setup: { + install: { + npmSpec: "@openclaw/tavily-search", + }, + }, + search: async () => ({ content: "ok" }), + }, + }, + ], + plugins: [ + { + id: "tavily-search", + name: "Tavily Search", + description: "Search the web using Tavily.", + origin: "bundled", + source: "/tmp/bundled/tavily-search", + configJsonSchema: { + type: "object", + required: ["apiKey"], + properties: { + apiKey: { type: "string", minLength: 1 }, + }, + }, + configUiHints: { + apiKey: { + label: "Tavily API key", + sensitive: true, + placeholder: "tvly-...", + }, + }, + }, + ], + typedHooks: [], + }); + + const cfg: OpenClawConfig = { + tools: { + web: { + search: { + provider: "tavily", + enabled: true, + }, + }, + }, + plugins: { + entries: { + "tavily-search": { + config: { + apiKey: "tvly-old", + }, + }, + }, + }, + }; + const { prompter } = createPrompter({ textValue: "tvly-new" }); + + const result = await configureSearchProviderSelection( + cfg, + "tavily", + prompter, + "configure-provider", + ); + + expect((prompter.text as ReturnType).mock.calls).toEqual( + expect.arrayContaining([ + [ + expect.objectContaining({ + message: "Tavily API key", + }), + ], + ]), + ); + expect(result.plugins?.entries?.["tavily-search"]?.config).toEqual({ + apiKey: "tvly-new", + }); + expect(result.tools?.web?.search?.provider).toBe("tavily"); + }); + it("sets provider and key for perplexity", async () => { const cfg: OpenClawConfig = {}; const { prompter } = createPrompter({ diff --git a/src/commands/onboard-search.ts b/src/commands/onboard-search.ts index 4203c84c4b8..df52ff769f0 100644 --- a/src/commands/onboard-search.ts +++ b/src/commands/onboard-search.ts @@ -1017,7 +1017,7 @@ export async function configureSearchProviderSelection( }); return nextConfig; } - if (selectedEntry.configured) { + if (selectedEntry.configured && intent === "switch-active") { const result = preserveSearchProviderIntent(config, next, intent, selectedEntry.value); await runAfterSearchProviderHooks({ hookRunner,