fix(memory-core): don't run the LLM reranker in vsearch/search modes (#88887)

vsearch/search are documented as vector/lexical-only modes, but
runQmdSearchViaMcporter omitted `rerank` from the query tool callArgs,
so QMD's query tool (which defaults rerank:true) ran the LLM reranker
anyway. Pass rerank:false for those modes; full "query" mode keeps it.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Brian Potter
2026-06-28 20:11:03 -05:00
committed by GitHub
parent be0c40bad2
commit cd31cbcd17
2 changed files with 47 additions and 0 deletions

View File

@@ -4070,6 +4070,46 @@ describe("QmdMemoryManager", () => {
await manager.close();
});
it("disables the LLM reranker (rerank:false) for vsearch mode via mcporter", async () => {
cfg = {
...cfg,
memory: {
backend: "qmd",
qmd: {
includeDefaultMemory: false,
searchMode: "vsearch",
update: { interval: "0s", debounceMs: 60_000, onBoot: false },
paths: [{ path: workspaceDir, pattern: "**/*.md", name: "workspace" }],
mcporter: { enabled: true, serverName: "qmd", startDaemon: false },
},
},
} as OpenClawConfig;
let captured: Record<string, unknown> | null = null;
spawnMock.mockImplementation((cmd: string, args: string[]) => {
const child = createMockChild({ autoClose: false });
if (isMcporterCommand(cmd) && args[0] === "call") {
captured = JSON.parse(args[args.indexOf("--args") + 1]);
emitAndClose(child, "stdout", JSON.stringify({ results: [] }));
return child;
}
emitAndClose(child, "stdout", "[]");
return child;
});
const { manager } = await createManager();
await manager.search("hello", { sessionKey: "agent:main:slack:dm:u123" });
await manager.close();
expect(captured).not.toBeNull();
const sentArgs = captured as unknown as Record<string, unknown>;
// vsearch is a vector-only mode (see buildV2Searches) — it must NOT trigger
// QMD's LLM reranker, which the "query" tool enables by default.
expect(sentArgs.rerank).toBe(false);
const searchTypes = (sentArgs.searches as Array<{ type?: unknown }>).map((s) => s.type);
expect(searchTypes).toEqual(["vec"]);
});
it("keeps hyphenated tokens in lexical QMD searches while normalizing semantic searches", async () => {
cfg = {
...cfg,

View File

@@ -2638,6 +2638,13 @@ export class QmdMemoryManager implements MemorySearchManager {
// its own reranking pipeline and does not accept a minScore parameter.
searches: this.buildV2Searches(params.query, params.searchCommand),
limit: params.limit,
// "search"/"vsearch" are lexical/vector-only modes (see buildV2Searches):
// they must not trigger the LLM reranker. QMD's "query" tool defaults
// rerank:true, so disable it explicitly for those modes; full "query"
// mode keeps reranking.
...(params.searchCommand === "search" || params.searchCommand === "vsearch"
? { rerank: false }
: {}),
}
: {
// QMD 1.x tools accept a flat query string.