From 9cfb56696f88226837fff023521c83c7668435d5 Mon Sep 17 00:00:00 2001 From: Tarun Sukhani Date: Sat, 7 Feb 2026 07:21:11 +0800 Subject: [PATCH] memory-neo4j: extract stripMessageWrappers helper, use in cleanup for accurate gating --- extensions/memory-neo4j/extractor.ts | 44 +++++++++++++++------------- extensions/memory-neo4j/index.ts | 7 +++-- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/extensions/memory-neo4j/extractor.ts b/extensions/memory-neo4j/extractor.ts index 3cc00ac9c3c..d4184c5c2e2 100644 --- a/extensions/memory-neo4j/extractor.ts +++ b/extensions/memory-neo4j/extractor.ts @@ -872,24 +872,28 @@ export function extractUserMessages(messages: unknown[]): string[] { } } - // Strip injected context, channel metadata wrappers, and system prefixes - // so the attention gate sees only the raw user text. - return texts - .map((t) => { - let s = t; - // Injected context from memory system - s = s.replace(/[\s\S]*?<\/relevant-memories>\s*/g, ""); - s = s.replace(/[\s\S]*?<\/core-memory-refresh>\s*/g, ""); - s = s.replace(/[\s\S]*?<\/system>\s*/g, ""); - // Media attachment preamble (appears before Telegram wrapper) - s = s.replace(/^\[media attached:[^\]]*\]\s*(?:To send an image[^\n]*\n?)*/i, ""); - // System exec output blocks (may appear before Telegram wrapper) - s = s.replace(/^(?:System:\s*\[[^\]]*\][^\n]*\n?)+/gi, ""); - // Telegram wrapper — may now be at start after previous strips - s = s.replace(/^\s*\[Telegram\s[^\]]+\]\s*/i, ""); - // "[message_id: NNN]" suffix - s = s.replace(/\n?\[message_id:\s*\d+\]\s*$/i, ""); - return s.trim(); - }) - .filter((t) => t.length >= 10); + // Strip wrappers then filter by length + return texts.map(stripMessageWrappers).filter((t) => t.length >= 10); +} + +/** + * Strip injected context, channel metadata wrappers, and system prefixes + * so the attention gate sees only the raw user text. + * Exported for use by the cleanup command. + */ +export function stripMessageWrappers(text: string): string { + let s = text; + // Injected context from memory system + s = s.replace(/[\s\S]*?<\/relevant-memories>\s*/g, ""); + s = s.replace(/[\s\S]*?<\/core-memory-refresh>\s*/g, ""); + s = s.replace(/[\s\S]*?<\/system>\s*/g, ""); + // Media attachment preamble (appears before Telegram wrapper) + s = s.replace(/^\[media attached:[^\]]*\]\s*(?:To send an image[^\n]*\n?)*/i, ""); + // System exec output blocks (may appear before Telegram wrapper) + s = s.replace(/^(?:System:\s*\[[^\]]*\][^\n]*\n?)+/gi, ""); + // Telegram wrapper — may now be at start after previous strips + s = s.replace(/^\s*\[Telegram\s[^\]]+\]\s*/i, ""); + // "[message_id: NNN]" suffix + s = s.replace(/\n?\[message_id:\s*\d+\]\s*$/i, ""); + return s.trim(); } diff --git a/extensions/memory-neo4j/index.ts b/extensions/memory-neo4j/index.ts index 19eca4e7e05..43902e1e55b 100644 --- a/extensions/memory-neo4j/index.ts +++ b/extensions/memory-neo4j/index.ts @@ -26,7 +26,7 @@ import { vectorDimsForModel, } from "./config.js"; import { Embeddings } from "./embeddings.js"; -import { extractUserMessages, runSleepCycle } from "./extractor.js"; +import { extractUserMessages, stripMessageWrappers, runSleepCycle } from "./extractor.js"; import { Neo4jMemoryClient } from "./neo4j-client.js"; import { hybridSearch } from "./search.js"; @@ -735,10 +735,11 @@ const memoryNeo4jPlugin = { opts.agent ? { agentId: opts.agent } : {}, ); - // Run each through the attention gate + // Strip channel metadata wrappers (same as the real pipeline) then gate const noise: Array<{ id: string; text: string; source: string }> = []; for (const mem of allMemories) { - if (!passesAttentionGate(mem.text)) { + const stripped = stripMessageWrappers(mem.text); + if (!passesAttentionGate(stripped)) { noise.push(mem); } }