Skip to content

Add Session Memory for Automatic Conversation History Management #752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

knowsuchagency
Copy link

@knowsuchagency knowsuchagency commented May 24, 2025

Add Session Memory for Automatic Conversation History Management

Overview

This PR introduces Session Memory, a new core feature that automatically maintains conversation history across multiple agent runs, eliminating the need to manually handle .to_input_list() between turns.

Key Features

🧠 Automatic Memory Management

  • Zero-effort conversation continuity: Agents automatically remember previous context without manual state management
  • Session-based organization: Each conversation is isolated by unique session IDs
  • Seamless integration: Works with existing Runner.run(), Runner.run_sync(), and Runner.run_streamed() methods

💾 Flexible Storage Options

  • In-memory SQLite: Perfect for temporary conversations during development
  • Persistent SQLite: File-based storage for conversations that survive application restarts
  • Custom implementations: Easy-to-implement protocol for Redis, PostgreSQL, or other backends

🔧 Simple API

# Before: Manual conversation management
result1 = await Runner.run(agent, "What's the weather?")
new_input = result1.to_input_list() + [{"role": "user", "content": "How about tomorrow?"}]
result2 = await Runner.run(agent, new_input)

# After: Automatic with Session Memory
memory = SQLiteSessionMemory()
config = RunConfig(memory=memory, session_id="user_123")

result1 = await Runner.run(agent, "What's the weather?", run_config=config)
result2 = await Runner.run(agent, "How about tomorrow?", run_config=config)  # Remembers context automatically

What's Included

Core Implementation

  • SessionMemory Protocol: Interface for implementing custom memory backends
  • SQLiteSessionMemory Class: Production-ready SQLite implementation with thread-safe operations
  • RunConfig Integration: New memory and session_id parameters for seamless usage

Documentation

  • Comprehensive guide: New docs/session_memory.md with examples, best practices, and API reference
  • Updated running agents docs: Enhanced conversation management section
  • API reference: Full mkdocstrings integration for auto-generated documentation

Examples

  • Complete working example: examples/basic/session_memory_example.py demonstrating real-world usage
  • Multiple conversation patterns: Shows how to manage different user sessions

Benefits

For Developers

  • Reduces boilerplate: No more manual .to_input_list() management
  • Prevents memory leaks: Automatic cleanup and organized storage
  • Easier debugging: Clear conversation history tracking
  • Production ready: Thread-safe, validated, and tested

For Applications

  • Better user experience: Seamless conversation continuity
  • Scalable architecture: Support for multiple concurrent conversations
  • Flexible deployment: In-memory for development, persistent for production
  • Multi-agent support: Same conversation history can be shared across different agents

Usage Examples

Basic Usage

from agents import Agent, Runner, RunConfig, SQLiteSessionMemory

agent = Agent(name="Assistant", instructions="Reply concisely.")
memory = SQLiteSessionMemory()
config = RunConfig(memory=memory, session_id="conversation_123")

# Conversation flows naturally
await Runner.run(agent, "Hi, I'm planning a trip to Japan", run_config=config)
await Runner.run(agent, "What's the best time to visit?", run_config=config)
await Runner.run(agent, "How about cherry blossom season?", run_config=config)

Multiple Sessions

# Different users get separate conversation histories
user1_config = RunConfig(memory=memory, session_id="user_alice")
user2_config = RunConfig(memory=memory, session_id="user_bob")

# Completely isolated conversations
await Runner.run(agent, "I like pizza", run_config=user1_config)
await Runner.run(agent, "I like sushi", run_config=user2_config)

Custom Memory Backend

class CustomMemory:
    """Custom memory implementation following the SessionMemory protocol."""
    
    async def get_messages(self, session_id: str) -> List[dict]:
        """Retrieve conversation history for the session."""
        ...
    
    async def add_messages(self, session_id: str, messages: List[dict]) -> None:
        """Store new messages for the session."""
        ...
    
    async def pop_message(self, session_id: str) -> dict | None:
        """Remove and return the most recent message from the session."""
        ...
    
    async def clear_session(self, session_id: str) -> None:
        """Clear all messages for the session."""
        ...

# Drop-in replacement for any storage backend
config = RunConfig(memory=CustomMemory(), session_id="session_123")

Technical Details

  • Thread-safe SQLite operations with connection pooling
  • Automatic schema management with proper indexing
  • JSON serialization for message storage
  • Graceful error handling with detailed validation
  • Memory-efficient conversation retrieval and storage

Breaking Changes

None. This is a purely additive feature that doesn't affect existing functionality.

Documentation

  • Updated core concepts in docs/index.md to highlight Session Memory as a key primitive
  • New comprehensive guide at docs/session_memory.md
  • Enhanced docs/running_agents.md with automatic vs manual conversation management
  • Full API reference integration via docs/ref/memory.md

Session Memory represents a significant quality-of-life improvement for building conversational AI applications with the Agents SDK, making it easier than ever to create stateful, context-aware agent interactions.

## Summary
- Introduced `SessionMemory` and `SQLiteSessionMemory` classes for automatic conversation history management.
- Updated `Agent` class to support session memory configuration.
- Enhanced `Runner` class to handle input preparation and result saving with session memory.
- Added example demonstrating session memory usage.
- Implemented tests for session memory functionality.

## Testing
- `make format`
- `make lint`
- `make mypy`
- `make tests`
- Added a check to raise a ValueError if `session_id` is not provided when session memory is enabled.
- Updated the `SessionMemory` class to use a Protocol instead of an abstract base class, simplifying the implementation.
- Modified tests to ensure an exception is raised when attempting to run with memory enabled but no session_id is provided.
- Introduced a section on creating custom memory implementations following the `SessionMemory` protocol.
- Added code examples demonstrating how to implement and use a custom memory class.
- Highlighted the requirement for `session_id` when session memory is enabled, with examples illustrating correct usage.
- Updated the Runner class to ensure that when memory=True, a single instance of SQLiteSessionMemory is created and reused across runs.
- Added a test to verify that the same memory instance is returned for multiple calls when memory is enabled.
- Ensured the agent stores the memory instance for consistency.
- Updated README and example scripts to utilize `SQLiteSessionMemory` explicitly instead of using a boolean flag for memory.
- Modified `RunConfig` to accept a memory instance directly, enhancing clarity and flexibility in session management.
- Adjusted tests to reflect the new memory handling approach, ensuring consistent behavior across different configurations.
- Updated `mkdocs.yml` to include `session_memory.md` in the documentation.
- Enhanced `index.md` to highlight the new **Session Memory** feature for automatic conversation history management.
- Modified `running_agents.md` to include details about the `memory` and `session_id` parameters in `RunConfig`.
- Added comprehensive documentation for session memory functionality in the new `session_memory.md` file, including usage examples and best practices.
- Included `memory.md` in the documentation by updating `mkdocs.yml`.
- Corrected links in `session_memory.md` to point to the appropriate memory classes.
- Created a new `memory.md` file detailing the `SessionMemory` and `SQLiteSessionMemory` classes.
…essions and messages

- Updated the constructor to accept `sessions_table` and `messages_table` parameters, allowing users to specify custom table names.
- Modified SQL queries to utilize the provided table names, ensuring flexibility in database schema.
- Adjusted index creation and deletion queries to reflect the new table name parameters.
- Implemented the `pop_message` method to remove and return the most recent message from a session.
- Updated the `SessionMemory` protocol to include the new method signature.
- Enhanced documentation in `session_memory.md` with examples demonstrating the usage of `pop_message`.
- Added tests to verify the functionality of `pop_message`, including edge cases for empty sessions and multiple sessions.
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.

1 participant