feat: implement reasoning logs API with database-only storage

Complete implementation of reasoning logs retrieval system that
replaces JSONL file-based logging with database-only storage.

Database Changes:
- Add trading_sessions table (one record per model-day)
- Add reasoning_logs table (conversation history with summaries)
- Add session_id column to positions table
- Add indexes for query performance

Agent Changes:
- Add conversation history tracking to BaseAgent
- Add AI-powered summary generation using same model
- Remove JSONL logging code (_log_message, _setup_logging)
- Preserve in-memory conversation tracking

ModelDayExecutor Changes:
- Create trading session at start of execution
- Store reasoning logs with AI-generated summaries
- Update session summary after completion
- Link positions to sessions via session_id

API Changes:
- Add GET /reasoning endpoint with filters (job_id, date, model)
- Support include_full_conversation parameter
- Return both summaries and full conversation on demand
- Include deployment mode info in responses

Documentation:
- Add complete API reference for GET /reasoning
- Add design document with architecture details
- Add implementation guide with step-by-step tasks
- Update Python and TypeScript client examples

Testing:
- Add 6 tests for conversation history tracking
- Add 4 tests for summary generation
- Add 5 tests for model_day_executor integration
- Add 8 tests for GET /reasoning endpoint
- Add 9 integration tests for E2E flow
- Update existing tests for schema changes

All 32 new feature tests passing. Total: 285 tests passing.
This commit is contained in:
2025-11-02 18:31:02 -05:00
parent 2f05418f42
commit f104164187
9 changed files with 3502 additions and 51 deletions

View File

@@ -90,7 +90,7 @@ class TestSchemaInitialization:
"""Test database schema initialization."""
def test_initialize_database_creates_all_tables(self, clean_db):
"""Should create all 9 tables."""
"""Should create all 10 tables."""
conn = get_db_connection(clean_db)
cursor = conn.cursor()
@@ -112,7 +112,8 @@ class TestSchemaInitialization:
'tool_usage',
'price_data',
'price_data_coverage',
'simulation_runs'
'simulation_runs',
'trading_sessions' # Added in reasoning logs feature
]
assert sorted(tables) == sorted(expected_tables)
@@ -192,9 +193,15 @@ class TestSchemaInitialization:
'idx_positions_model',
'idx_positions_date_model',
'idx_positions_unique',
'idx_positions_session_id', # Link positions to trading sessions
'idx_holdings_position_id',
'idx_holdings_symbol',
'idx_reasoning_logs_job_date_model',
'idx_sessions_job_id', # Trading sessions indexes
'idx_sessions_date',
'idx_sessions_model',
'idx_sessions_unique',
'idx_reasoning_logs_session_id', # Reasoning logs now linked to sessions
'idx_reasoning_logs_unique',
'idx_tool_usage_job_date_model'
]
@@ -371,7 +378,7 @@ class TestUtilityFunctions:
conn = get_db_connection(test_db_path)
cursor = conn.cursor()
cursor.execute("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
assert cursor.fetchone()[0] == 9 # Updated to reflect all tables
assert cursor.fetchone()[0] == 10 # Updated to reflect all tables including trading_sessions
conn.close()
# Drop all tables