Skip to content

feat(memory):support self-host mem0#403

Merged
AlbumenJ merged 4 commits intoagentscope-ai:mainfrom
shiyiyue1102:main-support-selfhost-mem0
Dec 31, 2025
Merged

feat(memory):support self-host mem0#403
AlbumenJ merged 4 commits intoagentscope-ai:mainfrom
shiyiyue1102:main-support-selfhost-mem0

Conversation

@shiyiyue1102
Copy link
Contributor

This pull request improves support for both platform and self-hosted Mem0 deployments in the long-term memory extension, making the API more flexible and robust. The main changes include allowing users to specify the Mem0 API type, updating endpoint handling in the client, and enhancing search request capabilities.

Mem0 API deployment flexibility and configuration:

  • The Mem0LongTermMemory builder and Mem0Client now accept an apiType parameter, allowing users to specify "platform" (default) or "self-hosted" deployments. Endpoints are selected accordingly, and example code and documentation have been updated to reflect this. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]

  • The Mem0Client class now chooses the correct API endpoints for memory add/search operations based on the apiType, supporting both platform and self-hosted Mem0. [1] [2] [3] [4] [5]

Robustness and compatibility improvements:

  • The Mem0Client search method now handles differences in response format between platform and self-hosted Mem0. It parses results accordingly to ensure compatibility. [1] [2]

  • The Mem0AddResponse and Mem0SearchResponse classes now ignore unknown JSON properties, increasing forward compatibility with future API changes. [1] [2] [3] [4]

Search request enhancements:

  • The Mem0SearchRequest class and its builder now support a userId field, which is automatically added to filters for compatibility with the v2 API. [1] [2] [3] [4] [5]

These changes make the Mem0 extension more flexible, easier to configure for different deployment scenarios, and more robust to API changes.Change-Id: If8c877e63f8d225d9e88e3830380ec855e7c9fd2
Co-developed-by: Aone Copilot noreply@alibaba-inc.com

AgentScope-Java Version

[The version of AgentScope-Java you are working on, e.g. 1.0.4, check your pom.xml dependency version or run mvn dependency:tree | grep agentscope-parent:pom(only mac/linux)]

Description

[Please describe the background, purpose, changes made, and how to test this PR]

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

Change-Id: If8c877e63f8d225d9e88e3830380ec855e7c9fd2
Co-developed-by: Aone Copilot <noreply@alibaba-inc.com>
Change-Id: I1e29c5f25f6cad7231dc77de3157801a98d1e319
Co-developed-by: Aone Copilot <noreply@alibaba-inc.com>
@codecov
Copy link

codecov bot commented Dec 31, 2025

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for self-hosted Mem0 deployments alongside the existing Platform Mem0 support, addressing API incompatibilities between the two deployment types. The implementation introduces an apiType parameter to select the appropriate endpoints and response parsing logic, while also improving robustness with JSON handling.

Key Changes:

  • Added apiType parameter to Mem0Client and Mem0LongTermMemory.Builder to distinguish between "platform" and "self-hosted" deployments
  • Implemented conditional endpoint selection and response parsing based on deployment type
  • Enhanced forward compatibility by adding @JsonIgnoreProperties(ignoreUnknown = true) to response classes

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
docs/zh/task/memory.md Added Chinese documentation explaining apiType parameter usage and configuration for both Platform and self-hosted Mem0
docs/en/task/memory.md Added English documentation explaining apiType parameter usage and configuration for both Platform and self-hosted Mem0
Mem0Client.java Added apiType parameter with endpoint selection logic and conditional response parsing for platform vs self-hosted APIs
Mem0LongTermMemory.java Updated builder to accept and pass apiType parameter to Mem0Client
Mem0SearchRequest.java Added userId field with automatic synchronization to filters for v2 API compatibility
Mem0AddResponse.java Added @JsonIgnoreProperties annotation for forward compatibility
Mem0SearchResponse.java Added @JsonIgnoreProperties annotation for forward compatibility
Mem0SearchResult.java Added @JsonIgnoreProperties annotation for forward compatibility
Mem0ClientTest.java Added comprehensive test coverage for self-hosted mode including endpoint verification and response format handling
Mem0Example.java Updated to support apiType configuration via environment variable
AutoMemoryExample.java Added LongTermMemoryMode import and changed sessionId (unrelated to main PR purpose)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +354 to +357
// Set userId after filters to ensure it's synced
if (userId != null) {
request.setUserId(userId);
}
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order of operations in the build() method could lead to data loss. If a user calls builder.filters() to set custom filters (line 228-230), and then also calls builder.userId(), the userId will be added to the builder's filters map at line 257. However, when build() is called, it first sets the filters at line 345 (which includes the userId), then calls setUserId() at line 356, which will try to add userId to filters again (line 190). While this won't cause an error (just overwrites the same key), the more serious issue is if setFilters() is called with a different Map reference, the setUserId call will add userId to that different map, which may not be the intended behavior. Consider either documenting this behavior clearly or restructuring to avoid this potential confusion.

Copilot uses AI. Check for mistakes.
Comment on lines 110 to 122

// Store API type (normalize to lowercase for comparison)
this.apiType = apiType != null ? apiType.toLowerCase() : "platform";

// Select endpoints based on API type
if ("self-hosted".equals(this.apiType)) {
this.addEndpoint = SELF_HOSTED_MEMORIES_ENDPOINT;
this.searchEndpoint = SELF_HOSTED_SEARCH_ENDPOINT;
} else {
// Default to platform endpoints
this.addEndpoint = PLATFORM_MEMORIES_ENDPOINT;
this.searchEndpoint = PLATFORM_SEARCH_ENDPOINT;
}
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The apiType parameter lacks input validation. When an invalid apiType value (neither "platform" nor "self-hosted") is provided, the code silently defaults to platform endpoints without any warning or error. This could lead to confusion during debugging if a user mistypes the apiType. Consider adding validation to reject invalid apiType values or at minimum log a warning when an unrecognized value is provided.

Copilot uses AI. Check for mistakes.
Comment on lines 330 to 341
/**
* Sets the Mem0 API type.
*
* @param apiType API type: "platform" for Platform Mem0 (default),
* "self-hosted" for self-hosted Mem0
* @return This builder
*/
public Builder apiType(String apiType) {
this.apiType = apiType;
return this;
}

Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new apiType parameter added to Mem0LongTermMemory.Builder lacks test coverage. While Mem0ClientTest has comprehensive tests for self-hosted mode, there are no tests in Mem0LongTermMemoryTest that verify the apiType parameter is correctly passed to Mem0Client. Consider adding tests to ensure that when apiType is set to "self-hosted" or "platform" in Mem0LongTermMemory.Builder, it properly configures the underlying Mem0Client with the correct endpoints.

Copilot uses AI. Check for mistakes.
Comment on lines +182 to +189
public String getUserId() {
return userId;
}

public void setUserId(String userId) {
this.userId = userId;
// Automatically sync to filters if set
if (userId != null && filters != null) {
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a potential NullPointerException if filters is null when setUserId is called. The method checks if userId is not null and filters is not null before adding to filters, but the filters field could potentially be null if not properly initialized. Consider adding a null-safety check or initializing filters if it's null, similar to what's done in the Builder.userId() method.

Suggested change
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
// Automatically sync to filters if set
if (userId != null && filters != null) {
/**
* Returns the user identifier associated with this search request.
*
* @return the user identifier, or {@code null} if not set
*/
public String getUserId() {
return userId;
}
/**
* Sets the user identifier and synchronizes it into the filters map.
*
* @param userId the user identifier; if non-null it will be stored in the filters map
*/
public void setUserId(String userId) {
this.userId = userId;
// Automatically sync to filters if set
if (userId != null) {
if (filters == null) {
filters = new HashMap<>();
}

Copilot uses AI. Check for mistakes.
Comment on lines +176 to +181
} catch (IOException e) {
// Re-throw IOException as-is (it already contains status code info)
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new IOException("Mem0 API " + operationName + " failed", e);
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The added catch blocks at lines 176-181 are redundant and don't add value. The IOException catch at line 176 re-throws the exception as-is without any transformation, and the generic Exception catch wraps exceptions that are already being thrown by the try-with-resources block. The original code already handles IOException appropriately through the Mono error handling. These catch blocks should be removed to simplify the code.

Suggested change
} catch (IOException e) {
// Re-throw IOException as-is (it already contains status code info)
throw e;
} catch (Exception e) {
// Wrap other exceptions
throw new IOException("Mem0 API " + operationName + " failed", e);

Copilot uses AI. Check for mistakes.
.hook(new AutoContextHook()) // Register the hook for automatic setup
.build();
String sessionId = "session111111111111";
String sessionId = "123453344";
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sessionId value has been changed from "session111111111111" to "123453344" without any clear reason in the PR description or comments. This appears to be an unrelated change that doesn't align with the stated purpose of this PR (adding self-hosted Mem0 support). If this is an intentional change, it should be documented or made in a separate commit.

Suggested change
String sessionId = "123453344";
String sessionId = "session111111111111";

Copilot uses AI. Check for mistakes.

import io.agentscope.core.ReActAgent;
import io.agentscope.core.formatter.dashscope.DashScopeChatFormatter;
import io.agentscope.core.memory.LongTermMemoryMode;
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import of LongTermMemoryMode appears to be added but was likely already being used in the file (at line 82 where .longTermMemoryMode(LongTermMemoryMode.STATIC_CONTROL) is called). However, if this import was missing before and is now being added, this is a bug fix rather than part of the self-hosted Mem0 feature. This should be clarified or separated into its own fix.

Copilot uses AI. Check for mistakes.
Change-Id: I903c3f79433843b9793e1a59b859ccc8e9b3c6b7
Co-developed-by: Aone Copilot <noreply@alibaba-inc.com>
@AlbumenJ AlbumenJ merged commit ad40eb5 into agentscope-ai:main Dec 31, 2025
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants