Id
73
Agent
Content
## Code Review - Ticket #94: Part 2 - Agent Session Logs
### Summary
PASS - All acceptance criteria met. Complete persistent terminal log storage system with two new models, REST API for log ingestion, MCP tools for querying, and 7-day retention cleanup.
### Files Changed
- 15 files (+686/-138 lines)
- 2 new models (AgentSession, AgentTerminalLog)
- 2 new migrations with proper indexes
- AgentSessionsController with start/ingest/end/show endpoints
- 2 new MCP tools (get_terminal_logs, list_agent_sessions)
- CleanupOldTerminalLogsJob with Solid Queue scheduling
- Comprehensive test coverage (31 examples)
### Acceptance Criteria Verification
#### 1. AgentSession and AgentTerminalLog Models ✓
**AgentSession (63 lines):**
- Fields: agent_id (FK), agent_identifier, started_at, ended_at, status (running/completed/failed), ticket_id
- AASM state machine with running → completed/failed transitions
- `has_many :terminal_logs` with `dependent: :destroy`
- Scopes: running, completed, failed, recent, for_agent, for_ticket
- `#duration` method calculates session length
- `#add_log` helper creates terminal log entries
**AgentTerminalLog (22 lines):**
- Fields: agent_session_id (FK), timestamp (bigint), output_line (text), line_type (stdout/stderr), ansi (boolean)
- Belongs to agent_session
- Scopes: chronological, reverse_chronological, with_ansi, without_ansi, stdout, stderr
- Delegates agent, agent_identifier, ticket_id to session
#### 2. Log Storage from agent-bridge to Rails ✓
**API Endpoints (AgentSessionsController):**
- `POST /api/v1/agent_sessions/start_session` - Creates new session
- `POST /api/v1/agent_sessions/:id/ingest` - Batch or single log ingestion
- `POST /api/v1/agent_sessions/:id/end_session` - Marks session complete/failed
- Internal auth via `X-Terminal-Internal` or API key
- Supports both batch (`logs[]`) and single (`line`) ingestion
**Agent Model:**
- Added `has_many :agent_sessions, dependent: :destroy`
#### 3. Scheduled Cleanup Job (7 Day Retention) ✓
**CleanupOldTerminalLogsJob (34 lines):**
- `DEFAULT_RETENTION_DAYS = 7`
- Deletes terminal logs older than retention period using `where("created_at < ?")`
- Cleans up empty sessions (no logs) with `where.missing(:terminal_logs)`
- Returns hash with deleted counts
- Configurable via parameter
**Solid Queue Schedule (recurring.yml):**
- Runs daily at 2am: `schedule: every day at 2am`
- Args: `7` for 7-day retention
- Configured for both development and production
#### 4. MCP Tool to Retrieve Historical Logs ✓
**New MCP Tools in mcp_controller.rb:**
1. `get_terminal_logs`:
- Parameters: agent_id, ticket_id, session_id, status, limit (100), include_session_info
- If session_id specified: returns logs from that specific session
- Otherwise: filters by agent/ticket/status and returns matching logs
- Returns formatted logs with timestamp, line, line_type, ansi
2. `list_agent_sessions`:
- Parameters: agent_id, ticket_id, status, limit (20)
- Returns session metadata without full logs
- Includes: id, agent_id, agent_identifier, ticket_id, status, started_at, ended_at, duration, log_count
### Additional Quality Observations
**Migrations:**
- Proper foreign key constraints
- Indexes on: agent_identifier, status, started_at, ticket_id (sessions)
- Indexes on: timestamp, created_at (logs)
- Uses `bigint` for timestamp to handle Unix millis
**Database Schema:**
- Proper `t.timestamps` with `null: false` defaults
- Text type for output_line (no length limit)
- Boolean with `default: false, null: false` for ansi
**AASM Transitions:**
- Auto-sets `ended_at` on complete/fail events
- Prevents invalid state transitions
**API Design:**
- Flexible authentication (internal header OR API key)
- Batch ingestion support for performance
- Returns session_id on start for tracking
- Includes duration calculation on session end
### Code Quality
- Clean model associations with proper dependent: :destroy
- Comprehensive validations (presence, inclusion)
- Useful scopes for common queries
- Proper test coverage (31 examples, all passing)
- Handles both batch and single log ingestion
- Proper HTTP status codes (201 for create, 200 for update, 404 for not found)
### No Issues Found
No bugs, security issues, or code quality problems identified. Ready for production use with consideration for database volume at high terminal output rates.
Comment type
code_review
Avo · © 2026 AvoHQ · v3.27.0