Skip to content

Commit 33f09f7

Browse files
notgitikagitikavj
andauthored
feat: configurable context_tag with user_context default (#279)
Co-authored-by: gitikavj <gitikavj@amazon.com>
1 parent 1bd22b7 commit 33f09f7

4 files changed

Lines changed: 89 additions & 5 deletions

File tree

src/bedrock_agentcore/memory/integrations/strands/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@ class AgentCoreMemoryConfig(BaseModel):
3131
retrieval_config: Optional dictionary mapping namespaces to retrieval configurations
3232
batch_size: Number of messages to batch before sending to AgentCore Memory.
3333
Default of 1 means immediate sending (no batching). Max 100.
34+
context_tag: XML tag name used to wrap retrieved memory context injected into messages.
35+
Default is "user_context".
3436
"""
3537

3638
memory_id: str = Field(min_length=1)
3739
session_id: str = Field(min_length=1)
3840
actor_id: str = Field(min_length=1)
3941
retrieval_config: Optional[Dict[str, RetrievalConfig]] = None
4042
batch_size: int = Field(default=1, ge=1, le=100)
43+
context_tag: str = Field(default="user_context", min_length=1)

src/bedrock_agentcore/memory/integrations/strands/session_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ def retrieve_for_namespace(namespace: str, retrieval_config: RetrievalConfig):
641641
if all_context:
642642
context_text = "\n".join(all_context)
643643
event.agent.messages[-1]["content"].insert(
644-
0, {"text": f"<retrieved_memory>{context_text}</retrieved_memory>"}
644+
0, {"text": f"<{self.config.context_tag}>{context_text}</{self.config.context_tag}>"}
645645
)
646646
logger.info("Retrieved %s customer context items", len(all_context))
647647

tests/bedrock_agentcore/memory/integrations/strands/test_agentcore_memory_session_manager.py

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,7 @@ def test_retrieve_customer_context_does_not_append_assistant_message(
19371937
# Memory prepended, original query remains last
19381938
content = mock_agent.messages[0]["content"]
19391939
assert len(content) == 2
1940-
assert "<retrieved_memory>" in content[0]["text"]
1940+
assert "<user_context>" in content[0]["text"]
19411941
assert content[1]["text"] == "What are my preferences?"
19421942

19431943
def test_retrieve_customer_context_no_assistant_message_multi_turn(
@@ -1982,5 +1982,86 @@ def test_retrieve_customer_context_no_assistant_message_multi_turn(
19821982
# Memory injected into last user message
19831983
content = mock_agent.messages[-1]["content"]
19841984
assert len(content) == 2
1985-
assert "<retrieved_memory>" in content[0]["text"]
1985+
assert "<user_context>" in content[0]["text"]
19861986
assert content[1]["text"] == "What do I like to eat?"
1987+
1988+
def test_retrieve_customer_context_custom_context_tag(self, mock_memory_client):
1989+
"""Test that a custom context_tag is used when configured."""
1990+
custom_config = AgentCoreMemoryConfig(
1991+
memory_id="test-memory-123",
1992+
session_id="test-session-456",
1993+
actor_id="test-actor-789",
1994+
retrieval_config={"user_preferences/{actorId}/": RetrievalConfig(top_k=5, relevance_score=0.3)},
1995+
context_tag="retrieved_memory",
1996+
)
1997+
1998+
mock_memory_client.retrieve_memories.return_value = [
1999+
{"content": {"text": "User likes sushi"}},
2000+
]
2001+
2002+
with patch(
2003+
"bedrock_agentcore.memory.integrations.strands.session_manager.MemoryClient",
2004+
return_value=mock_memory_client,
2005+
):
2006+
with patch("boto3.Session") as mock_boto_session:
2007+
mock_session = Mock()
2008+
mock_session.region_name = "us-west-2"
2009+
mock_session.client.return_value = Mock()
2010+
mock_boto_session.return_value = mock_session
2011+
2012+
with patch(
2013+
"strands.session.repository_session_manager.RepositorySessionManager.__init__", return_value=None
2014+
):
2015+
manager = AgentCoreMemorySessionManager(custom_config)
2016+
2017+
mock_agent = Mock()
2018+
mock_agent.messages = [{"role": "user", "content": [{"text": "What do I like?"}]}]
2019+
2020+
event = MessageAddedEvent(
2021+
agent=mock_agent, message={"role": "user", "content": [{"text": "What do I like?"}]}
2022+
)
2023+
manager.retrieve_customer_context(event)
2024+
2025+
content = mock_agent.messages[0]["content"]
2026+
assert "<retrieved_memory>" in content[0]["text"]
2027+
assert "</retrieved_memory>" in content[0]["text"]
2028+
2029+
def test_retrieve_customer_context_default_context_tag(self, mock_memory_client):
2030+
"""Test that the default context_tag is user_context."""
2031+
default_config = AgentCoreMemoryConfig(
2032+
memory_id="test-memory-123",
2033+
session_id="test-session-456",
2034+
actor_id="test-actor-789",
2035+
retrieval_config={"user_preferences/{actorId}/": RetrievalConfig(top_k=5, relevance_score=0.3)},
2036+
)
2037+
2038+
mock_memory_client.retrieve_memories.return_value = [
2039+
{"content": {"text": "User likes sushi"}},
2040+
]
2041+
2042+
with patch(
2043+
"bedrock_agentcore.memory.integrations.strands.session_manager.MemoryClient",
2044+
return_value=mock_memory_client,
2045+
):
2046+
with patch("boto3.Session") as mock_boto_session:
2047+
mock_session = Mock()
2048+
mock_session.region_name = "us-west-2"
2049+
mock_session.client.return_value = Mock()
2050+
mock_boto_session.return_value = mock_session
2051+
2052+
with patch(
2053+
"strands.session.repository_session_manager.RepositorySessionManager.__init__", return_value=None
2054+
):
2055+
manager = AgentCoreMemorySessionManager(default_config)
2056+
2057+
mock_agent = Mock()
2058+
mock_agent.messages = [{"role": "user", "content": [{"text": "What do I like?"}]}]
2059+
2060+
event = MessageAddedEvent(
2061+
agent=mock_agent, message={"role": "user", "content": [{"text": "What do I like?"}]}
2062+
)
2063+
manager.retrieve_customer_context(event)
2064+
2065+
content = mock_agent.messages[0]["content"]
2066+
assert "<user_context>" in content[0]["text"]
2067+
assert "</user_context>" in content[0]["text"]

tests_integ/memory/integrations/test_session_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def test_session_manager_with_retrieval_config_adds_context(self, test_memory_lt
151151
response2 = agent("What do I like to eat?")
152152
assert response2 is not None
153153
assert "sushi" in str(agent.messages)
154-
assert "<retrieved_memory>" in str(agent.messages)
154+
assert "<user_context>" in str(agent.messages)
155155

156156
def test_multiple_namespace_retrieval_config(self, test_memory_ltm):
157157
"""Test session manager with multiple namespace retrieval configurations."""
@@ -182,7 +182,7 @@ def test_multiple_namespace_retrieval_config(self, test_memory_ltm):
182182
response2 = agent("What do I like to eat?")
183183
assert response2 is not None
184184
assert "sushi" in str(agent.messages)
185-
assert "<retrieved_memory>" in str(agent.messages)
185+
assert "<user_context>" in str(agent.messages)
186186

187187
def test_session_manager_error_handling(self):
188188
"""Test session manager error handling with invalid configuration."""

0 commit comments

Comments
 (0)