From 8aa531c7faeab93fb02a31fc8091f62a192c1bcb Mon Sep 17 00:00:00 2001 From: Bartok Moltbot Date: Fri, 27 Feb 2026 00:32:17 -0500 Subject: [PATCH] fix(gateway): Pass session_db to AIAgent, fixing session_search error When running via the gateway (e.g. Telegram), the session_search tool returned: {"error": "session_search must be handled by the agent loop"} Root cause: - gateway/run.py creates AIAgent without passing session_db= - self._session_db is None in the agent instance - The dispatch condition "elif function_name == 'session_search' and self._session_db" skips when _session_db is None, falling through to the generic error This fix: 1. Initializes self._session_db in GatewayRunner.__init__() 2. Passes session_db to all AIAgent instantiations in gateway/run.py 3. Adds defensive fallback in run_agent.py to return a clear error when session_db is unavailable, instead of falling through Fixes #105 --- gateway/run.py | 12 ++++++++++++ run_agent.py | 19 +++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/gateway/run.py b/gateway/run.py index f59374ea4..71d5c60d4 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -149,6 +149,14 @@ class GatewayRunner: # Key: session_key, Value: {"command": str, "pattern_key": str} self._pending_approvals: Dict[str, Dict[str, str]] = {} + # Initialize session database for session_search tool support + self._session_db = None + try: + from hermes_state import SessionDB + self._session_db = SessionDB() + except Exception as e: + logger.debug("SQLite session store not available: %s", e) + def _flush_memories_before_reset(self, old_entry): """Prompt the agent to save memories/skills before an auto-reset. @@ -177,6 +185,7 @@ class GatewayRunner: quiet_mode=True, enabled_toolsets=["memory", "skills"], session_id=old_entry.session_id, + session_db=self._session_db, ) # Build conversation history from transcript @@ -862,6 +871,7 @@ class GatewayRunner: _flush_api_key = os.getenv("OPENAI_API_KEY") or os.getenv("OPENROUTER_API_KEY", "") _flush_base_url = os.getenv("OPENAI_BASE_URL") or os.getenv("OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1") _flush_model = os.getenv("HERMES_MODEL") or os.getenv("LLM_MODEL", "anthropic/claude-opus-4.6") + _flush_session_db = self._session_db def _do_flush(): tmp_agent = AIAgent( model=_flush_model, @@ -871,6 +881,7 @@ class GatewayRunner: quiet_mode=True, enabled_toolsets=["memory"], session_id=old_entry.session_id, + session_db=_flush_session_db, ) # Build simple message list from transcript msgs = [] @@ -1530,6 +1541,7 @@ class GatewayRunner: session_id=session_id, tool_progress_callback=progress_callback if tool_progress_enabled else None, platform=platform_key, + session_db=self._session_db, ) # Store agent reference for interrupt support diff --git a/run_agent.py b/run_agent.py index 467281d01..67121d20f 100644 --- a/run_agent.py +++ b/run_agent.py @@ -1467,14 +1467,17 @@ class AIAgent: tool_duration = time.time() - tool_start_time if self.quiet_mode: print(f" {_get_cute_tool_message_impl('todo', function_args, tool_duration, result=function_result)}") - elif function_name == "session_search" and self._session_db: - from tools.session_search_tool import session_search as _session_search - function_result = _session_search( - query=function_args.get("query", ""), - role_filter=function_args.get("role_filter"), - limit=function_args.get("limit", 3), - db=self._session_db, - ) + elif function_name == "session_search": + if not self._session_db: + function_result = json.dumps({"success": False, "error": "Session database not available."}) + else: + from tools.session_search_tool import session_search as _session_search + function_result = _session_search( + query=function_args.get("query", ""), + role_filter=function_args.get("role_filter"), + limit=function_args.get("limit", 3), + db=self._session_db, + ) tool_duration = time.time() - tool_start_time if self.quiet_mode: print(f" {_get_cute_tool_message_impl('session_search', function_args, tool_duration, result=function_result)}")