Skip to content

Commit 3a9bbb6

Browse files
committed
chore: update Mem0MemoryStore for Mem0 v3
1 parent c77f01c commit 3a9bbb6

2 files changed

Lines changed: 30 additions & 22 deletions

File tree

haystack_experimental/memory_stores/mem0/memory_store.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,26 +50,25 @@ def add_memories(
5050
user_id: str | None = None,
5151
run_id: str | None = None,
5252
agent_id: str | None = None,
53-
async_mode: bool = False,
5453
**kwargs: Any,
5554
) -> list[dict[str, Any]]:
5655
"""
5756
Add ChatMessage memories to Mem0.
5857
5958
:param messages: List of ChatMessage objects with memory metadata
60-
:param infer: Whether to infer facts from the messages. If False, the whole message will
61-
be added as a memory.
59+
:param infer: Whether to infer facts from the messages. If False, the whole message will be added as a memory.
60+
With `infer=False`, Mem0 returns the added memory ids synchronously. With `infer=True`, Mem0 may return a
61+
pending status without any memory ids; in that case, the extracted memories become available via
62+
`search_memories` once the server finishes indexing them.
6263
:param user_id: The user ID to to store and retrieve memories from the memory store.
6364
:param run_id: The run ID to to store and retrieve memories from the memory store.
6465
:param agent_id: The agent ID to to store and retrieve memories from the memory store.
6566
If you want Mem0 to store chat messages from the assistant, you need to set the agent_id.
66-
:param async_mode: Whether to add memories asynchronously.
67-
If True, the method will return immediately and the memories will be added in the background.
6867
:param kwargs: Additional keyword arguments to pass to the Mem0 client.add method.
6968
Note: ChatMessage.meta in the list of messages will be ignored because Mem0 doesn't allow
7069
passing metadata for each message in the list. You can pass metadata for the whole memory
7170
by passing the `metadata` keyword argument to the method.
72-
:returns: List of objects with the memory_id and the memory
71+
:returns: List of objects with the memory_id and the memory.
7372
"""
7473
added_ids = []
7574
ids = self._get_ids(user_id, run_id, agent_id)
@@ -85,11 +84,13 @@ def add_memories(
8584
# we save the role of the message in the metadata
8685
mem0_messages.append({"content": message.text, "role": message.role.value})
8786
try:
88-
status = self.client.add(messages=mem0_messages, infer=infer, **ids, async_mode=async_mode, **kwargs)
89-
if status:
87+
status = self.client.add(messages=mem0_messages, infer=infer, **ids, **kwargs)
88+
if status and "results" in status:
9089
for result in status["results"]:
91-
memory_id = {"memory_id": result.get("id"), "memory": result["memory"]}
92-
added_ids.append(memory_id)
90+
# Mem0 v3 wraps the memory text under a `data` key; older shapes exposed it directly
91+
data = result.get("data")
92+
memory_text = data.get("memory") if isinstance(data, dict) else result.get("memory")
93+
added_ids.append({"memory_id": result.get("id"), "memory": memory_text})
9394
except Exception as e:
9495
raise RuntimeError(f"Failed to add memory message: {e}") from e
9596
return added_ids

test/memory_stores/test_mem0_memory_store.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ def test_add_memories(self, sample_messages, memory_store):
9292
"""Test adding memories successfully."""
9393
store, user_id = memory_store
9494
result = store.add_memories(messages=sample_messages, user_id=user_id)
95-
# with infer=True (default), two messages are converted to a single memory
96-
assert len(result) == 1
95+
assert result == []
9796

9897
@pytest.mark.skipif(
9998
not os.environ.get("MEM0_API_KEY", None),
@@ -115,9 +114,7 @@ def test_add_memories_with_metadata(self, memory_store):
115114
"""Test adding memories with metadata."""
116115
store, user_id = memory_store
117116
messages = [ChatMessage.from_user("User likes to work with python on NLP projects")]
118-
result = store.add_memories(
119-
messages=messages, user_id=user_id, metadata={"key": "value"}, async_mode=False
120-
)
117+
result = store.add_memories(messages=messages, infer=False, user_id=user_id, metadata={"key": "value"})
121118
assert len(result) == 1
122119

123120
@pytest.mark.skipif(
@@ -201,20 +198,30 @@ def test_delete_memory(self, sample_messages, memory_store):
201198
def test_role_based_memories(self, memory_store):
202199
store, user_id = memory_store
203200
unique_agent_id = _get_unique_user_id()
204-
messages = [
201+
# in Mem0 v3, to keep user and assistant turns searchable by their own entity id,
202+
# they must be added in separate calls
203+
user_messages = [
205204
ChatMessage.from_user("I'm planning to watch a movie tonight. Any recommendations?"),
206-
ChatMessage.from_assistant("How about thriller movies? They can be quite engaging."),
207205
ChatMessage.from_user("I'm not a big fan of thriller movies but I love sci-fi movies."),
206+
]
207+
assistant_messages = [
208+
ChatMessage.from_assistant("How about thriller movies? They can be quite engaging."),
208209
ChatMessage.from_assistant(
209210
"Got it! Then I would recommend Interstellar or Inception? I would also recommend watching some "
210211
"Japanese anime movies."
211212
),
212213
]
213-
store.add_memories(messages=messages, infer=False, user_id=user_id, agent_id=unique_agent_id)
214-
assistant_mem = store.search_memories(filters={"field": "agent_id", "operator": "==", "value": unique_agent_id})
215-
user_mem = store.search_memories(filters={"field": "user_id", "operator": "==", "value": user_id})
216-
assert len(assistant_mem) == 2
217-
assert len(user_mem) == 2
214+
store.add_memories(messages=user_messages, infer=False, user_id=user_id)
215+
store.add_memories(messages=assistant_messages, infer=False, agent_id=unique_agent_id)
216+
try:
217+
assistant_mem = store.search_memories(
218+
filters={"field": "agent_id", "operator": "==", "value": unique_agent_id}
219+
)
220+
user_mem = store.search_memories(filters={"field": "user_id", "operator": "==", "value": user_id})
221+
assert len(assistant_mem) == 2
222+
assert len(user_mem) == 2
223+
finally:
224+
store.delete_all_memories(agent_id=unique_agent_id)
218225

219226
@pytest.mark.skipif(
220227
not (os.environ.get("MEM0_API_KEY", None) and os.environ.get("OPENAI_API_KEY", None)),

0 commit comments

Comments
 (0)