-
Notifications
You must be signed in to change notification settings - Fork 0
Comparing changes
Open a pull request
base repository: rachhek/openai-agents-python
base: main
head repository: openai/openai-agents-python
compare: main
- 17 commits
- 53 files changed
- 5 contributors
Commits on Jul 10, 2025
-
Add Sessions for Automatic Conversation History Management (openai#752)
# Overview Resolves openai#745 This PR introduces **Sessions**, 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 ### 🔌 Extensible Session Protocol - **Library-agnostic design**: Clean protocol interface allows any storage backend - **Drop-in implementations**: Easy integration with Redis, PostgreSQL, MongoDB, or any custom storage - **Production-ready interface**: Async-first design with proper error handling and type safety - **Vendor flexibility**: Library authors can provide their own Session implementations ### 💾 Built-in SQLite Implementation - **In-memory SQLite**: Perfect for temporary conversations during development - **Persistent SQLite**: File-based storage for conversations that survive application restarts - **Thread-safe operations**: Production-ready with connection pooling and proper concurrency handling ### 🔧 Simple API ```python # 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 Sessions session = SQLiteSession("user_123") result1 = await Runner.run(agent, "What's the weather?", session=session) result2 = await Runner.run(agent, "How about tomorrow?", session=session) # Remembers context automatically ``` ## What's Included ### Core Session Protocol - **`Session` Protocol**: Clean, async interface that any storage backend can implement - **Type-safe design**: Full type hints and runtime validation - **Standard operations**: `get_items()`, `add_items()`, `pop_item()`, `clear_session()` - **Extensibility-first**: Designed for third-party implementations ### Reference Implementation - **`SQLiteSession` Class**: Production-ready SQLite implementation - **Automatic schema management**: Creates tables and indexes automatically - **Connection pooling**: Thread-safe operations with proper resource management - **Flexible storage**: In-memory or persistent file-based databases ### Runner Integration - **New `session` parameter**: Drop-in addition to existing `Runner` methods - **Backward compatibility**: Zero breaking changes to existing code - **Automatic history management**: Prepends conversation history before each run ## Session Protocol for Library Authors The Session protocol provides a clean interface for implementing custom storage backends: ```python from agents.memory import Session from typing import List class MyCustomSession: """Custom session implementation following the Session protocol.""" def __init__(self, session_id: str): self.session_id = session_id # Your initialization here async def get_items(self, limit: int | None = None) -> List[dict]: """Retrieve conversation history for this session.""" # Your implementation here pass async def add_items(self, items: List[dict]) -> None: """Store new items for this session.""" # Your implementation here pass async def pop_item(self) -> dict | None: """Remove and return the most recent item from this session.""" # Your implementation here pass async def clear_session(self) -> None: """Clear all items for this session.""" # Your implementation here pass # Works seamlessly with any custom implementation result = await Runner.run(agent, "Hello", session=MyCustomSession("session_123")) ``` ### Example Third-Party Implementations ```python # Redis-based session (hypothetical library implementation) from redis_sessions import RedisSession session = RedisSession("user_123", redis_url="redis://localhost:6379") # PostgreSQL-based session (hypothetical library implementation) from postgres_sessions import PostgreSQLSession session = PostgreSQLSession("user_123", connection_string="postgresql://...") # Cloud-based session (hypothetical library implementation) from cloud_sessions import CloudSession session = CloudSession("user_123", api_key="...", region="us-east-1") # All work identically with the Runner result = await Runner.run(agent, "Hello", session=session) ``` ## Benefits ### For Application Developers - **Reduces boilerplate**: No more manual `.to_input_list()` management - **Prevents memory leaks**: Automatic cleanup and organized storage - **Easier debugging**: Clear conversation history tracking - **Flexible storage**: Choose the right backend for your needs ### For Library Authors - **Clean integration**: Simple protocol to implement for any storage backend - **Type safety**: Full type hints and runtime validation - **Async-first**: Modern async/await design throughout - **Documentation**: Comprehensive examples and API reference ### For Applications - **Better user experience**: Seamless conversation continuity - **Scalable architecture**: Support for multiple concurrent conversations - **Flexible deployment**: In-memory for development, production storage for scale - **Multi-agent support**: Same conversation history can be shared across different agents ## Usage Examples ### Basic Usage with SQLiteSession ```python from agents import Agent, Runner, SQLiteSession agent = Agent(name="Assistant", instructions="Reply concisely.") session = SQLiteSession("conversation_123") # Conversation flows naturally await Runner.run(agent, "Hi, I'm planning a trip to Japan", session=session) await Runner.run(agent, "What's the best time to visit?", session=session) await Runner.run(agent, "How about cherry blossom season?", session=session) ``` ### Multiple Sessions with Isolation ```python # Different users get separate conversation histories session_alice = SQLiteSession("user_alice") session_bob = SQLiteSession("user_bob") # Completely isolated conversations await Runner.run(agent, "I like pizza", session=session_alice) await Runner.run(agent, "I like sushi", session=session_bob) ``` ### Persistent vs In-Memory Storage ```python # In-memory database (lost when process ends) session = SQLiteSession("user_123") # Persistent file-based database session = SQLiteSession("user_123", "conversations.db") ``` ### Session Management Operations ```python session = SQLiteSession("user_123") # Get all items in a session items = await session.get_items() # Add new items to a session new_items = [ {"role": "user", "content": "Hello"}, {"role": "assistant", "content": "Hi there!"} ] await session.add_items(new_items) # Remove and return the most recent item (useful for corrections) last_item = await session.pop_item() # Clear all items from a session await session.clear_session() ``` ### Message Correction Pattern ```python # User wants to correct their last question user_message = await session.pop_item() # Remove user's question assistant_message = await session.pop_item() # Remove agent's response # Ask a corrected question result = await Runner.run( agent, "What's 2 + 3?", # Corrected question session=session ) ``` ## Technical Details ### Session Protocol Design - **Async-first**: All operations are async for non-blocking I/O - **Type-safe**: Full type hints with runtime validation - **Error handling**: Graceful degradation and detailed error messages - **Resource management**: Proper cleanup and connection handling ### SQLiteSession Implementation - **Thread-safe operations** with connection pooling - **Automatic schema management** with proper indexing - **JSON serialization** for message storage - **Memory-efficient** conversation retrieval and storage - **Cross-platform compatibility** ## 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 Sessions as a key primitive - New comprehensive guide at `docs/sessions.md` with protocol implementation examples - Enhanced `docs/running_agents.md` with automatic vs manual conversation management - Full API reference integration via `docs/ref/memory.md` - Implementation guide for library authors Sessions represent a significant architectural improvement for building conversational AI applications with the Agents SDK. The extensible Session protocol enables the ecosystem to provide specialized storage backends while maintaining a consistent, simple API for application developers. --------- Co-authored-by: Rohan Mehta <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 6b94ad0 - Browse repository at this point
Copy the full SHA 6b94ad0View commit details
Commits on Jul 11, 2025
-
Updated llm_as_a_judge.py (openai#1055)
Updated the evaluator agent’s instructions in llm_as_a_judge.py to prevent infinite evaluation loops. The agent is now instructed to provide a final evaluation after 5 attempts, allowing approval if the story outline is good enough, even if it is not perfect.
Configuration menu - View commit details
-
Copy full SHA for a9757de - Browse repository at this point
Copy the full SHA a9757deView commit details -
[1/n] Break Agent into AgentBase+Agent (openai#1068)
This allows base agent stuff to be shared with the realtime agent
Configuration menu - View commit details
-
Copy full SHA for e5d3ad7 - Browse repository at this point
Copy the full SHA e5d3ad7View commit details -
[2/n] Introduce RealtimeAgent (openai#1069)
Similar to the TS version. --- [//]: # (BEGIN SAPLING FOOTER) * __->__ openai#1069 * openai#1068
Configuration menu - View commit details
-
Copy full SHA for 9222bee - Browse repository at this point
Copy the full SHA 9222beeView commit details -
[3/n] Config and items for realtime (openai#1070)
Similar to the TS version. - Config is the things you can set on the session - Items are similar to responses items. I'm using an abstraction instead of reusing the ones in the openai SDK, to reduce the amount of work for other providers --- [//]: # (BEGIN SAPLING FOOTER) * openai#1074 * openai#1073 * openai#1072 * openai#1071 * __->__ openai#1070 * openai#1069 * openai#1068
Configuration menu - View commit details
-
Copy full SHA for 78675ff - Browse repository at this point
Copy the full SHA 78675ffView commit details -
[4/n] Transport interface + events (openai#1071)
Transport interface for actually connecting to the backend and managing realtime conversations. The transport emits events. --- [//]: # (BEGIN SAPLING FOOTER) * openai#1074 * openai#1073 * openai#1072 * __->__ openai#1071
Configuration menu - View commit details
-
Copy full SHA for 9d32577 - Browse repository at this point
Copy the full SHA 9d32577View commit details -
[5/n] OpenAI realtime transport impl (openai#1072)
Uses the openai realtime impl over websockets. Unlike the TS version, only supports websockets - no in browser stuff. --- [//]: # (BEGIN SAPLING FOOTER) * openai#1074 * openai#1073 * __->__ openai#1072 * openai#1071
Configuration menu - View commit details
-
Copy full SHA for 8b7d862 - Browse repository at this point
Copy the full SHA 8b7d862View commit details -
[6/n] RealtimeSession + events (openai#1073)
RealtimeSession is like Runner, except for Realtime. It's also stateful and manages the conversation for you. --- [//]: # (BEGIN SAPLING FOOTER) * openai#1076 * openai#1074 * __->__ openai#1073 * openai#1072 * openai#1071
Configuration menu - View commit details
-
Copy full SHA for 3e0122c - Browse repository at this point
Copy the full SHA 3e0122cView commit details -
[7/n] Demo for realtime (openai#1074)
Mostly working demo. Plays audio, shows event log. --- [//]: # (BEGIN SAPLING FOOTER) * openai#1076 * __->__ openai#1074
Configuration menu - View commit details
-
Copy full SHA for 38c5235 - Browse repository at this point
Copy the full SHA 38c5235View commit details -
Fix typo in Evaluator Instructions (capitalization of "After 5 attemp… (
openai#1067) Corrected the capitalization of "after" to "After" in the evaluator instructions string to ensure grammatical consistency and proper formatting.
Configuration menu - View commit details
-
Copy full SHA for c078c69 - Browse repository at this point
Copy the full SHA c078c69View commit details
Commits on Jul 12, 2025
-
[8/n] Make realtime more like the rest of agents sdk (openai#1076)
Key changes: 1. Transport -> model. 2. Extract any model settings into `RealtimeSessionModelSettings`. 3. RealtimeRunConfig, similar to the RunConfig in `run.py`. 4. RealtimeRunner now exists, similar to Runner. Returns a RealtimeSession when you call run(). 5. RealtimeSession now uses streaming events instead of listener. --- [//]: # (BEGIN SAPLING FOOTER) * openai#1080 * openai#1079 * __->__ openai#1076
Configuration menu - View commit details
-
Copy full SHA for 3a64c6f - Browse repository at this point
Copy the full SHA 3a64c6fView commit details -
Tests for realtime runner (openai#1079)
--- [//]: # (BEGIN SAPLING FOOTER) * openai#1080 * __->__ openai#1079 * openai#1076
Configuration menu - View commit details
-
Copy full SHA for c0974d7 - Browse repository at this point
Copy the full SHA c0974d7View commit details -
Configuration menu - View commit details
-
Copy full SHA for 7a00edd - Browse repository at this point
Copy the full SHA 7a00eddView commit details -
Configuration menu - View commit details
-
Copy full SHA for aab7bdd - Browse repository at this point
Copy the full SHA aab7bddView commit details -
Fix openai#968 by upgrading openai package to the latest (openai#1034)
This pull request resolves openai#968
Configuration menu - View commit details
-
Copy full SHA for eafd8df - Browse repository at this point
Copy the full SHA eafd8dfView commit details -
Realtime guardrail support (openai#1082)
Guadrails with debouncing support. Output only. --- [//]: # (BEGIN SAPLING FOOTER) * openai#1084 * __->__ openai#1082
Configuration menu - View commit details
-
Copy full SHA for a4499d4 - Browse repository at this point
Copy the full SHA a4499d4View commit details -
Realtime tracing (openai#1084)
Just sends tracing info to the server. --- [//]: # (BEGIN SAPLING FOOTER) * __->__ openai#1084 * openai#1082
Configuration menu - View commit details
-
Copy full SHA for 741da67 - Browse repository at this point
Copy the full SHA 741da67View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff main...main