From 70a0a5ff4a20bcf1cf5f94f3d13629c09ae2b517 Mon Sep 17 00:00:00 2001 From: teknium1 Date: Wed, 4 Mar 2026 06:06:40 -0800 Subject: [PATCH] fix: exclude current session from session_search results MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit session_search was returning the current session if it matched the query, which is redundant — the agent already has the current conversation context. This wasted an LLM summarization call and a result slot. Added current_session_id parameter to session_search(). The agent passes self.session_id and the search filters out any results where either the raw or parent-resolved session ID matches. Both the raw match and the parent-resolved match are checked to handle child sessions from delegation. Two tests added verifying the exclusion works and that other sessions are still returned. --- run_agent.py | 1 + tests/tools/test_session_search.py | 59 ++++++++++++++++++++++++++++++ tools/session_search_tool.py | 12 +++++- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/run_agent.py b/run_agent.py index 448387772..aef2fb884 100644 --- a/run_agent.py +++ b/run_agent.py @@ -2476,6 +2476,7 @@ class AIAgent: role_filter=function_args.get("role_filter"), limit=function_args.get("limit", 3), db=self._session_db, + current_session_id=self.session_id, ) tool_duration = time.time() - tool_start_time if self.quiet_mode: diff --git a/tests/tools/test_session_search.py b/tests/tools/test_session_search.py index 8ba040ec1..645e08ffc 100644 --- a/tests/tools/test_session_search.py +++ b/tests/tools/test_session_search.py @@ -145,3 +145,62 @@ class TestSessionSearch: mock_db = object() result = json.loads(session_search(query=" ", db=mock_db)) assert result["success"] is False + + def test_current_session_excluded(self): + """session_search should never return the current session.""" + from unittest.mock import MagicMock + from tools.session_search_tool import session_search + + mock_db = MagicMock() + current_sid = "20260304_120000_abc123" + + # Simulate FTS5 returning matches only from the current session + mock_db.search_messages.return_value = [ + {"session_id": current_sid, "content": "test match", "source": "cli", + "session_started": 1709500000, "model": "test"}, + ] + mock_db.get_session.return_value = {"parent_session_id": None} + + result = json.loads(session_search( + query="test", db=mock_db, current_session_id=current_sid, + )) + assert result["success"] is True + assert result["count"] == 0 + assert result["results"] == [] + + def test_current_session_excluded_keeps_others(self): + """Other sessions should still be returned when current is excluded.""" + from unittest.mock import MagicMock + from tools.session_search_tool import session_search + + mock_db = MagicMock() + current_sid = "20260304_120000_abc123" + other_sid = "20260303_100000_def456" + + mock_db.search_messages.return_value = [ + {"session_id": current_sid, "content": "match 1", "source": "cli", + "session_started": 1709500000, "model": "test"}, + {"session_id": other_sid, "content": "match 2", "source": "telegram", + "session_started": 1709400000, "model": "test"}, + ] + mock_db.get_session.return_value = {"parent_session_id": None} + mock_db.get_messages_as_conversation.return_value = [ + {"role": "user", "content": "hello"}, + {"role": "assistant", "content": "hi there"}, + ] + + # Mock the summarizer to return a simple summary + import tools.session_search_tool as sst + original_client = sst._async_aux_client + sst._async_aux_client = None # Disable summarizer → returns None + + result = json.loads(session_search( + query="test", db=mock_db, current_session_id=current_sid, + )) + + sst._async_aux_client = original_client + + assert result["success"] is True + # 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", [])] diff --git a/tools/session_search_tool.py b/tools/session_search_tool.py index b11b79fda..31693ec8f 100644 --- a/tools/session_search_tool.py +++ b/tools/session_search_tool.py @@ -183,11 +183,13 @@ def session_search( role_filter: str = None, limit: int = 3, db=None, + current_session_id: str = None, ) -> str: """ Search past sessions and return focused summaries of matching conversations. Uses FTS5 to find matches, then summarizes the top sessions with Gemini Flash. + The current session is excluded from results since the agent already has that context. """ if db is None: return json.dumps({"success": False, "error": "Session database not available."}, ensure_ascii=False) @@ -238,11 +240,16 @@ def session_search( break return sid - # Group by resolved (parent) session_id, dedup + # Group by resolved (parent) session_id, dedup, skip current session 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: + continue + if current_session_id and raw_sid == current_session_id: + continue if resolved_sid not in seen_sessions: result = dict(result) result["session_id"] = resolved_sid @@ -368,6 +375,7 @@ registry.register( query=args.get("query", ""), role_filter=args.get("role_filter"), limit=args.get("limit", 3), - db=kw.get("db")), + db=kw.get("db"), + current_session_id=kw.get("current_session_id")), check_fn=check_session_search_requirements, )