From e93b539a8f658f2dbc9b16e219ab09a418e1866e Mon Sep 17 00:00:00 2001 From: Teknium Date: Sun, 22 Mar 2026 11:22:10 -0700 Subject: [PATCH 1/2] feat(session_search): add recent sessions mode when query is omitted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When session_search is called without a query (or with an empty query), it now returns metadata for the most recent sessions instead of erroring. This lets the agent quickly see what was worked on recently without needing specific keywords. Returns for each session: session_id, title, source, started_at, last_active, message_count, preview (first user message). Zero LLM cost — pure DB query. Current session lineage and child delegation sessions are excluded. The agent can then keyword-search specific sessions if it needs deeper context from any of them. --- tools/session_search_tool.py | 65 +++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/tools/session_search_tool.py b/tools/session_search_tool.py index 7f5332c54..704043829 100644 --- a/tools/session_search_tool.py +++ b/tools/session_search_tool.py @@ -179,6 +179,58 @@ async def _summarize_session( return None +def _list_recent_sessions(db, limit: int, current_session_id: str = None) -> str: + """Return metadata for the most recent sessions (no LLM calls).""" + try: + sessions = db.list_sessions_rich(limit=limit + 5) # fetch extra to skip current + + # Resolve current session lineage to exclude it + current_root = None + if current_session_id: + try: + sid = current_session_id + visited = set() + while sid and sid not in visited: + visited.add(sid) + s = db.get_session(sid) + parent = s.get("parent_session_id") if s else None + sid = parent if parent else None + current_root = max(visited, key=len) if visited else current_session_id + except Exception: + current_root = current_session_id + + results = [] + for s in sessions: + sid = s.get("id", "") + if current_root and (sid == current_root or sid == current_session_id): + continue + # Skip child/delegation sessions (they have parent_session_id) + if s.get("parent_session_id"): + continue + results.append({ + "session_id": sid, + "title": s.get("title") or None, + "source": s.get("source", ""), + "started_at": s.get("started_at", ""), + "last_active": s.get("last_active", ""), + "message_count": s.get("message_count", 0), + "preview": s.get("preview", ""), + }) + if len(results) >= limit: + break + + return json.dumps({ + "success": True, + "mode": "recent", + "results": results, + "count": len(results), + "message": f"Showing {len(results)} most recent sessions. Use a keyword query to search specific topics.", + }, ensure_ascii=False) + except Exception as e: + logging.error("Error listing recent sessions: %s", e, exc_info=True) + return json.dumps({"success": False, "error": f"Failed to list recent sessions: {e}"}, ensure_ascii=False) + + def session_search( query: str, role_filter: str = None, @@ -195,11 +247,14 @@ def session_search( if db is None: return json.dumps({"success": False, "error": "Session database not available."}, ensure_ascii=False) + limit = min(limit, 5) # Cap at 5 sessions to avoid excessive LLM calls + + # Recent sessions mode: when query is empty, return metadata for recent sessions. + # No LLM calls — just DB queries for titles, previews, timestamps. if not query or not query.strip(): - return json.dumps({"success": False, "error": "Query cannot be empty."}, ensure_ascii=False) + return _list_recent_sessions(db, limit, current_session_id) query = query.strip() - limit = min(limit, 5) # Cap at 5 sessions to avoid excessive LLM calls try: # Parse role filter @@ -385,7 +440,7 @@ SESSION_SEARCH_SCHEMA = { "properties": { "query": { "type": "string", - "description": "Search query — keywords, phrases, or boolean expressions to find in past sessions.", + "description": "Search query — keywords, phrases, or boolean expressions to find in past sessions. Omit to list recent sessions instead (no search, just metadata).", }, "role_filter": { "type": "string", @@ -397,7 +452,7 @@ SESSION_SEARCH_SCHEMA = { "default": 3, }, }, - "required": ["query"], + "required": [], }, } @@ -410,7 +465,7 @@ registry.register( toolset="session_search", schema=SESSION_SEARCH_SCHEMA, handler=lambda args, **kw: session_search( - query=args.get("query", ""), + query=args.get("query") or "", role_filter=args.get("role_filter"), limit=args.get("limit", 3), db=kw.get("db"), From 1e9ff53a740299bb61ea322a6f629302d3ee5eaf Mon Sep 17 00:00:00 2001 From: Teknium Date: Tue, 24 Mar 2026 18:08:06 -0700 Subject: [PATCH 2/2] docs: clarify two-mode behavior in session_search schema description --- tools/session_search_tool.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/session_search_tool.py b/tools/session_search_tool.py index 704043829..3c419cabd 100644 --- a/tools/session_search_tool.py +++ b/tools/session_search_tool.py @@ -419,8 +419,14 @@ def check_session_search_requirements() -> bool: SESSION_SEARCH_SCHEMA = { "name": "session_search", "description": ( - "Search your long-term memory of past conversations. This is your recall -- " + "Search your long-term memory of past conversations, or browse recent sessions. This is your recall -- " "every past session is searchable, and this tool summarizes what happened.\n\n" + "TWO MODES:\n" + "1. Recent sessions (no query): Call with no arguments to see what was worked on recently. " + "Returns titles, previews, and timestamps. Zero LLM cost, instant. " + "Start here when the user asks what were we working on or what did we do recently.\n" + "2. Keyword search (with query): Search for specific topics across all past sessions. " + "Returns LLM-generated summaries of matching sessions.\n\n" "USE THIS PROACTIVELY when:\n" "- The user says 'we did this before', 'remember when', 'last time', 'as I mentioned'\n" "- The user asks about a topic you worked on before but don't have in current context\n" @@ -440,7 +446,7 @@ SESSION_SEARCH_SCHEMA = { "properties": { "query": { "type": "string", - "description": "Search query — keywords, phrases, or boolean expressions to find in past sessions. Omit to list recent sessions instead (no search, just metadata).", + "description": "Search query — keywords, phrases, or boolean expressions to find in past sessions. Omit this parameter entirely to browse recent sessions instead (returns titles, previews, timestamps with no LLM cost).", }, "role_filter": { "type": "string",