docs(infra): OpenMemory deployment + 2026-05-31 hotfix (list_memories crash + add truncation)
This commit is contained in:
parent
4c39f51ec3
commit
2c5c8b40f3
1 changed files with 48 additions and 0 deletions
48
infrastructure/OPENMEMORY.md
Normal file
48
infrastructure/OPENMEMORY.md
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
# OpenMemory (mem0)
|
||||||
|
|
||||||
|
Selbst-gehosteter Memory-Store mit MCP-Schnittstelle. Wird u. a. von Cursor und Jervais/Hermes als persistentes Gedaechtnis genutzt.
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
- **Host:** CT122 auf pve-hetzner (Tailscale-Gateway `root@100.88.230.59`), interne IP `10.10.10.122`.
|
||||||
|
- **Container:** Docker Compose unter `/root/mem0/openmemory/` (`docker-compose.yml`):
|
||||||
|
- `openmemory-openmemory-mcp-1` (`mem0/openmemory-mcp`) — API/MCP auf Port `8765`, `uvicorn main:app --reload --workers 4`.
|
||||||
|
- `openmemory-mem0_store-1` (`qdrant/qdrant`) — Vektor-Store, Collection `openmemory`.
|
||||||
|
- `openmemory-openmemory-ui-1` (`mem0/openmemory-ui`) — Dashboard auf Port `3000`.
|
||||||
|
- **App-Quellcode (bind-mount):** Host `/root/mem0/openmemory/api` → Container `/usr/src/openmemory`.
|
||||||
|
- **Aktive Konfiguration:** NICHT `config.json`, sondern DB-Tabelle `configs` (key `main`) in `/usr/src/openmemory/openmemory.db`. LLM = `gpt-4o-mini` via OpenRouter (`OPENAI_BASE_URL=https://openrouter.ai/api/v1`), Embedder `text-embedding-3-small`.
|
||||||
|
- **Zugang vom Cursor-Host:** SSH-Tunnel `openmemory-tunnel.service` (autossh) leitet `localhost:8765` → `10.10.10.122:8765`. MCP-URL in `mcp.json`: `http://localhost:8765/mcp/cursor/sse/orbitalo`.
|
||||||
|
- **Logs:** `docker logs openmemory-openmemory-mcp-1` (json-file, keine Rotation konfiguriert).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hotfix — 2026-05-31
|
||||||
|
|
||||||
|
Behob zwei Fehlfunktionen.
|
||||||
|
|
||||||
|
## Symptome
|
||||||
|
1. `list_memories` lieferte hart: `Error getting memories: fromisoformat: argument must be str`.
|
||||||
|
2. `add_memories` mit laengeren Texten gab still `{"results": []}` zurueck (nicht gespeichert), ohne sichtbaren Client-Fehler.
|
||||||
|
|
||||||
|
## Root Causes
|
||||||
|
1. **Gemischte Timestamp-Typen in qdrant.** 274 von 663 Punkten hatten `hash` und `created_at` als **Integer** (alte Records einer frueheren mem0-Version), neuere als String/ISO.
|
||||||
|
- `mem0.memory.main._normalize_iso_timestamp_to_utc()` fing nur `ValueError`; bei int wirft `datetime.fromisoformat()` ein `TypeError` → `get_all`/`list_memories` crasht komplett.
|
||||||
|
- Zusaetzlich verlangt das Pydantic-Modell `MemoryItem` Strings fuer `hash`/`created_at` → `ValidationError` bei int.
|
||||||
|
2. **Truncation des Extraktor-LLM-JSON.** `max_tokens: 2000` zu klein; beim Update-Memory-Schritt (Prompt enthaelt alle bestehenden Memories) wurde das JSON abgeschnitten → `Invalid JSON response` → leeres `results`.
|
||||||
|
- Hinweis: Leeres `results` kann AUCH legitim sein (LLM-Dedup → `event: NONE`/`NOOP`). Nur das abgeschnittene JSON ist der Bug.
|
||||||
|
|
||||||
|
## Fixes (angewendet + verifiziert)
|
||||||
|
1. **qdrant-Daten normalisiert:** 274 Records, `hash` int→`str`, `created_at`/`updated_at` epoch-int→ISO-UTC. Backup: `api/qdrant_intfix_backup-20260531.json`.
|
||||||
|
2. **mem0-Library tolerant:** `site-packages/mem0/memory/main.py` `except ValueError:` → `except (ValueError, TypeError):`. Backup `.bak-tsfix-20260531` (NICHT rebuild-fest).
|
||||||
|
3. **Durabler Monkeypatch (rebuild-fest):** in `api/main.py` nach den Imports — ueberschreibt `_normalize_iso_timestamp_to_utc` so, dass Nicht-String-Werte unveraendert durchgereicht werden. Backup `api/main.py.bak-tsfix-20260531`.
|
||||||
|
4. **max_tokens erhoeht:** DB-Config `configs.main` → `mem0.llm.config.max_tokens` `2000` → `8000`. Backup `api/config_main.bak-20260531.json`.
|
||||||
|
|
||||||
|
## Verifikation
|
||||||
|
- `_normalize_iso_timestamp_to_utc(1774205916)` gibt int zurueck statt Crash; ISO weiterhin korrekt.
|
||||||
|
- `list_memories()` liefert JSON-Array (100), 0 verbleibende int-Records.
|
||||||
|
- Langer `add_memories` → gueltiges JSON, `event: ADD` (Dedup korrekt `NONE`/`NOOP`).
|
||||||
|
- Live ueber Cursor-MCP (nach Client-Reload) beide Tools ok.
|
||||||
|
|
||||||
|
## Nach Container-Rebuild beachten
|
||||||
|
- Persistent: Fix 1 (qdrant-Daten), Fix 3 (Monkeypatch in `main.py`), Fix 4 (DB-Config).
|
||||||
|
- Verloren bei Image-Rebuild: Fix 2 (site-packages) — durch Fix 3 abgedeckt.
|
||||||
|
- Container-Neustart invalidiert MCP-Sessions → Clients muessen neu initialisieren (`-32602` = request before initialization). In Cursor: MCP `openmemory` toggeln oder Fenster neu laden.
|
||||||
Loading…
Add table
Reference in a new issue