authorgravatar for lucenz@proton.meSimone <lucenz@proton.me> 2026-09-02 21:47:46+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-02 15:47:46-04:00
log2a7a449cca3c7760b689a54b3aa02476a206dbc9
treeb8a735579bf19e6525b36d86afc41845b43c7293
parentaab4049646ffa8b9bcff92562992e6c3a8554bf0
signature Signed by PGP key B5690EEEBB952194

fix(web): hide deleted providers with prototype keys (#8337)

Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com>

2 files changed, 83 insertions(+), 6 deletions(-)

apps/web/src/providerInstances.test.ts+71
......@@ -119,6 +119,77 @@ describe("applyProviderInstanceSettings", () => {
119119
120120 expect(entry?.enabled).toBe(false);
121121 });
122
123 it.each(["constructor", "toString"])(
124 "treats a removed custom instance named %s as disabled",
125 (instanceId) => {
126 const entries = deriveProviderInstanceEntries([
127 provider({
128 provider: ProviderDriverKind.make("claudeAgent"),
129 instanceId,
130 }),
131 ]);
132 const [entry] = applyProviderInstanceSettings(entries, {
133 providerInstances: {},
134 providers: {} as never,
135 });
136
137 expect(entry?.enabled).toBe(false);
138 },
139 );
140
141 it("uses settings for a configured custom instance named constructor", () => {
142 const instanceId = ProviderInstanceId.make("constructor");
143 const entries = deriveProviderInstanceEntries([
144 provider({
145 provider: ProviderDriverKind.make("claudeAgent"),
146 instanceId,
147 }),
148 ]);
149 const [entry] = applyProviderInstanceSettings(entries, {
150 providerInstances: {
151 [instanceId]: {
152 driver: ProviderDriverKind.make("claudeAgent"),
153 enabled: false,
154 },
155 },
156 providers: {} as never,
157 });
158
159 expect(entry?.enabled).toBe(false);
160 });
161
162 it("treats a removed default instance for a fork driver as disabled", () => {
163 const driver = ProviderDriverKind.make("constructor");
164 const entries = deriveProviderInstanceEntries([
165 provider({
166 provider: driver,
167 instanceId: "constructor",
168 }),
169 ]);
170 const [entry] = applyProviderInstanceSettings(entries, {
171 providerInstances: {},
172 providers: {} as never,
173 });
174
175 expect(entry?.isDefault).toBe(true);
176 expect(entry?.enabled).toBe(false);
177 });
178
179 it("uses legacy settings for a built-in default instance", () => {
180 const entries = deriveProviderInstanceEntries([
181 provider({
182 provider: ProviderDriverKind.make("codex"),
183 instanceId: "codex",
184 }),
185 ]);
186 const [entry] = applyProviderInstanceSettings(entries, {
187 providerInstances: {},
188 providers: { codex: { enabled: false } } as never,
189 });
190
191 expect(entry?.enabled).toBe(false);
192 });
122193});
123194
124195describe("deriveProviderInstanceEntries", () => {
apps/web/src/providerInstances.ts+12-6
......@@ -233,9 +233,10 @@ export function deriveProviderEntriesByEnvironment(
233233 * settings write, so picker visibility must follow settings rather than waiting
234234 * for probe reconciliation.
235235 *
236 * Non-default instances only exist through `providerInstances`; if one is
237 * absent there, its streamed snapshot is stale (for example immediately after
238 * deletion) and is treated as disabled.
236 * Only built-in default instances have a legacy `providers` entry. Every
237 * other instance exists through `providerInstances`; if it is absent there,
238 * its streamed snapshot is stale (for example immediately after deletion)
239 * and is treated as disabled.
239240 */
240241export function applyProviderInstanceSettings(
241242 entries: ReadonlyArray<ProviderInstanceEntry>,
......@@ -246,11 +247,16 @@ export function applyProviderInstanceSettings(
246247 >;
247248
248249 return entries.map((entry) => {
249 const explicitInstance = settings.providerInstances?.[entry.instanceId];
250 const explicitInstance = Object.hasOwn(settings.providerInstances, entry.instanceId)
251 ? settings.providerInstances[entry.instanceId]
252 : undefined;
253 const legacyProvider = Object.hasOwn(legacyProviders, entry.driverKind)
254 ? legacyProviders[entry.driverKind]
255 : undefined;
250256 const enabled = explicitInstance
251257 ? resolveProviderInstanceEnabled(explicitInstance)
252 : entry.isDefault
253 ? (legacyProviders[entry.driverKind]?.enabled ?? entry.enabled)
258 : entry.isDefault && legacyProvider
259 ? (legacyProvider.enabled ?? entry.enabled)
254260 : false;
255261 return enabled === entry.enabled ? entry : { ...entry, enabled };
256262 });