From 20f2ec3ab28e460df65fdd109c9a74f822057a5c Mon Sep 17 00:00:00 2001 From: ArthurErlich Date: Mon, 7 Sep 2026 19:20:14 +0200 Subject: [PATCH 1/3] feat: add qdrant and neo4j for RAG vector/graph storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the two databases as infra services (own volume, ai-stack network, host-published UI ports like comfyui) for an upcoming RAG pipeline. Extraction/chunking/orchestration code is out of scope for this repo — it's app logic that calls into these DBs and llama-server, not compose infra. Neo4j password follows the omniroute secret pattern: blank in .env.example, auto-generated by scripts/update.sh. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01DjhxWirQepKFEQj1huXNJR --- .env.example | 5 +++++ docker-compose.yml | 30 ++++++++++++++++++++++++++++++ scripts/update.sh | 1 + 3 files changed, 36 insertions(+) diff --git a/.env.example b/.env.example index 5108412..6a59b6d 100644 --- a/.env.example +++ b/.env.example @@ -141,3 +141,8 @@ LLAMA_FAST_PARALLEL=1 COMFYUI_DIFFUSION_MODEL_FILE=qwen_image_fp8_e4m3fn.safetensors COMFYUI_TEXT_ENCODER_FILE=qwen_2.5_vl_7b_fp8_scaled.safetensors COMFYUI_VAE_FILE=qwen_image_vae.safetensors + +# --- RAG databases (qdrant + neo4j, see wayfinder notes) --- +# No auth on qdrant (its default) — same trust boundary as llama-server: +# ai-stack is not exposed off-box. Random, filled in automatically: +NEO4J_PASSWORD= diff --git a/docker-compose.yml b/docker-compose.yml index 5c0ed1d..9659d9f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -303,6 +303,34 @@ services: depends_on: - llama-server + # RAG vector store — see docs/agents/... (wayfinder). Dashboard UI published + # directly like comfyui above, not gatewayed through omniroute (it isn't an + # LLM provider). + qdrant: + image: qdrant/qdrant:latest + container_name: qdrant + volumes: + - qdrant-data:/qdrant/storage + ports: + - "6333:6333" + restart: unless-stopped + networks: [ai-stack] + + # RAG graph store, native vector index too (can absorb qdrant's job later + # if the two-DB split proves unnecessary — see wayfinder notes). + neo4j: + image: neo4j:5-community + container_name: neo4j + environment: + - NEO4J_AUTH=neo4j/${NEO4J_PASSWORD:?run scripts/update.sh first to resolve this} + volumes: + - neo4j-data:/data + ports: + - "7474:7474" # browser UI + - "7687:7687" # bolt + restart: unless-stopped + networks: [ai-stack] + networks: ai-stack: @@ -310,3 +338,5 @@ volumes: models: omniroute-data: comfyui-data: + qdrant-data: + neo4j-data: diff --git a/scripts/update.sh b/scripts/update.sh index d3c9054..cb2d922 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -175,6 +175,7 @@ set_if_blank OMNIROUTE_STORAGE_ENCRYPTION_KEY "$(openssl rand -hex 32)" set_if_blank OMNIROUTE_MACHINE_ID_SALT "$(openssl rand -hex 16)" set_if_blank OMNIROUTE_CLI_SALT "$(openssl rand -hex 16)" set_if_blank OMNIROUTE_WS_BRIDGE_SECRET "$(openssl rand -hex 32)" +set_if_blank NEO4J_PASSWORD "$(openssl rand -hex 16)" echo "==> resolving SEARXNG_LAN_IP" # search.home is a LAN mDNS/local-DNS name — resolvable from this host, just From 2bfe6dbd290c3947a4b952040e0c300b1d4939e8 Mon Sep 17 00:00:00 2001 From: ArthurErlich Date: Mon, 7 Sep 2026 19:40:51 +0200 Subject: [PATCH 2/3] docs: point knowledge.proxy-ai.home at Neo4j's browser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents the NPM route for the RAG knowledge graph alongside the existing proxy-ai.home/search.home entries. Neo4j (not Qdrant) gets the hostname — it's the human-facing graph browser; Qdrant's dashboard stays on its raw port for now. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01DjhxWirQepKFEQj1huXNJR --- docs/network-access.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/network-access.md b/docs/network-access.md index 5dffaa8..5bcc51f 100644 --- a/docs/network-access.md +++ b/docs/network-access.md @@ -16,3 +16,9 @@ As of [issue #31](https://git.arthurerlich.de/haylan/LLM-Server/issues/31) (migr - The **dashboard** (`${OMNIROUTE_DASHBOARD_PORT:-20128}`) is never registered in NPM at all, and `docker-compose.yml` never publishes that port to the host either — it manages every workload's keys, so it doesn't belong on the public internet, same reasoning as LiteLLM's old `/ui`. Unlike LiteLLM, OmniRoute's split-port mode means this is structural (no network route exists) rather than an NPM path-deny rule that has to be maintained and could be misconfigured. Reach the dashboard only from the host itself or over SSH port-forward. **Every gateway call already requires a valid API key** (Bearer token, see `docs/proxy-key-onboarding.md`), so no extra NPM-level auth is needed for the external hostname. + +## RAG knowledge graph (Neo4j) — `knowledge.proxy-ai.home` + +Set up as an NPM Proxy Host pointing at this machine's LAN IP on Neo4j's Browser port (`7474`, see `docker-compose.yml`'s `neo4j` service, [PR #50](https://git.arthurerlich.de/haylan/LLM-Server/pulls/50)). Internal-only, same as `proxy-ai.home` — no DMZ/external route, this is admin/dev tooling, not a client-facing endpoint. Bolt (`7687`, the actual query protocol) isn't proxied through NPM at all — clients on the LAN reach it directly at `:7687`. + +Qdrant's dashboard (`6333`) stays on its raw LAN IP/port for now — no hostname assigned yet. From 7a654ead91ddac633c6d33603d975609467b5a96 Mon Sep 17 00:00:00 2001 From: ArthurErlich Date: Mon, 7 Sep 2026 19:54:38 +0200 Subject: [PATCH 3/3] chore: ignore .qwen/temp --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 77761ae..3e7eeb7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ data/ .leankg/ .cache/ +.qwen/temp \ No newline at end of file