diff --git a/packages/coding-agent/src/modes/controllers/selector-controller.ts b/packages/coding-agent/src/modes/controllers/selector-controller.ts index 9d56ad2c0..37983afe8 100644 --- a/packages/coding-agent/src/modes/controllers/selector-controller.ts +++ b/packages/coding-agent/src/modes/controllers/selector-controller.ts @@ -40,7 +40,9 @@ import { import { AUTO_THINKING, type ConfiguredThinkingLevel } from "../../thinking"; import { isImageProviderPreference, + isSearchProviderId, isSearchProviderPreference, + setExcludedSearchProviders, setPreferredImageProvider, setPreferredSearchProvider, } from "../../tools"; @@ -419,6 +421,11 @@ export class SelectorController { setPreferredSearchProvider(value); } break; + case "providers.webSearchExclude": + if (Array.isArray(value)) { + setExcludedSearchProviders(value.filter(isSearchProviderId)); + } + break; case "providers.image": if (isImageProviderPreference(value)) { setPreferredImageProvider(value); diff --git a/packages/coding-agent/test/web/search/provider-chain.test.ts b/packages/coding-agent/test/web/search/provider-chain.test.ts index b887ec174..2aa3d6248 100644 --- a/packages/coding-agent/test/web/search/provider-chain.test.ts +++ b/packages/coding-agent/test/web/search/provider-chain.test.ts @@ -1,5 +1,6 @@ import { afterEach, describe, expect, it } from "bun:test"; import type { AuthStorage } from "@oh-my-pi/pi-ai"; +import { SelectorController } from "@oh-my-pi/pi-coding-agent/modes/controllers/selector-controller"; import { resolveProviderChain, setExcludedSearchProviders, @@ -37,15 +38,6 @@ afterEach(() => { }); describe("resolveProviderChain", () => { - it("keeps the preferred provider first when it is available and not excluded", async () => { - enableKeyBackedProviders(); - setExcludedSearchProviders(SEARCH_PROVIDER_ORDER.filter(id => id !== "brave" && id !== "jina")); - - const providers = await resolveProviderChain(authStorage, "brave"); - - expect(providers.map(provider => provider.id)).toEqual(["brave", "jina"]); - }); - it("omits excluded providers from the fallback chain", async () => { enableKeyBackedProviders(); setExcludedSearchProviders(SEARCH_PROVIDER_ORDER.filter(id => id !== "jina")); @@ -63,4 +55,18 @@ describe("resolveProviderChain", () => { expect(providers.map(provider => provider.id)).toEqual(["jina"]); }); + + it("applies live settings edits to the exclusion chain", async () => { + enableKeyBackedProviders(); + const controller = new SelectorController({} as unknown as ConstructorParameters[0]); + + controller.handleSettingChange( + "providers.webSearchExclude", + SEARCH_PROVIDER_ORDER.filter(id => id !== "jina"), + ); + + const providers = await resolveProviderChain(authStorage, "auto"); + + expect(providers.map(provider => provider.id)).toEqual(["jina"]); + }); });