Memory/QMD: treat prefixed no-results markers as empty

This commit is contained in:
Vignesh Natarajan
2026-02-14 15:31:40 -08:00
parent abf42abd41
commit 2547514b47
3 changed files with 26 additions and 2 deletions

View File

@@ -45,6 +45,7 @@ Docs: https://docs.openclaw.ai
- Memory/QMD: parse qmd scope keys once per request to avoid repeated parsing in scope checks.
- Memory/QMD: query QMD index using exact docid matches before falling back to prefix lookup for better recall correctness and index efficiency.
- Memory/QMD: make QMD result JSON parsing resilient to noisy command output by extracting the first JSON array from noisy `stdout`.
- Memory/QMD: treat prefixed `no results found` marker output as an empty result set in qmd JSON parsing. (#11302) Thanks @blazerui.
- Memory/QMD: pass result limits to `search`/`vsearch` commands so QMD can cap results earlier.
- Memory/QMD: avoid reading full markdown files when a `from/lines` window is requested in QMD reads.
- Memory/QMD: skip rewriting unchanged session export markdown files during sync to reduce disk churn.

View File

@@ -29,6 +29,17 @@ complete`,
expect(results).toEqual([]);
});
it("treats prefixed no-results marker output as an empty result set", () => {
expect(parseQmdQueryJson("warning: no results found", "")).toEqual([]);
expect(parseQmdQueryJson("", "[qmd] warning: no results found\n")).toEqual([]);
});
it("does not treat arbitrary non-marker text as no-results output", () => {
expect(() =>
parseQmdQueryJson("warning: search completed; no results found for this query", ""),
).toThrow(/qmd query returned invalid JSON/i);
});
it("throws when stdout cannot be interpreted as qmd JSON", () => {
expect(() => parseQmdQueryJson("this is not json", "")).toThrow(
/qmd query returned invalid JSON/i,

View File

@@ -46,8 +46,20 @@ export function parseQmdQueryJson(stdout: string, stderr: string): QmdQueryResul
}
function isQmdNoResultsOutput(raw: string): boolean {
const normalized = raw.trim().toLowerCase().replace(/\s+/g, " ");
return normalized === "no results found" || normalized === "no results found.";
const lines = raw
.split(/\r?\n/)
.map((line) => line.trim().toLowerCase().replace(/\s+/g, " "))
.filter((line) => line.length > 0);
return lines.some((line) => isQmdNoResultsLine(line));
}
function isQmdNoResultsLine(line: string): boolean {
if (line === "no results found" || line === "no results found.") {
return true;
}
return /^(?:\[[^\]]+\]\s*)?(?:(?:warn(?:ing)?|info|error|qmd)\s*:\s*)+no results found\.?$/.test(
line,
);
}
function summarizeQmdStderr(raw: string): string {