From 8144d6b554e63e39c6b64bbd9f74014f73e28a6f Mon Sep 17 00:00:00 2001 From: twentyOne2x Date: Sat, 18 Jul 2026 01:30:20 +0200 Subject: [PATCH] Preserve Leo subject anchors across long followups (#187) --- .../vps/leo-db-context/__init__.py | 2 +- .../test_hermes_leoclean_db_context_plugin.py | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/hermes-agent/leoclean-plugins/vps/leo-db-context/__init__.py b/hermes-agent/leoclean-plugins/vps/leo-db-context/__init__.py index 763390b..90b3c04 100644 --- a/hermes-agent/leoclean-plugins/vps/leo-db-context/__init__.py +++ b/hermes-agent/leoclean-plugins/vps/leo-db-context/__init__.py @@ -26,7 +26,7 @@ MAX_EVIDENCE_EXCERPT_CHARS = 600 MAX_RETRIEVAL_ANCHORS = 8 MAX_RETRIEVAL_SUBJECT_ANCHORS = 2 MAX_RETRIEVAL_FALLBACK_ANCHORS = 3 -RETRIEVAL_HISTORY_USER_TURNS = 6 +RETRIEVAL_HISTORY_USER_TURNS = 12 DATABASE_REASONING_PROTOCOL_VERSION = "leo-db-reasoning-v2" WORD_RE = re.compile(r"\b\w+(?:[-']\w+)*\b") LIST_PREFIX_RE = re.compile(r"^(\s*(?:[-*]|\d+[.)])\s+)(.*)$") diff --git a/tests/test_hermes_leoclean_db_context_plugin.py b/tests/test_hermes_leoclean_db_context_plugin.py index af111d7..5831998 100644 --- a/tests/test_hermes_leoclean_db_context_plugin.py +++ b/tests/test_hermes_leoclean_db_context_plugin.py @@ -484,6 +484,36 @@ def test_plugin_anchors_followup_retrieval_to_recent_user_topics_without_assista assert len(anchors) <= module.MAX_RETRIEVAL_ANCHORS +def test_plugin_preserves_explicit_subject_across_a_long_followup_chain() -> None: + module = load_plugin() + query = ( + "Turn the surviving claim into a review-only proposal: exact body, confidence, falsifier, required " + "sources, and links to claims that support or contradict it. Do not stage or write anything." + ) + history = [ + { + "role": "user", + "content": "Under what conditions would LivingIP ownership make a culture worse?", + }, + {"role": "assistant", "content": "UNRELATED_ASSISTANT_SECRET about another domain."}, + {"role": "user", "content": "challenge which mechanism is causal."}, + {"role": "user", "content": "compare the two designs."}, + {"role": "user", "content": "retract the strongest version."}, + {"role": "user", "content": "state the weaker surviving position."}, + {"role": "user", "content": "make the confidence explicit."}, + {"role": "user", "content": "add the smallest falsification test."}, + {"role": "user", "content": "separate direct support from analogy."}, + {"role": "user", "content": "keep the result proposed only."}, + {"role": "user", "content": query}, + ] + + retrieval_query, anchors = module._contextual_retrieval_query(query, history) + + assert retrieval_query == query + assert anchors == ["LivingIP"] + assert "UNRELATED_ASSISTANT_SECRET" not in retrieval_query + + def test_plugin_keeps_operational_query_separate_from_contextual_anchors(tmp_path: Path) -> None: module = load_plugin() home = tmp_path / "profile"