0
# Memory and Sessions
1
2
Sessions provide automatic conversation history management across multiple agent runs, eliminating the need to manually track and pass conversation history. The SDK includes built-in session implementations for SQLite, Redis, OpenAI Conversations API, and supports custom session backends.
3
4
## Capabilities
5
6
### Session Protocol
7
8
Base interface for session implementations.
9
10
```python { .api }
11
class SessionABC:
12
"""
13
Base class for sessions.
14
15
Implement this protocol to create custom session storage.
16
"""
17
18
async def get_items() -> list[TResponseInputItem]:
19
"""
20
Get conversation items from session.
21
22
Returns:
23
- list[TResponseInputItem]: Conversation history
24
"""
25
26
async def add_items(items: list[TResponseInputItem]) -> None:
27
"""
28
Add items to session.
29
30
Parameters:
31
- items: Items to add to history
32
"""
33
34
async def clear() -> None:
35
"""Clear all items from session."""
36
37
Session = SessionABC # Type alias
38
```
39
40
### SQLite Session
41
42
File-based or in-memory session storage using SQLite.
43
44
```python { .api }
45
class SQLiteSession(SessionABC):
46
"""
47
SQLite-based session storage.
48
49
Stores conversation history in SQLite database file
50
or in-memory database.
51
"""
52
53
def __init__(session_id: str, db_path: str = ":memory:"):
54
"""
55
Initialize SQLite session.
56
57
Parameters:
58
- session_id: Unique session identifier
59
- db_path: Path to SQLite database file (default: ":memory:" for in-memory)
60
"""
61
62
async def get_items() -> list[TResponseInputItem]:
63
"""Get conversation items."""
64
65
async def add_items(items: list[TResponseInputItem]) -> None:
66
"""Add items to session."""
67
68
async def clear() -> None:
69
"""Clear session."""
70
```
71
72
Usage example:
73
74
```python
75
from agents import Agent, Runner, SQLiteSession
76
77
agent = Agent(
78
name="Assistant",
79
instructions="Reply concisely."
80
)
81
82
# File-based session
83
session = SQLiteSession("user_123", "conversations.db")
84
85
# First turn
86
result = await Runner.run(
87
agent,
88
"What city is the Golden Gate Bridge in?",
89
session=session
90
)
91
print(result.final_output) # "San Francisco"
92
93
# Second turn - history automatically loaded
94
result = await Runner.run(
95
agent,
96
"What state is it in?",
97
session=session
98
)
99
print(result.final_output) # "California"
100
101
# In-memory session (default)
102
memory_session = SQLiteSession("temp_conversation")
103
```
104
105
### OpenAI Conversations Session
106
107
Session using OpenAI's Conversations API for storage.
108
109
```python { .api }
110
class OpenAIConversationsSession(SessionABC):
111
"""
112
OpenAI Conversations API session.
113
114
Stores conversation history using OpenAI's
115
managed conversation storage.
116
"""
117
118
def __init__(conversation_id: str, client: AsyncOpenAI):
119
"""
120
Initialize OpenAI Conversations session.
121
122
Parameters:
123
- conversation_id: OpenAI conversation ID
124
- client: AsyncOpenAI client instance
125
"""
126
127
async def get_items() -> list[TResponseInputItem]:
128
"""Get conversation items."""
129
130
async def add_items(items: list[TResponseInputItem]) -> None:
131
"""Add items to session."""
132
133
async def clear() -> None:
134
"""Clear session."""
135
```
136
137
Usage example:
138
139
```python
140
from agents import Agent, Runner, OpenAIConversationsSession
141
from openai import AsyncOpenAI
142
143
client = AsyncOpenAI()
144
agent = Agent(name="Assistant")
145
146
# Use OpenAI Conversations API
147
session = OpenAIConversationsSession("conv_123", client)
148
149
result = await Runner.run(
150
agent,
151
"Hello!",
152
session=session
153
)
154
```
155
156
### Session Input Callback
157
158
Customize how session history is merged with current input.
159
160
```python { .api }
161
SessionInputCallback = Callable[
162
[list[TResponseInputItem], list[TResponseInputItem]],
163
MaybeAwaitable[list[TResponseInputItem]]
164
]
165
```
166
167
Usage example:
168
169
```python
170
from agents import RunConfig
171
172
async def merge_session_input(session_items, current_items):
173
"""
174
Custom logic for merging session history with current input.
175
176
Parameters:
177
- session_items: Items from session
178
- current_items: Current input items
179
180
Returns:
181
- list: Merged items
182
"""
183
# Keep last 10 messages from session
184
recent_session = session_items[-10:]
185
return recent_session + current_items
186
187
config = RunConfig(
188
session_input_callback=merge_session_input
189
)
190
191
result = await Runner.run(
192
agent,
193
"Hello",
194
session=session,
195
run_config=config
196
)
197
```
198
199
## Advanced Session Implementations
200
201
Extended session implementations in `agents.extensions.memory`.
202
203
### Redis Session
204
205
Distributed session storage using Redis.
206
207
```python { .api }
208
# In agents.extensions.memory
209
class RedisSession(SessionABC):
210
"""
211
Redis-based session storage.
212
213
Provides scalable, distributed conversation storage
214
suitable for production deployments.
215
216
Requires: pip install 'openai-agents[redis]'
217
"""
218
219
def __init__(session_id: str, redis_client):
220
"""
221
Initialize Redis session.
222
223
Parameters:
224
- session_id: Unique session identifier
225
- redis_client: Redis client instance
226
"""
227
228
@classmethod
229
def from_url(session_id: str, url: str):
230
"""
231
Create session from Redis URL.
232
233
Parameters:
234
- session_id: Session identifier
235
- url: Redis connection URL
236
237
Returns:
238
- RedisSession: Configured session
239
"""
240
```
241
242
Usage example:
243
244
```python
245
from agents import Agent, Runner
246
from agents.extensions.memory import RedisSession
247
248
# From URL
249
session = RedisSession.from_url("user_123", "redis://localhost:6379/0")
250
251
# Or with client
252
import redis.asyncio as redis
253
redis_client = redis.Redis(host='localhost', port=6379, db=0)
254
session = RedisSession("user_123", redis_client)
255
256
result = await Runner.run(agent, "Hello", session=session)
257
```
258
259
### SQLAlchemy Session
260
261
Database-agnostic session using SQLAlchemy ORM.
262
263
```python { .api }
264
# In agents.extensions.memory
265
class SQLAlchemySession(SessionABC):
266
"""
267
SQLAlchemy-based session storage.
268
269
Supports any database backend compatible with SQLAlchemy
270
(PostgreSQL, MySQL, SQLite, etc.).
271
272
Requires: pip install sqlalchemy
273
"""
274
275
def __init__(session_id: str, engine):
276
"""
277
Initialize SQLAlchemy session.
278
279
Parameters:
280
- session_id: Session identifier
281
- engine: SQLAlchemy engine
282
"""
283
```
284
285
Usage example:
286
287
```python
288
from agents import Agent, Runner
289
from agents.extensions.memory import SQLAlchemySession
290
from sqlalchemy import create_engine
291
292
# PostgreSQL
293
engine = create_engine("postgresql://user:pass@localhost/dbname")
294
session = SQLAlchemySession("user_123", engine)
295
296
# MySQL
297
engine = create_engine("mysql://user:pass@localhost/dbname")
298
session = SQLAlchemySession("user_456", engine)
299
300
result = await Runner.run(agent, "Hello", session=session)
301
```
302
303
### Advanced SQLite Session
304
305
Enhanced SQLite session with additional features.
306
307
```python { .api }
308
# In agents.extensions.memory
309
class AdvancedSQLiteSession(SessionABC):
310
"""
311
Advanced SQLite session with additional features.
312
313
Provides enhanced querying, metadata storage,
314
and performance optimizations.
315
"""
316
317
def __init__(session_id: str, db_path: str, options: dict = None):
318
"""
319
Initialize advanced SQLite session.
320
321
Parameters:
322
- session_id: Session identifier
323
- db_path: Database file path
324
- options: Additional configuration options
325
"""
326
```
327
328
### Dapr Session
329
330
Session storage using Dapr state management.
331
332
```python { .api }
333
# In agents.extensions.memory
334
class DaprSession(SessionABC):
335
"""
336
Dapr state store session.
337
338
Integrates with Dapr for cloud-native, portable
339
state management across multiple backends.
340
341
Requires: pip install dapr
342
"""
343
344
def __init__(session_id: str, store_name: str, dapr_client):
345
"""
346
Initialize Dapr session.
347
348
Parameters:
349
- session_id: Session identifier
350
- store_name: Dapr state store name
351
- dapr_client: Dapr client instance
352
"""
353
```
354
355
Usage example:
356
357
```python
358
from agents import Agent, Runner
359
from agents.extensions.memory import DaprSession
360
from dapr.clients import DaprClient
361
362
with DaprClient() as dapr_client:
363
session = DaprSession("user_123", "statestore", dapr_client)
364
result = await Runner.run(agent, "Hello", session=session)
365
```
366
367
### Encrypted Session Wrapper
368
369
Wrapper for encrypting session data at rest.
370
371
```python { .api }
372
# In agents.extensions.memory
373
class EncryptSession:
374
"""
375
Encrypted session wrapper.
376
377
Wraps any session implementation with encryption
378
for sensitive conversation data.
379
"""
380
381
def __init__(inner_session: Session, encryption_key: bytes):
382
"""
383
Initialize encrypted session wrapper.
384
385
Parameters:
386
- inner_session: Session to wrap
387
- encryption_key: Encryption key for data
388
"""
389
```
390
391
Usage example:
392
393
```python
394
from agents import SQLiteSession
395
from agents.extensions.memory import EncryptSession
396
397
# Wrap any session with encryption
398
base_session = SQLiteSession("user_123", "conversations.db")
399
encryption_key = b"your-32-byte-encryption-key-here"
400
encrypted_session = EncryptSession(base_session, encryption_key)
401
402
result = await Runner.run(agent, "Sensitive data", session=encrypted_session)
403
```
404
405
## Session Usage Patterns
406
407
### Basic Session Usage
408
409
```python
410
from agents import Agent, Runner, SQLiteSession
411
412
agent = Agent(name="Assistant", instructions="Be helpful.")
413
session = SQLiteSession("user_123")
414
415
# First conversation
416
result = await Runner.run(agent, "My name is Alice", session=session)
417
418
# Later conversation - remembers context
419
result = await Runner.run(agent, "What's my name?", session=session)
420
# Response: "Your name is Alice"
421
```
422
423
### Multiple Sessions
424
425
```python
426
# Different users maintain separate histories
427
user1_session = SQLiteSession("user_1", "app.db")
428
user2_session = SQLiteSession("user_2", "app.db")
429
430
result1 = await Runner.run(agent, "I like Python", session=user1_session)
431
result2 = await Runner.run(agent, "I like Java", session=user2_session)
432
433
# Each session has independent history
434
```
435
436
### Session with Synchronous Runner
437
438
```python
439
# Sessions work with both async and sync runners
440
session = SQLiteSession("user_123")
441
442
result = Runner.run_sync(agent, "Hello", session=session)
443
result = Runner.run_sync(agent, "How are you?", session=session)
444
```
445
446
### Clearing Session History
447
448
```python
449
# Clear conversation history
450
await session.clear()
451
452
# Fresh conversation
453
result = await Runner.run(agent, "Start fresh", session=session)
454
```
455
456
### Session Inspection
457
458
```python
459
# Get current session items
460
items = await session.get_items()
461
print(f"Session has {len(items)} messages")
462
463
# Manually add items (advanced)
464
await session.add_items([
465
{"type": "user", "content": "Custom message"}
466
])
467
```
468
469
## Custom Session Implementation
470
471
Create a custom session backend by implementing the SessionABC protocol:
472
473
```python
474
from agents.memory import SessionABC
475
from agents import TResponseInputItem
476
477
class MyCustomSession(SessionABC):
478
"""Custom session using your own storage."""
479
480
def __init__(self, session_id: str):
481
self.session_id = session_id
482
# Initialize your storage
483
484
async def get_items(self) -> list[TResponseInputItem]:
485
"""Load from your storage."""
486
items = await my_storage.load(self.session_id)
487
return items
488
489
async def add_items(self, items: list[TResponseInputItem]) -> None:
490
"""Save to your storage."""
491
await my_storage.append(self.session_id, items)
492
493
async def clear(self) -> None:
494
"""Clear from your storage."""
495
await my_storage.delete(self.session_id)
496
497
# Use custom session
498
session = MyCustomSession("user_123")
499
result = await Runner.run(agent, "Hello", session=session)
500
```
501
502
Examples of custom storage backends:
503
- Cloud storage (S3, Azure Blob, GCS)
504
- NoSQL databases (MongoDB, DynamoDB)
505
- In-memory caches (Memcached)
506
- Message queues with persistence
507
- Custom encrypted storage
508
509
## Best Practices
510
511
1. **Session IDs**: Use stable, unique identifiers (user IDs, conversation IDs)
512
2. **Database Choice**: SQLite for single-server, Redis/PostgreSQL for distributed
513
3. **Encryption**: Use EncryptSession for sensitive conversations
514
4. **History Limits**: Implement custom session_input_callback to limit history size
515
5. **Cleanup**: Periodically clear old sessions to manage storage
516
6. **Error Handling**: Handle session storage failures gracefully
517
7. **Testing**: Test session persistence across restarts
518
8. **Monitoring**: Track session storage performance and size
519