Skip to content

Commit 64fe82c

Browse files
fix(memory): preserve qmd cli boot freshness
1 parent 714b924 commit 64fe82c

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

extensions/memory-core/src/memory/qmd-manager.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,59 @@ describe("QmdMemoryManager", () => {
797797
await manager?.close();
798798
});
799799

800+
it("preserves blocking boot update freshness for one-shot CLI mode", async () => {
801+
cfg = {
802+
...cfg,
803+
memory: {
804+
backend: "qmd",
805+
qmd: {
806+
includeDefaultMemory: false,
807+
update: {
808+
interval: "5m",
809+
debounceMs: 60_000,
810+
onBoot: true,
811+
waitForBootSync: true,
812+
},
813+
paths: [{ path: workspaceDir, pattern: "**/*.md", name: "workspace" }],
814+
},
815+
},
816+
} as OpenClawConfig;
817+
818+
const updateSpawned = createDeferred<void>();
819+
let releaseUpdate: (() => void) | null = null;
820+
spawnMock.mockImplementation((_cmd: string, args: string[]) => {
821+
if (args[0] === "update") {
822+
const child = createMockChild({ autoClose: false });
823+
releaseUpdate = () => child.closeWith(0);
824+
updateSpawned.resolve();
825+
return child;
826+
}
827+
return createMockChild();
828+
});
829+
830+
const createPromise = createManager({ mode: "cli" });
831+
await updateSpawned.promise;
832+
let created = false;
833+
void createPromise.then(() => {
834+
created = true;
835+
});
836+
await new Promise<void>((resolve) => {
837+
setImmediate(resolve);
838+
});
839+
expect(created).toBe(false);
840+
expect(watchMock).not.toHaveBeenCalled();
841+
842+
(releaseUpdate as (() => void) | null)?.();
843+
const { manager } = await createPromise;
844+
const updateCalls = spawnMock.mock.calls
845+
.map((call: unknown[]) => call[1] as string[])
846+
.filter((args: string[]) => args[0] === "update" || args[0] === "embed");
847+
expect(updateCalls).toStrictEqual([["update"]]);
848+
expect(watchMock).not.toHaveBeenCalled();
849+
850+
await manager?.close();
851+
});
852+
800853
it("keeps one-shot CLI searches from scheduling session-start updates", async () => {
801854
cfg = {
802855
...cfg,

extensions/memory-core/src/memory/qmd-manager.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,11 @@ export class QmdMemoryManager implements MemorySearchManager {
497497

498498
await this.ensureCollections();
499499
if (mode === "cli") {
500+
if (this.qmd.update.onBoot && this.qmd.update.waitForBootSync) {
501+
await this.runUpdate("boot:cli", true).catch((err: unknown) => {
502+
log.warn(`qmd cli boot update failed: ${String(err)}`);
503+
});
504+
}
500505
log.info(
501506
`qmd manager initialized for agent "${this.agentId}" mode=cli collections=${this.qmd.collections.length} durationMs=${Date.now() - startTime}`,
502507
);

0 commit comments

Comments
 (0)