diff --git a/apps/web/src/providerInstances.test.ts b/apps/web/src/providerInstances.test.ts index b64a5e25d50..3e809e17f58 100644 --- a/apps/web/src/providerInstances.test.ts +++ b/apps/web/src/providerInstances.test.ts @@ -119,6 +119,77 @@ describe("applyProviderInstanceSettings", () => { expect(entry?.enabled).toBe(false); }); + + it.each(["constructor", "toString"])( + "treats a removed custom instance named %s as disabled", + (instanceId) => { + const entries = deriveProviderInstanceEntries([ + provider({ + provider: ProviderDriverKind.make("claudeAgent"), + instanceId, + }), + ]); + const [entry] = applyProviderInstanceSettings(entries, { + providerInstances: {}, + providers: {} as never, + }); + + expect(entry?.enabled).toBe(false); + }, + ); + + it("uses settings for a configured custom instance named constructor", () => { + const instanceId = ProviderInstanceId.make("constructor"); + const entries = deriveProviderInstanceEntries([ + provider({ + provider: ProviderDriverKind.make("claudeAgent"), + instanceId, + }), + ]); + const [entry] = applyProviderInstanceSettings(entries, { + providerInstances: { + [instanceId]: { + driver: ProviderDriverKind.make("claudeAgent"), + enabled: false, + }, + }, + providers: {} as never, + }); + + expect(entry?.enabled).toBe(false); + }); + + it("treats a removed default instance for a fork driver as disabled", () => { + const driver = ProviderDriverKind.make("constructor"); + const entries = deriveProviderInstanceEntries([ + provider({ + provider: driver, + instanceId: "constructor", + }), + ]); + const [entry] = applyProviderInstanceSettings(entries, { + providerInstances: {}, + providers: {} as never, + }); + + expect(entry?.isDefault).toBe(true); + expect(entry?.enabled).toBe(false); + }); + + it("uses legacy settings for a built-in default instance", () => { + const entries = deriveProviderInstanceEntries([ + provider({ + provider: ProviderDriverKind.make("codex"), + instanceId: "codex", + }), + ]); + const [entry] = applyProviderInstanceSettings(entries, { + providerInstances: {}, + providers: { codex: { enabled: false } } as never, + }); + + expect(entry?.enabled).toBe(false); + }); }); describe("deriveProviderInstanceEntries", () => { diff --git a/apps/web/src/providerInstances.ts b/apps/web/src/providerInstances.ts index ef60d554dd7..7cd045387f6 100644 --- a/apps/web/src/providerInstances.ts +++ b/apps/web/src/providerInstances.ts @@ -233,9 +233,10 @@ export function deriveProviderEntriesByEnvironment( * settings write, so picker visibility must follow settings rather than waiting * for probe reconciliation. * - * Non-default instances only exist through `providerInstances`; if one is - * absent there, its streamed snapshot is stale (for example immediately after - * deletion) and is treated as disabled. + * Only built-in default instances have a legacy `providers` entry. Every + * other instance exists through `providerInstances`; if it is absent there, + * its streamed snapshot is stale (for example immediately after deletion) + * and is treated as disabled. */ export function applyProviderInstanceSettings( entries: ReadonlyArray, @@ -246,11 +247,16 @@ export function applyProviderInstanceSettings( >; return entries.map((entry) => { - const explicitInstance = settings.providerInstances?.[entry.instanceId]; + const explicitInstance = Object.hasOwn(settings.providerInstances, entry.instanceId) + ? settings.providerInstances[entry.instanceId] + : undefined; + const legacyProvider = Object.hasOwn(legacyProviders, entry.driverKind) + ? legacyProviders[entry.driverKind] + : undefined; const enabled = explicitInstance ? resolveProviderInstanceEnabled(explicitInstance) - : entry.isDefault - ? (legacyProviders[entry.driverKind]?.enabled ?? entry.enabled) + : entry.isDefault && legacyProvider + ? (legacyProvider.enabled ?? entry.enabled) : false; return enabled === entry.enabled ? entry : { ...entry, enabled }; });