Python: Remove unsupported memory scoping params from mem0/redis samples and docs (#4367)

* Python: Remove unsupported memory scoping params from samples and docs

Fixes #4353

The `Mem0ContextProvider` and `RedisContextProvider` no longer support
`thread_id` or `scope_to_per_operation_thread_id` parameters. This commit
updates the affected samples and READMEs to use only the currently
supported API (`user_id`, `agent_id`, `application_id`).

Changes:
- mem0_sessions.py: Remove `thread_id` and
  `scope_to_per_operation_thread_id` from examples 1 and 2, rewrite to
  demonstrate user-scoped and agent-scoped memory patterns
- redis_sessions.py: Update module docstring to remove references to
  removed thread scoping params
- mem0/README.md: Update Memory Scoping docs to reflect current API
- redis/README.md: Remove `thread_id` and
  `scope_to_per_operation_thread_id` references from docs

* Address Copilot review: rename thread_scope functions, fix docstring

- Rename `example_global_thread_scope` -> `example_global_memory_scope`
- Rename `example_per_operation_thread_scope` -> `example_agent_scoped_memory`
- Update example 2 docstring to mention `application_id` alongside
  `user_id` and `agent_id` since it's set in the provider config
- Update module docstring scenario 2 to include `application_id`

* fix: rebase onto main, address giles17 review feedback

- Resolve merge conflicts by rebasing all 4 original files onto current main
- Address giles17's agent review suggestions:
  - mem0_basic.py: update comment to remove thread_id from scoping list
  - mem0_oss.py: update comment to remove thread_id from scoping list
  - redis_sessions.py: rename Example 2 from "Agent-Scoped Memory" to
    "Hybrid Vector Search" to accurately describe what it demonstrates
  - redis/README.md: update Example 2 description to match renamed example

---------

Co-authored-by: Tao Chen <taochen@microsoft.com>
Co-authored-by: Giles Odigwe <79032838+giles17@users.noreply.github.com>
This commit is contained in:
L. Elaine Dazzio
2026-03-31 21:57:23 +00:00
committed by GitHub
co-authored by Tao Chen Giles Odigwe
parent 3a49b1d6dd
commit 1e527a328c
6 changed files with 81 additions and 99 deletions
@@ -9,7 +9,7 @@ This folder contains examples demonstrating how to use the Mem0 context provider
| File | Description |
|------|-------------|
| [`mem0_basic.py`](mem0_basic.py) | Basic example of using Mem0 context provider to store and retrieve user preferences across different conversation threads. |
| [`mem0_sessions.py`](mem0_sessions.py) | Advanced example demonstrating different thread scoping strategies with Mem0. Covers global thread scope (memories shared across all operations), per-operation thread scope (memories isolated per thread), and multiple agents with different memory configurations for personal vs. work contexts. |
| [`mem0_sessions.py`](mem0_sessions.py) | Example demonstrating different memory scoping strategies with Mem0. Covers user-scoped memory (memories shared across all sessions for the same user), agent-scoped memory (memories isolated per agent), and multiple agents with different memory configurations for personal vs. work contexts. |
| [`mem0_oss.py`](mem0_oss.py) | Example of using the Mem0 Open Source self-hosted version as the context provider. Demonstrates setup and configuration for local deployment. |
## Prerequisites
@@ -40,16 +40,8 @@ Set the following environment variables:
### Memory Scoping
The Mem0 context provider supports different scoping strategies:
The Mem0 context provider supports scoping via identifiers:
- **Global Scope** (`scope_to_per_operation_thread_id=False`): Memories are shared across all conversation threads
- **Thread Scope** (`scope_to_per_operation_thread_id=True`): Memories are isolated per conversation thread
### Memory Association
Mem0 records can be associated with different identifiers:
- `user_id`: Associate memories with a specific user
- `agent_id`: Associate memories with a specific agent
- `thread_id`: Associate memories with a specific conversation thread
- `application_id`: Associate memories with an application context
- **User scope** (`user_id`): Associate memories with a specific user, shared across all sessions
- **Agent scope** (`agent_id`): Isolate memories per agent persona
- **Application scope** (`application_id`): Associate memories with an application context
@@ -31,7 +31,7 @@ def retrieve_company_report(company_code: str, detailed: bool) -> str:
async def main() -> None:
"""Example of memory usage with Mem0 context provider."""
print("=== Mem0 Context Provider Example ===")
# Each record in Mem0 should be associated with agent_id or user_id or application_id or thread_id.
# Each record in Mem0 should be associated with agent_id or user_id or application_id.
# In this example, we associate Mem0 records with user_id.
user_id = str(uuid.uuid4())
# For Azure authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
@@ -32,7 +32,7 @@ def retrieve_company_report(company_code: str, detailed: bool) -> str:
async def main() -> None:
"""Example of memory usage with local Mem0 OSS context provider."""
print("=== Mem0 Context Provider Example ===")
# Each record in Mem0 should be associated with agent_id or user_id or application_id or thread_id.
# Each record in Mem0 should be associated with agent_id or user_id or application_id.
# In this example, we associate Mem0 records with user_id.
user_id = str(uuid.uuid4())
# For Azure authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
@@ -1,7 +1,6 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import uuid
from agent_framework import Agent, tool
from agent_framework.foundry import FoundryChatClient
@@ -27,52 +26,49 @@ def get_user_preferences(user_id: str) -> str:
return preferences.get(user_id, "No specific preferences found")
async def example_global_thread_scope() -> None:
"""Example 1: Global thread_id scope (memories shared across all operations)."""
print("1. Global Thread Scope Example:")
async def example_user_scoped_memory() -> None:
"""Example 1: User-scoped memory (memories shared across all sessions for the same user)."""
print("1. User-Scoped Memory Example:")
print("-" * 40)
global_thread_id = str(uuid.uuid4())
user_id = "user123"
async with (
AzureCliCredential() as credential,
Agent(
client=FoundryChatClient(credential=credential),
name="GlobalMemoryAssistant",
name="UserMemoryAssistant",
instructions="You are an assistant that remembers user preferences across conversations.",
tools=get_user_preferences,
context_providers=[
Mem0ContextProvider(
source_id="mem0",
user_id=user_id,
thread_id=global_thread_id,
scope_to_per_operation_thread_id=False, # Share memories across all sessions
)
],
) as global_agent,
) as user_agent,
):
# Store some preferences in the global scope
# Store some preferences
query = "Remember that I prefer technical responses with code examples when discussing programming."
print(f"User: {query}")
result = await global_agent.run(query)
result = await user_agent.run(query)
print(f"Agent: {result}\n")
# Create a new session - but memories should still be accessible due to global scope
new_session = global_agent.create_session()
# Create a new session - memories should still be accessible via user_id scoping
new_session = user_agent.create_session()
query = "What do you know about my preferences?"
print(f"User (new session): {query}")
result = await global_agent.run(query, session=new_session)
result = await user_agent.run(query, session=new_session)
print(f"Agent: {result}\n")
async def example_per_operation_thread_scope() -> None:
"""Example 2: Per-operation thread scope (memories isolated per session).
async def example_agent_scoped_memory() -> None:
"""Example 2: Agent-scoped memory (memories isolated per agent_id).
Note: When scope_to_per_operation_thread_id=True, the provider is bound to a single session
throughout its lifetime. Use the same session object for all operations with that provider.
Note: Use different agent_id values to isolate memories between different
agent personas, even when the user_id is the same.
"""
print("2. Per-Operation Thread Scope Example:")
print("2. Agent-Scoped Memory Example:")
print("-" * 40)
user_id = "user123"
@@ -82,48 +78,45 @@ async def example_per_operation_thread_scope() -> None:
Agent(
client=FoundryChatClient(credential=credential),
name="ScopedMemoryAssistant",
instructions="You are an assistant with thread-scoped memory.",
instructions="You are an assistant with agent-scoped memory.",
tools=get_user_preferences,
context_providers=[
Mem0ContextProvider(
source_id="mem0",
user_id=user_id,
scope_to_per_operation_thread_id=True, # Isolate memories per session
agent_id="scoped_assistant",
)
],
) as scoped_agent,
):
# Create a specific session for this scoped provider
dedicated_session = scoped_agent.create_session()
# Store some information in the dedicated session
# Store some information
query = "Remember that for this conversation, I'm working on a Python project about data analysis."
print(f"User (dedicated session): {query}")
result = await scoped_agent.run(query, session=dedicated_session)
print(f"User: {query}")
result = await scoped_agent.run(query)
print(f"Agent: {result}\n")
# Test memory retrieval in the same dedicated session
# Test memory retrieval
query = "What project am I working on?"
print(f"User (same dedicated session): {query}")
result = await scoped_agent.run(query, session=dedicated_session)
print(f"User: {query}")
result = await scoped_agent.run(query)
print(f"Agent: {result}\n")
# Store more information in the same session
# Store more information
query = "Also remember that I prefer using pandas and matplotlib for this project."
print(f"User (same dedicated session): {query}")
result = await scoped_agent.run(query, session=dedicated_session)
print(f"User: {query}")
result = await scoped_agent.run(query)
print(f"Agent: {result}\n")
# Test comprehensive memory retrieval
query = "What do you know about my current project and preferences?"
print(f"User (same dedicated session): {query}")
result = await scoped_agent.run(query, session=dedicated_session)
print(f"User: {query}")
result = await scoped_agent.run(query)
print(f"Agent: {result}\n")
async def example_multiple_agents() -> None:
"""Example 3: Multiple agents with different thread configurations."""
print("3. Multiple Agents with Different Thread Configurations:")
"""Example 3: Multiple agents with different memory configurations."""
print("3. Multiple Agents with Different Memory Configurations:")
print("-" * 40)
agent_id_1 = "agent_personal"
@@ -178,11 +171,11 @@ async def example_multiple_agents() -> None:
async def main() -> None:
"""Run all Mem0 thread management examples."""
print("=== Mem0 Thread Management Example ===\n")
"""Run all Mem0 memory management examples."""
print("=== Mem0 Memory Management Example ===\n")
await example_global_thread_scope()
await example_per_operation_thread_scope()
await example_user_scoped_memory()
await example_agent_scoped_memory()
await example_multiple_agents()