Skip to content

Commit 5e8e95e

Browse files
AnkushKocursoragent
andcommitted
fix(memory): address clawsweeper review on Windows sqlite-vec retry
- Codex P2: honor explicit extensionPath before importing the bundled sqlite-vec module. Explicit paths now short-circuit at the top of loadSqliteVecExtension (matching current main's ordering), so configured override paths work even when the sqlite-vec package is not installed — consistent with the regression test added by BunsDev. - Codex P3: add a CHANGELOG entry under Unreleased/Fixes referencing #68892. - Tests: extend sqlite-vec.test.ts with four focused cases: Windows retry succeeds and returns the suffixless path; Windows dual failure surfaces both errors via { cause }; non-Windows platforms do not retry on bundled load failure; explicit extensionPath is already covered by the existing test and remains unaffected. Squashes the previously separate review-feedback commit into a single clean rebased state on top of current main. Co-authored-by: Cursor <[email protected]>
1 parent d319b0b commit 5e8e95e

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Docs: https://docs.openclaw.ai
6969

7070
### Fixes
7171

72+
- Memory/Windows: retry sqlite-vec extension load without the `.dll` suffix when the bundled `load()` call fails on Windows, matching SQLite's automatic suffix-appending convention; returns the effective suffixless path so subsequent reloads (after reindex/reset) use the correct path. Fixes #68892. Thanks @JustInCache.
7273
- TUI/sessions: bound the session picker to recent rows and use exact lookup-style refreshes for the active session, so dusty stores no longer make TUI hydrate weeks-old transcripts before becoming responsive. Thanks @vincentkoc.
7374
- Doctor/gateway: report recent supervisor restart handoffs in `openclaw doctor --deep`, using the installed service environment when available so service-managed clean exits are visible in guided diagnostics. Thanks @shakkernerd.
7475
- Gateway/status: show recent supervisor restart handoffs in `openclaw gateway status --deep`, including JSON details, so clean service-managed restarts are reported as restart handoffs instead of opaque stopped-service diagnostics. Thanks @shakkernerd.

packages/memory-host-sdk/src/host/sqlite-vec.test.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,84 @@ describe("loadSqliteVecExtension", () => {
5454
expect(db.enableLoadExtension).toHaveBeenCalledWith(true);
5555
expect(db.loadExtension).not.toHaveBeenCalled();
5656
});
57+
58+
it("retries without .dll suffix on Windows when bundled load fails", async () => {
59+
const loadablePath = "C:\\sqlite-vec\\vec0.dll";
60+
vi.doMock("sqlite-vec", () => ({
61+
getLoadablePath: () => loadablePath,
62+
load: vi.fn().mockImplementation(() => {
63+
throw new Error("no such module: vec0");
64+
}),
65+
}));
66+
const { loadSqliteVecExtension } = await importLoader();
67+
const db = {
68+
enableLoadExtension: vi.fn(),
69+
loadExtension: vi.fn(),
70+
};
71+
72+
const originalPlatform = process.platform;
73+
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
74+
try {
75+
const result = await loadSqliteVecExtension({ db: db as never });
76+
expect(result.ok).toBe(true);
77+
expect(result.extensionPath).toBe("C:\\sqlite-vec\\vec0");
78+
expect(db.loadExtension).toHaveBeenCalledWith("C:\\sqlite-vec\\vec0");
79+
} finally {
80+
Object.defineProperty(process, "platform", { value: originalPlatform, configurable: true });
81+
}
82+
});
83+
84+
it("chains both errors when Windows .dll retry also fails", async () => {
85+
const loadablePath = "C:\\sqlite-vec\\vec0.dll";
86+
vi.doMock("sqlite-vec", () => ({
87+
getLoadablePath: () => loadablePath,
88+
load: vi.fn().mockImplementation(() => {
89+
throw new Error("first: no such module: vec0");
90+
}),
91+
}));
92+
const { loadSqliteVecExtension } = await importLoader();
93+
const db = {
94+
enableLoadExtension: vi.fn(),
95+
loadExtension: vi.fn().mockImplementation(() => {
96+
throw new Error("retry: no such module: vec0");
97+
}),
98+
};
99+
100+
const originalPlatform = process.platform;
101+
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
102+
try {
103+
const result = await loadSqliteVecExtension({ db: db as never });
104+
expect(result.ok).toBe(false);
105+
expect(result.error).toContain("both load attempts failed on Windows");
106+
expect(result.error).toContain("retry: no such module: vec0");
107+
} finally {
108+
Object.defineProperty(process, "platform", { value: originalPlatform, configurable: true });
109+
}
110+
});
111+
112+
it("does not retry on non-Windows platforms when bundled load fails", async () => {
113+
const loadablePath = "/usr/lib/sqlite-vec/vec0.so";
114+
vi.doMock("sqlite-vec", () => ({
115+
getLoadablePath: () => loadablePath,
116+
load: vi.fn().mockImplementation(() => {
117+
throw new Error("no such module: vec0");
118+
}),
119+
}));
120+
const { loadSqliteVecExtension } = await importLoader();
121+
const db = {
122+
enableLoadExtension: vi.fn(),
123+
loadExtension: vi.fn(),
124+
};
125+
126+
const originalPlatform = process.platform;
127+
Object.defineProperty(process, "platform", { value: "linux", configurable: true });
128+
try {
129+
const result = await loadSqliteVecExtension({ db: db as never });
130+
expect(result.ok).toBe(false);
131+
expect(result.error).toContain("no such module");
132+
expect(db.loadExtension).not.toHaveBeenCalled();
133+
} finally {
134+
Object.defineProperty(process, "platform", { value: originalPlatform, configurable: true });
135+
}
136+
});
57137
});

0 commit comments

Comments
 (0)