Reorganize /docs with numbered TOC; deployment rewrite for actual homelab
- /docs/ now contains 12 numbered guides + index.md (navigator).
- Old duplicates removed: nexa-core/doc/, DEPLOYMENT.md, PLAN.md,
config/{classification_logic,workflows_spec}.md.
- 09-deployment.md targets the running infra (LXC 104 docker host,
Zoraxy at 192.168.1.4, existing Memos/n8n/LiteLLM/Nextcloud/Qdrant)
rather than spinning a parallel stack; minimal-config approach.
- 11-open-questions.md tracks user-info-required blockers.
- 12-optimization-opportunities.md captures homelab tweaks.
- CLAUDE.md added so future agent runs know repo conventions and infra.
This commit is contained in:
@@ -1,629 +0,0 @@
|
||||
# NEXA Deployment Guide
|
||||
|
||||
## 🚀 Architektur-Überblick
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ MEMOS (Port 5230) │
|
||||
│ Interface, Voice-Input, Webhooks │
|
||||
└────────────────────┬────────────────────────────┘
|
||||
│
|
||||
┌───────────┼───────────┐
|
||||
↓ ↓ ↓
|
||||
┌────────┐ ┌────────┐ ┌──────────┐
|
||||
│ n8n │ │ SAIA │ │ Nextcloud│
|
||||
│Logic │ │LiteLLM │ │Tasks/Mail│
|
||||
│7879 │ │4000 │ │80/443 │
|
||||
└────┬───┘ └────┬───┘ └─────┬────┘
|
||||
│ │ │
|
||||
┌────┴───────────┼────────────┴────┐
|
||||
↓ ↓ ↓
|
||||
┌─────────┐ ┌────────────┐ ┌──────────────┐
|
||||
│ QDRANT │ │ GraphDB │ │ Obsidian │
|
||||
│Vector │ │ (Ontotext) │ │(local sync) │
|
||||
│6333 │ │7200 │ │ │
|
||||
└─────────┘ └────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Voraussetzungen
|
||||
|
||||
### Hardware
|
||||
- **CPU**: Min. 4 Cores (empfohlen 8)
|
||||
- **RAM**: Min. 16 GB (empfohlen 32 GB)
|
||||
- **Storage**: Min. 100 GB SSD (für Datenbanken & Backups)
|
||||
- **Network**: Stabile Verbindung, HTTPS-ready
|
||||
|
||||
### Software
|
||||
- Docker & Docker Compose (Version 20.10+)
|
||||
- Git
|
||||
- Bash
|
||||
- curl/wget
|
||||
- `.env` Datei aus `.env.example` (mit Secrets gefüllt)
|
||||
|
||||
### Accounts & Credentials
|
||||
- Nextcloud Instanz mit Admin-Zugang
|
||||
- OpenAI API-Key (für SAIA/LiteLLM)
|
||||
- Obsidian Vault Zugang lokalem Filesystem
|
||||
|
||||
---
|
||||
|
||||
## 🐳 Schritt 1: Docker Compose Setup
|
||||
|
||||
### 1.1 Repository klonen
|
||||
|
||||
```bash
|
||||
git clone https://github.com/noheton/nexa.git
|
||||
cd nexa/nexa-core
|
||||
```
|
||||
|
||||
### 1.2 .env konfigurieren
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# WICHTIG: Alle Secrets eintragen!
|
||||
# - MEMOS_API_KEY
|
||||
# - SAIA_API_KEY
|
||||
# - NC_APP_PASSWORD
|
||||
# - QDRANT_API_KEY
|
||||
# - GRAPHDB_PASSWORD
|
||||
nano .env
|
||||
```
|
||||
|
||||
### 1.3 docker-compose.yml erstellen
|
||||
|
||||
```bash
|
||||
cat > docker-compose.yml << 'EOF'
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# ===== MEMOS (Interface) =====
|
||||
memos:
|
||||
image: neosmemo/memos:latest
|
||||
container_name: nexa-memos
|
||||
ports:
|
||||
- "5230:5230"
|
||||
volumes:
|
||||
- ./data/memos:/root/.memos
|
||||
environment:
|
||||
MEMOS_PORT: "5230"
|
||||
MEMOS_DRIVER: sqlite
|
||||
MEMOS_DSN: /root/.memos/memos.db
|
||||
networks:
|
||||
- nexa
|
||||
restart: unless-stopped
|
||||
|
||||
# ===== n8n (Workflow Engine) =====
|
||||
n8n:
|
||||
image: n8nio/n8n:latest
|
||||
container_name: nexa-n8n
|
||||
ports:
|
||||
- "5678:5678"
|
||||
volumes:
|
||||
- ./data/n8n:/home/node/.n8n
|
||||
- ./n8n-workflows:/workflows
|
||||
environment:
|
||||
N8N_BASIC_AUTH_ACTIVE: "true"
|
||||
N8N_BASIC_AUTH_USER: "${N8N_USER:-admin}"
|
||||
N8N_BASIC_AUTH_PASSWORD: "${N8N_PASSWORD:-nexa_secure_pass}"
|
||||
N8N_HOST: "${N8N_DOMAIN:-localhost}"
|
||||
N8N_PORT: "5678"
|
||||
N8N_PROTOCOL: https
|
||||
N8N_WEBHOOK_URL: "https://${N8N_DOMAIN:-localhost}/webhook"
|
||||
GENERIC_TIMEZONE: Europe/Berlin
|
||||
DB_TYPE: sqlite
|
||||
DB_SQLITE_PATH: /home/node/.n8n/nexa.db
|
||||
networks:
|
||||
- nexa
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- memos
|
||||
|
||||
# ===== QDRANT (Vector DB) =====
|
||||
qdrant:
|
||||
image: qdrant/qdrant:latest
|
||||
container_name: nexa-qdrant
|
||||
ports:
|
||||
- "6333:6333"
|
||||
volumes:
|
||||
- ./data/qdrant:/qdrant/storage
|
||||
environment:
|
||||
QDRANT_API_KEY: "${QDRANT_API_KEY}"
|
||||
networks:
|
||||
- nexa
|
||||
restart: unless-stopped
|
||||
|
||||
# ===== GraphDB (Ontotext SPARQL) =====
|
||||
graphdb:
|
||||
image: ontotext/graphdb:10-ee
|
||||
container_name: nexa-graphdb
|
||||
ports:
|
||||
- "7200:7200"
|
||||
volumes:
|
||||
- ./data/graphdb:/opt/graphdb/data
|
||||
- ./config/graphdb-init.ttl:/graphdb-import/import.ttl
|
||||
environment:
|
||||
GDB_JAVA_OPTS: "-Xmx8g -Xms4g"
|
||||
GDB_PASSWORD: "${GRAPHDB_PASSWORD}"
|
||||
networks:
|
||||
- nexa
|
||||
restart: unless-stopped
|
||||
|
||||
# ===== SAIA / LiteLLM Proxy (optional - wenn lokal) =====
|
||||
# (Falls SAIA extern gehostet: nicht nötig)
|
||||
|
||||
networks:
|
||||
nexa:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
nexa_memos:
|
||||
nexa_n8n:
|
||||
nexa_qdrant:
|
||||
nexa_graphdb:
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Schritt 2: Individuelle Service-Konfiguration
|
||||
|
||||
### 2.1 MEMOS Initialisierung
|
||||
|
||||
```bash
|
||||
# Nach memos startup (ca. 30s)
|
||||
curl -X POST http://localhost:5230/api/v1/auth/signup \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "nexa",
|
||||
"password": "secure_password"
|
||||
}'
|
||||
|
||||
# API-Token generieren
|
||||
TOKEN=$(curl -X POST http://localhost:5230/api/v1/auth/signin \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"nexa","password":"secure_password"}' \
|
||||
| jq -r '.data.token')
|
||||
|
||||
echo "MEMOS_API_KEY=$TOKEN" >> .env
|
||||
```
|
||||
|
||||
### 2.2 Qdrant Konfiguration
|
||||
|
||||
```bash
|
||||
# Warte auf Qdrant startup
|
||||
sleep 10
|
||||
|
||||
# Erstelle Collection für Nexa
|
||||
curl -X PUT "http://localhost:6333/collections/nexa_knowledge" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "api-key: ${QDRANT_API_KEY}" \
|
||||
-d '{
|
||||
"vectors": {
|
||||
"size": 1536,
|
||||
"distance": "Cosine"
|
||||
},
|
||||
"optimizers_config": {
|
||||
"deleted_threshold": 0.2,
|
||||
"vacuum_threshold": 0.5,
|
||||
"default_segment_number": 5,
|
||||
"max_segment_number": 30,
|
||||
"memmap_threshold": 268435456,
|
||||
"indexing_threshold": 20000,
|
||||
"flush_interval_sec": 10,
|
||||
"max_optimization_threads": 4
|
||||
}
|
||||
}'
|
||||
|
||||
echo "✅ Qdrant Collection erstellt"
|
||||
```
|
||||
|
||||
### 2.3 GraphDB Initialisierung
|
||||
|
||||
```bash
|
||||
# Warte auf GraphDB startup
|
||||
sleep 15
|
||||
|
||||
# Erstelle Repository
|
||||
GRAPHDB_URL="http://localhost:7200"
|
||||
|
||||
curl -X POST "$GRAPHDB_URL/rest/repositories" \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${GRAPHDB_PASSWORD}" \
|
||||
-d '{
|
||||
"id": "nexa_knowledge",
|
||||
"title": "Nexa Knowledge Graph",
|
||||
"type": "free",
|
||||
"params": {
|
||||
"baseURL": {
|
||||
"label": "Base URL",
|
||||
"value": "http://nexa.local/"
|
||||
},
|
||||
"defaultLanguage": {
|
||||
"label": "Default language",
|
||||
"value": "en"
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
echo "✅ GraphDB Repository erstellt"
|
||||
```
|
||||
|
||||
### 2.4 n8n Workflows Import
|
||||
|
||||
```bash
|
||||
# Warte auf n8n startup (ca. 60s)
|
||||
sleep 60
|
||||
|
||||
# Importiere Discovery Workflow
|
||||
curl -X POST http://localhost:5678/api/v1/workflows \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${N8N_PASSWORD}" \
|
||||
-d @n8n-workflows/phase-1/1_1_discovery_workflow.json
|
||||
|
||||
# Importiere Memos Bridge
|
||||
curl -X POST http://localhost:5678/api/v1/workflows \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${N8N_PASSWORD}" \
|
||||
-d @n8n-workflows/phase-1/1_2_memos_bridge_v2.json
|
||||
|
||||
# Importiere Email Butler
|
||||
curl -X POST http://localhost:5678/api/v1/workflows \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${N8N_PASSWORD}" \
|
||||
-d @n8n-workflows/phase-2/2_1_email_butler.json
|
||||
|
||||
echo "✅ n8n Workflows importiert"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Schritt 3: Deployment starten
|
||||
|
||||
### 3.1 Docker Compose Up
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
|
||||
# Logs überwachen
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
### 3.2 Health Checks
|
||||
|
||||
```bash
|
||||
# Health Check Script
|
||||
check_service() {
|
||||
local name=$1
|
||||
local url=$2
|
||||
echo "Checking $name..."
|
||||
if curl -s "$url" > /dev/null; then
|
||||
echo "✅ $name: OK"
|
||||
else
|
||||
echo "❌ $name: FAILED"
|
||||
fi
|
||||
}
|
||||
|
||||
sleep 30
|
||||
|
||||
check_service "Memos" "http://localhost:5230"
|
||||
check_service "n8n" "http://localhost:5678"
|
||||
check_service "Qdrant" "http://localhost:6333/health"
|
||||
check_service "GraphDB" "http://localhost:7200/health"
|
||||
|
||||
echo ""
|
||||
echo "🎯 Service URLs:"
|
||||
echo " - Memos: http://localhost:5230"
|
||||
echo " - n8n: http://localhost:5678"
|
||||
echo " - Qdrant: http://localhost:6333"
|
||||
echo " - GraphDB: http://localhost:7200"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Schritt 4: Konfiguration via Command System
|
||||
|
||||
### 4.1 Discovery-Workflow triggern
|
||||
|
||||
```bash
|
||||
# In Memos Memo erstellen:
|
||||
# #nexa:config
|
||||
|
||||
# Oder via API:
|
||||
curl -X POST http://localhost:5678/api/v1/workflows/run \
|
||||
-H "Content-Type: application/json" \
|
||||
-u "admin:${N8N_PASSWORD}" \
|
||||
-d '{
|
||||
"workflowId": "discovery-workflow-id"
|
||||
}'
|
||||
```
|
||||
|
||||
### 4.2 Automatische Konfiguration laden
|
||||
|
||||
Nach erfolgreichem Discovery werden Nextcloud-Listen-IDs:
|
||||
|
||||
```bash
|
||||
# Es wird automatisch aktualisiert in:
|
||||
# - Qdrant: als Metadata
|
||||
# - n8n: als Umgebungsvariablen
|
||||
# - Memos: als Confirmation-Memo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Schritt 5: Reverse Proxy Setup (Production)
|
||||
|
||||
### 5.1 Nginx Configuration
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/nexa.conf << 'EOF'
|
||||
upstream memos_backend {
|
||||
server localhost:5230;
|
||||
}
|
||||
|
||||
upstream n8n_backend {
|
||||
server localhost:5678;
|
||||
}
|
||||
|
||||
upstream qdrant_backend {
|
||||
server localhost:6333;
|
||||
}
|
||||
|
||||
upstream graphdb_backend {
|
||||
server localhost:7200;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name nexa.yourdomain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/nexa.yourdomain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/nexa.yourdomain.com/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
# MEMOS
|
||||
location / {
|
||||
proxy_pass http://memos_backend;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
|
||||
# n8n
|
||||
location /n8n/ {
|
||||
proxy_pass http://n8n_backend/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# Qdrant (nur intern, wenn nötig)
|
||||
location /qdrant/ {
|
||||
allow 10.0.0.0/8;
|
||||
deny all;
|
||||
proxy_pass http://qdrant_backend/;
|
||||
}
|
||||
|
||||
# GraphDB (nur intern)
|
||||
location /graphdb/ {
|
||||
allow 10.0.0.0/8;
|
||||
deny all;
|
||||
proxy_pass http://graphdb_backend/;
|
||||
}
|
||||
|
||||
# Webhook endpoint für externe Services
|
||||
location /webhook/ {
|
||||
proxy_pass http://n8n_backend/webhook/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name nexa.yourdomain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
EOF
|
||||
|
||||
# Aktivieren
|
||||
sudo ln -s /etc/nginx/sites-available/nexa.conf /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Schritt 6: Monitoring & Backups
|
||||
|
||||
### 6.1 Backup Script
|
||||
|
||||
```bash
|
||||
cat > scripts/backup_nexa.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
BACKUP_DIR="./backups/$(date +%Y%m%d_%H%M%S)"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
echo "🔄 Backing up Nexa..."
|
||||
|
||||
# Backup Datenbanken
|
||||
docker-compose exec -T qdrant tar czf - /qdrant/storage > "$BACKUP_DIR/qdrant.tar.gz"
|
||||
docker-compose exec -T graphdb tar czf - /opt/graphdb/data > "$BACKUP_DIR/graphdb.tar.gz"
|
||||
docker-compose exec -T memos tar czf - /root/.memos > "$BACKUP_DIR/memos.tar.gz"
|
||||
docker-compose exec -T n8n tar czf - /home/node/.n8n > "$BACKUP_DIR/n8n.tar.gz"
|
||||
|
||||
# Backup Configs
|
||||
cp .env "$BACKUP_DIR/.env.backup"
|
||||
cp docker-compose.yml "$BACKUP_DIR/docker-compose.yml.backup"
|
||||
|
||||
echo "✅ Backup completed: $BACKUP_DIR"
|
||||
|
||||
# Optional: zu S3 hochladen
|
||||
# aws s3 sync "$BACKUP_DIR" s3://nexa-backups/$(date +%Y%m%d)/
|
||||
EOF
|
||||
|
||||
chmod +x scripts/backup_nexa.sh
|
||||
|
||||
# Tägliches Backup (cron)
|
||||
echo "0 2 * * * /path/to/nexa/scripts/backup_nexa.sh" | crontab -
|
||||
```
|
||||
|
||||
### 6.2 Health Check Monitoring
|
||||
|
||||
```bash
|
||||
cat > scripts/monitor_nexa.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# Monitore Service Status
|
||||
SERVICES=("memos" "n8n" "qdrant" "graphdb")
|
||||
|
||||
for service in "${SERVICES[@]}"; do
|
||||
if docker-compose ps $service | grep -q "Up"; then
|
||||
echo "✅ $service: Running"
|
||||
else
|
||||
echo "❌ $service: DOWN"
|
||||
# Restart bei Fehler
|
||||
docker-compose restart $service
|
||||
fi
|
||||
done
|
||||
EOF
|
||||
|
||||
chmod +x scripts/monitor_nexa.sh
|
||||
|
||||
# Alle 5 Minuten
|
||||
echo "*/5 * * * * /path/to/nexa/scripts/monitor_nexa.sh" | crontab -
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Schritt 7: Validation & Testing
|
||||
|
||||
### 7.1 End-to-End Test
|
||||
|
||||
```bash
|
||||
cat > scripts/test_nexa.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
echo "🧪 Testing Nexa Installation..."
|
||||
|
||||
# Test 1: Memos API
|
||||
echo "Test 1: Memos API"
|
||||
if curl -s http://localhost:5230/api/v1/auth/status | jq . > /dev/null 2>&1; then
|
||||
echo "✅ Memos: OK"
|
||||
else
|
||||
echo "❌ Memos: FAILED"
|
||||
fi
|
||||
|
||||
# Test 2: n8n API
|
||||
echo "Test 2: n8n API"
|
||||
if curl -s -u "admin:${N8N_PASSWORD}" http://localhost:5678/api/v1/workflows | jq . > /dev/null 2>&1; then
|
||||
echo "✅ n8n: OK"
|
||||
else
|
||||
echo "❌ n8n: FAILED"
|
||||
fi
|
||||
|
||||
# Test 3: Qdrant Collection
|
||||
echo "Test 3: Qdrant Collection"
|
||||
if curl -s -H "api-key: ${QDRANT_API_KEY}" http://localhost:6333/collections/nexa_knowledge | jq . > /dev/null 2>&1; then
|
||||
echo "✅ Qdrant: OK"
|
||||
else
|
||||
echo "❌ Qdrant: FAILED"
|
||||
fi
|
||||
|
||||
# Test 4: GraphDB Repository
|
||||
echo "Test 4: GraphDB Repository"
|
||||
if curl -s -u "admin:${GRAPHDB_PASSWORD}" http://localhost:7200/repositories | jq . > /dev/null 2>&1; then
|
||||
echo "✅ GraphDB: OK"
|
||||
else
|
||||
echo "❌ GraphDB: FAILED"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🎯 Create Test Memo:"
|
||||
MEMO=$(curl -s -X POST http://localhost:5230/api/v1/memos \
|
||||
-H "Authorization: Bearer ${MEMOS_API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"content": "Test memo - #nexa:config"}' | jq -r '.id')
|
||||
|
||||
echo "✅ Test Memo created: $MEMO"
|
||||
echo "Check Memos UI to verify webhook triggers Discovery"
|
||||
EOF
|
||||
|
||||
chmod +x scripts/test_nexa.sh
|
||||
./scripts/test_nexa.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🆘 Troubleshooting
|
||||
|
||||
### Problem: Memos kann sich nicht mit n8n verbinden
|
||||
|
||||
```bash
|
||||
# Überprüfe n8n Webhook URL in Memos config
|
||||
curl http://localhost:5678/webhook/memos
|
||||
|
||||
# Falls 404: Workflow ist nicht aktiviert/deployed
|
||||
docker-compose logs n8n | grep webhook
|
||||
```
|
||||
|
||||
### Problem: GraphDB startet nicht
|
||||
|
||||
```bash
|
||||
# Memory-Limit erhöhen
|
||||
docker-compose exec graphdb -e "GDB_JAVA_OPTS=-Xmx16g -Xms8g" restart
|
||||
|
||||
# Logs checken
|
||||
docker-compose logs graphdb
|
||||
```
|
||||
|
||||
### Problem: Qdrant Collection leer
|
||||
|
||||
```bash
|
||||
# Überprüfe ob Memos Bridge Workflow läuft
|
||||
docker-compose logs n8n | grep "memos_bridge"
|
||||
|
||||
# Manuell test
|
||||
curl -X POST http://localhost:5230/api/v1/memos \
|
||||
-H "Authorization: Bearer ${MEMOS_API_KEY}" \
|
||||
-d '{"content": "- [ ] Test task #nexa"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Next Steps
|
||||
|
||||
1. ✅ **Phase 1 deployt**: Memos Bridge & Discovery laufen
|
||||
2. ⏳ **Phase 2 aktivieren**: Email Butler (wenn Nextcloud Mail konfiguriert)
|
||||
3. ⏳ **Phase 3 setup**: Qdrant Embedding Pipeline
|
||||
4. ⏳ **Phase 4 integration**: GraphRAG Queries testen
|
||||
5. ⏳ **Phase 5**: Home Assistant Voice Integration
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support & Debugging
|
||||
|
||||
```bash
|
||||
# Alle Logs in eine Datei sammeln
|
||||
docker-compose logs > deployment_logs.txt
|
||||
|
||||
# Spezifischer Service
|
||||
docker-compose logs n8n --tail 100
|
||||
|
||||
# Wiederherstellung aus Backup
|
||||
./scripts/restore_nexa.sh backup/2024-01-15_120000/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Deployment abgeschlossen! Nexa ist nun betriebsbereit.** 🚀
|
||||
@@ -1,27 +0,0 @@
|
||||
# NEXA: Implementierungs-Fahrplan 🚀
|
||||
|
||||
Dieser Plan beschreibt die schrittweise Aktivierung des Nervensystems.
|
||||
|
||||
## Phase 1: Die Wirbelsäule (Basis-Konnektivität)
|
||||
- [ ] **1.1 Memos-n8n Bridge:** Webhook-Anbindung und Filter-Logik.
|
||||
- [ ] **1.2 SAIA-Integration:** LiteLLM Proxy in n8n einbinden (Chat-Funktion via Kommentare).
|
||||
- [ ] **1.3 Git-Sync:** Automatisches Backup der n8n-Workflows in dieses Repo.
|
||||
|
||||
## Phase 2: Die Sinnesorgane (Input-Kanäle)
|
||||
- [ ] **2.1 Email-Butler:** Automatisierte Filterung und Zusammenfassung der ~20 täglichen Mails.
|
||||
- [ ] **2.2 RSS Morning Digest:** Täglich kuratierte News-Zusammenfassung in Memos.
|
||||
- [ ] **2.3 Bluesky-Antenne:** Speichern von gelikten Posts als Wissens-Schnipsel.
|
||||
|
||||
## Phase 3: Das Gedächtnis (Qdrant & RAG)
|
||||
- [ ] **3.1 Embedding-Pipeline:** Automatische Vektorisierung von Memos & Obsidian.
|
||||
- [ ] **3.2 Context-Retrieval:** Nexa nutzt Qdrant-Wissen für Antworten (#ask).
|
||||
- [ ] **3.3 S3-Langzeitarchiv:** Backup der Qdrant-Snapshots auf den S3-Server.
|
||||
|
||||
## Phase 4: Die Motorik (Organisation & Handeln)
|
||||
- [ ] **4.1 Nextcloud Task-Sync:** Bidirektionaler Status-Abgleich (Memos <-> NC Tasks).
|
||||
- [ ] **4.2 Timeboxing-Agent:** Intelligente Kalender-Slot-Vorschläge basierend auf Tasks.
|
||||
- [ ] **4.3 Karakeep-Kuration:** Automatischer Review-Prozess für gespeicherte Links.
|
||||
|
||||
## Phase 5: Alltags-Integration (Feinschliff)
|
||||
- [ ] **5.1 Home Assistant Voice:** Nexa als Wake-Word Integration.
|
||||
- [ ] **5.2 System-Monitoring:** Alarme von Proxmox/Backrest direkt in den Memos-System-Feed.
|
||||
+14
-12
@@ -1,15 +1,17 @@
|
||||
# NEXA 🧠
|
||||
**The Neural Nexus for Information & Automation**
|
||||
# nexa-core
|
||||
|
||||
Nexa ist das zentrale Nervensystem meines IT-Setups.
|
||||
Runtime artifacts for Nexa: n8n workflows, configuration, AI prompts, scripts.
|
||||
|
||||
## 🏗 Architektur
|
||||
- **Interface:** Memos
|
||||
- **Logic:** n8n
|
||||
- **Memory:** Qdrant & Obsidian
|
||||
- **Intelligence:** SAIA (via LiteLLM)
|
||||
📖 Documentation lives one level up in [`../docs/`](../docs/index.md).
|
||||
|
||||
## 📁 Struktur
|
||||
- `n8n-workflows/`: JSON-Exporte der Gehirn-Logik.
|
||||
- `ai-prompts/`: System-Prompts für Nexa.
|
||||
- `config/`: Schemata für Qdrant und API-Mappings.
|
||||
## Layout
|
||||
|
||||
- `n8n-workflows/` — exported workflows (per phase). Imported into the running n8n.
|
||||
- `ai-prompts/` — system prompts for SAIA / LiteLLM.
|
||||
- `config/` — runtime config (`agents.yaml`, `infra_manifest.yaml`, `qdrant_schema.json`).
|
||||
- `scripts/` — automation helpers (workflow backup, etc.).
|
||||
- `.env.example` — bootstrap secrets only; runtime config lives in Qdrant `_config` namespace.
|
||||
|
||||
## Quickstart
|
||||
|
||||
See [`../docs/09-deployment.md`](../docs/09-deployment.md).
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# Nexa Klassifizierungs-Logik
|
||||
|
||||
Dieser Fragebogen dient der Feinabstimmung von SAIA, um Tasks korrekt zu routen.
|
||||
|
||||
### A. Schlüsselwörter & Projekte (Arbeit)
|
||||
*Welche Begriffe triggern zwingend die Work-Liste?*
|
||||
- [ ] Projekt-Namen (z.B. "Nexa-Core", "Infrastruktur-Audit")
|
||||
- [ ] Rollenspezifische Begriffe ("Meeting", "Report", "Deadline")
|
||||
- [ ] Tools, die nur im Job vorkommen.
|
||||
|
||||
### B. Ausschlusskriterien (Privat)
|
||||
*Was darf niemals in die Work-Liste?*
|
||||
- [ ] Lebensmittel, Rezepte, Haushalt.
|
||||
- [ ] Bluesky-Input (sofern nicht explizit als Recherche markiert).
|
||||
- [ ] Finanz-Mails (Privat-Bank).
|
||||
|
||||
### C. Umgang mit Unschärfe
|
||||
- **Default:** Wenn < 70% Sicherheit -> `Personal`.
|
||||
- **Interaktion:** Nexa erstellt einen Kommentar: "In welche Liste soll das? [W/P]".
|
||||
@@ -1,16 +0,0 @@
|
||||
# Spezifikation: Phase 2 - Task-Router
|
||||
|
||||
## 1. Trigger
|
||||
* **Typ:** Webhook (Memos)
|
||||
* **Filter:** `payload.content` enthält `- [ ]` ODER `#todo`.
|
||||
|
||||
## 2. Intelligence Node (SAIA)
|
||||
* **Prompt:** "Analysiere folgende Notiz. Gib als JSON zurück: { "context": "work" | "personal", "summary": "string", "urgency": 1-5 }."
|
||||
* **Kontext-Zufuhr:** Lade die letzten 5 Obsidian-Projekttitel aus Qdrant als Referenz hoch.
|
||||
|
||||
## 3. Switch Node
|
||||
* **Route 1:** Context == "work" -> Nextcloud Create Task (List ID: Work).
|
||||
* **Route 2:** Context == "personal" -> Nextcloud Create Task (List ID: Personal).
|
||||
|
||||
## 4. Feedback Loop
|
||||
* Poste die Task-ID und den gewählten Kontext als Kommentar unter das Original-Memo.
|
||||
@@ -1,131 +0,0 @@
|
||||
# Nexa Command System - #nexa:command
|
||||
|
||||
Nexa "hört" auf folgende Kommandos in Memos-Kommentaren oder als Memo-Inhalt mit Hashtag:
|
||||
|
||||
## 🔧 Konfigurations-Kommandos
|
||||
|
||||
### #nexa:config
|
||||
- **Beschreibung**: Triggert Autodiscovery aller Services (Nextcloud, Qdrant, etc.)
|
||||
- **Antwort**: Postet Report mit gefundenen Konfigurationen
|
||||
- **Speichert**: Settings in DynoDB / Qdrant Metadata (nicht in .env)
|
||||
|
||||
```
|
||||
#nexa:config
|
||||
```
|
||||
|
||||
**Beispiel-Response:**
|
||||
```
|
||||
✅ Autodiscovery abgeschlossen:
|
||||
- Nextcloud Listen: Work (id=123), Personal (id=456), Shopping (id=789), Wishes (id=1011)
|
||||
- Qdrant Collection: nexa_knowledge (1536 dims, Cosine)
|
||||
- Nextcloud Mail: 3 Accounts erkannt (Office 365, Gmail, Privat)
|
||||
```
|
||||
|
||||
### #nexa:status
|
||||
- **Beschreibung**: Zeigt den aktuellen System-Status
|
||||
- **Antwort**: Uptime, verbundene Systeme, Memory-Stats
|
||||
|
||||
```
|
||||
#nexa:status
|
||||
```
|
||||
|
||||
### #nexa:sync-obsidian
|
||||
- **Beschreibung**: Triggert sofortige Synchronisierung mit Obsidian Vault
|
||||
- **Optional Parameter**: `--vault=/path/to/vault` oder `--force` für Neuindexierung
|
||||
|
||||
```
|
||||
#nexa:sync-obsidian --force
|
||||
```
|
||||
|
||||
## 📊 Memory & RAG Kommandos
|
||||
|
||||
### #nexa:ask [question]
|
||||
- **Beschreibung**: Semantische Suche in Qdrant (RAG) basierend auf Obsidian + Memos
|
||||
- **Antwort**: Top-3 Treffer mit Quellen
|
||||
|
||||
```
|
||||
#nexa:ask Wie implementierten wir das JWT-Middleware-Pattern?
|
||||
```
|
||||
|
||||
### #nexa:learn [topic]
|
||||
- **Beschreibung**: Explizit neue Information in Qdrant speichern (mit Tags)
|
||||
- **Optional**: `--tag=architecture` `--source=obsidian/notes/arch.md`
|
||||
|
||||
```
|
||||
#nexa:learn Das Routing-Schema unterscheidet Work vs. Personal via SAIA-Kontext-Analyse --tag=architecture
|
||||
```
|
||||
|
||||
## 🎯 Workflow-Kommandos
|
||||
|
||||
### #nexa:route-test [text]
|
||||
- **Beschreibung**: Testet die Klassifizierung (Work/Personal) ohne Task zu erstellen
|
||||
|
||||
```
|
||||
#nexa:route-test Muss morgen die Präsentation für den Client fertigstellen
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```
|
||||
💬 Klassifizierung (Test-Mode):
|
||||
- Kontext: WORK
|
||||
- Vertrauen: 0.95
|
||||
- Begründung: "Client-Präsentation → professioneller Kontext"
|
||||
```
|
||||
|
||||
### #nexa:email-digest
|
||||
- **Beschreibung**: Triggert sofortige Email-Zusammenfassung (sonst tägl. 7 Uhr)
|
||||
|
||||
```
|
||||
#nexa:email-digest
|
||||
```
|
||||
|
||||
## 🔐 Admin-Kommandos
|
||||
|
||||
### #nexa:reset-config
|
||||
- **Beschreibung**: Löscht gespeicherte Konfiguration, triggert neuen Autodiscovery
|
||||
- **Warnung**: Alle benutzerdefinierten Settings werden vergessen
|
||||
|
||||
```
|
||||
#nexa:reset-config
|
||||
```
|
||||
|
||||
### #nexa:export-state
|
||||
- **Beschreibung**: Exportiert aktuellen State als JSON (für Backups)
|
||||
|
||||
```
|
||||
#nexa:export-state
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Implementierung in n8n
|
||||
|
||||
Ein **Command Parser** läuft immer mit:
|
||||
|
||||
1. **Memos Webhook** empfängt alle Memos
|
||||
2. **Regex Check**: Sucht nach `#nexa:command`
|
||||
3. **Router**: Versendet an entsprechenden n8n-Workflow
|
||||
4. **Antwort**: Postet Reply als Kommentar/Edit
|
||||
|
||||
**Command Parser Regex:**
|
||||
```
|
||||
^#nexa:(\w+)(?:\s+([^\n]*?))?(?:$|\s*--)
|
||||
```
|
||||
|
||||
Extrahiert: `[command, parameters]`
|
||||
|
||||
---
|
||||
|
||||
## 🎛️ Dynamische Konfigurationsspeicherung
|
||||
|
||||
Statt .env zu editieren:
|
||||
|
||||
1. **First Run**: `#nexa:config` speichert zu lokalen Metadata
|
||||
2. **Speich-Ziel**:
|
||||
- **Primary**: Qdrant Metadata (als `_config` Namespace)
|
||||
- **Fallback**: `nexa-core/config/runtime_config.json` (gitignored)
|
||||
- **Notfall**: .env (nur initial)
|
||||
|
||||
3. **Reload-Logik**: Bei jedem Workflow-Start werden Settings aus Qdrant geladen
|
||||
|
||||
Das macht Nexa vollständig selbstständig nach dem initialem Setup!
|
||||
@@ -1,273 +0,0 @@
|
||||
# GraphRAG für Nexa - Strukturelles Wissen & Beziehungen
|
||||
|
||||
## 🧠 Zwei-Säulen-Memory-Architektur
|
||||
|
||||
Nexa nutzt zwei komplementäre Speicher für vollständiges Verständnis:
|
||||
|
||||
### Säule 1: Qdrant (Vector DB) - Semantische Ähnlichkeit
|
||||
- **Frage**: "Was ist ähnlich, was ist relevant?"
|
||||
- **Speichert**: Embeddings von Memos, Obsidian-Notes, E-Mail-Digests
|
||||
- **Suche**: Cosine Similarity über 1536-dimensionale Vektoren
|
||||
- **Antwort**: Top-k semantisch ähnliche Dokumente (RAG)
|
||||
|
||||
**Beispiel:**
|
||||
```
|
||||
Frage: "Wie war die JWT-Implementation in unserem letzten Projekt?"
|
||||
→ Qdrant findet: 10 ähnliche Snippets → Prompt-Context
|
||||
```
|
||||
|
||||
### Säule 2: Neo4j (Graph DB) - Strukturelle Beziehungen
|
||||
- **Frage**: "Wer ist beteiligt? Was hängt davon ab? Wie ist es organisiert?"
|
||||
- **Speichert**:
|
||||
- **Knoten (Nodes)**: Projects, Tasks, People, Technologies, Dates
|
||||
- **Kanten (Relationships)**: `USES`, `OWNS`, `DEPENDS_ON`, `MENTIONS`, `CREATED_BY`
|
||||
- **Suche**: Cypher-Queries über Netzwerk-Topologie
|
||||
- **Antwort**: Pfade, zentrale Knoten, Abhängigkeitsanalyse
|
||||
|
||||
**Beispiel:**
|
||||
```cypher
|
||||
MATCH (tech:Technology)-[USES*]->*(service:Service),
|
||||
(tech)-[:MENTIONED_IN]->(task:Task)
|
||||
WHERE tech.name = "JWT" AND task.status = "DONE"
|
||||
RETURN tech, service, task
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Neo4j Schema für Nexa
|
||||
|
||||
### Node-Typen
|
||||
|
||||
```cypher
|
||||
(Project {name, startDate, status, priority})
|
||||
(Task {title, description, status, urgency: 1-5, context: "work"|"personal"})
|
||||
(Person {name, role, email})
|
||||
(Technology {name, category: "framework"|"language"|"tool"})
|
||||
(Topic {name, domain})
|
||||
(File {path, type, lastModified})
|
||||
(Note {id, content_hash, created_at})
|
||||
```
|
||||
|
||||
### Relationship-Typen
|
||||
|
||||
| Beziehung | Von | Zu | Beschreibung |
|
||||
|-----------|-----|-----------|-------------|
|
||||
| `OWNS` | Person | Task/Project | Wer ist verantwortlich |
|
||||
| `USES` | Task/Project | Technology | Welche Tech wird verwendet |
|
||||
| `DEPENDS_ON` | Task/Project | Task/Project | Hängt davon ab |
|
||||
| `CREATED_BY` | Note | Person | Autor einer Notiz |
|
||||
| `MENTIONS` | Note/Task | Topic/Technology | Verweist auf |
|
||||
| `RELATED_TO` | Task | Task | Zusammenhängend |
|
||||
| `CHILD_OF` | Task | Project | Task gehört zu Project |
|
||||
| `SCHEDULED_FOR` | Task | Date | Zeitliche Zuordnung |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Synchronisierungs-Flows
|
||||
|
||||
### 1. **Memos → Neo4j** (automatisch beim Erstellen)
|
||||
|
||||
Wenn ein Memo mit `- [ ]` erstellt wird:
|
||||
|
||||
```
|
||||
Memo-Content: "Muss JWT-Middleware für Auth-Service refaktorieren"
|
||||
↓
|
||||
SAIA extrahiert Entitäten:
|
||||
- Technologie: "JWT-Middleware", "Auth-Service"
|
||||
- Kontext: "work"
|
||||
- Urgenz: 3
|
||||
↓
|
||||
Erstelle in Neo4j:
|
||||
- Task node (title="JWT-Middleware refaktorieren")
|
||||
- Technology nodes: JWT, Auth-Service
|
||||
- Relationships: Task -[USES]-> JWT, Task -[USES]-> Auth-Service
|
||||
- Task -[CREATED_BY]-> Me (Person node)
|
||||
```
|
||||
|
||||
### 2. **Obsidian → Neo4j** (#nexa:sync-obsidian)
|
||||
|
||||
Beim Sync von Obsidian-Vault:
|
||||
|
||||
```
|
||||
File: obsidian/projects/nexa-deployment.md
|
||||
↓
|
||||
Header Struktur wird zu Graph:
|
||||
- Project "Nexa Deployment"
|
||||
- Technologies: Docker, n8n, Nextcloud
|
||||
- Dependencies: "requires infrastructure setup"
|
||||
↓
|
||||
Erstelle:
|
||||
- Project nodes mit Metadata
|
||||
- Hierarchie: Project -[CONTAINS]-> Task -[USES]-> Technology
|
||||
```
|
||||
|
||||
### 3. **Nextcloud Tasks → Neo4j** (bidirektional)
|
||||
|
||||
Wenn Task in Nextcloud erstellt/gelöcht:
|
||||
|
||||
```
|
||||
Nextcloud Task: "Review JWT implementation" (in Work-List)
|
||||
↓
|
||||
n8n Trigger erkennt Änderung
|
||||
↓
|
||||
Update Neo4j:
|
||||
- Task node status = "active"
|
||||
- Task -[DEPENDS_ON]-> related Task (falls Beziehung existiert)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🤖 GraphRAG Queries - Praktische Anwendungen
|
||||
|
||||
### Query 1: "Zeige alle offenen Tasks, die JWT betreffen"
|
||||
|
||||
```cypher
|
||||
MATCH (tech:Technology {name:"JWT"}),
|
||||
(tech)-[:MENTIONED_IN|USES]-(task:Task),
|
||||
(task)-[:CHILD_OF]->(project:Project)
|
||||
WHERE task.status IN ["NEEDS-ACTION", "IN-PROGRESS"]
|
||||
RETURN project.name, task.title, task.urgency
|
||||
ORDER BY task.urgency DESC
|
||||
```
|
||||
|
||||
### Query 2: "Von welchen Tasks/Projects hängt Auth-Service ab?"
|
||||
|
||||
```cypher
|
||||
MATCH path = (dependent)-[:DEPENDS_ON*]->(service:Technology {name:"Auth-Service"})
|
||||
RETURN [x IN nodes(path) | x.name], length(path)
|
||||
ORDER BY length(path) ASC
|
||||
```
|
||||
|
||||
### Query 3: "Wer arbeitet an diesem Projekt und auf welchen Technologien?"
|
||||
|
||||
```cypher
|
||||
MATCH (person:Person)-[:OWNS]->(task:Task)-[:CHILD_OF]->(project:Project {name:"Nexa"}),
|
||||
(task)-[:USES]->(tech:Technology)
|
||||
RETURN person.name, collect(task.title), collect(tech.name)
|
||||
```
|
||||
|
||||
### Query 4: "Was ist seit gestern neu an Technologien/Themen gelernt?"
|
||||
|
||||
```cypher
|
||||
MATCH (note:Note)-[:MENTIONS]->(topic:Topic)
|
||||
WHERE note.created_at > datetime.now() - duration('P1D')
|
||||
RETURN DISTINCT topic.name, count(note) as mentions
|
||||
ORDER BY mentions DESC
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 GraphRAG-Enhanced Answer Generation
|
||||
|
||||
Wenn Nutzer `#nexa:ask` fragt:
|
||||
|
||||
```
|
||||
#nexa:ask Wie stehen die JWT-Tasks zur Deadline?
|
||||
↓
|
||||
┌─────────────┴──────────────┐
|
||||
↓ ↓
|
||||
[Qdrant] [Neo4j]
|
||||
Semantic Structural
|
||||
Search Search
|
||||
↓ ↓
|
||||
Top-3 Notes (JWT)-[DEPENDS_ON]
|
||||
mit ähnlichem → Connected Tasks
|
||||
Kontext → Critical Path
|
||||
↓ ↓
|
||||
Combine: Merge + Rank
|
||||
↓
|
||||
System Prompt (SAIA):
|
||||
"Basierend auf diesem Wissen und diesen Abhängigkeiten, beantworte:"
|
||||
↓
|
||||
Response mit:
|
||||
- Semantisch relevanter Information (Qdrant)
|
||||
- Strukturellem Kontext (Neo4j)
|
||||
- Abhängigkeitsanalyse
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ n8n Integration (Phase 3)
|
||||
|
||||
### Workflow: Graph-Sync Trigger
|
||||
|
||||
```
|
||||
[Memos Webhook]
|
||||
↓
|
||||
[Parse Content]
|
||||
↓
|
||||
[SAIA: Extract Entities]
|
||||
├→ Tasks, Projects, Technologies, People
|
||||
└→ Relationships (uses, depends_on, mentions)
|
||||
↓
|
||||
[Neo4j: Create/Update Nodes & Relationships]
|
||||
↓
|
||||
[Index in Qdrant Metadata: Add graph_node_id]
|
||||
```
|
||||
|
||||
### Workflow: Question Router
|
||||
|
||||
```
|
||||
[#nexa:ask Query]
|
||||
↓
|
||||
[Parallel Search]
|
||||
├→ [Qdrant: Vector Similarity]
|
||||
├→ [Neo4j: Graph Query (auto-generated Cypher)]
|
||||
└→ [Rank & Merge Results]
|
||||
↓
|
||||
[SAIA: Generate Answer with Context]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Commands für Graph-Management
|
||||
|
||||
### #nexa:graph-status
|
||||
Zeigt Statistiken der Graph-DB
|
||||
```
|
||||
#nexa:graph-status
|
||||
```
|
||||
|
||||
Response:
|
||||
```
|
||||
📊 Neo4j Graph Status:
|
||||
- Nodes: 342 (Tasks: 145, Projects: 12, Technologies: 52, Notes: 133)
|
||||
- Relationships: 1,247
|
||||
- Density: 0.34
|
||||
- Most Connected: "JWT-Middleware" (27 connections)
|
||||
```
|
||||
|
||||
### #nexa:graph-trace [entity]
|
||||
Zeigt alle Verbindungen für eine Entität
|
||||
```
|
||||
#nexa:graph-trace JWT-Middleware
|
||||
```
|
||||
|
||||
### #nexa:graph-rebuild
|
||||
Rekonstruiert Graph aus Obsidian + Memos (einmalig, danach inkrementell)
|
||||
```
|
||||
#nexa:graph-rebuild --force
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Phase 3 Roadmap (Graph Integration)
|
||||
|
||||
- [ ] **3.1 Neo4j Setup**: Collection, Constraints, Indexes
|
||||
- [ ] **3.2 Graph-Sync Workflow**: Automatische Entity Extraction
|
||||
- [ ] **3.3 GraphRAG Pipeline**: Kombinierte Qdrant + Neo4j Queries
|
||||
- [ ] **3.4 Dependency Tracker**: Warnt vor zirkulären Dependencies
|
||||
- [ ] **3.5 Critical Path Analysis**: Berechnet längsten Weg im Graph
|
||||
|
||||
---
|
||||
|
||||
## 💡 Warum zwei DBs?
|
||||
|
||||
| Szenario | Qdrant | Neo4j | Kombi |
|
||||
|----------|--------|-------|-------|
|
||||
| "Welche Note war ähnlich?" | ✅ Best | ❌ | Qdrant |
|
||||
| "Welche Tasks blockieren diesen Task?" | ❌ | ✅ Best | Neo4j |
|
||||
| "Erkläre mir dieses Projekt umfassend" | ✅ Context | ✅ Structure | **Beide!** |
|
||||
| "Finde alle JWT-bezogenen offenen Work" | ✅ Semantic | ✅ Crisp | **Beide!** |
|
||||
|
||||
Kombiniert: **Vollständiges Verständnis** statt nur Suchindex oder nur Struktur.
|
||||
@@ -1,79 +0,0 @@
|
||||
# 🔗 Nexa Integrations-Matrix (V2)
|
||||
|
||||
Diese Matrix definiert die logische Trennung zwischen privaten und beruflichen Datenströmen sowie die Anbindung der Infrastruktur.
|
||||
|
||||
---
|
||||
|
||||
## 1. Die Dualität: Arbeit vs. Privat
|
||||
Nexa muss strikt zwischen zwei Kontexten unterscheiden, da die Datenquellen variieren:
|
||||
|
||||
### A. Bereich: ARBEIT (Work)
|
||||
* **Sichtbarkeit:** Eingeschränkt (kein Zugriff auf Arbeits-E-Mails oder Firmen-Server).
|
||||
* **Datenquellen:**
|
||||
* Separate Nextcloud Task-Liste (`Work_Tasks`).
|
||||
* Separater Nextcloud Kalender (`Work_Calendar`).
|
||||
* Memos mit Tag `#work` oder semantischer Erkennung.
|
||||
* **Nexa-Fokus:** Timeblocking, Fokus-Zeiten, Vorbereitung von Meetings basierend auf Obsidian-Notizen.
|
||||
|
||||
### B. Bereich: PRIVAT (Personal)
|
||||
* **Sichtbarkeit:** Vollständig.
|
||||
* **Datenquellen:**
|
||||
* Nextcloud Task-Liste (`Personal_Tasks`).
|
||||
* Haupt-Kalender.
|
||||
* E-Mails (IMAP - 20 Mails/Tag).
|
||||
* Bluesky, RSS, Karakeep.
|
||||
* **Nexa-Fokus:** Automatisierung des Alltags, Kuratierung von Wissen, E-Mail-Management.
|
||||
|
||||
### Karakeep & Shopping-Logik
|
||||
* **Schnittstelle:** Karakeep API / RSS.
|
||||
* **Listen-Routing:**
|
||||
* **Einkaufsliste:** Automatischer Sync für Items mit hoher Frequenz (Lebensmittel, Drogerie).
|
||||
* **Wunschliste:** Speicherort für "Entdeckungen". Nexa fügt bei Wunschlisten-Items automatisch den aktuellen Preis und eine kurze SAIA-Zusammenfassung hinzu ("Warum du das speichern wolltest").
|
||||
* **Review-Cycle:** Einmal im Monat fragt Nexa bei Wunschlisten-Items nach: "Immer noch interessiert oder kann das weg?"
|
||||
|
||||
---
|
||||
|
||||
## 2. Kern-Infrastruktur (The Brain & Spine)
|
||||
|
||||
| Komponente | Rolle im System |
|
||||
| :--- | :--- |
|
||||
| **Memos** | Zentraler Input (Drafts, Ideen, schnelle Tasks). Schnittstelle für Nexa-Antworten. |
|
||||
| **n8n** | Logik-Engine. Führt die Klassifizierung Arbeit vs. Privat durch. |
|
||||
| **SAIA (LiteLLM)** | Entscheidet anhand des Inhalts, in welchen Kalender/Liste ein Eintrag gehört. |
|
||||
| **Qdrant** | Langzeitgedächtnis. Speichert Projektwissen (Work) und privates Wissen getrennt. |
|
||||
| **Arcane** | Verwaltung der Docker-Container (n8n, Qdrant, Memos). |
|
||||
|
||||
---
|
||||
|
||||
## 3. Spezifische Datenflüsse & Logik
|
||||
|
||||
### Task-Routing (Das Gehirn-Filter)
|
||||
1. **Input:** Neues Memo oder Spracheingabe.
|
||||
2. **Analyse:** SAIA prüft: "Ist das Business oder Privat?"
|
||||
3. **Routing:** * `Arbeits-Kontext` -> Eintrag in `Work_Tasks`.
|
||||
* `Privat-Kontext` -> Eintrag in `Personal_Tasks`.
|
||||
4. **Timeboxing:** Nexa scannt den `Work_Calendar` auf Lücken und schlägt Slots für `Work_Tasks` vor.
|
||||
|
||||
### E-Mail Management (Nur Privat)
|
||||
* Nexa filtert die 20 täglichen Privat-Mails.
|
||||
* Wichtige private Termine werden in den privaten Kalender extrahiert.
|
||||
* Newsletter landen als Zusammenfassung in Memos.
|
||||
|
||||
### Wissens-Management (Obsidian & Qdrant)
|
||||
* Obsidian-Notizen (Arbeit & Privat) werden in Qdrant indiziert.
|
||||
* Nexa nutzt dieses Wissen, um Arbeits-Tasks besser zu beschreiben, auch wenn sie keinen Zugriff auf die Arbeits-E-Mails hat.
|
||||
|
||||
---
|
||||
|
||||
## 4. Monitoring & Hardware (Home Assistant)
|
||||
|
||||
| Dienst | Reiz-Typ | Nexa-Reaktion |
|
||||
| :--- | :--- | :--- |
|
||||
| **Home Assistant** | Voice / Sensorik | Nexa nimmt Sprachbefehle entgegen und meldet Alarme (Haus). |
|
||||
| **Proxmox** | Stabilität | Meldung an Nexa bei Hardware-Problemen. |
|
||||
| **S3 Server** | Archiv | Langzeit-Backups der Wissensdatenbank. |
|
||||
|
||||
---
|
||||
|
||||
## 5. Ergänzungen für das Setup (Vorschlag)
|
||||
* **Zwei-Faktor-Klassifizierung:** Einführung von expliziten Tags (`#w` für Work, `#p` für Privat) für Grenzfälle, in denen SAIA den Kontext nicht eindeutig bestimmen kann.
|
||||
@@ -1,80 +0,0 @@
|
||||
📑 Projekt Nexa: Scoping & Vision
|
||||
1. Vision & Zielsetzung
|
||||
Nexa ist als "Zentrales Nervensystem" konzipiert. Das Ziel ist die Schaffung einer intelligenten Middleware zwischen Input-Quellen (Memos, E-Mail, RSS), Wissensspeichern (Obsidian, Qdrant) und Organisations-Tools (Nextcloud Calendar/Tasks).
|
||||
|
||||
Kernziele:
|
||||
Kognitive Entlastung: Nexa sortiert, filtert und schlägt vor, anstatt nur zu speichern.
|
||||
|
||||
Kontext-Trennung: Saubere, KI-gestützte Unterscheidung zwischen Privat und Arbeit.
|
||||
|
||||
Single Point of Interaction: Memos fungiert als primäre Schnittstelle ("The Voice & Ear").
|
||||
|
||||
Wissens-Synergie: Verknüpfung von flüchtigen Memos mit tiefem Wissen in Obsidian via semantischer Suche.
|
||||
|
||||
2. Abgrenzung (Scope)
|
||||
Um die Komplexität beherrschbar zu halten, wird das Projekt wie folgt abgegrenzt:
|
||||
|
||||
In-Scope (Was Nexa tut):
|
||||
Triaging: Klassifizierung von 20 Mails/Tag (Privat).
|
||||
|
||||
Task-Routing: Verteilung von Aufgaben auf die richtige Nextcloud-Liste (Work vs. Personal).
|
||||
|
||||
Scheduling: Vorschlagen von Timeboxen im Arbeitskalender.
|
||||
|
||||
Memory: Aufbau eines Langzeitgedächtnisses in Qdrant.
|
||||
|
||||
Monitoring: Aggregation kritischer IT-Alarme (Proxmox, Backrest).
|
||||
|
||||
Out-of-Scope (Was Nexa NICHT tut):
|
||||
Kein direkter Zugriff auf Arbeits-IT (E-Mail/Server).
|
||||
|
||||
Keine aktive Bearbeitung von Dokumenten (außer Metadaten-Extraktion).
|
||||
|
||||
Keine Ersetzung von Spezial-UIs (z.B. Arcane oder Portainer für Container-Management).
|
||||
|
||||
3. Phasenmodell der Entwicklung
|
||||
Der Aufbau erfolgt iterativ, um frühzeitig Mehrwert zu generieren.
|
||||
|
||||
Phase 1: Die Wirbelsäule (Konnektivität)
|
||||
Fokus: Datenfluss zwischen Memos, n8n und SAIA.
|
||||
|
||||
Meilenstein: Nexa antwortet auf Memos und kann einfache Fragen beantworten.
|
||||
|
||||
Technik: Webhooks, REST-API, LiteLLM-Proxy.
|
||||
|
||||
Phase 2: Sensorik & Klassifizierung (The Senses)
|
||||
Fokus: E-Mail-Filterung und das Routing-System.
|
||||
|
||||
Meilenstein: Nexa erkennt den Unterschied zwischen "Arbeits-Task" und "Privat-Task" ohne manuelle Tags.
|
||||
|
||||
Technik: IMAP-Node, n8n-Logic-Router, System-Prompts für Kontext-Analyse.
|
||||
|
||||
Phase 3: Das semantische Gedächtnis (The Brain)
|
||||
Fokus: Anbindung von Qdrant und Obsidian.
|
||||
|
||||
Meilenstein: RAG (Retrieval Augmented Generation). Nexa beantwortet Fragen basierend auf deinen archivierten Notizen.
|
||||
|
||||
Technik: Embeddings-Pipeline, Qdrant-Vektor-Suche.
|
||||
|
||||
Phase 4: Proaktive Motorik (The Assistant)
|
||||
Fokus: Kalender-Integration und Timeboxing.
|
||||
|
||||
Meilenstein: Nexa schlägt morgens proaktiv Fokus-Zeiten im Arbeitskalender vor.
|
||||
|
||||
Technik: Nextcloud CalDAV/CardDAV Integration, Optimierungs-Logik für freie Slots.
|
||||
|
||||
Phase 5: Physische Präsenz (Voice & Alarms)
|
||||
Fokus: Home Assistant Voice & Monitoring-Integration.
|
||||
|
||||
Meilenstein: Nexa spricht über HA-Voice und meldet kritische Systemzustände proaktiv.
|
||||
|
||||
Technik: Home Assistant API, Wyoming Protocol, ntfy/Memos-Push.
|
||||
|
||||
4. Erfolgsmetriken
|
||||
Woran merken wir, dass Nexa funktioniert?
|
||||
|
||||
Reduktion der Mail-Interaktion: Weniger Zeit in der Mail-App, mehr Fokus auf den Nexa-Digest.
|
||||
|
||||
Kalender-Füllrate: Fokus-Slots für Arbeit sind automatisch geblockt.
|
||||
|
||||
Such-Geschwindigkeit: Informationen aus alten Memos/Obsidian werden via #ask sofort gefunden.
|
||||
Reference in New Issue
Block a user