diff --git a/packages/server/src/server/daemon-config-store.test.ts b/packages/server/src/server/daemon-config-store.test.ts index cf5677e744..1bb6680259 100644 --- a/packages/server/src/server/daemon-config-store.test.ts +++ b/packages/server/src/server/daemon-config-store.test.ts @@ -468,6 +468,21 @@ describe("DaemonConfigStore", () => { expect(store.get().agentProfiles).toEqual([{ id, name: id, provider: id, options: {} }]); }); + test("a provider edit in the same write does not hide which adapter a profile runs on", async () => { + const store = storeWithLegacyProfiles(); + + await store.patch({ + providers: { "my-codex": { label: "Renamed" } }, + agentProfiles: [ + { id: "p", name: "P", provider: "my-codex", featureValues: { fast_mode: false } }, + ], + }); + + expect(store.get().agentProfiles).toEqual([ + { id: "p", name: "P", provider: "my-codex", options: { service_tier: "default" } }, + ]); + }); + test("a malformed value rejects the write and leaves config reads working", async () => { const store = storeWithLegacyProfiles(); diff --git a/packages/server/src/server/daemon-config-store.ts b/packages/server/src/server/daemon-config-store.ts index 55b7cd0caa..c762999458 100644 --- a/packages/server/src/server/daemon-config-store.ts +++ b/packages/server/src/server/daemon-config-store.ts @@ -465,6 +465,18 @@ export class DaemonConfigStore { return this.enqueue(() => this.applySupportedPatch({ skills: { selection } })); } + private foldPatchProfiles< + T extends { agentProfiles?: AgentProfile[]; providers?: Record }, + >(submittedPatch: T): T { + return foldConfigProfiles({ + config: submittedPatch, + // The provider graph this request will commit, so `extends` survives a partial edit. + providers: deepMerge(this.current.providers ?? {}, submittedPatch.providers ?? {}), + source: "client write", + held: this.current.agentProfiles, + }); + } + private async applySupportedPatch( parsedPatch: SupportedMutableConfigPatch, ): Promise { @@ -474,12 +486,7 @@ export class DaemonConfigStore { ); } const { removeProviders = [], ...submittedPatch } = parsedPatch; - const patch = foldConfigProfiles({ - config: submittedPatch, - providers: { ...this.current.providers, ...submittedPatch.providers }, - source: "client write", - held: this.current.agentProfiles, - }); + const patch = this.foldPatchProfiles(submittedPatch); const { features: speechPatch, ...configPatch } = patch; const removedProviders = Array.from(new Set(removeProviders)); const merged = deepMerge(this.current, configPatch);