Architecture 5 Session - djvolz/coda-code-assistant GitHub Wiki

Session Module Architecture

Design Document Purpose

This document describes the architectural design of the Session module, including:

  • High-level architecture and structure for conversation persistence
  • Design decisions for message storage and retrieval
  • Patterns for database management and context optimization
  • Component relationships between storage, management, and context handling

Code References

Overview

The Session module provides conversation persistence and management for Coda Code Assistant. It uses SQLAlchemy with SQLite to store sessions, messages, and metadata, while providing intelligent context management for optimal LLM interactions. The architecture centers around the SessionManager class in coda/session/manager.py.

Module Structure

coda/session/
├── __init__.py          # Module exports
├── manager.py           # Core session management
├── database.py          # SQLite connection handling
├── models.py            # SQLAlchemy data models
├── context.py           # Context window optimization
└── commands.py          # CLI command implementations

Key Components

Component 1: Session Manager

Location: coda/session/manager.py

Purpose: Central orchestrator for all session operations

Key Methods:

  • create_session(): Creates new conversation sessions
  • add_message(): Adds messages with metadata tracking
  • get_session_context(): Retrieves optimized conversation context
  • search_sessions(): Full-text search across sessions
  • export_session(): Exports in multiple formats

Component 2: Database Layer

Location: coda/session/database.py

Purpose: Manages SQLite connections and database operations

Key Features:

  • Connection pooling with SQLAlchemy
  • WAL mode for concurrent access
  • Full-text search (FTS5) initialization
  • Database maintenance operations

Component 3: Data Models

Location: coda/session/models.py

Purpose: SQLAlchemy ORM models for data persistence

Key Models:

  • Session: Conversation session with metadata
  • Message: Individual messages with token tracking
  • Tag: Organizational tags for sessions
  • Attachment: File attachments for messages

Component 4: Context Manager

Location: coda/session/context.py

Purpose: Intelligent context window optimization for LLMs

Key Features:

  • Model-specific context limits
  • Token counting and estimation
  • Message prioritization strategies
  • Context summarization

Implementation Details

Design Patterns Used

Repository Pattern

Implementation: coda/session/manager.py

Why this pattern: Abstracts database operations from business logic, making the system more testable and maintainable.

class SessionManager:
    """Manages session persistence and operations."""
    
    def __init__(self, database: SessionDatabase | None = None):
        self.db = database or SessionDatabase()
        self.context_manager = ContextManager()

Unit of Work Pattern

Implementation: coda/session/database.py

Why this pattern: Ensures database operations are atomic and consistent.

@contextmanager
def get_session(self) -> DBSession:
    """Get a database session context manager."""
    session = self.SessionLocal()
    try:
        yield session
        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()

Data Flow

sequenceDiagram
    participant CLI
    participant SessionManager
    participant Database
    participant SQLite
    participant FTS
    
    CLI->>SessionManager: create_session()
    SessionManager->>Database: get_session()
    Database->>SQLite: BEGIN TRANSACTION
    SessionManager->>SQLite: INSERT INTO sessions
    SessionManager->>SQLite: COMMIT
    
    CLI->>SessionManager: add_message()
    SessionManager->>Database: get_session()
    SessionManager->>SQLite: INSERT INTO messages
    SessionManager->>FTS: INSERT INTO messages_fts
    SessionManager->>SQLite: UPDATE sessions (stats)
    Database->>SQLite: COMMIT
    
    CLI->>SessionManager: search_sessions(query)
    SessionManager->>FTS: MATCH query
    FTS->>SessionManager: Return matches
    SessionManager->>SQLite: Fetch full data
    SessionManager->>CLI: Return results
Loading

Database Schema

erDiagram
    Session ||--o{ Message : contains
    Session ||--o{ Tag : has
    Session ||--o| Session : branches_from
    Message ||--o{ Attachment : has
    Message ||--|| Session : belongs_to
    
    Session {
        string id PK
        string name
        string provider
        string model
        datetime created_at
        datetime updated_at
        int message_count
        int total_tokens
        float total_cost
    }
    
    Message {
        string id PK
        string session_id FK
        int sequence
        string role
        text content
        int prompt_tokens
        int completion_tokens
        datetime created_at
    }
    
    Tag {
        string id PK
        string name
        string color
    }
Loading

API Reference

Public Classes

SessionManager

Location: coda/session/manager.py

Purpose: Main interface for session operations

Key Methods:

  • create_session(name, provider, model, **kwargs): Create new session
  • add_message(session_id, role, content, **kwargs): Add message
  • get_session(session_id): Retrieve session by ID
  • get_active_sessions(limit, offset): List active sessions
  • search_sessions(query, limit): Search with FTS
  • export_session(session_id, format): Export session data

SessionDatabase

Location: coda/session/database.py

Purpose: Database connection and initialization

Key Methods:

  • __init__(db_path): Initialize with custom path
  • get_session(): Get database session context
  • vacuum(): Optimize database storage
  • backup(backup_path): Create database backup

Design Decisions

Key Architectural Choices

Decision 1: SQLite with SQLAlchemy ORM

Context: Need for local, file-based storage without external dependencies Decision: Use SQLite with SQLAlchemy ORM for data persistence Rationale:

  • Zero configuration database
  • Excellent performance for single-user scenarios
  • Rich querying capabilities with SQLAlchemy
  • Easy backup and portability Trade-offs:
  • Pros: Simple deployment, no server required, ACID compliant
  • Cons: Limited concurrent write performance Implementation: See database.py

Decision 2: FTS5 for Search

Context: Need for fast full-text search across message history Decision: Use SQLite's FTS5 virtual table Rationale: Native SQLite feature with excellent performance Trade-offs:

  • Pros: Fast search, minimal overhead, ranking support
  • Cons: Requires separate index maintenance Implementation: FTS table creation in database.py and search in manager.py

Decision 3: Context Window Management

Context: LLMs have token limits requiring intelligent message selection Decision: Separate ContextManager for optimization strategies Rationale: Decouple context logic from persistence layer Trade-offs:

  • Pros: Flexible strategies, model-specific handling
  • Cons: Additional complexity Implementation: See context.py

Design Principles

  1. Separation of Concerns: Database, business logic, and context optimization are separate
  2. Fail-Safe Defaults: Transactions rollback on error, sensible defaults throughout
  3. Performance First: Indexes on commonly queried fields, efficient FTS
  4. Extensibility: Easy to add new export formats, storage backends

Configuration

Config File: ~/.config/coda/config.toml Database Location: ~/.config/coda/sessions.db

Configuration Options

Option Type Default Description
session.autosave bool true Auto-save messages
session.max_export_size int 10MB Max export file size
session.fts_enabled bool true Enable full-text search

Dependencies

Internal Dependencies

  • coda.configuration: Configuration management
  • coda.constants: Database path constants

External Dependencies

  • sqlalchemy>=2.0.0: ORM and database toolkit
  • sqlite3: Built-in Python SQLite support

Testing

Test Coverage

  • Unit tests: tests/test_session.py
  • Integration tests: tests/session/test_session_integration.py
  • Database tests: tests/session/test_database.py

Key Test Cases

  1. Session Creation: Tests session initialization with various parameters
  2. Message Addition: Tests message persistence and statistics updates
  3. FTS Search: Tests full-text search functionality
  4. Export Formats: Tests JSON, Markdown, HTML exports

Error Handling

Exception Types

  • SessionNotFoundError: When session ID doesn't exist
  • DatabaseError: For database operation failures
  • ExportError: For export format issues

Error Flow

try:
    session = self.get_session(session_id)
    if not session:
        raise SessionNotFoundError(f"Session {session_id} not found")
except SQLAlchemyError as e:
    logger.error(f"Database error: {e}")
    raise DatabaseError(str(e))

Performance Considerations

  1. Connection Pooling: Static pool prevents connection overhead
  2. WAL Mode: Better concurrency for reads during writes
  3. Lazy Loading: Messages loaded on demand, not with session
  4. Indexed Fields: All commonly queried fields have indexes

Security Considerations

  1. SQL Injection Prevention: All queries use parameterized statements
  2. File Path Validation: Database path sanitized on initialization
  3. No Credential Storage: No sensitive data in session database

Examples

Basic Usage

from coda.session import SessionManager

# Create manager
manager = SessionManager()

# Create session
session = manager.create_session(
    name="Python Help",
    provider="openai",
    model="gpt-4"
)

# Add messages
manager.add_message(
    session_id=session.id,
    role="user",
    content="How do I read a file in Python?"
)

# Search sessions
results = manager.search_sessions("python file")

Export Example

# Export to various formats
json_export = manager.export_session(session.id, format="json")
markdown_export = manager.export_session(session.id, format="markdown")
html_export = manager.export_session(session.id, format="html")

Integration Points

With Other Modules

  1. CLI Module: Session commands in interactive_cli.py
  2. Provider Module: Stores provider responses and metadata
  3. Agent Module: Tool invocation results stored in messages

Extension Points

  1. Custom Export Formats: Add methods like _export_csv()
  2. Alternative Storage: Implement new database backend
  3. Search Strategies: Extend search with semantic capabilities

Known Limitations

  1. Single User: Designed for local, single-user scenarios
  2. SQLite Limits: Large databases may need optimization
  3. No Remote Sync: Local storage only, no cloud backup

References

Related Documentation

Source Files

All files referenced in this document:

  • coda/session/manager.py
  • coda/session/database.py
  • coda/session/models.py
  • coda/session/context.py
  • coda/session/commands.py
  • tests/test_session.py
  • tests/session/
⚠️ **GitHub.com Fallback** ⚠️