Compare commits

..

2 Commits

Author SHA1 Message Date
Devin AI
8cd1ffc2c2 Fix lint issues in test file
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-04-12 01:48:39 +00:00
Devin AI
85cd4ebc5f Fix #2591: Fix KeyError in contextual memory with Mem0 provider
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-04-12 01:46:56 +00:00
4 changed files with 48 additions and 48 deletions

View File

@@ -56,7 +56,7 @@ class ContextualMemory:
stm_results = self.stm.search(query)
formatted_results = "\n".join(
[
f"- {result['memory'] if self.memory_provider == 'mem0' else result['context']}"
f"- {result['context']}"
for result in stm_results
]
)
@@ -89,7 +89,7 @@ class ContextualMemory:
em_results = self.em.search(query)
formatted_results = "\n".join(
[
f"- {result['memory'] if self.memory_provider == 'mem0' else result['context']}"
f"- {result['context']}"
for result in em_results
] # type: ignore # Invalid index type "str" for "str"; expected type "SupportsIndex | slice"
)

View File

@@ -117,8 +117,6 @@ class Mem0Storage(Storage):
# Discard the filters for now since we create the filters
# automatically when the crew is created.
results = self.memory.search(**params)
if isinstance(results, dict) and 'results' in results:
return [r for r in results['results'] if r["score"] >= score_threshold]
return [r for r in results if r["score"] >= score_threshold]
def _get_user_id(self) -> str:

View File

@@ -0,0 +1,46 @@
from unittest.mock import MagicMock, patch
import pytest
from crewai.memory.contextual.contextual_memory import ContextualMemory
def test_contextual_memory_with_mem0_provider():
"""Test that contextual memory properly handles Mem0 results."""
stm_mock = MagicMock()
ltm_mock = MagicMock()
em_mock = MagicMock()
um_mock = MagicMock()
exm_mock = MagicMock() # External memory mock
mock_result = {
'id': 'test-id',
'metadata': 'some metadata',
'context': 'test context data',
'score': 0.95
}
stm_mock.search.return_value = [mock_result]
em_mock.search.return_value = [mock_result]
um_mock.search.return_value = [{'memory': 'user memory'}] # User memory has different structure
exm_mock.search.return_value = [{'memory': 'external memory'}] # External memory structure
memory_config = {"provider": "mem0"}
context_memory = ContextualMemory(
memory_config=memory_config,
stm=stm_mock,
ltm=ltm_mock,
em=em_mock,
um=um_mock,
exm=exm_mock
)
result = context_memory._fetch_stm_context("test query")
stm_mock.search.assert_called_once_with("test query")
assert "test context data" in result
entity_result = context_memory._fetch_entity_context("test query")
em_mock.search.assert_called_once_with("test query")
assert "test context data" in entity_result

View File

@@ -15,7 +15,6 @@ from crewai.task import Task
class MockCrew:
def __init__(self, memory_config):
self.memory_config = memory_config
self.agents = [] # Add empty agents list for testing
@pytest.fixture
@@ -154,46 +153,3 @@ def test_mem0_storage_with_explict_config(
mem0_storage_with_memory_client_using_explictly_config.memory_config
== expected_config
)
def test_mem0_storage_external_memory_search(
mem0_storage_with_memory_client_using_config_from_crew, mock_mem0_memory_client
):
"""Test that Mem0Storage search correctly handles external memory with metadata parameter."""
mem0_storage_with_memory_client_using_config_from_crew.memory_type = "external"
mock_search_response = {
'results': [
{
'id': '1',
'score': 0.9,
'metadata': {'type': 'external'},
'memory': 'test external memory 1'
},
{
'id': '2',
'score': 0.8,
'metadata': {'type': 'external'},
'memory': 'test external memory 2'
},
{
'id': '3',
'score': 0.3, # Below threshold
'metadata': {'type': 'external'},
'memory': 'test external memory 3'
}
]
}
mock_mem0_memory_client.search.return_value = mock_search_response
results = mem0_storage_with_memory_client_using_config_from_crew.search(
"test query",
score_threshold=0.5
)
mock_mem0_memory_client.search.assert_called_once()
assert len(results) == 2
assert results[0]['score'] == 0.9
assert results[1]['score'] == 0.8