mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-20 21:23:23 +00:00
fix(memory): prefer --mask over --glob for qmd collection pattern flag (#58736)
* fix(memory): prefer --mask over --glob for qmd collection pattern flag
qmd 2.0.1 silently ignores the --glob flag when creating collections,
causing all patterns (e.g. MEMORY.md, memory.md) to fall back to the
default **/*.md glob. This leads to collection conflicts when multiple
collections target the same workspace directory with different patterns.
The existing flag negotiation logic in addCollection() tries --glob
first (when collectionPatternFlag is null), and since qmd accepts the
flag without error, OpenClaw never falls back to --mask. The result is
that memory-root-{agent} gets created with **/*.md instead of MEMORY.md,
and memory-alt-{agent} fails with a duplicate path+pattern conflict.
Fix: default collectionPatternFlag to '--mask' so the working flag is
tried first. The fallback to --glob is preserved for older qmd versions
that may not support --mask.
* docs(changelog): note qmd collection flag fix
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
@@ -19,6 +19,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Channels/WhatsApp: pass inbound message timestamp to model context so the AI can see when WhatsApp messages were sent. (#58590) Thanks @Maninae
|
||||
- Web UI/OpenResponses: preserve rewritten stream snapshots in webchat and keep OpenResponses final streamed text aligned when models rewind earlier output. (#58641) Thanks @neeravmakwana
|
||||
- MiniMax/plugins: auto-enable the bundled MiniMax plugin for API-key auth/config so MiniMax image generation and other plugin-owned capabilities load without manual plugin allowlisting. (#57127) Thanks @tars90percent.
|
||||
- Memory/QMD: prefer `--mask` over `--glob` when creating QMD collections so default memory collections keep their intended patterns and stop colliding on restart. (#58643) Thanks @GitZhangChi.
|
||||
- Gateway/HTTP: skip failing HTTP request stages so one broken facade no longer forces every HTTP endpoint to return 500. (#58746) Thanks @yelog
|
||||
|
||||
## 2026.3.31
|
||||
|
||||
@@ -749,7 +749,10 @@ describe("QmdMemoryManager", () => {
|
||||
const child = createMockChild({ autoClose: false });
|
||||
const pathArg = args[2] ?? "";
|
||||
const name = args[args.indexOf("--name") + 1] ?? "";
|
||||
const pattern = args[args.indexOf("--glob") + 1] ?? args[args.indexOf("--mask") + 1] ?? "";
|
||||
const globIdx = args.indexOf("--glob");
|
||||
const maskIdx = args.indexOf("--mask");
|
||||
const pattern =
|
||||
(globIdx !== -1 ? args[globIdx + 1] : maskIdx !== -1 ? args[maskIdx + 1] : "") ?? "";
|
||||
const hasConflict = [...legacyCollections.entries()].some(
|
||||
([existingName, info]) =>
|
||||
existingName !== name && info.path === pathArg && info.pattern === pattern,
|
||||
@@ -827,7 +830,10 @@ describe("QmdMemoryManager", () => {
|
||||
const child = createMockChild({ autoClose: false });
|
||||
const pathArg = args[2] ?? "";
|
||||
const name = args[args.indexOf("--name") + 1] ?? "";
|
||||
const pattern = args[args.indexOf("--glob") + 1] ?? args[args.indexOf("--mask") + 1] ?? "";
|
||||
const globIdx = args.indexOf("--glob");
|
||||
const maskIdx = args.indexOf("--mask");
|
||||
const pattern =
|
||||
(globIdx !== -1 ? args[globIdx + 1] : maskIdx !== -1 ? args[maskIdx + 1] : "") ?? "";
|
||||
const hasConflict = [...listedCollections.entries()].some(
|
||||
([existingName, info]) =>
|
||||
existingName !== name && info.path === pathArg && info.pattern === pattern,
|
||||
@@ -887,7 +893,7 @@ describe("QmdMemoryManager", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("falls back to --mask when qmd collection add rejects --glob", async () => {
|
||||
it("prefers --mask for collection add and falls back to --glob when --mask is rejected", async () => {
|
||||
cfg = {
|
||||
...cfg,
|
||||
memory: {
|
||||
@@ -909,10 +915,10 @@ describe("QmdMemoryManager", () => {
|
||||
}
|
||||
if (args[0] === "collection" && args[1] === "add") {
|
||||
const child = createMockChild({ autoClose: false });
|
||||
const flag = args.includes("--glob") ? "--glob" : args.includes("--mask") ? "--mask" : "";
|
||||
const flag = args.includes("--mask") ? "--mask" : args.includes("--glob") ? "--glob" : "";
|
||||
addFlagCalls.push(flag);
|
||||
if (flag === "--glob") {
|
||||
emitAndClose(child, "stderr", "unknown flag: --glob", 1);
|
||||
if (flag === "--mask") {
|
||||
emitAndClose(child, "stderr", "unknown flag: --mask", 1);
|
||||
return child;
|
||||
}
|
||||
queueMicrotask(() => child.closeWith(0));
|
||||
@@ -924,7 +930,7 @@ describe("QmdMemoryManager", () => {
|
||||
const { manager } = await createManager({ mode: "full" });
|
||||
await manager.close();
|
||||
|
||||
expect(addFlagCalls).toEqual(["--glob", "--mask", "--mask", "--mask"]);
|
||||
expect(addFlagCalls).toEqual(["--mask", "--glob", "--glob", "--glob"]);
|
||||
expect(logWarnMock).toHaveBeenCalledWith(
|
||||
expect.stringContaining("retrying with legacy compatibility flag"),
|
||||
);
|
||||
|
||||
@@ -274,7 +274,7 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
private attemptedNullByteCollectionRepair = false;
|
||||
private attemptedDuplicateDocumentRepair = false;
|
||||
private readonly sessionWarm = new Set<string>();
|
||||
private collectionPatternFlag: QmdCollectionPatternFlag | null = null;
|
||||
private collectionPatternFlag: QmdCollectionPatternFlag | null = "--mask";
|
||||
|
||||
private constructor(params: {
|
||||
cfg: OpenClawConfig;
|
||||
|
||||
Reference in New Issue
Block a user