Initial upload

This commit is contained in:
2025-11-11 11:47:15 +01:00
commit 7c24dab288
48 changed files with 2761 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
# Memory Stack (External Ollama)
## Deploy
```
bash deploy.sh http://<OLLAMA-IP>:<PORT>
```
## Test
```
curl http://localhost:8085/health
```

View File

@@ -0,0 +1,25 @@
version: "3.8"
services:
qdrant:
image: qdrant/qdrant:latest
container_name: memory-qdrant
volumes:
- /srv/docker/services/memory/qdrant:/qdrant/storage
ports:
- "127.0.0.1:6333:6333"
restart: unless-stopped
memory-api:
build:
context: ./memory-api
container_name: memory-api
environment:
- QDRANT_URL=http://qdrant:6333
- OLLAMA_API={{OLLAMA_API}}
- COLLECTION_NAME=chat-memory
ports:
- "127.0.0.1:8085:8085"
depends_on:
- qdrant
restart: unless-stopped

View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
ensure_root
detect_pkg_manager
install_docker
if ask_to_install "RAG Memory Stack (Qdrant + Memory API)"; then
log "=== RAG Memory Stack Installation ==="
read -rp "Ollama API URL (z.B. http://127.0.0.1:11434): " OLLAMA_API_URL
OLLAMA_API_URL=${OLLAMA_API_URL:-http://127.0.0.1:11434}
BASE="/srv/docker/services/memory"
$SUDO mkdir -p "$BASE/qdrant"
$SUDO cp -r "$(dirname "${BASH_SOURCE[0]}")/memory-api" "$BASE/"
$SUDO cp "$(dirname "${BASH_SOURCE[0]}")/compose.yaml" "$BASE/docker-compose.yml"
cd "$BASE"
$SUDO sed -i "s|{{OLLAMA_API}}|$OLLAMA_API_URL|g" docker-compose.yml
log "🚀 Starte RAG Memory Stack..."
$SUDO docker compose up -d --build
log "Attempting to pull embedding model from remote Ollama..."
$SUDO curl -s -X POST "$OLLAMA_API_URL/api/pull" -H 'Content-Type: application/json' -d '{"name": "nomic-embed-text"}' || log "Notice: Model pull failed (possibly using a gateway). Continuing."
log "✅ RAG Memory Stack läuft unter: http://<server-ip>:8085"
else
log "${YELLOW}⏭ RAG Memory Stack übersprungen.${NC}"
fi

View File

@@ -0,0 +1,8 @@
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 8085
CMD ["python", "app.py"]

View File

@@ -0,0 +1,40 @@
from fastapi import FastAPI
import requests, os
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct
import hashlib
import json
app = FastAPI()
QDRANT_URL = os.getenv("QDRANT_URL")
OLLAMA_API = os.getenv("OLLAMA_API")
COLLECTION_NAME = os.getenv("COLLECTION_NAME", "chat-memory")
client = QdrantClient(url=QDRANT_URL)
@app.get("/health")
def health():
return {"status": "ok", "qdrant": QDRANT_URL, "ollama": OLLAMA_API}
def embed(text):
r = requests.post(f"{OLLAMA_API}/api/embeddings", json={"model":"nomic-embed-text","prompt":text})
return r.json()["embedding"]
@app.post("/store")
def store(item: dict):
text = item["text"]
metadata = item.get("metadata", {})
vec = embed(text)
pid = hashlib.sha256(text.encode()).hexdigest()
client.upsert(collection_name=COLLECTION_NAME, points=[PointStruct(id=pid, vector=vec, payload={"text": text, **metadata})])
return {"stored": True}
@app.post("/search")
def search(query: dict):
q = query["text"]
top_k = query.get("top_k", 5)
vec = embed(q)
result = client.search(collection_name=COLLECTION_NAME, query_vector=vec, limit=top_k)
return [{"score": r.score, "text": r.payload["text"]} for r in result]

View File

@@ -0,0 +1,4 @@
fastapi
uvicorn
requests
qdrant-client