feat: add OSS/self-hosted mem0 support in dashboard plugin#13
feat: add OSS/self-hosted mem0 support in dashboard plugin#13terencez127 wants to merge 7 commits into
Conversation
The plugin previously only supported mem0 Cloud (MemoryClient + API key).
Users running self-hosted mem0 (mode=oss in mem0.json with Qdrant/Ollama)
would get a hard 'Mem0 API key not configured' error from the dashboard.
Changes:
- _load_mem0_config: detect oss_mode (mode=="oss" or oss block present)
and surface oss_config for downstream use
- _mem0_payload: branch on oss_mode; OSS path uses mem0.Memory(config=oss_cfg)
with user_id/agent_id kwargs; cloud path unchanged
- base response now includes mem0_mode field ("oss" or "cloud") for UI display
Tested against a local Qdrant+Ollama stack (nomic-embed-text, llama3.2:3b).
Two bugs in the initial OSS support:
1. Memory() requires a MemoryConfig Pydantic object, not a raw dict.
Passing oss_cfg directly raised 'dict object has no attribute embedder'.
Fix: coerce via MemoryConfig.model_validate(oss_cfg) with **-fallback.
2. OSS Memory.get_all() / .search() take filters={} not top-level
user_id/agent_id kwargs (same API shape as the cloud client).
Fix: use filters={'user_id': ..., 'agent_id': ...} and top_k= for search.
Fixes from code review of the initial OSS patch: #1 & xraysight#2 - Silent swallow + duplicate import bug: Hoist MemoryConfig import above both try blocks, catch ImportError explicitly with a user-facing error. Replace 'pass' fallthrough (which silently called Memory(config=raw_dict) and always crashed) with an explicit error message returned to the dashboard. xraysight#3 - mode:oss with flat config layout ignored: When mem0.json uses {"mode":"oss", "llm":{...}} (flat, no "oss" sub-block), oss_config was None and Memory() was called with no config at all, ignoring user settings. Now: flat layout is detected and the whole file_cfg (minus "mode" key) is used as oss_config. xraysight#4 - agent_id asymmetry between OSS and cloud scope: OSS was always injecting agent_id="hermes" (the default) into filters, causing OSS to return a narrower result set than cloud for the same user. Now: agent_id filter only applied when explicitly set to a non-default value, matching cloud path behaviour. xraysight#5 - rerank not forwarded to OSS search: Memory.search() supports rerank=bool. Now forwarded consistently with the cloud path. xraysight#6 - double file_cfg.get('oss') call: Replaced with a single _oss_block local variable. xraysight#7 - get_all() fetches unbounded, client-side limit only: Memory.get_all() and Memory.search() both support top_k. Now passed server-side so large local vector stores are not over-fetched.
|
Hi @terencez127, thanks for your contribution! The backend direction looks good, and the local test suite passes ( Before I can accept/merge this PR, could you please address a few remaining items?
Once those are addressed, I’ll be comfortable reviewing again for approval. |
Problem
The plugin only supported mem0 Cloud (
MemoryClient+ API key). Users running self-hosted mem0 with"mode": "oss"inmem0.json(Qdrant + Ollama or other local stack) hit a hard error in the dashboard:Changes
_load_mem0_configmem0.jsonhas"mode": "oss"or an"oss"config blockoss_mode(bool) andoss_config(dict) for downstream use_mem0_payloadoss_modemem0.Memory(config=oss_cfg)and callsget_all/searchwithuser_id/agent_idkwargsMemoryClient+ API key guard)mem0_modefield ("oss"or"cloud") for UI displayTested
Local stack: Qdrant on localhost:6333, Ollama with
nomic-embed-textembedder andllama3.2:3bLLM,mem0.jsonmode=oss.