mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 09:41:11 +00:00
fix(memory): warn cleanly on degraded vector recall
This commit is contained in:
@@ -856,13 +856,14 @@ export async function runMemoryIndex(opts: MemoryCommandOptions) {
|
||||
if (qmdIndexSummary) {
|
||||
defaultRuntime.log(qmdIndexSummary);
|
||||
}
|
||||
// HELM-0251: surface warning if vec0/chunks_vec was not updated
|
||||
const postIndexStatus = manager.status();
|
||||
const vectorEnabled = postIndexStatus.vector?.enabled ?? false;
|
||||
const vectorAvailable = postIndexStatus.vector?.available;
|
||||
const vectorLoadErr = postIndexStatus.vector?.loadError;
|
||||
if (vectorEnabled && vectorAvailable === false) {
|
||||
const errDetail = vectorLoadErr ? `: ${vectorLoadErr}` : "";
|
||||
// Indexing still persisted chunks/FTS state; keep the command successful but
|
||||
// emit a stderr warning so operators and scripts can detect degraded recall.
|
||||
defaultRuntime.error(
|
||||
`Memory index WARNING (${agentId}): chunks_vec not updated — sqlite-vec unavailable${errDetail}. Vector recall degraded.`,
|
||||
);
|
||||
|
||||
@@ -529,6 +529,33 @@ describe("memory cli", () => {
|
||||
expect(log).toHaveBeenCalledWith("Memory index updated (main).");
|
||||
});
|
||||
|
||||
it("warns on stderr when index completes without sqlite-vec embeddings", async () => {
|
||||
const close = vi.fn(async () => {});
|
||||
const sync = vi.fn(async () => {});
|
||||
mockManager({
|
||||
sync,
|
||||
status: () =>
|
||||
makeMemoryStatus({
|
||||
vector: {
|
||||
enabled: true,
|
||||
available: false,
|
||||
loadError: "load failed",
|
||||
},
|
||||
}),
|
||||
close,
|
||||
});
|
||||
|
||||
const error = spyRuntimeErrors(defaultRuntime);
|
||||
await runMemoryCli(["index"]);
|
||||
|
||||
expectCliSync(sync);
|
||||
expect(error).toHaveBeenCalledWith(
|
||||
"Memory index WARNING (main): chunks_vec not updated — sqlite-vec unavailable: load failed. Vector recall degraded.",
|
||||
);
|
||||
expect(close).toHaveBeenCalled();
|
||||
expect(process.exitCode).toBeUndefined();
|
||||
});
|
||||
|
||||
it("logs qmd index file path and size after index", async () => {
|
||||
const close = vi.fn(async () => {});
|
||||
const sync = vi.fn(async () => {});
|
||||
|
||||
@@ -655,11 +655,10 @@ export abstract class MemoryManagerEmbeddingOps extends MemoryManagerSyncOps {
|
||||
.run(chunk.text, id, entry.path, source, model, chunk.startLine, chunk.endLine);
|
||||
}
|
||||
}
|
||||
// HELM-0251: warn if chunks were written but chunks_vec was not updated
|
||||
if (this.vector.enabled && !vectorReady && chunks.length > 0) {
|
||||
const errDetail = this.vector.loadError ? `: ${this.vector.loadError}` : "";
|
||||
log.warn(
|
||||
`HELM-0251: chunks written for ${entry.path} without vector embeddings — chunks_vec not updated (sqlite-vec unavailable${errDetail}). Vector recall degraded for this file.`,
|
||||
`chunks written for ${entry.path} without vector embeddings — chunks_vec not updated (sqlite-vec unavailable${errDetail}). Vector recall degraded for this file.`,
|
||||
);
|
||||
}
|
||||
this.upsertFileRecord(entry, source);
|
||||
|
||||
Reference in New Issue
Block a user