Files
rag-pipeline-docker/references/memory-os-session.md
T
2026-09-06 13:51:06 +00:00

108 lines
3.8 KiB
Markdown

# Memory OS Deployment — Session Details
## Environment
- Host: Linux, no Docker Desktop
- Ollama: Docker container on `ollama_default` network, port 11434
- Worker: Docker Compose stack with Qdrant + Redis + ARQ worker
- Obsidian vault: `/opt/hermes/obsidian-vault/`
- Wiki path: `/opt/hermes/vault/wiki/raw/obsidian/`
- State file: `~/.hermes/wiki_ingest_state.json` (tracks ingested files by hash)
- Sync state: `~/.hermes/obsidian_sync_state.json`
## Docker Compose Path
`/opt/hermes/memory-os/docker/docker-compose.yml`
## .env File
`/opt/hermes/memory-os/docker/.env` — contains:
- `OLLAMA_BASE_URL=http://ollama:11434`
- `OLLAMA_MODEL=qwen3-8b-64k`
- `OLLAMA_EMBEDDING_MODEL=nomic-embed-text:latest`
- `EMBEDDING_API_BASE=http://ollama:11434/v1`
- `EMBEDDING_DIMS=768`
- `REDIS_PASSWORD`, `QDRANT_API_KEY`, `OPENROUTER_API_KEY`
## Error: Reflection Failing
**Symptom:** `j_failed=90` on worker, all from `cron:process_reflection`
**Error:**
```
httpx.ConnectError: [Errno -2] Name or service not known
```
The worker was trying `http://host.docker.internal:11434/api/generate`
**Root cause:** `OLLAMA_BASE_URL` defaulted to `http://host.docker.internal:11434` in `services/llm.py`:
```python
OLLAMA_BASE_URL = os.environ.get("OLLAMA_BASE_URL", "http://host.docker.internal:11434")
```
This variable was not listed in `docker-compose.yml` under `worker.environment`, so the container fell back to the hardcoded default.
**Fix:**
1. Added `OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://ollama:11434}` and `OLLAMA_MODEL: ${OLLAMA_MODEL:-qwen3-8b-64k}` to `docker-compose.yml`
2. Added `OLLAMA_MODEL=qwen3-8b-64k` to `.env`
3. Connected worker to `ollama_default` external network in compose
4. `docker compose up -d --force-recreate worker` to rebuild
## Network Layout
```
worker (memory-os_default: 172.24.0.x, ollama_default: 172.18.0.3)
→ ollama (ollama_default: 172.18.0.5) via DNS
→ qdrant (memory-os_default) via DNS
→ redis (memory-os_default) via DNS
search-api (memory-os_default: 172.24.0.x, ollama_default: 172.18.0.x)
→ ollama (ollama_default) via DNS
→ qdrant (memory-os_default) via DNS
```
## Qdrant Collection
- Name: `knowledge_base`
- Points: 683
- Dense vector: 768 dims, Cosine distance
- Sparse vector: BM25 (on_disk=True)
- Embedding model: `nomic-embed-text:latest`
## Search API
**Path:** `/opt/hermes/memory-os/search_api/main.py`
**Port:** localhost:8000
**Docker image:** `docker-search-api` (built from `search_api/Dockerfile`)
**Files:**
```
search_api/
├── Dockerfile
├── requirements.txt # fastapi, uvicorn, httpx, pydantic
└── main.py # FastAPI app with POST /search and GET /health
```
**Endpoints:**
- `GET /health` → `{"status": "ok", "qdrant": true, "ollama": true}`
- `POST /search` → body: `{"query": "search text", "top_k": 3}` → `{"query": "...", "results": [...], "total": N}`
## Cron Jobs
### sync+ingest (LLM-driven, every 10m)
- Name: `memory-os obsidian sync + ingest`
- Schedule: every 10 minutes
- Prompt: Runs sync script + ingest pipeline
- Tools: terminal only
### micro-reflection trigger (no_agent, every 5m, silent)
- Name: `memory-os micro-reflection trigger`
- Schedule: `*/5 * * * *`
- Script: `docker exec docker-worker-1 python3 /app/scripts/reflection_trigger.py`
- `no_agent: true` — no LLM tokens, just runs the script
- `deliver: local` — silent, no Telegram notifications
- Script path must be mounted into container: `- ../scripts:/app/scripts:ro` in docker-compose.yml
## Scripts
- `scripts/test_qdrant_search.py` — standalone test: takes --query, gets embedding, searches Qdrant, prints top-5
- `scripts/sync_obsidian_to_wiki.py` — copies .md from Obsidian vault to wiki path, tracks state
- `scripts/wiki_continuous_ingest.py` — detects new/changed files, enqueues to ARQ worker
- `scripts/reflection_trigger.py` — checks idle, respects budget, enqueues micro-reflection