Remove custom providers from settings (#1951)

* feat(providers): remove custom providers from settings

Add a destructive removal flow so mistaken custom providers can be deleted from config.json instead of only disabled.

* test(app): cover provider removal with e2e

Move provider removal coverage out of mocked component tests and into the real Settings flow.

* fix(providers): keep removal live after config updates
This commit is contained in:
Mohamed Boudra
2026-07-16 16:11:51 +02:00
committed by GitHub
parent 6aba0370ae
commit e528a0db06
23 changed files with 920 additions and 35 deletions

View File

@@ -104,6 +104,7 @@ export interface ProviderSnapshotEntry {
provider: AgentProvider;
status: ProviderStatus;
enabled: boolean;
source?: "builtin" | "custom";
error?: string;
models?: AgentModelDefinition[];
modes?: AgentMode[];

View File

@@ -368,4 +368,18 @@ describe("checkout PR schemas", () => {
projectAdd: true,
});
});
test("accepts the provider removal server_info feature flag", () => {
expect(
ServerInfoStatusPayloadSchema.parse({
status: "server_info",
serverId: "srv_test",
features: {
providerRemoval: true,
},
}).features,
).toEqual({
providerRemoval: true,
});
});
});

View File

@@ -38,6 +38,18 @@ describe("provider snapshot message schemas", () => {
expect(parsed.enabled).toBe(true);
});
test("preserves provider snapshot entry source", () => {
const parsed = ProviderSnapshotEntrySchema.parse({
provider: "gemini",
status: "ready",
enabled: true,
source: "custom",
label: "Gemini",
});
expect(parsed.source).toBe("custom");
});
test("defaults missing enabled state in providers snapshot response entries", () => {
const parsed = GetProvidersSnapshotResponseMessageSchema.parse({
type: "get_providers_snapshot_response",

View File

@@ -163,6 +163,7 @@ export const MutableDaemonConfigPatchSchema = z
providers: z
.record(z.string(), MutableDaemonProviderConfigSchema.partial().passthrough())
.optional(),
removeProviders: z.array(z.string().min(1)).optional(),
metadataGeneration: MutableMetadataGenerationConfigSchema.partial().optional(),
autoArchiveAfterMerge: z.boolean().optional(),
enableTerminalAgentHooks: z.boolean().optional(),
@@ -263,6 +264,7 @@ export const ProviderSnapshotEntrySchema = z.object({
provider: AgentProviderSchema,
status: ProviderStatusSchema,
enabled: z.boolean().optional().default(true),
source: z.enum(["builtin", "custom"]).optional(),
error: z.string().optional(),
models: z.array(AgentModelDefinitionSchema).optional(),
modes: z.array(AgentModeSchema).optional(),
@@ -2471,6 +2473,8 @@ export const ServerInfoStatusPayloadSchema = z
workspaceGithubRepositorySearch: z.boolean().optional(),
// COMPAT(projectCreateDirectory): added in v0.1.108, remove gate after 2027-01-15.
projectCreateDirectory: z.boolean().optional(),
// COMPAT(providerRemoval): added in v0.1.105, drop the gate when floor >= v0.1.105.
providerRemoval: z.boolean().optional(),
})
.optional(),
})