Refactor client API based on OpenAPI spec and add mem0_delete tool
- Update client.py to use correct API endpoints from OpenAPI spec - Add delete() method for memory deletion - Add mem0_delete tool with schema and handler - Simplify API calls to match actual Mem0 OSS server format
This commit is contained in:
+47
-27
@@ -112,6 +112,24 @@ CONCLUDE_SCHEMA = {
|
||||
},
|
||||
}
|
||||
|
||||
DELETE_SCHEMA = {
|
||||
"name": "mem0_delete",
|
||||
"description": (
|
||||
"Delete a specific memory by ID. Use when user explicitly requests "
|
||||
"to remove or forget a stored fact."
|
||||
),
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memory_id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the memory to delete.",
|
||||
},
|
||||
},
|
||||
"required": ["memory_id"],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# MemoryProvider implementation
|
||||
@@ -279,9 +297,8 @@ class Mem0LocalMemoryProvider(MemoryProvider):
|
||||
client = self._get_client()
|
||||
results = client.search(
|
||||
query=query,
|
||||
filters=self._read_filters(),
|
||||
rerank=self._rerank,
|
||||
top_k=5,
|
||||
user_id=self._user_id,
|
||||
limit=5,
|
||||
)
|
||||
if results:
|
||||
lines = [
|
||||
@@ -311,11 +328,12 @@ class Mem0LocalMemoryProvider(MemoryProvider):
|
||||
def _sync():
|
||||
try:
|
||||
client = self._get_client()
|
||||
messages = [
|
||||
{"role": "user", "content": user_content},
|
||||
{"role": "assistant", "content": assistant_content},
|
||||
]
|
||||
client.add(messages, filters=self._write_filters(), infer=True)
|
||||
# Combine user and assistant content for context
|
||||
combined = f"User: {user_content}\nAssistant: {assistant_content}"
|
||||
client.add(
|
||||
message=combined,
|
||||
user_id=self._user_id,
|
||||
)
|
||||
self._record_success()
|
||||
except Exception as e:
|
||||
self._record_failure()
|
||||
@@ -330,7 +348,7 @@ class Mem0LocalMemoryProvider(MemoryProvider):
|
||||
self._sync_thread.start()
|
||||
|
||||
def get_tool_schemas(self) -> List[Dict[str, Any]]:
|
||||
return [PROFILE_SCHEMA, SEARCH_SCHEMA, CONCLUDE_SCHEMA]
|
||||
return [PROFILE_SCHEMA, SEARCH_SCHEMA, CONCLUDE_SCHEMA, DELETE_SCHEMA]
|
||||
|
||||
def handle_tool_call(self, tool_name: str, args: dict, **kwargs) -> str:
|
||||
if self._is_breaker_open():
|
||||
@@ -347,15 +365,11 @@ class Mem0LocalMemoryProvider(MemoryProvider):
|
||||
|
||||
if tool_name == "mem0_profile":
|
||||
try:
|
||||
memories = client.get_all(filters=self._read_filters())
|
||||
memories = client.get_all(user_id=self._user_id)
|
||||
self._record_success()
|
||||
if not memories:
|
||||
return json.dumps({"result": "No memories stored yet."})
|
||||
lines = [
|
||||
m.get("text") or m.get("memory", "")
|
||||
for m in memories
|
||||
if m.get("text") or m.get("memory")
|
||||
]
|
||||
lines = [m.get("text", "") for m in memories if m.get("text")]
|
||||
return json.dumps({"result": "\n".join(lines), "count": len(lines)})
|
||||
except Exception as e:
|
||||
self._record_failure()
|
||||
@@ -365,23 +379,18 @@ class Mem0LocalMemoryProvider(MemoryProvider):
|
||||
query = args.get("query", "")
|
||||
if not query:
|
||||
return tool_error("Missing required parameter: query")
|
||||
rerank = args.get("rerank", False)
|
||||
top_k = min(int(args.get("top_k", 10)), 50)
|
||||
try:
|
||||
results = client.search(
|
||||
query=query,
|
||||
filters=self._read_filters(),
|
||||
rerank=rerank,
|
||||
top_k=top_k,
|
||||
user_id=self._user_id,
|
||||
limit=top_k,
|
||||
)
|
||||
self._record_success()
|
||||
if not results:
|
||||
return json.dumps({"result": "No relevant memories found."})
|
||||
items = [
|
||||
{
|
||||
"memory": r.get("text") or r.get("memory", ""),
|
||||
"score": r.get("score", 0),
|
||||
}
|
||||
{"memory": r.get("text", ""), "score": r.get("score", 0)}
|
||||
for r in results
|
||||
]
|
||||
return json.dumps({"results": items, "count": len(items)})
|
||||
@@ -395,9 +404,8 @@ class Mem0LocalMemoryProvider(MemoryProvider):
|
||||
return tool_error("Missing required parameter: conclusion")
|
||||
try:
|
||||
client.add(
|
||||
[{"role": "user", "content": conclusion}],
|
||||
filters=self._write_filters(),
|
||||
infer=False, # Store verbatim
|
||||
message=conclusion,
|
||||
user_id=self._user_id,
|
||||
)
|
||||
self._record_success()
|
||||
return json.dumps({"result": "Fact stored."})
|
||||
@@ -405,6 +413,18 @@ class Mem0LocalMemoryProvider(MemoryProvider):
|
||||
self._record_failure()
|
||||
return tool_error(f"Failed to store: {e}")
|
||||
|
||||
elif tool_name == "mem0_delete":
|
||||
memory_id = args.get("memory_id", "")
|
||||
if not memory_id:
|
||||
return tool_error("Missing required parameter: memory_id")
|
||||
try:
|
||||
client.delete(memory_id=memory_id)
|
||||
self._record_success()
|
||||
return json.dumps({"result": "Memory deleted."})
|
||||
except Exception as e:
|
||||
self._record_failure()
|
||||
return tool_error(f"Failed to delete: {e}")
|
||||
|
||||
return tool_error(f"Unknown tool: {tool_name}")
|
||||
|
||||
def shutdown(self) -> None:
|
||||
@@ -435,7 +455,7 @@ def register(ctx) -> None:
|
||||
"""Create a handler closure for a specific tool."""
|
||||
return lambda args, **kwargs: provider.handle_tool_call(tool_name, args)
|
||||
|
||||
for schema in [PROFILE_SCHEMA, SEARCH_SCHEMA, CONCLUDE_SCHEMA]:
|
||||
for schema in [PROFILE_SCHEMA, SEARCH_SCHEMA, CONCLUDE_SCHEMA, DELETE_SCHEMA]:
|
||||
ctx.register_tool(
|
||||
name=schema["name"],
|
||||
toolset="mem0_local",
|
||||
|
||||
Reference in New Issue
Block a user