feat(mem0-plugin): support self-hosted Mem0 server via MEM0_BASE_URL
Adds an optional MEM0_BASE_URL override (env var, falling back to settings.json's base_url, defaulting to the hosted Platform unchanged) so the plugin's REST-backed hooks can talk to a self-hosted server/ deployment instead of api.mem0.ai. A new scripts/_api.py centralizes the hosted-vs-self-hosted protocol differences (unversioned paths, X-API-Key auth, agent_id instead of app_id) that every hook previously hardcoded, and all 9 urllib call sites now route through it. MCP tools have no self-hosted backend (server/ implements no MCP), so they continue to talk to the hosted Platform regardless of MEM0_BASE_URL; this is documented rather than silently left unclear. Coding-category customization also has no self-hosted SDK equivalent and now skips cleanly with a log message instead of failing. Closes MEM-5647
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
"""Shared mem0 search API helper.
|
||||
|
||||
Wraps POST /v3/memories/search/ into a single function call.
|
||||
All pre-fetch hooks use this instead of duplicating urllib boilerplate.
|
||||
Wraps the search endpoint (hosted Platform or self-hosted server) into a
|
||||
single function call. All pre-fetch hooks use this instead of duplicating
|
||||
urllib boilerplate.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -10,7 +11,8 @@ import json
|
||||
import os
|
||||
import urllib.request
|
||||
|
||||
SEARCH_URL = "https://api.mem0.ai/v3/memories/search/"
|
||||
from _api import auth_headers, project_field, search_url
|
||||
|
||||
SEARCH_TIMEOUT = 5
|
||||
|
||||
|
||||
@@ -34,12 +36,8 @@ def should_rerank() -> bool:
|
||||
|
||||
def _do_search(api_key: str, payload: dict) -> list[dict]:
|
||||
body = json.dumps(payload).encode()
|
||||
req = urllib.request.Request(
|
||||
SEARCH_URL,
|
||||
data=body,
|
||||
headers={"Authorization": f"Token {api_key}", "Content-Type": "application/json"},
|
||||
method="POST",
|
||||
)
|
||||
headers = {**auth_headers(api_key), "Content-Type": "application/json"}
|
||||
req = urllib.request.Request(search_url(), data=body, headers=headers, method="POST")
|
||||
with urllib.request.urlopen(req, timeout=SEARCH_TIMEOUT) as r:
|
||||
data = json.loads(r.read())
|
||||
return data if isinstance(data, list) else data.get("results", [])
|
||||
@@ -64,7 +62,7 @@ def search_memories(
|
||||
if global_search:
|
||||
filters: dict = {"OR": [{"user_id": "*"}]}
|
||||
else:
|
||||
base_clauses: list[dict] = [{"user_id": user_id}, {"app_id": project_id}]
|
||||
base_clauses: list[dict] = [{"user_id": user_id}, {project_field(): project_id}]
|
||||
if metadata_type:
|
||||
base_clauses.append({"metadata": {"type": metadata_type}})
|
||||
if metadata_filters:
|
||||
|
||||
Reference in New Issue
Block a user