Compare commits

..

2 Commits

Author SHA1 Message Date
dbd8f0141c fix: initialize agent properly in API mode
Fixed critical bug where ModelDayExecutor._initialize_agent() created
a BaseAgent but never called agent.initialize(), leaving self.model=None.
This caused 'NoneType' object has no attribute 'bind' error when
run_trading_session() tried to create the langchain agent.

Changes:
- Made _initialize_agent() async
- Added await agent.initialize() call
- Updated call site to await async function

Now properly initializes MCP client, tools, and AI model before
executing trading sessions, matching the working CLI mode pattern.
2025-11-02 19:39:43 -05:00
fb32bb12c5 fix: check column existence before creating indexes
Fixes startup error 'no such column: session_id' that occurs when
_create_indexes() tries to create indexes on columns that don't exist yet.

The issue occurred when initializing a database from scratch:
1. _migrate_schema() adds session_id column to positions table
2. _create_indexes() tries to create index on session_id
3. But on fresh databases, positions table was created without session_id
4. Migration runs after table creation, before index creation
5. Index creation fails because column doesn't exist yet

Solution: Check if columns exist before creating indexes on them.

This ensures the database can be initialized both:
- Fresh (CREATE TABLE without session_id, then ALTER TABLE, then CREATE INDEX)
- Migrated (ALTER TABLE adds column, then CREATE INDEX)

Tested: All 21 database tests passing
2025-11-02 19:24:19 -05:00
2 changed files with 18 additions and 8 deletions

View File

@@ -438,12 +438,19 @@ def _create_indexes(cursor: sqlite3.Cursor) -> None:
""")
# Positions table - add index for simulation_run_id and session_id
cursor.execute("""
CREATE INDEX IF NOT EXISTS idx_positions_run_id ON positions(simulation_run_id)
""")
cursor.execute("""
CREATE INDEX IF NOT EXISTS idx_positions_session_id ON positions(session_id)
""")
# Check if columns exist before creating indexes
cursor.execute("PRAGMA table_info(positions)")
position_columns = [row[1] for row in cursor.fetchall()]
if 'simulation_run_id' in position_columns:
cursor.execute("""
CREATE INDEX IF NOT EXISTS idx_positions_run_id ON positions(simulation_run_id)
""")
if 'session_id' in position_columns:
cursor.execute("""
CREATE INDEX IF NOT EXISTS idx_positions_session_id ON positions(session_id)
""")
def drop_all_tables(db_path: str = "data/jobs.db") -> None:

View File

@@ -126,7 +126,7 @@ class ModelDayExecutor:
os.environ["RUNTIME_ENV_PATH"] = self.runtime_config_path
# Initialize agent
agent = self._initialize_agent()
agent = await self._initialize_agent()
# Run trading session
logger.info(f"Running trading session for {self.model_sig} on {self.date}")
@@ -209,7 +209,7 @@ class ModelDayExecutor:
"""Execute model-day simulation (sync entry point)."""
return self.execute_sync()
def _initialize_agent(self):
async def _initialize_agent(self):
"""
Initialize trading agent with config.
@@ -259,6 +259,9 @@ class ModelDayExecutor:
# - Database initialization is handled by JobManager
# - File-based position tracking is only for standalone/CLI mode
# Initialize MCP client and AI model
await agent.initialize()
return agent
def _create_trading_session(self, cursor) -> int: