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
|
||||
assert result["sessions_searched"] == 1
|
||||
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
|
||||
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 = {}
|
||||
for result in raw_results:
|
||||
raw_sid = result["session_id"]
|
||||
resolved_sid = _resolve_to_parent(raw_sid)
|
||||
# Skip the current session — the agent already has that context
|
||||
if current_session_id and resolved_sid == current_session_id:
|
||||
# Skip the current session lineage — the agent already has that
|
||||
# context, even if older turns live in parent fragments.
|
||||
if current_lineage_root and resolved_sid == current_lineage_root:
|
||||
continue
|
||||
if current_session_id and raw_sid == current_session_id:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user