diff --git a/CHANGELOG.md b/CHANGELOG.md index e4f2a5f7fe4..42c3d056110 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -121,6 +121,7 @@ Docs: https://docs.openclaw.ai - Dependencies: override transitive `ip-address` to `10.2.0` so the runtime lockfile no longer includes the vulnerable `10.1.0` build flagged by Dependabot alert 109. Thanks @vincentkoc. - Plugins/install: apply OpenClaw's npm security overrides inside managed external plugin npm roots so hoisted plugin dependencies inherit the host package hardening. Thanks @vincentkoc. - Feishu: hydrate missing native topic starter thread IDs before session routing so first turns and follow-ups stay in the same topic session. Fixes #78262. Thanks @joeyzenghuan. +- Memory Wiki: skip empty and whitespace-only source pages when refreshing generated Related blocks, preventing blank pages from being rewritten into Related-only stubs. Fixes #78121. Thanks @amknight. - LINE: reject `dmPolicy: "open"` configs without wildcard `allowFrom` so webhook DMs fail validation instead of being acknowledged and silently blocked before inbound processing. Fixes #78316. - Telegram/Codex: keep message-tool-only progress drafts visible and render native Codex tool progress once per tool instead of duplicating item/tool draft lines. Fixes #75641. (#77949) Thanks @keshavbotagent. - Providers/xAI: stop sending OpenAI-style reasoning effort controls to native Grok Responses models, so `xai/grok-4.3` no longer fails live Docker/Gateway runs with `Invalid reasoning effort`. diff --git a/extensions/memory-wiki/src/compile.test.ts b/extensions/memory-wiki/src/compile.test.ts index 4a3bc8bf1c5..494513d2232 100644 --- a/extensions/memory-wiki/src/compile.test.ts +++ b/extensions/memory-wiki/src/compile.test.ts @@ -170,6 +170,24 @@ describe("compileMemoryWikiVault", () => { ); }); + it("does not rewrite empty source pages into related-only stubs", async () => { + const { rootDir, config } = await createVault({ + rootDir: nextCaseRoot(), + initialize: true, + }); + const emptySourcePath = path.join(rootDir, "sources", "empty.md"); + const whitespaceSourcePath = path.join(rootDir, "sources", "whitespace.md"); + await fs.writeFile(emptySourcePath, "", "utf8"); + await fs.writeFile(whitespaceSourcePath, " \n\t", "utf8"); + + const result = await compileMemoryWikiVault(config); + + await expect(fs.readFile(emptySourcePath, "utf8")).resolves.toBe(""); + await expect(fs.readFile(whitespaceSourcePath, "utf8")).resolves.toBe(" \n\t"); + expect(result.updatedFiles).not.toContain(emptySourcePath); + expect(result.updatedFiles).not.toContain(whitespaceSourcePath); + }); + it("does not relate every page through a broad shared source", async () => { const { rootDir, config } = await createVault({ rootDir: nextCaseRoot(), diff --git a/extensions/memory-wiki/src/compile.ts b/extensions/memory-wiki/src/compile.ts index 4d876d8a10c..7d59bb22d6b 100644 --- a/extensions/memory-wiki/src/compile.ts +++ b/extensions/memory-wiki/src/compile.ts @@ -776,6 +776,9 @@ async function refreshPageRelatedBlocks(params: { continue; } const original = await root.readText(page.relativePath); + if (original.trim().length === 0) { + continue; + } const updated = withTrailingNewline( replaceManagedMarkdownBlock({ original,