Python: fix(mem0): support mem0ai 2.x in Mem0ContextProvider - #6129
Python: fix(mem0): support mem0ai 2.x in Mem0ContextProvider#6129youneshima wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates the Mem0 integration to work with mem0ai v2 semantics by passing entity IDs via a filters dict and adjusting behavior around app_id depending on whether the client is OSS or Platform.
Changes:
- Bump
mem0aidependency from>=1,<2to>=2,<3. - Update
Mem0ContextProvider.before_run()to always callsearch(query=..., filters=...), droppingapp_idfor OSSAsyncMemory. - Update/add tests to assert filter handling for OSS vs Platform clients, including
app_idbehavior.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| python/packages/mem0/agent_framework_mem0/_context_provider.py | Switches Mem0 search to v2-style filters dict; drops app_id for OSS client. |
| python/packages/mem0/tests/test_mem0_context_provider.py | Updates/extends tests to validate new filters behavior for OSS and Platform clients. |
| python/packages/mem0/pyproject.toml | Bumps mem0ai major version constraint to v2. |
|
@microsoft-github-policy-service agree company="Mem0" |
| should_close_client = True | ||
|
|
||
| self.api_key = api_key | ||
| self.application_id = application_id |
There was a problem hiding this comment.
We can throw in an error in case client is OSS client i.e AsyncMemory and application_id is passed as well.
Ideally should be done once we know what type of client is being initialized
There was a problem hiding this comment.
or the surface can remain application_id but internally we can route it to run_id if this is passed for oss client
| from agent_framework._agents import SupportsAgentRun | ||
|
|
||
|
|
||
| class _MemorySearchResponse_v1_1(TypedDict): |
There was a problem hiding this comment.
We can deprecate this as now search is always a list now.
| search_kwargs["filters"] = filters | ||
| filters = {key: value for key, value in filters.items() if key != "app_id"} | ||
|
|
||
| search_response: _MemorySearchResponse_v1_1 | _MemorySearchResponse_v2 = await self.mem0_client.search( # type: ignore[misc] |
There was a problem hiding this comment.
As mentioned above _MemorySearchResponse_v1_1 can be deprecated
| """Validates that at least one usable filter is provided for the configured client.""" | ||
| if not self.agent_id and not self.user_id and not self.application_id: | ||
| raise ValueError("At least one of the filters: agent_id, user_id, or application_id is required.") | ||
| if isinstance(self.mem0_client, AsyncMemory) and not self.user_id and not self.agent_id: |
There was a problem hiding this comment.
I see the intent but messaging can be improved, right now even if users are sending application_id (in OSS client) it would seem as if it matters but actually it doesn't
| messages=messages, | ||
| user_id=self.user_id, | ||
| agent_id=self.agent_id, | ||
| metadata={"application_id": self.application_id}, |
There was a problem hiding this comment.
If we're passing the application_id in metadata then criticism of it not being supported on OSS client becomes invalid.
Metadata are handled by both SDKs, and also it would break the filters, as direct filter={application_id: "app123"} cannot be used to filter metadata directly on Platform Client
| filters["user_id"] = self.user_id | ||
| if self.agent_id: | ||
| filters["agent_id"] = self.agent_id | ||
| if self.application_id: |
There was a problem hiding this comment.
Application ID as mentioned above when passed as metadata cannot directly be used in filter like this
There was a problem hiding this comment.
The Key we're using is application_id on R170 while saving, then while searching how can it be app_id???
| filters: dict[str, Any] = {} | ||
| if self.user_id: | ||
| filters["user_id"] = self.user_id | ||
| if self.agent_id: |
There was a problem hiding this comment.
agent_id and user_id are mutually exclusive and tend to break when used together when in same filter group
There was a problem hiding this comment.
This is not a major blocker but still an issue
|
youneshima can you catch up to main and fix the merge conflicts? |
| search_kwargs.update(filters) | ||
| else: | ||
| search_kwargs["filters"] = filters | ||
| filters = {key: value for key, value in filters.items() if key != "app_id"} |
There was a problem hiding this comment.
Could we update the corresponding platform add path to use this same 2.x filters shape before bumping the dependency? before_run() now searches with filters={...}, but after_run() still calls AsyncMemoryClient.add() with top-level user_id/agent_id and metadata={"application_id": ...}; in mem0ai 2.0.4, that becomes a /v3/memories/add/ payload whose identity fields are not under filters. That can reject platform stores or write memories under a scope this new search path will not read back, and the existing store test still asserts the old payload shape.
|
Superseded by #7004, which applies the mem0ai 2.x compatibility update on the current branch and keeps the Python checks passing. |
Motivation and Context
agent-framework-mem0pinsmem0ai>=1.0.0,<2, so every install resolves to the legacymem0ai==1.0.11rather than the current 2.x line. This bumps the pin tomem0ai>=2.0.0,<3and adaptsMem0ContextProviderto the mem0 2.x API so new installs land on current mem0.Description
In mem0 >=2.0,
search()rejects top-level entity params (user_id/agent_id/run_id) and requires them in afilters={...}dict — for both the OSSAsyncMemoryand PlatformAsyncMemoryClientclients. The previous OSS path passed entity IDs as top-level kwargs, which now raisesValueError: Top-level entity parameters ... are not supported in search().Changes:
before_runnow passesfilters=for both client types (the OSS/Platform branch collapses to the shared 2.x convention).app_idis dropped from the OSS filters: OSS recognizes onlyuser_id/agent_id/run_idas entities, so anapp_idfilter would be treated as a non-matching metadata filter and silently exclude all results. The Platform client keepsapp_id(a recognized Platform entity).add()is unchanged — it still accepts top-level entity kwargs in 2.x.No change to
Mem0ContextProvider's public API (constructor and hook signatures are identical). Not a breaking change for consumers.Verified end to end against real
mem0ai==2.0.4with an OSSAsyncMemory: the store (after_run) → search (before_run) round trip succeeds, where it raisedValueErrorbefore the fix.Contribution Checklist