@@ -4,10 +4,38 @@ The Agents SDK provides built-in session memory to automatically maintain conver
44
55Sessions stores conversation history for a specific session, allowing agents to maintain context without requiring explicit manual memory management. This is particularly useful for building chat applications or multi-turn conversations where you want the agent to remember previous interactions.
66
7+ ## Installation
8+
9+ ### SQLite Sessions
10+ SQLite sessions are available by default with no additional dependencies required.
11+
12+ ### Redis Sessions
13+ Redis sessions require the Redis package, which is included as a dependency:
14+
15+ ``` bash
16+ # Redis support is included by default
17+ pip install openai-agents
18+
19+ # Or if you already have the package installed
20+ pip install redis[hiredis]
21+ ```
22+
23+ You'll also need a Redis server running. For development, you can use Docker:
24+
25+ ``` bash
26+ # Start Redis with Docker
27+ docker run -d -p 6379:6379 redis:latest
28+
29+ # Or install Redis locally (macOS)
30+ brew install redis
31+ redis-server
32+ ```
33+
734## Quick start
835
936``` python
10- from agents import Agent, Runner, SQLiteSession
37+ from agents import Agent, Runner
38+ from agents.memory.providers.sqlite import SQLiteSession
1139
1240# Create agent
1341agent = Agent(
@@ -60,7 +88,7 @@ This eliminates the need to manually call `.to_input_list()` and manage conversa
6088Sessions supports several operations for managing conversation history:
6189
6290``` python
63- from agents import SQLiteSession
91+ from agents.memory.providers.sqlite import SQLiteSession
6492
6593session = SQLiteSession(" user_123" , " conversations.db" )
6694
@@ -87,7 +115,8 @@ await session.clear_session()
87115The ` pop_item ` method is particularly useful when you want to undo or modify the last item in a conversation:
88116
89117``` python
90- from agents import Agent, Runner, SQLiteSession
118+ from agents import Agent, Runner
119+ from agents.memory.providers.sqlite import SQLiteSession
91120
92121agent = Agent(name = " Assistant" )
93122session = SQLiteSession(" correction_example" )
@@ -125,7 +154,7 @@ result = await Runner.run(agent, "Hello")
125154### SQLite memory
126155
127156``` python
128- from agents import SQLiteSession
157+ from agents.memory.providers.sqlite import SQLiteSession
129158
130159# In-memory database (lost when process ends)
131160session = SQLiteSession(" user_123" )
@@ -141,10 +170,89 @@ result = await Runner.run(
141170)
142171```
143172
173+ ### Redis memory
174+
175+ ``` python
176+ from agents.memory.providers.redis import RedisSession
177+
178+ # Basic Redis session (localhost:6379, default database)
179+ session = RedisSession(" user_123" )
180+
181+ # Redis session with custom configuration
182+ session = RedisSession(
183+ session_id = " user_123" ,
184+ redis_url = " redis://localhost:6379" ,
185+ db = 1 ,
186+ session_prefix = " chat_session" ,
187+ messages_prefix = " chat_messages" ,
188+ ttl = 3600 # Session expires after 1 hour
189+ )
190+
191+ # Use the session
192+ result = await Runner.run(
193+ agent,
194+ " Hello" ,
195+ session = session
196+ )
197+
198+ # Remember to close the Redis connection when done
199+ await session.close()
200+
201+ # Or use async context manager for automatic cleanup
202+ async with RedisSession(" user_123" ) as session:
203+ result = await Runner.run(
204+ agent,
205+ " Hello" ,
206+ session = session
207+ )
208+ # Connection automatically closed when exiting the context
209+ ```
210+
211+ ### Redis Session Manager
212+
213+ For production applications with multiple sessions, use the Redis Session Manager for connection pooling:
214+
215+ ``` python
216+ from agents.memory.providers.redis import RedisSessionManager
217+
218+ # Create a session manager with connection pooling
219+ manager = RedisSessionManager(
220+ redis_url = " redis://localhost:6379" ,
221+ db = 0 ,
222+ default_ttl = 7200 , # 2 hours default TTL
223+ max_connections = 10
224+ )
225+
226+ # Get session instances that share the connection pool
227+ session1 = manager.get_session(" user_123" )
228+ session2 = manager.get_session(" user_456" , ttl = 3600 ) # Custom TTL
229+
230+ # Use sessions normally
231+ result1 = await Runner.run(agent, " Hello" , session = session1)
232+ result2 = await Runner.run(agent, " Hi there" , session = session2)
233+
234+ # List all sessions
235+ session_ids = await manager.list_sessions()
236+ print (f " Active sessions: { session_ids} " )
237+
238+ # Delete a specific session
239+ await manager.delete_session(" user_123" )
240+
241+ # Close the manager and all connections
242+ await manager.close()
243+
244+ # Or use async context manager
245+ async with RedisSessionManager() as manager:
246+ session = manager.get_session(" user_123" )
247+ result = await Runner.run(agent, " Hello" , session = session)
248+ # Connections automatically closed when exiting
249+ ```
250+
144251### Multiple sessions
145252
146253``` python
147- from agents import Agent, Runner, SQLiteSession
254+ from agents import Agent, Runner
255+ from agents.memory.providers.sqlite import SQLiteSession
148256
149257agent = Agent(name = " Assistant" )
150258
@@ -168,7 +276,7 @@ result2 = await Runner.run(
168276
169277You can implement your own session memory by creating a class that follows the [ ` Session ` ] [ agents.memory.session.Session ] protocol:
170278
171- ```` python
279+ ``` python
172280from agents.memory import Session
173281from typing import List
174282
@@ -200,12 +308,15 @@ class MyCustomSession:
200308 pass
201309
202310# Use your custom session
311+ from agents import Agent, Runner
312+
203313agent = Agent(name = " Assistant" )
204314result = await Runner.run(
205315 agent,
206316 " Hello" ,
207317 session = MyCustomSession(" my_session" )
208318)
319+ ```
209320
210321## Session management
211322
@@ -219,9 +330,10 @@ Use meaningful session IDs that help you organize conversations:
219330
220331### Memory persistence
221332
222- - Use in - memory SQLite (`SQLiteSession(" session_id" )` ) for temporary conversations
223- - Use file - based SQLite (`SQLiteSession(" session_id" , " path/to/db.sqlite" )` ) for persistent conversations
224- - Consider implementing custom session backends for production systems (Redis, PostgreSQL, etc.)
333+ - Use in-memory SQLite (` SQLiteSession("session_id") ` ) for temporary conversations
334+ - Use file-based SQLite (` SQLiteSession("session_id", "path/to/db.sqlite") ` ) for persistent conversations
335+ - Use Redis (` RedisSession("session_id") ` ) for distributed applications and when you need features like automatic expiration
336+ - Consider implementing custom session backends for specialized production systems
225337
226338### Session management
227339
@@ -232,8 +344,15 @@ await session.clear_session()
232344# Different agents can share the same session
233345support_agent = Agent(name = " Support" )
234346billing_agent = Agent(name = " Billing" )
347+
348+ # SQLite session example
349+ from agents.memory.providers.sqlite import SQLiteSession
235350session = SQLiteSession(" user_123" )
236351
352+ # Redis session example
353+ from agents.memory.providers.redis import RedisSession
354+ session = RedisSession(" user_123" , ttl = 3600 )
355+
237356# Both agents will see the same conversation history
238357result1 = await Runner.run(
239358 support_agent,
@@ -253,7 +372,8 @@ Here's a complete example showing session memory in action:
253372
254373```python
255374import asyncio
256- from agents import Agent, Runner, SQLiteSession
375+ from agents import Agent, Runner
376+ from agents.memory.providers.sqlite import SQLiteSession
257377
258378
259379async def main ():
@@ -311,9 +431,118 @@ if __name__ == "__main__":
311431 asyncio.run(main())
312432```
313433
434+ ## Redis Example
435+
436+ Here's a complete example showing Redis session memory in action:
437+
438+ ``` python
439+ import asyncio
440+ from agents import Agent, Runner
441+ from agents.memory.providers.redis import RedisSession, RedisSessionManager
442+
443+
444+ async def redis_example ():
445+ # Create an agent
446+ agent = Agent(
447+ name = " Assistant" ,
448+ instructions = " Reply very concisely." ,
449+ )
450+
451+ print (" === Redis Session Example ===" )
452+ print (" Using Redis for distributed session memory.\n " )
453+
454+ # Example 1: Basic Redis session
455+ async with RedisSession(" user_456" , ttl = 3600 ) as session:
456+ print (" First turn with Redis:" )
457+ print (" User: What's the capital of France?" )
458+ result = await Runner.run(
459+ agent,
460+ " What's the capital of France?" ,
461+ session = session
462+ )
463+ print (f " Assistant: { result.final_output} " )
464+ print ()
465+
466+ print (" Second turn:" )
467+ print (" User: What's the population?" )
468+ result = await Runner.run(
469+ agent,
470+ " What's the population?" ,
471+ session = session
472+ )
473+ print (f " Assistant: { result.final_output} " )
474+ print ()
475+
476+ # Example 2: Redis Session Manager for production use
477+ async with RedisSessionManager(default_ttl = 7200 ) as manager:
478+ # Get multiple sessions that share connection pool
479+ session1 = manager.get_session(" user_123" )
480+ session2 = manager.get_session(" user_789" )
481+
482+ # Use sessions concurrently
483+ result1 = await Runner.run(
484+ agent,
485+ " Hello from session 1" ,
486+ session = session1
487+ )
488+ result2 = await Runner.run(
489+ agent,
490+ " Hello from session 2" ,
491+ session = session2
492+ )
493+
494+ print (" Session Manager Example:" )
495+ print (f " Session 1 response: { result1.final_output} " )
496+ print (f " Session 2 response: { result2.final_output} " )
497+ print ()
498+
499+ # List all active sessions
500+ session_ids = await manager.list_sessions()
501+ print (f " Active sessions: { session_ids} " )
502+
503+ # Clean up specific session
504+ await manager.delete_session(" user_789" )
505+ print (" Deleted session user_789" )
506+
507+ print (" === Redis Example Complete ===" )
508+
509+
510+ if __name__ == " __main__" :
511+ asyncio.run(redis_example())
512+ ```
513+
514+ ## Choosing the Right Session Backend
515+
516+ ### SQLite vs Redis
517+
518+ | Feature | SQLite | Redis |
519+ | ---------| --------| -------|
520+ | ** Setup** | No additional services required | Requires Redis server |
521+ | ** Persistence** | File-based or in-memory | In-memory with optional persistence |
522+ | ** Distribution** | Single process only | Multi-process/multi-server |
523+ | ** TTL/Expiration** | Manual cleanup required | Automatic expiration with TTL |
524+ | ** Concurrency** | Good for single application | Excellent for distributed systems |
525+ | ** Performance** | Fast for local access | Very fast, especially for concurrent access |
526+ | ** Use Cases** | Single-server applications, development | Production systems, microservices, scaling |
527+
528+ ### When to use SQLite:
529+ - Single-server applications
530+ - Development and testing
531+ - When you need file-based persistence
532+ - Simple deployment requirements
533+
534+ ### When to use Redis:
535+ - Multi-server applications
536+ - Microservices architecture
537+ - When you need automatic session expiration
538+ - High-concurrency applications
539+ - Distributed systems
540+
314541## API Reference
315542
316543For detailed API documentation, see:
317544
318- - [`Session` ][agents.memory.Session] - Protocol interface
319- - [`SQLiteSession` ][agents.memory.SQLiteSession] - SQLite implementation
545+ - [ ` Session ` ] [ agents.memory.Session ] - Protocol interface
546+ - [ ` SQLiteSession ` ] [ agents.memory.providers.sqlite.SQLiteSession ] - SQLite implementation
547+ - [ ` RedisSession ` ] [ agents.memory.providers.redis.RedisSession ] - Redis implementation
548+ - [ ` RedisSessionManager ` ] [ agents.memory.providers.redis.RedisSessionManager ] - Redis connection manager
0 commit comments