Repository: crewAIInc/crewAI
Pull request: Fix Mem0 OSS
Closes https://github.com/crewAIInc/crewAI/issues/2599

Problem statement:
[BUG] Mem0 (local config) - Memory.search() got an unexpected keyword argument 'metadata'
### Description

I am currently using local mem0 with the following config
```
local_mem0_config = {
        "vector_store": {
            "provider": "qdrant",
            "config": {
                "collection_name": "user_memory",
                "host": "192.168.0.222",
                "port": 6333,
                "embedding_model_dims": "1536",
            },
        },
        "llm": {
            "provider": "openai",
            "config": {"api_key": os.getenv("OPENAI_API_KEY"), "model": "gpt-4o-mini"},
        },
        "embedder": {
            "provider": "openai",
            "config": {
                "api_key": os.getenv("OPENAI_API_KEY"),
                "model": "text-embedding-3-small",
            },
        },
    }
```

My crew is defined as this
```
Crew(
            agents=self.agents,
            tasks=self.tasks,
            process=Process.sequential,
            verbose=True,
            memory=True,
            external_memory=ExternalMemory(
                embedder_config={
                    "provider": "mem0",
                    "config": {
                        "user_id": "jainish",
                        "local_mem0_config": self.local_mem0_config,
                    },
                }
            ),
            output_log_file="logs.json",
        )
```

The full traceback
```
Traceback (most recent call last):
  File "/Users/JainishSavalia/work/playground/crewAI/examples/main.py", line 27, in run_crew
    result = crew.kickoff(inputs=inputs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/crew.py", line 646, in kickoff
    result = self._run_sequential_process()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/crew.py", line 758, in _run_sequential_process
    return self._execute_tasks(self.tasks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/crew.py", line 861, in _execute_tasks
    task_output = task.execute_sync(
                  ^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/crewai/instrumentation.py", line 61, in wrapper
    return func(tracer, duration_histogram, token_histogram, wrapped, instance, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/crewai/instrumentation.py", line 149, in wrap_task_execute
    result = wrapped(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/task.py", line 328, in execute_sync
    return self._execute_core(agent, context, tools)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/task.py", line 472, in _execute_core
    raise e  # Re-raise the exception after emitting the event
    ^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/task.py", line 392, in _execute_core
    result = agent.execute_task(
             ^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/crewai/instrumentation.py", line 61, in wrapper
    return func(tracer, duration_histogram, token_histogram, wrapped, instance, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/crewai/instrumentation.py", line 108, in wrap_agent_execute_task
    result = wrapped(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/agent.py", line 212, in execute_task
    memory = contextual_memory.build_context_for_task(task, context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/memory/contextual/contextual_memory.py", line 46, in build_context_for_task
    context.append(self._fetch_external_context(query))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/memory/contextual/contextual_memory.py", line 130, in _fetch_external_context
    external_memories = self.exm.search(query)
                        ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/memory/memory.py", line 37, in search
    return self.storage.search(
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/memory/storage/mem0_storage.py", line 119, in search
    results = self.memory.search(**params)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Memory.search() got an unexpected keyword argument 'metadata'
```

The payload of mem0 has changed in v2 compared to v1 but can't find out any major difference as the older version should work as it is ("version": "v1.1" added in config).



### Steps to Reproduce

1. Create any crew which uses external memory with mem0 provider as shown above.
2. Run the crew.

### Expected behavior

The local mem0 search functionality should work as it does with the cloud one. 
I am using qdrant for my vector store.

### Screenshots/Code snippets

None

### Operating System

macOS Sonoma

### Python Version

3.11

### crewAI Version

0.114.0

### crewAI Tools Version

0.40.1

### Virtual Environment

Venv

### Evidence

Traceback (most recent call last):
  File "/Users/JainishSavalia/work/playground/crewAI/examples/main.py", line 27, in run_crew
    result = crew.kickoff(inputs=inputs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/crew.py", line 646, in kickoff
    result = self._run_sequential_process()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/crew.py", line 758, in _run_sequential_process
    return self._execute_tasks(self.tasks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/crew.py", line 861, in _execute_tasks
    task_output = task.execute_sync(
                  ^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/crewai/instrumentation.py", line 61, in wrapper
    return func(tracer, duration_histogram, token_histogram, wrapped, instance, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/crewai/instrumentation.py", line 149, in wrap_task_execute
    result = wrapped(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/task.py", line 328, in execute_sync
    return self._execute_core(agent, context, tools)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/task.py", line 472, in _execute_core
    raise e  # Re-raise the exception after emitting the event
    ^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/task.py", line 392, in _execute_core
    result = agent.execute_task(
             ^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/crewai/instrumentation.py", line 61, in wrapper
    return func(tracer, duration_histogram, token_histogram, wrapped, instance, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/crewai/instrumentation.py", line 108, in wrap_agent_execute_task
    result = wrapped(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/agent.py", line 212, in execute_task
    memory = contextual_memory.build_context_for_task(task, context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/memory/contextual/contextual_memory.py", line 46, in build_context_for_task
    context.append(self._fetch_external_context(query))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/memory/contextual/contextual_memory.py", line 130, in _fetch_external_context
    external_memories = self.exm.search(query)
                        ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/memory/memory.py", line 37, in search
    return self.storage.search(
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/JainishSavalia/work/playground/crewAI/src/crewai/memory/storage/mem0_storage.py", line 119, in search
    results = self.memory.search(**params)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Memory.search() got an unexpected keyword argument 'metadata'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/JainishSavalia/work/playground/crewAI/examples/main.py", line 40, in <module>
    run_crew()
  File "/Users/JainishSavalia/work/playground/crewAI/examples/main.py", line 34, in run_crew
    print(f"\nAn error occurred: {e.with_traceback()}")

### Possible Solution

None

### Additional context

None

Hints from issue discussion:
Hi @Jainish-S,
I think there is one bug associated with the use of local_mem0_config, 

This is the issue, #2587. the local config parameter is not being passed currently to the `Mem0`  class. 
@Vidit-Ostwal Yes I had found it earlier and have fixed it locally. 
> [@Vidit-Ostwal](https://github.com/Vidit-Ostwal) Yes I had found it earlier and have fixed it locally.

@Jainish-S still the issue is there?

@Vidit-Ostwal Yes the issue is still persistent when using local mem0, this doesn't arise when using the mem0 cloud provider config
@Jainish-S It happens when you don't set the api_key - I'll work in a solution for it this week
@lucasgomide, is this because `MemoryClient` and `Memory` have a different input parameter?
@lucasgomide If you don't mind, can I pick this up?
I think the solution is quite simple, just took a look at the `search` method for both `Memory` and `MemoryClient`.
and check on the type of object `self.memory` is?
> @lucasgomide If you don't mind, can I pick this up?
> I think the solution is quite simple, just took a look at the `search` method for both `Memory` and `MemoryClient`.
> and check on the type of object `self.memory` is?

Sure man, thank u so much..
@Vidit-Ostwal I think this PR handles that, right? https://github.com/crewAIInc/crewAI/pull/2604
> [@Vidit-Ostwal](https://github.com/Vidit-Ostwal) I think this PR handles that, right? [#2604](https://github.com/crewAIInc/crewAI/pull/2604)

I think so. The author @Dev-Khant, is the maintainer of mem0 itself. I think he pretty much knows what actually the issue is and the best way to resolve that as well.
Thanks for collaborating on this issue.

Commit message: fix lint and tests

Patch to review:
diff --git a/pyproject.toml b/pyproject.toml
index d85c43c932..fc393f003c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -60,7 +60,7 @@ pandas = [
 openpyxl = [
     "openpyxl>=3.1.5",
 ]
-mem0 = ["mem0ai>=0.1.29"]
+mem0 = ["mem0ai>=0.1.90"]
 docling = [
     "docling>=2.12.0",
 ]
diff --git a/src/crewai/memory/storage/mem0_storage.py b/src/crewai/memory/storage/mem0_storage.py
index 8357887272..114bd052fd 100644
--- a/src/crewai/memory/storage/mem0_storage.py
+++ b/src/crewai/memory/storage/mem0_storage.py
@@ -88,7 +88,9 @@ def save(self, value: Any, metadata: Dict[str, Any]) -> None:
             }
 
         if params:
-            self.memory.add(value, **params | {"output_format": "v1.1"})
+            if not hasattr(self, "llm"):
+                params["output_format"] = "v1.1"
+            self.memory.add(value, **params)
 
     def search(
         self,
@@ -96,7 +98,7 @@ def search(
         limit: int = 3,
         score_threshold: float = 0.35,
     ) -> List[Any]:
-        params = {"query": query, "limit": limit}
+        params = {"query": query, "limit": limit, "output_format": "v1.1"}
         if user_id := self._get_user_id():
             params["user_id"] = user_id
 
@@ -116,8 +118,10 @@ def search(
 
         # Discard the filters for now since we create the filters
         # automatically when the crew is created.
+        if hasattr(self, "llm"):
+            del params["metadata"], params["output_format"]
         results = self.memory.search(**params)
-        return [r for r in results if r["score"] >= score_threshold]
+        return [r for r in results["results"] if r["score"] >= score_threshold]
 
     def _get_user_id(self) -> str:
         return self._get_config().get("user_id", "")
diff --git a/tests/memory/user_memory_test.py b/tests/memory/user_memory_test.py
index 53514f6382..da974c3e31 100644
--- a/tests/memory/user_memory_test.py
+++ b/tests/memory/user_memory_test.py
@@ -1,4 +1,3 @@
-
 from unittest.mock import MagicMock, patch
 
 import pytest
@@ -65,4 +64,26 @@ def test_save_and_search(user_memory):
     with patch.object(UserMemory, 'search', return_value=expected_result) as mock_search:
         find = UserMemory.search("test value", score_threshold=0.01)[0]
         mock_search.assert_called_once_with("test value", score_threshold=0.01)
-        assert find == expected_result[0]
\ No newline at end of file
+        assert find == expected_result[0]
+
+def test_search_with_llm(user_memory):
+    """Test search behavior when llm attribute exists in storage."""
+    storage_mock = MagicMock()
+    setattr(storage_mock, "llm", True)
+
+    mock_search_results = {"results": [{"context": "test context", "score": 0.9}]}
+    storage_mock.search.return_value = mock_search_results
+    user_memory.storage = storage_mock
+
+    results = user_memory.search("test query")
+    
+    storage_mock.search.assert_called_once()
+    call_args = storage_mock.search.call_args[1]
+    assert "query" in call_args
+    assert "limit" in call_args
+    assert "score_threshold" in call_args
+
+    assert "metadata" not in call_args
+    assert "output_format" not in call_args
+
+    assert results == {"results": [{"context": "test context", "score": 0.9}]}
\ No newline at end of file
diff --git a/uv.lock b/uv.lock
index 21c8445f05..eb125e916e 100644
--- a/uv.lock
+++ b/uv.lock
@@ -726,7 +726,7 @@ requires-dist = [
     { name = "json5", specifier = ">=0.10.0" },
     { name = "jsonref", specifier = ">=1.1.0" },
     { name = "litellm", specifier = "==1.60.2" },
-    { name = "mem0ai", marker = "extra == 'mem0'", specifier = ">=0.1.29" },
+    { name = "mem0ai", marker = "extra == 'mem0'", specifier = ">=0.1.90" },
     { name = "openai", specifier = ">=1.13.3" },
     { name = "openpyxl", specifier = ">=3.1.5" },
     { name = "openpyxl", marker = "extra == 'openpyxl'", specifier = ">=3.1.5" },
@@ -2488,19 +2488,20 @@ wheels = [
 
 [[package]]
 name = "mem0ai"
-version = "0.1.29"
+version = "0.1.90"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "openai" },
     { name = "posthog" },
+    { name = "psycopg2-binary" },
     { name = "pydantic" },
     { name = "pytz" },
     { name = "qdrant-client" },
     { name = "sqlalchemy" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/a9/bf/152718f9da3844dd24d4c45850b2e719798b5ce9389adf4ec873ee8905ca/mem0ai-0.1.29.tar.gz", hash = "sha256:42adefb7a9b241be03fbcabadf5328abf91b4ac390bc97e5966e55e3cac192c5", size = 55201 }
+sdist = { url = "https://files.pythonhosted.org/packages/8f/47/4f49523dc5ae22c159a8931d6aad78df9e43119eb2f707adf1368e08ae30/mem0ai-0.1.90.tar.gz", hash = "sha256:b3c76213f03badc2d567ab44c6b1d498fa88c81b8bf1e747f73e1430fbc199fe", size = 87656 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/65/9b/755be84f669415b3b513cfd935e768c4c84ac5c1ab6ff6ac2dab990a261a/mem0ai-0.1.29-py3-none-any.whl", hash = "sha256:07bbfd4238d0d7da65d5e4cf75a217eeb5b2829834e399074b05bb046730a57f", size = 79558 },
+    { url = "https://files.pythonhosted.org/packages/0a/f1/5d4462784be0cad0f9bce727cac8a907a9c008a399567b19bb77b1ff99c7/mem0ai-0.1.90-py3-none-any.whl", hash = "sha256:dae0acb32fa1f860a0e7990028c8ca759c440cfa739476cae302878143b13301", size = 135956 },
 ]
 
 [[package]]
@@ -3673,6 +3674,50 @@ wheels = [
     { url = "https://files.pythonhosted.org/packages/05/33/2d74d588408caedd065c2497bdb5ef83ce6082db01289a1e1147f6639802/psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8", size = 249898 },
 ]
 
+[[package]]
+name = "psycopg2-binary"
+version = "2.9.10"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/7a/81/331257dbf2801cdb82105306042f7a1637cc752f65f2bb688188e0de5f0b/psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f", size = 3043397 },
+    { url = "https://files.pythonhosted.org/packages/e7/9a/7f4f2f031010bbfe6a02b4a15c01e12eb6b9b7b358ab33229f28baadbfc1/psycopg2_binary-2.9.10-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906", size = 3274806 },
+    { url = "https://files.pythonhosted.org/packages/e5/57/8ddd4b374fa811a0b0a0f49b6abad1cde9cb34df73ea3348cc283fcd70b4/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92", size = 2851361 },
+    { url = "https://files.pythonhosted.org/packages/f9/66/d1e52c20d283f1f3a8e7e5c1e06851d432f123ef57b13043b4f9b21ffa1f/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007", size = 3080836 },
+    { url = "https://files.pythonhosted.org/packages/a0/cb/592d44a9546aba78f8a1249021fe7c59d3afb8a0ba51434d6610cc3462b6/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0", size = 3264552 },
+    { url = "https://files.pythonhosted.org/packages/64/33/c8548560b94b7617f203d7236d6cdf36fe1a5a3645600ada6efd79da946f/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4", size = 3019789 },
+    { url = "https://files.pythonhosted.org/packages/b0/0e/c2da0db5bea88a3be52307f88b75eec72c4de62814cbe9ee600c29c06334/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1", size = 2871776 },
+    { url = "https://files.pythonhosted.org/packages/15/d7/774afa1eadb787ddf41aab52d4c62785563e29949613c958955031408ae6/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5", size = 2820959 },
+    { url = "https://files.pythonhosted.org/packages/5e/ed/440dc3f5991a8c6172a1cde44850ead0e483a375277a1aef7cfcec00af07/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5", size = 2919329 },
+    { url = "https://files.pythonhosted.org/packages/03/be/2cc8f4282898306732d2ae7b7378ae14e8df3c1231b53579efa056aae887/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53", size = 2957659 },
+    { url = "https://files.pythonhosted.org/packages/d0/12/fb8e4f485d98c570e00dad5800e9a2349cfe0f71a767c856857160d343a5/psycopg2_binary-2.9.10-cp310-cp310-win32.whl", hash = "sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b", size = 1024605 },
+    { url = "https://files.pythonhosted.org/packages/22/4f/217cd2471ecf45d82905dd09085e049af8de6cfdc008b6663c3226dc1c98/psycopg2_binary-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1", size = 1163817 },
+    { url = "https://files.pythonhosted.org/packages/9c/8f/9feb01291d0d7a0a4c6a6bab24094135c2b59c6a81943752f632c75896d6/psycopg2_binary-2.9.10-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff", size = 3043397 },
+    { url = "https://files.pythonhosted.org/packages/15/30/346e4683532011561cd9c8dfeac6a8153dd96452fee0b12666058ab7893c/psycopg2_binary-2.9.10-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c", size = 3274806 },
+    { url = "https://files.pythonhosted.org/packages/66/6e/4efebe76f76aee7ec99166b6c023ff8abdc4e183f7b70913d7c047701b79/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c", size = 2851370 },
+    { url = "https://files.pythonhosted.org/packages/7f/fd/ff83313f86b50f7ca089b161b8e0a22bb3c319974096093cd50680433fdb/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb", size = 3080780 },
+    { url = "https://files.pythonhosted.org/packages/e6/c4/bfadd202dcda8333a7ccafdc51c541dbdfce7c2c7cda89fa2374455d795f/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341", size = 3264583 },
+    { url = "https://files.pythonhosted.org/packages/5d/f1/09f45ac25e704ac954862581f9f9ae21303cc5ded3d0b775532b407f0e90/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a", size = 3019831 },
+    { url = "https://files.pythonhosted.org/packages/9e/2e/9beaea078095cc558f215e38f647c7114987d9febfc25cb2beed7c3582a5/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b", size = 2871822 },
+    { url = "https://files.pythonhosted.org/packages/01/9e/ef93c5d93f3dc9fc92786ffab39e323b9aed066ba59fdc34cf85e2722271/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7", size = 2820975 },
+    { url = "https://files.pythonhosted.org/packages/a5/f0/049e9631e3268fe4c5a387f6fc27e267ebe199acf1bc1bc9cbde4bd6916c/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e", size = 2919320 },
+    { url = "https://files.pythonhosted.org/packages/dc/9a/bcb8773b88e45fb5a5ea8339e2104d82c863a3b8558fbb2aadfe66df86b3/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68", size = 2957617 },
+    { url = "https://files.pythonhosted.org/packages/e2/6b/144336a9bf08a67d217b3af3246abb1d027095dab726f0687f01f43e8c03/psycopg2_binary-2.9.10-cp311-cp311-win32.whl", hash = "sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392", size = 1024618 },
+    { url = "https://files.pythonhosted.org/packages/61/69/3b3d7bd583c6d3cbe5100802efa5beacaacc86e37b653fc708bf3d6853b8/psycopg2_binary-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4", size = 1163816 },
+    { url = "https://files.pythonhosted.org/packages/49/7d/465cc9795cf76f6d329efdafca74693714556ea3891813701ac1fee87545/psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0", size = 3044771 },
+    { url = "https://files.pythonhosted.org/packages/8b/31/6d225b7b641a1a2148e3ed65e1aa74fc86ba3fee850545e27be9e1de893d/psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a", size = 3275336 },
+    { url = "https://files.pythonhosted.org/packages/30/b7/a68c2b4bff1cbb1728e3ec864b2d92327c77ad52edcd27922535a8366f68/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539", size = 2851637 },
+    { url = "https://files.pythonhosted.org/packages/0b/b1/cfedc0e0e6f9ad61f8657fd173b2f831ce261c02a08c0b09c652b127d813/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526", size = 3082097 },
+    { url = "https://files.pythonhosted.org/packages/18/ed/0a8e4153c9b769f59c02fb5e7914f20f0b2483a19dae7bf2db54b743d0d0/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1", size = 3264776 },
+    { url = "https://files.pythonhosted.org/packages/10/db/d09da68c6a0cdab41566b74e0a6068a425f077169bed0946559b7348ebe9/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e", size = 3020968 },
+    { url = "https://files.pythonhosted.org/packages/94/28/4d6f8c255f0dfffb410db2b3f9ac5218d959a66c715c34cac31081e19b95/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f", size = 2872334 },
+    { url = "https://files.pythonhosted.org/packages/05/f7/20d7bf796593c4fea95e12119d6cc384ff1f6141a24fbb7df5a668d29d29/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00", size = 2822722 },
+    { url = "https://files.pythonhosted.org/packages/4d/e4/0c407ae919ef626dbdb32835a03b6737013c3cc7240169843965cada2bdf/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5", size = 2920132 },
+    { url = "https://files.pythonhosted.org/packages/2d/70/aa69c9f69cf09a01da224909ff6ce8b68faeef476f00f7ec377e8f03be70/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47", size = 2959312 },
+    { url = "https://files.pythonhosted.org/packages/d3/bd/213e59854fafe87ba47814bf413ace0dcee33a89c8c8c814faca6bc7cf3c/psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64", size = 1025191 },
+    { url = "https://files.pythonhosted.org/packages/92/29/06261ea000e2dc1e22907dbbc483a1093665509ea586b29b8986a0e56733/psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0", size = 1164031 },
+]
+
 [[package]]
 name = "ptyprocess"
 version = "0.7.0"


Code review comments:
diff_hunk: @@ -116,8 +118,10 @@ def search(
 
         # Discard the filters for now since we create the filters
         # automatically when the crew is created.
+        if hasattr(self, "llm"):
path: src/crewai/memory/storage/mem0_storage.py
text: @user1:
Something feels off here… I think your test might be too addicted, because it really shouldn’t work like, ever!
I believe you should be checking `hasattr(self.memory, "llm")` instead of `self`, since even self has a defined llm model.
What bothers me most is that even when one test fails, it still goes unnoticed that’s kind of serious.

If I’m right about this, it’d be a good idea to revisit the tests

@author:
Hey yes you are correct `hasattr(self, "llm")` was accessing the LLM from crewai and not from Mem0. And that;s why the tests also passed. But now I have made the fix for it.