Skip to content

Conversation

andormarkus
Copy link

@andormarkus andormarkus commented Oct 14, 2025

Description

This PR adds DatabaseSessionManager to enable SQL database persistence for agent sessions, providing an alternative to file-based and S3-based session storage.

Why Database Sessions?

  1. Cloud-Agnostic Stateless Architecture: If you want to run your agent in a fully stateless manner in a cloud-agnostic way, saving to a database is a great option. This enables horizontal scaling, serverless deployments, and seamless container orchestration without relying on cloud-specific storage services.
  2. Cost-Effective at Scale: On high-volume agents, S3 API calls can be pretty expensive. Database sessions provide a more cost-effective solution for production workloads with frequent read/write operations.

Key Features

  • Multi-database Support: PostgreSQL, MySQL, and SQLite via SQLAlchemy
  • Thread-safe Operations: Connection pooling with shared engine support for production use
  • Schema Management: Alembic migrations included for database schema creation and evolution
  • Clean Architecture: Context manager pattern for DRY database operations with automatic transaction management
  • Error Handling: Automatic transaction rollback on errors with custom exception wrapping
  • Security: ID validation to prevent path traversal and injection attacks
  • Flexible Initialization: Support for both connection strings and pre-configured SQLAlchemy engines

Implementation Details

  1. DatabaseSessionManager Class (src/strands/session/database_session_manager.py)

    • Implements SessionRepository interface via RepositorySessionManager
    • Uses SQLAlchemy ORM with declarative models
    • Context manager (_db_session) for transaction management with auto-commit and rollback
    • Helper methods for validation: _validate_session_id, _validate_agent_id, _validate_ids
    • Proper resource cleanup with __del__ for owned engines
  2. Database Models (src/strands/session/database_models.py)

    • StrandsSession: Session metadata (id, type, timestamps)
    • StrandsAgent: Agent state and conversation manager state (JSON columns)
    • StrandsMessage: Messages with optional redaction (JSON columns, append-only)
    • Foreign key constraints with cascade delete
    • Automatic timestamp management
  3. Alembic Migrations (alembic/)

    • Example Alembic configuration at project root for users to reference
    • Initial migration script to create the three session tables
    • Supports schema evolution and database upgrades
    • Users can copy this setup for their own projects
  4. Optional Dependencies (pyproject.toml)

    • New database optional dependency group
    • Includes: sqlalchemy>=2.0.0, alembic>=1.13.0, psycopg2-binary, pymysql
    • Added to all extras group
  5. Comprehensive Testing (tests/strands/session/test_database_session_manager.py)

    • 43 unit tests covering all CRUD operations
    • Error handling and transaction rollback scenarios
    • Security validation (path traversal prevention)
    • Engine ownership and resource cleanup
    • Integration with existing session manager test patterns

Usage Example

1. Set up database schema with Alembic

# Copy the example Alembic setup from the SDK repo to your project
cp -r alembic/ your-project/
cp alembic.ini your-project/

# Update alembic.ini with your database connection string
# sqlalchemy.url = postgresql://user:pass@localhost:5432/strands

# Run migrations to create tables
alembic upgrade head

2. Use DatabaseSessionManager in your code

from strands.session import DatabaseSessionManager
from strands.agent import Agent
from strands.models import OpenAIModel

# Option 1: Simple connection string
session_manager = DatabaseSessionManager(
    session_id="user-123",
    connection_string="postgresql://user:pass@localhost:5432/strands"
)

# Option 2: Shared engine (recommended for FastAPI/production)
from sqlalchemy import create_engine

engine = create_engine("postgresql://user:pass@localhost:5432/strands")

session_manager = DatabaseSessionManager(
    session_id="user-123",
    engine=engine  # Shared across multiple session managers
)

# Use with agent
agent = Agent(
    agent_id="assistant",
    model=OpenAIModel(model_id="gpt-4"),
    session_manager=session_manager
)

Design Decisions

  1. Cloud-Agnostic Stateless Architecture: If you want to run your agent in a fully stateless manner in a cloud-agnostic way, saving to a database is a great option. This enables horizontal scaling, serverless deployments, and seamless container orchestration without relying on cloud-specific storage services.
  2. Synchronous Implementation: Consistent with existing S3SessionManager and FileSessionManager
  3. Message Updates: Messages support redaction via update_message, matching S3SessionManager behavior
  4. JSON Columns: Native JSON support for complex data structures (agent state, messages)
  5. Optional Dependency: SQLAlchemy is not required unless using DatabaseSessionManager
  6. Connection Pooling: Built-in SQLAlchemy connection pooling with pool_pre_ping for robustness

Related Issues

N/A - This is a new feature implementation

Documentation PR

Docs PR: strands-agents/docs#285

Comprehensive documentation has been added to the docs repository, including:

  • User Guide section in session-management.md with setup instructions and usage examples
  • Working Python example code demonstrating basic and production patterns
  • Alembic migration setup guide
  • Database schema structure documentation
  • Connection string examples for PostgreSQL, MySQL, and SQLite

Type of Change

New feature

Testing

  • All unit tests pass (hatch test) - 114 tests including 43 new tests for DatabaseSessionManager
  • All linting checks pass (hatch fmt --linter)
  • Code formatting applied (hatch fmt --formatter)
  • Type checking passes (mypy)
  • Integration tested with AWS Bedrock using validation script
  • Tested with SQLite (in-memory and file-based)
  • Thread safety verified through connection pooling patterns

Test Coverage

The implementation includes comprehensive test coverage:

  • CRUD operations (create, read, update, delete) for sessions, agents, and messages
  • Error handling and exception wrapping
  • Transaction rollback on failures
  • Security validation (invalid session/agent IDs)
  • Engine ownership and cleanup
  • Context manager behavior (auto-commit vs manual)
  • Edge cases (duplicate entries, missing data, etc.)

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly (inline docstrings)
  • I have added an appropriate example to the documentation to outline the feature (docs PR Issue in installing strands-agents[a2a] #285)
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Additional Notes

  • Uses Conventional Commits for commit message (feat(session): ...)
  • Follows existing session manager patterns for consistency
  • Aligns with development tenets (simple at any scale, extensible by design, composability)
  • No breaking changes to existing APIs

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Add support for database-backed session management with:
- sqlalchemy>=2.0.0 for ORM and database abstraction
- alembic>=1.13.0 for schema migrations
- psycopg2-binary>=2.9.0 for PostgreSQL support
- pymysql>=1.1.0 for MySQL support

Includes 'database' in 'all' extras group for convenience.
Initialize Alembic for database schema management:
- Add alembic.ini configuration
- Add alembic/env.py for manual migrations
- Create initial migration for 3 tables:
  - strands_sessions (session metadata)
  - strands_agents (agent state + conversation state)
  - strands_messages (append-only message log)
- Tested successfully with SQLite
Create ORM models for database session storage:
- StrandsSession: session metadata (id, type, timestamps)
- StrandsAgent: agent state + conversation manager state (JSON)
- StrandsMessage: append-only message log (JSON)
- Proper relationships with CASCADE deletes (both DB and ORM)
- Matches Alembic migration schema exactly
… support

Add DatabaseSessionManager to enable SQL database persistence for agent sessions.

Features:
- Support for PostgreSQL, MySQL, and SQLite via SQLAlchemy
- Thread-safe connection pooling with shared engine support
- Context manager pattern for DRY database operations
- Automatic transaction rollback on errors
- Security validation for session/agent IDs
- Comprehensive test coverage (43 tests)

Implementation:
- DatabaseSessionManager with SessionRepository interface
- SQLAlchemy models in database_models.py
- Helper methods for validation
- Context manager with auto-commit and error handling
- Optional dependency group database in pyproject.toml

Testing:
- All CRUD operations covered
- Error handling and transaction rollback
- Security validation (path traversal prevention)
- Engine cleanup and resource management
- Integration with existing session manager tests (114 tests passing)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants