diff --git a/src/memory/index.test.ts b/src/memory/index.test.ts index ba31067a2d..8d4a08a49d 100644 --- a/src/memory/index.test.ts +++ b/src/memory/index.test.ts @@ -52,7 +52,9 @@ describe("memory index", () => { let indexVectorPath = ""; let indexExtraPath = ""; - const persistentManagers = new Set(); + // Perf: keep managers open across tests, but only reset the one a test uses. + const managersByStorePath = new Map(); + const managersForCleanup = new Set(); beforeAll(async () => { fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-mem-fixtures-")); @@ -69,7 +71,7 @@ describe("memory index", () => { }); afterAll(async () => { - await Promise.all(Array.from(persistentManagers).map((manager) => manager.close())); + await Promise.all(Array.from(managersForCleanup).map((manager) => manager.close())); await fs.rm(fixtureRoot, { recursive: true, force: true }); }); @@ -88,10 +90,6 @@ describe("memory index", () => { // Clean additional paths that may have been created by earlier cases. await fs.rm(extraDir, { recursive: true, force: true }); - - for (const manager of persistentManagers) { - resetManagerForTest(manager); - } }); function resetManagerForTest(manager: MemoryIndexManager) { @@ -108,13 +106,25 @@ describe("memory index", () => { type TestCfg = Parameters[0]["cfg"]; async function getPersistentManager(cfg: TestCfg): Promise { + const storePath = cfg.agents?.defaults?.memorySearch?.store?.path; + if (!storePath) { + throw new Error("store path missing"); + } + const cached = managersByStorePath.get(storePath); + if (cached) { + resetManagerForTest(cached); + return cached; + } + const result = await getMemorySearchManager({ cfg, agentId: "main" }); expect(result.manager).not.toBeNull(); if (!result.manager) { throw new Error("manager missing"); } const manager = result.manager as MemoryIndexManager; - persistentManagers.add(manager); + managersByStorePath.set(storePath, manager); + managersForCleanup.add(manager); + resetManagerForTest(manager); return manager; } diff --git a/src/memory/manager.embedding-batches.test.ts b/src/memory/manager.embedding-batches.test.ts index 3471ca0992..0429ed385f 100644 --- a/src/memory/manager.embedding-batches.test.ts +++ b/src/memory/manager.embedding-batches.test.ts @@ -40,6 +40,14 @@ describe("memory embedding batches", () => { let managerLarge: MemoryIndexManager | null = null; let managerSmall: MemoryIndexManager | null = null; + function resetManagerForTest(manager: MemoryIndexManager | null) { + if (!manager) { + throw new Error("manager missing"); + } + (manager as unknown as { resetIndex: () => void }).resetIndex(); + (manager as unknown as { dirty: boolean }).dirty = true; + } + function createCfg(params: { indexPath: string; tokens: number }) { return { agents: { @@ -108,24 +116,15 @@ describe("memory embedding batches", () => { await fs.rm(memoryDir, { recursive: true, force: true }); await fs.mkdir(memoryDir, { recursive: true }); - - const reset = (manager: MemoryIndexManager | null) => { - if (!manager) { - throw new Error("manager missing"); - } - (manager as unknown as { resetIndex: () => void }).resetIndex(); - (manager as unknown as { dirty: boolean }).dirty = true; - }; - reset(managerLarge); - reset(managerSmall); }); it("splits large files across multiple embedding batches", async () => { // Keep this small but above the embedding batch byte threshold (8k) so we // exercise multi-batch behavior without generating lots of chunks/DB rows. - const line = "a".repeat(5000); + const line = "a".repeat(4200); const content = [line, line].join("\n"); await fs.writeFile(path.join(memoryDir, "2026-01-03.md"), content); + resetManagerForTest(managerLarge); if (!managerLarge) { throw new Error("manager missing"); } @@ -151,6 +150,7 @@ describe("memory embedding batches", () => { const line = "b".repeat(120); const content = Array.from({ length: 4 }, () => line).join("\n"); await fs.writeFile(path.join(memoryDir, "2026-01-04.md"), content); + resetManagerForTest(managerSmall); if (!managerSmall) { throw new Error("manager missing"); } @@ -190,6 +190,7 @@ describe("memory embedding batches", () => { } return realSetTimeout(handler, delay, ...args); }) as typeof setTimeout); + resetManagerForTest(managerSmall); if (!managerSmall) { throw new Error("manager missing"); } @@ -204,6 +205,7 @@ describe("memory embedding batches", () => { it("skips empty chunks so embeddings input stays valid", async () => { await fs.writeFile(path.join(memoryDir, "2026-01-07.md"), "\n\n\n"); + resetManagerForTest(managerSmall); if (!managerSmall) { throw new Error("manager missing"); }