-
Notifications
You must be signed in to change notification settings - Fork 2.7k
feat: add Redis session support for scalable distributed memory #1785
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
Merged
seratch
merged 13 commits into
openai:main
from
damianoneill:feature/redis-session-support
Sep 25, 2025
+1,757
−2
Merged
Changes from 1 commit
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
8d5ba83
feat: add Redis session support for scalable distributed memory
damianoneill e26b1ee
feat: enhance Redis session with client ownership and decode_response…
damianoneill 05d8681
refactor: improve Redis session test clarity and accuracy
damianoneill 73a2683
test: improve Redis session test coverage from 82% to 87%
damianoneill 2c4bd22
fix: Improve type safety in Redis session tests
damianoneill 1517065
Merge branch 'main' into feature/redis-session-support
damianoneill 583286b
test: add comprehensive test coverage for OpenAI conversations session
damianoneill f383bff
feat: improve Redis session example with session clearing
damianoneill abaa8c6
Merge branch 'main' into feature/redis-session-support
damianoneill 3aaf4b1
Merge branch 'main' into feature/redis-session-support
damianoneill e464160
Merge branch 'main' into feature/redis-session-support
damianoneill f231d59
Apply suggestions from code review
seratch eb8f7bb
Merge branch 'main' into feature/redis-session-support
seratch File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,3 +144,6 @@ cython_debug/ | |
# PyPI configuration file | ||
.pypirc | ||
.aider* | ||
|
||
# Redis database files | ||
dump.rdb |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# `RedisSession` | ||
|
||
::: agents.extensions.memory.redis_session.RedisSession |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
""" | ||
Example demonstrating Redis session memory functionality. | ||
|
||
This example shows how to use Redis-backed session memory to maintain conversation | ||
history across multiple agent runs with persistence and scalability. | ||
""" | ||
|
||
import asyncio | ||
|
||
from agents import Agent, Runner | ||
from agents.extensions.memory import RedisSession | ||
|
||
|
||
async def main(): | ||
# Create an agent | ||
agent = Agent( | ||
name="Assistant", | ||
instructions="Reply very concisely.", | ||
) | ||
|
||
print("=== Redis Session Example ===") | ||
print("This example requires Redis to be running on localhost:6379") | ||
print("Start Redis with: redis-server") | ||
print() | ||
|
||
# Create a Redis session instance | ||
session_id = "redis_conversation_123" | ||
try: | ||
session = RedisSession.from_url( | ||
session_id, | ||
url="redis://localhost:6379/0", # Use database 0 | ||
) | ||
|
||
# Test Redis connectivity | ||
if not await session.ping(): | ||
print("Redis server is not available!") | ||
print("Please start Redis server and try again.") | ||
return | ||
|
||
print("Connected to Redis successfully!") | ||
print(f"Session ID: {session_id}") | ||
print("The agent will remember previous messages automatically.\n") | ||
|
||
# First turn | ||
print("First turn:") | ||
print("User: What city is the Golden Gate Bridge in?") | ||
result = await Runner.run( | ||
agent, | ||
"What city is the Golden Gate Bridge in?", | ||
session=session, | ||
) | ||
print(f"Assistant: {result.final_output}") | ||
print() | ||
|
||
# Second turn - the agent will remember the previous conversation | ||
print("Second turn:") | ||
print("User: What state is it in?") | ||
result = await Runner.run(agent, "What state is it in?", session=session) | ||
print(f"Assistant: {result.final_output}") | ||
print() | ||
|
||
# Third turn - continuing the conversation | ||
print("Third turn:") | ||
print("User: What's the population of that state?") | ||
result = await Runner.run( | ||
agent, | ||
"What's the population of that state?", | ||
session=session, | ||
) | ||
print(f"Assistant: {result.final_output}") | ||
print() | ||
|
||
print("=== Conversation Complete ===") | ||
print("Notice how the agent remembered the context from previous turns!") | ||
print("Redis session automatically handles conversation history with persistence.") | ||
|
||
# Demonstrate session persistence | ||
print("\n=== Session Persistence Demo ===") | ||
all_items = await session.get_items() | ||
print(f"Total messages stored in Redis: {len(all_items)}") | ||
|
||
# Demonstrate the limit parameter | ||
print("\n=== Latest Items Demo ===") | ||
latest_items = await session.get_items(limit=2) | ||
print("Latest 2 items:") | ||
for i, msg in enumerate(latest_items, 1): | ||
role = msg.get("role", "unknown") | ||
content = msg.get("content", "") | ||
print(f" {i}. {role}: {content}") | ||
|
||
# Demonstrate session isolation with a new session | ||
print("\n=== Session Isolation Demo ===") | ||
new_session = RedisSession.from_url( | ||
"different_conversation_456", | ||
url="redis://localhost:6379/0", | ||
) | ||
|
||
print("Creating a new session with different ID...") | ||
result = await Runner.run( | ||
agent, | ||
"Hello, this is a new conversation!", | ||
session=new_session, | ||
) | ||
print(f"New session response: {result.final_output}") | ||
|
||
# Show that sessions are isolated | ||
original_items = await session.get_items() | ||
new_items = await new_session.get_items() | ||
print(f"Original session has {len(original_items)} items") | ||
print(f"New session has {len(new_items)} items") | ||
print("Sessions are completely isolated!") | ||
|
||
# Clean up the new session | ||
await new_session.clear_session() | ||
await new_session.close() | ||
|
||
# Optional: Demonstrate TTL (time-to-live) functionality | ||
print("\n=== TTL Demo ===") | ||
ttl_session = RedisSession.from_url( | ||
"ttl_demo_session", | ||
url="redis://localhost:6379/0", | ||
ttl=3600, # 1 hour TTL | ||
) | ||
|
||
await Runner.run( | ||
agent, | ||
"This message will expire in 1 hour", | ||
session=ttl_session, | ||
) | ||
print("Created session with 1-hour TTL - messages will auto-expire") | ||
|
||
await ttl_session.close() | ||
|
||
# Close the main session | ||
await session.close() | ||
|
||
except Exception as e: | ||
print(f"Error: {e}") | ||
print("Make sure Redis is running on localhost:6379") | ||
|
||
|
||
async def demonstrate_advanced_features(): | ||
"""Demonstrate advanced Redis session features.""" | ||
print("\n=== Advanced Features Demo ===") | ||
|
||
# Custom key prefix for multi-tenancy | ||
tenant_session = RedisSession.from_url( | ||
"user_123", | ||
url="redis://localhost:6379/0", | ||
key_prefix="tenant_abc:sessions", # Custom prefix for isolation | ||
) | ||
|
||
try: | ||
if await tenant_session.ping(): | ||
print("Custom key prefix demo:") | ||
await Runner.run( | ||
Agent(name="Support", instructions="Be helpful"), | ||
"Hello from tenant ABC", | ||
session=tenant_session, | ||
) | ||
print("Session with custom key prefix created successfully") | ||
|
||
await tenant_session.close() | ||
except Exception as e: | ||
print(f"Advanced features error: {e}") | ||
|
||
|
||
if __name__ == "__main__": | ||
asyncio.run(main()) | ||
asyncio.run(demonstrate_advanced_features()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.