fix(memory): verify qmd conflict before rebind · openclaw/openclaw@49db190
MonkeyLeeT
·
2026-05-09
·
via Recent Commits to openclaw:main
File tree
extensions/memory-core/src/memory
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1049,7 +1049,7 @@ describe("QmdMemoryManager", () => {
|
1049 | 1049 | ); |
1050 | 1050 | }); |
1051 | 1051 | |
1052 | | -it("rebinds a path-pattern conflict when qmd add reports the stale collection name", async () => { |
| 1052 | +it("refuses to rebind a stderr-only path-pattern conflict without collection metadata", async () => { |
1053 | 1053 | cfg = { |
1054 | 1054 | ...cfg, |
1055 | 1055 | memory: { |
@@ -1111,10 +1111,10 @@ describe("QmdMemoryManager", () => {
|
1111 | 1111 | const { manager } = await createManager({ mode: "full" }); |
1112 | 1112 | await manager.close(); |
1113 | 1113 | |
1114 | | -expect(removeCalls).toEqual(["workspace-legacy"]); |
1115 | | -expect(addCalls).toEqual(["workspace-main", "workspace-main"]); |
1116 | | -expect(logWarnMock).toHaveBeenCalledWith(expect.stringContaining("rebinding")); |
1117 | | -expect(logWarnMock).not.toHaveBeenCalledWith( |
| 1114 | +expect(removeCalls).toEqual([]); |
| 1115 | +expect(addCalls).toEqual(["workspace-main"]); |
| 1116 | +expect(logWarnMock).not.toHaveBeenCalledWith(expect.stringContaining("rebinding")); |
| 1117 | +expect(logWarnMock).toHaveBeenCalledWith( |
1118 | 1118 | expect.stringContaining("qmd collection add skipped for workspace-main"), |
1119 | 1119 | ); |
1120 | 1120 | }); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -671,7 +671,23 @@ export class QmdMemoryManager implements MemorySearchManager {
|
671 | 671 | conflictName = this.findCollectionByPathPattern(collection, existing); |
672 | 672 | } |
673 | 673 | |
674 | | -conflictName ??= this.parseConflictingCollectionNameFromAddError(addErrorMessage); |
| 674 | +if (!conflictName) { |
| 675 | +const parsedConflictName = this.parseConflictingCollectionNameFromAddError(addErrorMessage); |
| 676 | +const parsedDetails = parsedConflictName ? existing.get(parsedConflictName) : undefined; |
| 677 | +if ( |
| 678 | +parsedConflictName && |
| 679 | +parsedDetails?.path && |
| 680 | +typeof parsedDetails.pattern === "string" && |
| 681 | +this.pathsMatch(parsedDetails.path, collection.path) && |
| 682 | +this.patternsMatchForManagedCollection( |
| 683 | +collection.path, |
| 684 | +parsedDetails.pattern, |
| 685 | +collection.pattern, |
| 686 | +) |
| 687 | +) { |
| 688 | +conflictName = parsedConflictName; |
| 689 | +} |
| 690 | +} |
675 | 691 | |
676 | 692 | if (!conflictName) { |
677 | 693 | return false; |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。