diff --git a/src/agents/live-model-filter.test.ts b/src/agents/live-model-filter.test.ts index ccfb8c79f9a..4f1c449882f 100644 --- a/src/agents/live-model-filter.test.ts +++ b/src/agents/live-model-filter.test.ts @@ -1,13 +1,32 @@ -import { describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, it } from "vitest"; +import { clearPluginDiscoveryCache } from "../plugins/discovery.js"; +import { clearPluginManifestRegistryCache } from "../plugins/manifest-registry.js"; import { shouldExcludeProviderFromDefaultHighSignalLiveSweep } from "./live-model-filter.js"; +function hermeticProviderRegistryEnv(): NodeJS.ProcessEnv { + return { + OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY: "1", + OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE: "1", + OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE: "1", + VITEST: "1", + } as NodeJS.ProcessEnv; +} + describe("shouldExcludeProviderFromDefaultHighSignalLiveSweep", () => { + beforeEach(() => { + clearPluginDiscoveryCache(); + clearPluginManifestRegistryCache(); + }); + it("excludes dedicated harness providers from the default high-signal sweep", () => { + const env = hermeticProviderRegistryEnv(); + expect( shouldExcludeProviderFromDefaultHighSignalLiveSweep({ provider: "codex", useExplicitModels: false, providerFilter: null, + env, }), ).toBe(true); expect( @@ -15,6 +34,7 @@ describe("shouldExcludeProviderFromDefaultHighSignalLiveSweep", () => { provider: "openai-codex", useExplicitModels: false, providerFilter: null, + env, }), ).toBe(true); expect( @@ -22,16 +42,20 @@ describe("shouldExcludeProviderFromDefaultHighSignalLiveSweep", () => { provider: "codex-cli", useExplicitModels: false, providerFilter: null, + env, }), ).toBe(true); }); it("keeps dedicated harness providers when explicitly requested by provider filter", () => { + const env = hermeticProviderRegistryEnv(); + expect( shouldExcludeProviderFromDefaultHighSignalLiveSweep({ provider: "codex", useExplicitModels: false, providerFilter: new Set(["codex"]), + env, }), ).toBe(false); expect( @@ -39,6 +63,7 @@ describe("shouldExcludeProviderFromDefaultHighSignalLiveSweep", () => { provider: "openai-codex", useExplicitModels: false, providerFilter: new Set(["codex-cli"]), + env, }), ).toBe(false); expect( @@ -46,6 +71,7 @@ describe("shouldExcludeProviderFromDefaultHighSignalLiveSweep", () => { provider: "openai-codex", useExplicitModels: false, providerFilter: new Set(["openai"]), + env, }), ).toBe(false); }); @@ -66,6 +92,7 @@ describe("shouldExcludeProviderFromDefaultHighSignalLiveSweep", () => { provider: "openai", useExplicitModels: false, providerFilter: null, + env: hermeticProviderRegistryEnv(), }), ).toBe(false); }); diff --git a/src/agents/models-config.providers.live-filter.test.ts b/src/agents/models-config.providers.live-filter.test.ts index 2e562b77f17..ddd8bda6143 100644 --- a/src/agents/models-config.providers.live-filter.test.ts +++ b/src/agents/models-config.providers.live-filter.test.ts @@ -1,15 +1,31 @@ -import { describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, it } from "vitest"; +import { clearPluginDiscoveryCache } from "../plugins/discovery.js"; +import { clearPluginManifestRegistryCache } from "../plugins/manifest-registry.js"; import { resolveProviderDiscoveryFilterForTest } from "./models-config.providers.implicit.js"; +function liveFilterEnv(overrides: NodeJS.ProcessEnv): NodeJS.ProcessEnv { + return { + OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY: "1", + OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE: "1", + OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE: "1", + VITEST: "1", + ...overrides, + } as NodeJS.ProcessEnv; +} + describe("resolveProviderDiscoveryFilterForTest", () => { + beforeEach(() => { + clearPluginDiscoveryCache(); + clearPluginManifestRegistryCache(); + }); + it("maps live provider backend ids to owning plugin ids", () => { expect( resolveProviderDiscoveryFilterForTest({ - env: { + env: liveFilterEnv({ OPENCLAW_LIVE_TEST: "1", OPENCLAW_LIVE_PROVIDERS: "claude-cli", - VITEST: "1", - } as NodeJS.ProcessEnv, + }), }), ).toEqual(["anthropic"]); }); @@ -17,11 +33,10 @@ describe("resolveProviderDiscoveryFilterForTest", () => { it("honors gateway live provider filters too", () => { expect( resolveProviderDiscoveryFilterForTest({ - env: { + env: liveFilterEnv({ OPENCLAW_LIVE_TEST: "1", OPENCLAW_LIVE_GATEWAY_PROVIDERS: "claude-cli", - VITEST: "1", - } as NodeJS.ProcessEnv, + }), }), ).toEqual(["anthropic"]); }); @@ -29,11 +44,10 @@ describe("resolveProviderDiscoveryFilterForTest", () => { it("keeps explicit plugin-id filters when no owning provider plugin exists", () => { expect( resolveProviderDiscoveryFilterForTest({ - env: { + env: liveFilterEnv({ OPENCLAW_LIVE_TEST: "1", OPENCLAW_LIVE_PROVIDERS: "openrouter", - VITEST: "1", - } as NodeJS.ProcessEnv, + }), }), ).toEqual(["openrouter"]); }); diff --git a/src/agents/models-config.providers.plugin-allowlist-compat.test.ts b/src/agents/models-config.providers.plugin-allowlist-compat.test.ts index e39b145fec6..6c2e6c07757 100644 --- a/src/agents/models-config.providers.plugin-allowlist-compat.test.ts +++ b/src/agents/models-config.providers.plugin-allowlist-compat.test.ts @@ -1,11 +1,27 @@ -import { describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, it } from "vitest"; import { withBundledPluginAllowlistCompat, withBundledPluginEnablementCompat, } from "../plugins/bundled-compat.js"; +import { clearPluginDiscoveryCache } from "../plugins/discovery.js"; +import { clearPluginManifestRegistryCache } from "../plugins/manifest-registry.js"; import { resolveEnabledProviderPluginIds } from "../plugins/providers.js"; +function providerRegistryEnv(): NodeJS.ProcessEnv { + return { + OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY: "1", + OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE: "1", + OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE: "1", + VITEST: "1", + } as NodeJS.ProcessEnv; +} + describe("implicit provider plugin allowlist compatibility", () => { + beforeEach(() => { + clearPluginDiscoveryCache(); + clearPluginManifestRegistryCache(); + }); + it("keeps bundled implicit providers discoverable when plugins.allow is set", () => { const config = withBundledPluginEnablementCompat({ config: withBundledPluginAllowlistCompat({ @@ -22,7 +38,7 @@ describe("implicit provider plugin allowlist compatibility", () => { expect( resolveEnabledProviderPluginIds({ config, - env: { VITEST: "1" } as NodeJS.ProcessEnv, + env: providerRegistryEnv(), onlyPluginIds: ["kilocode", "moonshot", "openrouter"], }), ).toEqual(["kilocode", "moonshot", "openrouter"]); @@ -45,7 +61,7 @@ describe("implicit provider plugin allowlist compatibility", () => { expect( resolveEnabledProviderPluginIds({ config, - env: { VITEST: "1" } as NodeJS.ProcessEnv, + env: providerRegistryEnv(), onlyPluginIds: ["kilocode", "moonshot", "openrouter"], }), ).toEqual(["moonshot", "openrouter"]); diff --git a/src/commands/doctor/shared/channel-doctor.test.ts b/src/commands/doctor/shared/channel-doctor.test.ts index a5f2ff7ec8e..025b22ea390 100644 --- a/src/commands/doctor/shared/channel-doctor.test.ts +++ b/src/commands/doctor/shared/channel-doctor.test.ts @@ -14,6 +14,11 @@ const mocks = vi.hoisted(() => ({ resolveReadOnlyChannelPluginsForConfig: vi.fn(), })); +const READ_ONLY_CHANNEL_DOCTOR_OPTIONS = { + includePersistedAuthState: false, + includeSetupRuntimeFallback: true, +} as const; + vi.mock("../../../channels/plugins/registry.js", () => ({ getLoadedChannelPlugin: (...args: Parameters) => mocks.getLoadedChannelPlugin(...args), @@ -84,9 +89,10 @@ function mockBundledMatrixRuntimePlugin(doctor?: Record) { function expectMatrixDoctorLookupCalls(cfg?: unknown) { if (cfg) { - expect(mocks.resolveReadOnlyChannelPluginsForConfig).toHaveBeenCalledWith(cfg, { - includePersistedAuthState: false, - }); + expect(mocks.resolveReadOnlyChannelPluginsForConfig).toHaveBeenCalledWith( + cfg, + READ_ONLY_CHANNEL_DOCTOR_OPTIONS, + ); } expect(mocks.getLoadedChannelPlugin).toHaveBeenCalledWith("matrix"); expect(mocks.getBundledChannelSetupPlugin).toHaveBeenCalledWith("matrix"); @@ -238,7 +244,7 @@ describe("channel doctor compatibility mutations", () => { expect(mocks.resolveReadOnlyChannelPluginsForConfig).toHaveBeenCalledWith(cfg, { env, - includePersistedAuthState: false, + ...READ_ONLY_CHANNEL_DOCTOR_OPTIONS, }); }); @@ -295,9 +301,10 @@ describe("channel doctor compatibility mutations", () => { }); expect(result).toEqual(["channels.matrix extra"]); - expect(mocks.resolveReadOnlyChannelPluginsForConfig).toHaveBeenCalledWith(cfg, { - includePersistedAuthState: false, - }); + expect(mocks.resolveReadOnlyChannelPluginsForConfig).toHaveBeenCalledWith( + cfg, + READ_ONLY_CHANNEL_DOCTOR_OPTIONS, + ); expect(collectEmptyAllowlistExtraWarnings.mock.calls[0]?.[0]).not.toHaveProperty("cfg"); }); @@ -374,7 +381,7 @@ describe("channel doctor compatibility mutations", () => { expect(mocks.resolveReadOnlyChannelPluginsForConfig).toHaveBeenCalledTimes(1); expect(mocks.resolveReadOnlyChannelPluginsForConfig).toHaveBeenCalledWith(cfg, { env, - includePersistedAuthState: false, + ...READ_ONLY_CHANNEL_DOCTOR_OPTIONS, }); expect(collectEmptyAllowlistExtraWarnings).toHaveBeenCalledTimes(3); expect(shouldSkipDefaultEmptyGroupAllowlistWarning).toHaveBeenCalledTimes(1);