diff --git a/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts b/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts index c41f2f6495..1ef9bfb68f 100644 --- a/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts +++ b/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts @@ -210,7 +210,7 @@ describe("legacy config detection", () => { }, }); expect(res.changes).toContain( - "Merged memorySearch → agents.defaults.memorySearch (preserved explicit agents.defaults overrides).", + "Merged memorySearch → agents.defaults.memorySearch (filled missing fields from legacy; kept explicit agents.defaults values).", ); expect(res.config?.agents?.defaults?.memorySearch).toMatchObject({ provider: "openai", @@ -219,6 +219,37 @@ describe("legacy config detection", () => { query: { maxResults: 7 }, }); }); + it("keeps nested agents.defaults.memorySearch values when merging legacy defaults", async () => { + vi.resetModules(); + const { migrateLegacyConfig } = await import("./config.js"); + const res = migrateLegacyConfig({ + memorySearch: { + query: { + maxResults: 7, + minScore: 0.25, + hybrid: { enabled: true, textWeight: 0.8, vectorWeight: 0.2 }, + }, + }, + agents: { + defaults: { + memorySearch: { + query: { + maxResults: 3, + hybrid: { enabled: false }, + }, + }, + }, + }, + }); + + expect(res.config?.agents?.defaults?.memorySearch).toMatchObject({ + query: { + maxResults: 3, + minScore: 0.25, + hybrid: { enabled: false, textWeight: 0.8, vectorWeight: 0.2 }, + }, + }); + }); it("migrates tools.bash to tools.exec", async () => { vi.resetModules(); const { migrateLegacyConfig } = await import("./config.js"); diff --git a/src/config/legacy.migrations.part-3.ts b/src/config/legacy.migrations.part-3.ts index a762f74141..18db0da19c 100644 --- a/src/config/legacy.migrations.part-3.ts +++ b/src/config/legacy.migrations.part-3.ts @@ -30,10 +30,12 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_3: LegacyConfigMigration[] = [ defaults.memorySearch = legacyMemorySearch; changes.push("Moved memorySearch → agents.defaults.memorySearch."); } else { - mergeMissing(existing, legacyMemorySearch); - defaults.memorySearch = existing; + // agents.defaults stays authoritative; legacy top-level config only fills gaps. + const merged = structuredClone(existing); + mergeMissing(merged, legacyMemorySearch); + defaults.memorySearch = merged; changes.push( - "Merged memorySearch → agents.defaults.memorySearch (preserved explicit agents.defaults overrides).", + "Merged memorySearch → agents.defaults.memorySearch (filled missing fields from legacy; kept explicit agents.defaults values).", ); }