⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/bedrock_agentcore/memory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ session.add_turns([
# Search long-term memories (after memory extraction has occurred)
memories = session.search_long_term_memories(
query="what food does the user like",
namespace_prefix="/food/user-123",
namespace_prefix="/food/user-123/",
top_k=5
)

Expand Down Expand Up @@ -219,8 +219,8 @@ def my_llm(user_input: str, memories: List[Dict]) -> str:

# Configure memory retrieval with multiple namespaces
retrieval_config = {
"support/facts/{sessionId}": RetrievalConfig(top_k=5, relevance_score=0.3),
"user/preferences/{actorId}": RetrievalConfig(top_k=3, relevance_score=0.5)
"support/facts/{sessionId}/": RetrievalConfig(top_k=5, relevance_score=0.3),
"user/preferences/{actorId}/": RetrievalConfig(top_k=3, relevance_score=0.5)
}

# Process complete conversation turn with automatic memory integration
Expand Down Expand Up @@ -301,7 +301,7 @@ session2 = manager.create_memory_session(
```python
# List all memory records in a namespace
records = session.list_long_term_memory_records(
namespace_prefix="/user/preferences/user-123",
namespace_prefix="/user/preferences/user-123/",
max_results=20
)

Expand All @@ -327,7 +327,7 @@ Learn more here!: [Working example](metadata-workflow.ipynb)
# Step 1: Retrieve relevant memories
memories = session.search_long_term_memories(
query="previous discussion",
namespace_prefix="support/facts/session-456",
namespace_prefix="support/facts/session-456/",
top_k=5
)

Expand Down
14 changes: 7 additions & 7 deletions src/bedrock_agentcore/memory/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def __getattr__(self, name: str):
client = MemoryClient()

# These calls are forwarded to the appropriate boto3 client
response = client.list_memory_records(memoryId="mem-123", namespace="test")
response = client.list_memory_records(memoryId="mem-123", namespace="test/")
metadata = client.get_memory_metadata(memoryId="mem-123")
"""
if name in self._ALLOWED_GMDP_METHODS and hasattr(self.gmdp_client, name):
Expand Down Expand Up @@ -296,12 +296,12 @@ def retrieve_memories(
# Correct - exact namespace
memories = client.retrieve_memories(
memory_id="mem-123",
namespace="support/facts/session-456",
namespace="support/facts/session-456/",
query="customer preferences"
)

# Incorrect - wildcards not supported
# memories = client.retrieve_memories(..., namespace="support/facts/*", ...)
# memories = client.retrieve_memories(..., namespace="support/facts/*/", ...)
"""
if "*" in namespace:
logger.error("Wildcards are not supported in namespaces. Please provide exact namespace.")
Expand Down Expand Up @@ -730,7 +730,7 @@ def my_llm(user_input: str, memories: List[Dict]) -> str:
session_id="session-456",
user_input="What did we discuss yesterday?",
llm_callback=my_llm,
retrieval_namespace="support/facts/{sessionId}"
retrieval_namespace="support/facts/{sessionId}/"
)
"""
# Step 1: Retrieve relevant memories
Expand Down Expand Up @@ -1758,8 +1758,8 @@ def wait_for_memories(
existing memories in the namespace, this method may return True immediately
even if new extractions haven't completed.
2. Wildcards (*) are NOT supported in namespaces. You must provide the exact
namespace path with all variables resolved (e.g., "support/facts/session-123"
not "support/facts/*").
namespace path with all variables resolved (e.g., "support/facts/session-123/"
not "support/facts/*/").

For subsequent extractions in populated namespaces, use a fixed wait time:
time.sleep(150) # Wait 2.5 minutes for extraction
Expand Down Expand Up @@ -1931,7 +1931,7 @@ def _add_default_namespaces(self, strategies: List[Dict[str, Any]]) -> List[Dict

if "namespaces" not in strategy_config:
strategy_type = StrategyType(strategy_type_key)
strategy_config["namespaces"] = DEFAULT_NAMESPACES.get(strategy_type, ["custom/{actorId}/{sessionId}"])
strategy_config["namespaces"] = DEFAULT_NAMESPACES.get(strategy_type, ["custom/{actorId}/{sessionId}/"])

self._validate_strategy_config(strategy_copy, strategy_type_key)

Expand Down
8 changes: 4 additions & 4 deletions src/bedrock_agentcore/memory/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ class MessageRole(Enum):

# Default namespaces for each strategy type
DEFAULT_NAMESPACES: Dict[StrategyType, List[str]] = {
StrategyType.SEMANTIC: ["/strategies/{memoryStrategyId}/actors/{actorId}"],
StrategyType.SUMMARY: ["/strategies/{memoryStrategyId}/actors/{actorId}/sessions/{sessionId}"],
StrategyType.USER_PREFERENCE: ["/strategies/{memoryStrategyId}/actors/{actorId}"],
StrategyType.EPISODIC: ["/strategies/{memoryStrategyId}/actors/{actorId}/sessions/{sessionId}"],
StrategyType.SEMANTIC: ["/strategies/{memoryStrategyId}/actors/{actorId}/"],
StrategyType.SUMMARY: ["/strategies/{memoryStrategyId}/actors/{actorId}/sessions/{sessionId}/"],
StrategyType.USER_PREFERENCE: ["/strategies/{memoryStrategyId}/actors/{actorId}/"],
StrategyType.EPISODIC: ["/strategies/{memoryStrategyId}/actors/{actorId}/sessions/{sessionId}/"],
}


Expand Down
20 changes: 10 additions & 10 deletions src/bedrock_agentcore/memory/integrations/strands/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,19 @@ comprehensive_memory = client.create_memory_and_wait(
{
"summaryMemoryStrategy": {
"name": "SessionSummarizer",
"namespaces": ["/summaries/{actorId}/{sessionId}"]
"namespaces": ["/summaries/{actorId}/{sessionId}/"]
}
},
{
"userPreferenceMemoryStrategy": {
"name": "PreferenceLearner",
"namespaces": ["/preferences/{actorId}"]
"namespaces": ["/preferences/{actorId}/"]
}
},
{
"semanticMemoryStrategy": {
"name": "FactExtractor",
"namespaces": ["/facts/{actorId}"]
"namespaces": ["/facts/{actorId}/"]
}
}
]
Expand All @@ -143,7 +143,7 @@ config = AgentCoreMemoryConfig(
session_id=SESSION_ID,
actor_id=ACTOR_ID,
retrieval_config={
"/preferences/{actorId}": RetrievalConfig(
"/preferences/{actorId}/": RetrievalConfig(
top_k=5,
relevance_score=0.7
)
Expand All @@ -161,15 +161,15 @@ config = AgentCoreMemoryConfig(
session_id=SESSION_ID,
actor_id=ACTOR_ID,
retrieval_config={
"/preferences/{actorId}": RetrievalConfig(
"/preferences/{actorId}/": RetrievalConfig(
top_k=5,
relevance_score=0.7
),
"/facts/{actorId}": RetrievalConfig(
"/facts/{actorId}/": RetrievalConfig(
top_k=10,
relevance_score=0.3
),
"/summaries/{actorId}/{sessionId}": RetrievalConfig(
"/summaries/{actorId}/{sessionId}/": RetrievalConfig(
top_k=5,
relevance_score=0.5
)
Expand Down Expand Up @@ -233,9 +233,9 @@ https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/memory-strategies.

### Namespace Patterns

- `/preferences/{actorId}`: User-specific preferences
- `/facts/{actorId}`: User-specific facts
- `/summaries/{actorId}/{sessionId}`: Session-specific summaries
- `/preferences/{actorId}/`: User-specific preferences
- `/facts/{actorId}/`: User-specific facts
- `/summaries/{actorId}/{sessionId}/`: Session-specific summaries


---
Expand Down
6 changes: 3 additions & 3 deletions src/bedrock_agentcore/memory/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def my_llm(user_input: str, memories: List[Dict]) -> str:
session_id="session-789",
user_input="What did we discuss?",
llm_callback=my_llm,
retrieval_namespace="support/facts/{sessionId}"
retrieval_namespace="support/facts/{sessionId}/"
)
```

Expand Down Expand Up @@ -298,8 +298,8 @@ def my_llm(user_input: str, memories: List[Dict]) -> str:
return response['content']

retrieval_config = {
"support/facts/{sessionId}": RetrievalConfig(top_k=5, relevance_score=0.3),
"user/preferences/{actorId}": RetrievalConfig(top_k=3, relevance_score=0.5)
"support/facts/{sessionId}/": RetrievalConfig(top_k=5, relevance_score=0.3),
"user/preferences/{actorId}/": RetrievalConfig(top_k=3, relevance_score=0.5)
}

memories, response, event = manager.process_turn_with_llm(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ def agentcore_config():
def agentcore_config_with_retrieval():
"""Create a test AgentCore Memory configuration with retrieval config."""
retrieval_config = {
"user_preferences/{actorId}": RetrievalConfig(top_k=5, relevance_score=0.3),
"session_context/{sessionId}": RetrievalConfig(top_k=3, relevance_score=0.5),
"user_preferences/{actorId}/": RetrievalConfig(top_k=5, relevance_score=0.3),
"session_context/{sessionId}/": RetrievalConfig(top_k=3, relevance_score=0.5),
}
return AgentCoreMemoryConfig(
memory_id="test-memory-123",
Expand Down Expand Up @@ -471,17 +471,17 @@ def test_validate_namespace_resolution(self, session_manager):

# Valid resolution
assert session_manager._validate_namespace_resolution(
"user_preferences/{actorId}", "user_preferences/test-actor"
"user_preferences/{actorId}/", "user_preferences/test-actor/"
)

# Mock invalid resolution
session_manager._validate_namespace_resolution.return_value = False
assert not session_manager._validate_namespace_resolution(
"user_preferences/{actorId}", "user_preferences/{actorId}"
"user_preferences/{actorId}/", "user_preferences/{actorId}/"
)

# Invalid - empty result
assert not session_manager._validate_namespace_resolution("test_namespace", "")
assert not session_manager._validate_namespace_resolution("test_namespace/", "")

def test_load_long_term_memories_with_validation_failure(self, mock_memory_client, test_agent):
"""Test LTM loading with namespace validation failure."""
Expand All @@ -490,7 +490,7 @@ def test_load_long_term_memories_with_validation_failure(self, mock_memory_clien
memory_id="test-memory-123",
session_id="test-session-456",
actor_id="test-actor",
retrieval_config={"user_preferences/{invalidVar}": RetrievalConfig(top_k=5, relevance_score=0.3)},
retrieval_config={"user_preferences/{invalidVar}/": RetrievalConfig(top_k=5, relevance_score=0.3)},
)

with patch(
Expand Down Expand Up @@ -563,23 +563,23 @@ def mock_generate_query(namespace, config, agent):

# Test preferences namespace
config = RetrievalConfig(top_k=5, relevance_score=0.3)
query = session_manager._generate_initialization_query("user_preferences/{actorId}", config, test_agent)
query = session_manager._generate_initialization_query("user_preferences/{actorId}/", config, test_agent)
assert query == "user preferences settings"

# Test context namespace
query = session_manager._generate_initialization_query("session_context/{sessionId}", config, test_agent)
query = session_manager._generate_initialization_query("session_context/{sessionId}/", config, test_agent)
assert query == "conversation context history"

# Test semantic namespace
query = session_manager._generate_initialization_query("semantic_knowledge", config, test_agent)
query = session_manager._generate_initialization_query("semantic_knowledge/", config, test_agent)
assert query == "facts knowledge information"

# Test facts namespace
query = session_manager._generate_initialization_query("facts_database", config, test_agent)
query = session_manager._generate_initialization_query("facts_database/", config, test_agent)
assert query == "facts knowledge information"

# Test fallback
query = session_manager._generate_initialization_query("unknown_namespace", config, test_agent)
query = session_manager._generate_initialization_query("unknown_namespace/", config, test_agent)
assert query == "context preferences facts"

def test_generate_initialization_query_custom(self, session_manager, test_agent):
Expand All @@ -589,7 +589,7 @@ def test_generate_initialization_query_custom(self, session_manager, test_agent)
# Mock the method since it doesn't exist yet
session_manager._generate_initialization_query = Mock(return_value="custom query for testing")

query = session_manager._generate_initialization_query("user_preferences/{actorId}", config, test_agent)
query = session_manager._generate_initialization_query("user_preferences/{actorId}/", config, test_agent)
assert query == "custom query for testing"

def test_retrieve_contextual_memories_all_namespaces(self, agentcore_config_with_retrieval, mock_memory_client):
Expand Down Expand Up @@ -617,11 +617,11 @@ def test_retrieve_contextual_memories_all_namespaces(self, agentcore_config_with
manager.retrieve_contextual_memories = Mock(
return_value=[
{
"namespace": "user_preferences/test-actor-789",
"namespace": "user_preferences/test-actor-789/",
"memories": [{"content": "Relevant memory", "relevanceScore": 0.8}],
},
{
"namespace": "session_context/test-session-456",
"namespace": "session_context/test-session-456/",
"memories": [{"content": "Less relevant memory", "relevanceScore": 0.2}],
},
]
Expand Down Expand Up @@ -657,13 +657,13 @@ def test_retrieve_contextual_memories_specific_namespaces(
manager.retrieve_contextual_memories = Mock(
return_value=[
{
"namespace": "user_preferences/test-actor-789",
"namespace": "user_preferences/test-actor-789/",
"memories": [{"content": "User preference memory", "relevanceScore": 0.9}],
}
]
)
results = manager.retrieve_contextual_memories(
"What are my preferences?", namespaces=["user_preferences/{actorId}"]
"What are my preferences?", namespaces=["user_preferences/{actorId}/"]
)

# Should return results for specified namespace only
Expand Down Expand Up @@ -695,7 +695,7 @@ def test_retrieve_contextual_memories_invalid_namespace(self, agentcore_config_w
):
manager = AgentCoreMemorySessionManager(agentcore_config_with_retrieval)
manager.retrieve_contextual_memories = Mock(return_value={})
results = manager.retrieve_contextual_memories("test query", namespaces=["nonexistent_namespace"])
results = manager.retrieve_contextual_memories("test query", namespaces=["nonexistent_namespace/"])

# Should return empty results
assert results == {}
Expand Down Expand Up @@ -755,27 +755,27 @@ def test_load_long_term_memories_exception_handling(
def test_namespace_variable_resolution(self, session_manager):
"""Test namespace variable resolution with various combinations."""
# Test basic variable resolution
namespace = "user_preferences/{actorId}"
namespace = "user_preferences/{actorId}/"
resolved = namespace.format(
actorId=session_manager.config.actor_id, sessionId=session_manager.config.session_id, memoryStrategyId=""
)
assert resolved == "user_preferences/test-actor-789"
assert resolved == "user_preferences/test-actor-789/"

# Test multiple variables
namespace = "context/{sessionId}/actor/{actorId}"
namespace = "context/{sessionId}/actor/{actorId}/"
resolved = namespace.format(
actorId=session_manager.config.actor_id, sessionId=session_manager.config.session_id, memoryStrategyId=""
)
assert resolved == "context/test-session-456/actor/test-actor-789"
assert resolved == "context/test-session-456/actor/test-actor-789/"

# Test with strategy ID
namespace = "strategy/{memoryStrategyId}/user/{actorId}"
namespace = "strategy/{memoryStrategyId}/user/{actorId}/"
resolved = namespace.format(
actorId=session_manager.config.actor_id,
sessionId=session_manager.config.session_id,
memoryStrategyId="test_strategy",
)
assert resolved == "strategy/test_strategy/user/test-actor-789"
assert resolved == "strategy/test_strategy/user/test-actor-789/"

def test_generate_initialization_query_patterns(self, session_manager, test_agent):
"""Test initialization query generation with various namespace patterns."""
Expand All @@ -796,17 +796,17 @@ def mock_generate_query(namespace, config, agent):

# Test various preference patterns
patterns_and_expected = [
("user_preferences/{actorId}", "user preferences settings"),
("preferences/global", "user preferences settings"),
("my_preferences", "user preferences settings"),
("session_context/{sessionId}", "conversation context history"),
("context/history", "conversation context history"),
("conversation_context", "conversation context history"),
("semantic_memory", "facts knowledge information"),
("facts_database", "facts knowledge information"),
("knowledge_semantic", "facts knowledge information"),
("random_namespace", "context preferences facts"),
("unknown", "context preferences facts"),
("user_preferences/{actorId}/", "user preferences settings"),
("preferences/global/", "user preferences settings"),
("my_preferences/", "user preferences settings"),
("session_context/{sessionId}/", "conversation context history"),
("context/history/", "conversation context history"),
("conversation_context/", "conversation context history"),
("semantic_memory/", "facts knowledge information"),
("facts_database/", "facts knowledge information"),
("knowledge_semantic/", "facts knowledge information"),
("random_namespace/", "context preferences facts"),
("unknown/", "context preferences facts"),
]

for namespace, expected_query in patterns_and_expected:
Expand Down Expand Up @@ -1063,7 +1063,7 @@ def test_retrieve_customer_context_filters_by_relevance_score(self, mock_memory_
memory_id="test-memory-123",
session_id="test-session-456",
actor_id="test-actor-789",
retrieval_config={"test_namespace": RetrievalConfig(top_k=10, relevance_score=0.5)},
retrieval_config={"test_namespace/": RetrievalConfig(top_k=10, relevance_score=0.5)},
)

with patch(
Expand Down
4 changes: 2 additions & 2 deletions tests/bedrock_agentcore/memory/models/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def test_memory_record_initialization(self):
data = {
"memoryRecordId": "record-123",
"content": {"text": "This is a memory record"},
"namespace": "user/preferences",
"namespace": "user/preferences/",
"relevanceScore": 0.95,
"createdAt": "2023-01-01T00:00:00Z",
}
Expand All @@ -144,7 +144,7 @@ def test_memory_record_initialization(self):

def test_memory_record_dict_access(self):
"""Test MemoryRecord dictionary-like access."""
data = {"memoryRecordId": "record-456", "namespace": "support/facts"}
data = {"memoryRecordId": "record-456", "namespace": "support/facts/"}
memory_record = MemoryRecord(data)

assert "memoryRecordId" in memory_record
Expand Down
Loading
Loading