From e9684340622b1c7f2a397e345d88ec05ecb2eff0 Mon Sep 17 00:00:00 2001 From: Bill Date: Sun, 2 Nov 2025 22:42:17 -0500 Subject: [PATCH] fix: reload tools after context injection and prevent database locking Critical fixes for ContextInjector and database concurrency: 1. ContextInjector Not Working: - Made set_context() async to reload tools after recreating MCP client - Tools from old client (without interceptor) were still being used - Now tools are reloaded from new client with interceptor active - This ensures buy/sell calls properly receive injected parameters 2. Database Locking: - Closed main connection before _write_results_to_db() opens new one - SQLite doesn't handle concurrent write connections well - Prevents "database is locked" error during position writes Changes: - agent/base_agent/base_agent.py: - async def set_context() instead of def set_context() - Added: self.tools = await self.client.get_tools() - api/model_day_executor.py: - await agent.set_context(context_injector) - conn.close() before _write_results_to_db() Root Cause: When recreating the MCP client with tool_interceptors, the old tools were still cached in self.tools and being passed to the AI agent. The interceptor was never invoked, so job_id/signature/date were missing. --- agent/base_agent/base_agent.py | 5 ++++- api/model_day_executor.py | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/agent/base_agent/base_agent.py b/agent/base_agent/base_agent.py index e73059e..1cee85d 100644 --- a/agent/base_agent/base_agent.py +++ b/agent/base_agent/base_agent.py @@ -221,7 +221,7 @@ class BaseAgent: print(f"✅ Agent {self.signature} initialization completed") - def set_context(self, context_injector: "ContextInjector") -> None: + async def set_context(self, context_injector: "ContextInjector") -> None: """ Inject ContextInjector after initialization. @@ -241,6 +241,9 @@ class BaseAgent: tool_interceptors=[context_injector] ) + # CRITICAL: Reload tools from new client so they use the interceptor + self.tools = await self.client.get_tools() + print(f"✅ Context injected: signature={context_injector.signature}, " f"date={context_injector.today_date}, job_id={context_injector.job_id}, " f"session_id={context_injector.session_id}") diff --git a/api/model_day_executor.py b/api/model_day_executor.py index d3b5af7..ce8beb8 100644 --- a/api/model_day_executor.py +++ b/api/model_day_executor.py @@ -140,7 +140,7 @@ class ModelDayExecutor: job_id=self.job_id, session_id=session_id ) - agent.set_context(context_injector) + await agent.set_context(context_injector) # Run trading session logger.info(f"Running trading session for {self.model_sig} on {self.date}") @@ -155,10 +155,13 @@ class ModelDayExecutor: # Update session summary await self._update_session_summary(cursor, session_id, conversation, agent) - # Store positions (pass session_id) - self._write_results_to_db(agent, session_id) - + # Commit and close connection before _write_results_to_db opens a new one conn.commit() + conn.close() + conn = None # Mark as closed + + # Store positions (pass session_id) - this opens its own connection + self._write_results_to_db(agent, session_id) # Update status to completed self.job_manager.update_job_detail_status(