diff --git a/packages/coding-agent/src/memories/index.ts b/packages/coding-agent/src/memories/index.ts index 9a07849c8..8ba5d8634 100644 --- a/packages/coding-agent/src/memories/index.ts +++ b/packages/coding-agent/src/memories/index.ts @@ -166,6 +166,11 @@ const memoryToolDeveloperInstructionsBySession = new WeakMap< MemoryInstructionSession, CachedMemoryToolDeveloperInstructions >(); +const memoryToolDeveloperInstructionsByRoot = new Map(); + +function getMemoryInstructionRoot(agentDir: string, settings: Settings): string { + return getMemoryRoot(agentDir, settings.getCwd()); +} function getMemoryInstructionSessionFile(session: MemoryInstructionSession): string | undefined { return session.sessionManager.getSessionFile() ?? undefined; @@ -177,7 +182,7 @@ async function readMemoryToolDeveloperInstructionsSnapshot( ): Promise { const cfg = loadMemoryConfig(settings); if (!cfg.enabled) return undefined; - const memoryRoot = getMemoryRoot(agentDir, settings.getCwd()); + const memoryRoot = getMemoryInstructionRoot(agentDir, settings); let summary = ""; try { @@ -255,8 +260,10 @@ export async function refreshMemoryToolDeveloperInstructionsCacheAfterStartup( const sessionFile = getMemoryInstructionSessionFile(session); const cached = memoryToolDeveloperInstructionsBySession.get(session); const current = await readMemoryToolDeveloperInstructionsSnapshot(agentDir, settings); + const root = getMemoryInstructionRoot(agentDir, settings); + const baseline = memoryToolDeveloperInstructionsByRoot.get(root); const cachedLearned = cached && cached.sessionFile === sessionFile ? cached.snapshot?.learned : undefined; - const learned = cachedLearned ?? current?.learned ?? ""; + const learned = cachedLearned ?? baseline?.learned ?? ""; const snapshot = current ? { summary: current.summary, learned } : undefined; cacheMemoryToolDeveloperInstructions(session, sessionFile, snapshot, settings); } @@ -271,6 +278,7 @@ export async function buildMemoryToolDeveloperInstructions( ): Promise { if (!session) { const snapshot = await readMemoryToolDeveloperInstructionsSnapshot(agentDir, settings); + memoryToolDeveloperInstructionsByRoot.set(getMemoryInstructionRoot(agentDir, settings), snapshot); return renderMemoryToolDeveloperInstructionsSnapshot(snapshot, settings); } diff --git a/packages/coding-agent/test/autolearn-learn-local.test.ts b/packages/coding-agent/test/autolearn-learn-local.test.ts index 30288520d..fd82ee142 100644 --- a/packages/coding-agent/test/autolearn-learn-local.test.ts +++ b/packages/coding-agent/test/autolearn-learn-local.test.ts @@ -198,13 +198,15 @@ describe("learned-lesson read-back", () => { expect(await buildMemoryToolDeveloperInstructions(agentDir, settings, session)).toBeUndefined(); }); - it("refreshes consolidated summaries without rereading learned lessons from the active session", async () => { + it("uses the pre-session learned snapshot when startup refresh has no session cache yet", async () => { const settings = Settings.isolated({ "memory.backend": "local" }); - const session = sessionWithFile("session-consolidate.jsonl"); - // First build (before background consolidation finishes) snapshots an empty learned.md. - expect(await buildMemoryToolDeveloperInstructions(agentDir, settings, session)).toBeUndefined(); + await saveLearnedLesson(agentDir, settings.getCwd(), { content: "Prior-session lesson" }); + const initial = await buildMemoryToolDeveloperInstructions(agentDir, settings); + expect(initial).toContain("Prior-session lesson"); - // The active session learns while the background pipeline is still running. + const session = sessionWithFile("session-consolidate.jsonl"); + // The active session learns while the background pipeline is still running, + // before any session-scoped prompt rebuild has populated the WeakMap. await saveLearnedLesson(agentDir, settings.getCwd(), { content: "Active-session lesson" }); // Background pipeline writes the consolidated summary later. const root = getMemoryRoot(agentDir, settings.getCwd()); @@ -213,6 +215,7 @@ describe("learned-lesson read-back", () => { await refreshMemoryToolDeveloperInstructionsCacheAfterStartup(session, agentDir, settings); const out = await buildMemoryToolDeveloperInstructions(agentDir, settings, session); expect(out).toContain("Consolidated guidance here."); + expect(out).toContain("Prior-session lesson"); expect(out).not.toContain("Active-session lesson"); const nextSession = sessionWithFile("session-after-consolidate.jsonl");