Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions apps/web/src/providerInstances.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down
18 changes: 12 additions & 6 deletions apps/web/src/providerInstances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProviderInstanceEntry>,
Expand All @@ -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 };
});
Expand Down
Loading