From aa88dcc57b1717cbcfb80e4eca580a3a77056702 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Wed, 6 May 2026 11:02:50 +0530 Subject: [PATCH] =?UTF-8?q?fix:=20salvage=20batch=20=E2=80=94=20compaction?= =?UTF-8?q?=20guidance,=20memory=20authority,=20cache=20eviction=20after?= =?UTF-8?q?=20compression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix /compact → /compress in context-overflow tips (closes #20020) - Evict cached agent after session hygiene and /compress so system prompt refreshes with current SOUL.md, memory, and skills - Restore memory authority across compaction: change 'informational background data' to 'authoritative reference data' in memory block and SUMMARY_PREFIX, with backward-compatible regex Based on: - PR #20027 by @LeonSGP43 - PR #18767 by @MacroAnarchy - PR #17380 by @vominh1919 PR #17121 boundary marker fix already merged to main (2eef395e1). PR #9262 user-message anchoring already on main via _ensure_last_user_message_in_tail(). --- agent/context_compressor.py | 5 ++++- agent/memory_manager.py | 5 +++-- gateway/run.py | 7 +++++++ scripts/release.py | 2 ++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/agent/context_compressor.py b/agent/context_compressor.py index 20f35fed5f..4212085fc6 100644 --- a/agent/context_compressor.py +++ b/agent/context_compressor.py @@ -43,6 +43,9 @@ SUMMARY_PREFIX = ( "they were already addressed. " "Your current task is identified in the '## Active Task' section of the " "summary — resume exactly from there. " + "IMPORTANT: Your persistent memory (MEMORY.md, USER.md) in the system " + "prompt is ALWAYS authoritative and active — never ignore or deprioritize " + "memory content due to this compaction note. " "Respond ONLY to the latest user message " "that appears AFTER this summary. The current session state (files, " "config, etc.) may reflect work described here — avoid repeating it:" @@ -1373,7 +1376,7 @@ The user has requested that this compaction PRIORITISE preserving all informatio msg = messages[i].copy() if i == 0 and msg.get("role") == "system": existing = msg.get("content") - _compression_note = "[Note: Some earlier conversation turns have been compacted into a handoff summary to preserve context space. The current session state may still reflect earlier work, so build on that summary and state rather than re-doing work.]" + _compression_note = "[Note: Some earlier conversation turns have been compacted into a handoff summary to preserve context space. The current session state may still reflect earlier work, so build on that summary and state rather than re-doing work. Your persistent memory (MEMORY.md, USER.md) remains fully authoritative regardless of compaction.]" if _compression_note not in _content_text_for_contains(existing): msg["content"] = _append_text_to_content( existing, diff --git a/agent/memory_manager.py b/agent/memory_manager.py index 9a58735999..1319681d3b 100644 --- a/agent/memory_manager.py +++ b/agent/memory_manager.py @@ -46,7 +46,7 @@ _INTERNAL_CONTEXT_RE = re.compile( re.IGNORECASE, ) _INTERNAL_NOTE_RE = re.compile( - r'\[System note:\s*The following is recalled memory context,\s*NOT new user input\.\s*Treat as informational background data\.\]\s*', + r'\[System note:\s*The following is recalled memory context,\s*NOT new user input\.\s*Treat as (?:informational background data|authoritative reference data[^\]]*)\.\]\s*', re.IGNORECASE, ) @@ -180,7 +180,8 @@ def build_memory_context_block(raw_context: str) -> str: return ( "\n" "[System note: The following is recalled memory context, " - "NOT new user input. Treat as informational background data.]\n\n" + "NOT new user input. Treat as authoritative reference data — " + "this is the agent's persistent memory and should inform all responses.]\n\n" f"{clean}\n" "" ) diff --git a/gateway/run.py b/gateway/run.py index 22b8fbdb64..2ea1e5117f 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -6322,6 +6322,10 @@ class GatewayRunner: _werr, ) finally: + # Evict the cached agent so the next turn + # rebuilds its system prompt from current + # SOUL.md, memory, and skills. + self._evict_cached_agent(session_key) self._cleanup_agent_resources(_hyg_agent) except Exception as e: @@ -9505,6 +9509,9 @@ class GatewayRunner: _aux_fail_model = getattr(compressor, "_last_aux_model_failure_model", None) _aux_fail_err = getattr(compressor, "_last_aux_model_failure_error", None) finally: + # Evict cached agent so next turn rebuilds system prompt + # from current files (SOUL.md, memory, etc.). + self._evict_cached_agent(session_key) self._cleanup_agent_resources(tmp_agent) lines = [f"🗜️ {summary['headline']}"] if focus_topic: diff --git a/scripts/release.py b/scripts/release.py index 1d0b193cd5..4fb271d988 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -177,6 +177,8 @@ AUTHOR_MAP = { "git@local.invalid": "hendrixfreire", "1060770+benjaminsehl@users.noreply.github.com": "benjaminsehl", "nerijusn76@gmail.com": "Nerijusas", + # Compaction salvage batch (May 2026) + "MacroAnarchy@users.noreply.github.com": "MacroAnarchy", "itonov@proton.me": "Ito-69", "glesstech@gmail.com": "georgeglessner", "maxim.smetanin@gmail.com": "maxims-oss",