mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 15:01:34 +08:00
fix(session_search): exclude current session lineage
Cherry-picked from PR #2201 by @Gutslabs. session_search resolved hits to parent/root sessions but only excluded the exact current_session_id. If the active session was a child continuation (compression/delegation), its parent could still appear as a 'past' conversation result. Fix: resolve current_session_id to its lineage root before filtering, so the entire active lineage (parent and children) is excluded.
This commit is contained in:
@@ -214,3 +214,61 @@ class TestSessionSearch:
|
|||||||
# Current session should be skipped, only other_sid should appear
|
# Current session should be skipped, only other_sid should appear
|
||||||
assert result["sessions_searched"] == 1
|
assert result["sessions_searched"] == 1
|
||||||
assert current_sid not in [r.get("session_id") for r in result.get("results", [])]
|
assert current_sid not in [r.get("session_id") for r in result.get("results", [])]
|
||||||
|
|
||||||
|
def test_current_child_session_excludes_parent_lineage(self):
|
||||||
|
"""Compression/delegation parents should be excluded for the active child session."""
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
from tools.session_search_tool import session_search
|
||||||
|
|
||||||
|
mock_db = MagicMock()
|
||||||
|
mock_db.search_messages.return_value = [
|
||||||
|
{"session_id": "parent_sid", "content": "match", "source": "cli",
|
||||||
|
"session_started": 1709500000, "model": "test"},
|
||||||
|
]
|
||||||
|
|
||||||
|
def _get_session(session_id):
|
||||||
|
if session_id == "child_sid":
|
||||||
|
return {"parent_session_id": "parent_sid"}
|
||||||
|
if session_id == "parent_sid":
|
||||||
|
return {"parent_session_id": None}
|
||||||
|
return None
|
||||||
|
|
||||||
|
mock_db.get_session.side_effect = _get_session
|
||||||
|
|
||||||
|
result = json.loads(session_search(
|
||||||
|
query="test", db=mock_db, current_session_id="child_sid",
|
||||||
|
))
|
||||||
|
|
||||||
|
assert result["success"] is True
|
||||||
|
assert result["count"] == 0
|
||||||
|
assert result["results"] == []
|
||||||
|
assert result["sessions_searched"] == 0
|
||||||
|
|
||||||
|
def test_current_root_session_excludes_child_lineage(self):
|
||||||
|
"""Delegation child hits should be excluded when they resolve to the current root session."""
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
from tools.session_search_tool import session_search
|
||||||
|
|
||||||
|
mock_db = MagicMock()
|
||||||
|
mock_db.search_messages.return_value = [
|
||||||
|
{"session_id": "child_sid", "content": "match", "source": "cli",
|
||||||
|
"session_started": 1709500000, "model": "test"},
|
||||||
|
]
|
||||||
|
|
||||||
|
def _get_session(session_id):
|
||||||
|
if session_id == "root_sid":
|
||||||
|
return {"parent_session_id": None}
|
||||||
|
if session_id == "child_sid":
|
||||||
|
return {"parent_session_id": "root_sid"}
|
||||||
|
return None
|
||||||
|
|
||||||
|
mock_db.get_session.side_effect = _get_session
|
||||||
|
|
||||||
|
result = json.loads(session_search(
|
||||||
|
query="test", db=mock_db, current_session_id="root_sid",
|
||||||
|
))
|
||||||
|
|
||||||
|
assert result["success"] is True
|
||||||
|
assert result["count"] == 0
|
||||||
|
assert result["results"] == []
|
||||||
|
assert result["sessions_searched"] == 0
|
||||||
|
|||||||
@@ -251,13 +251,20 @@ def session_search(
|
|||||||
break
|
break
|
||||||
return sid
|
return sid
|
||||||
|
|
||||||
# Group by resolved (parent) session_id, dedup, skip current session
|
current_lineage_root = (
|
||||||
|
_resolve_to_parent(current_session_id) if current_session_id else None
|
||||||
|
)
|
||||||
|
|
||||||
|
# Group by resolved (parent) session_id, dedup, skip the current
|
||||||
|
# session lineage. Compression and delegation create child sessions
|
||||||
|
# that still belong to the same active conversation.
|
||||||
seen_sessions = {}
|
seen_sessions = {}
|
||||||
for result in raw_results:
|
for result in raw_results:
|
||||||
raw_sid = result["session_id"]
|
raw_sid = result["session_id"]
|
||||||
resolved_sid = _resolve_to_parent(raw_sid)
|
resolved_sid = _resolve_to_parent(raw_sid)
|
||||||
# Skip the current session — the agent already has that context
|
# Skip the current session lineage — the agent already has that
|
||||||
if current_session_id and resolved_sid == current_session_id:
|
# context, even if older turns live in parent fragments.
|
||||||
|
if current_lineage_root and resolved_sid == current_lineage_root:
|
||||||
continue
|
continue
|
||||||
if current_session_id and raw_sid == current_session_id:
|
if current_session_id and raw_sid == current_session_id:
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user