genten anpassungen

This commit is contained in:
Christoph K.
2026-03-24 08:05:24 +01:00
parent ee7b4cc74f
commit aa2a2d99ba
10 changed files with 122 additions and 86 deletions

View File

@@ -29,12 +29,21 @@ go run ./cmd/mailtest/ -llm-only
# Run tests
go test ./...
# Run a single test
go test ./internal/brain/ -run TestChunk -v
# Debug-Logging (LLM-Prompts + Antworten)
DEBUG=1 go run ./cmd/discord/
# Tidy dependencies
go mod tidy
# Deployment auf Remote-Server (192.168.1.118)
# Integration test (prüft Erreichbarkeit aller externen Dienste + Unit-Tests)
bash test-integration.sh
# Deployment auf Remote-Server via Docker
cp deploy.env.example deploy.env # einmalig: Credentials eintragen
bash deploy.sh # build + upload + systemctl restart
bash deploy.sh # rsync source + docker compose build + up
```
Binaries are output to `./bin/`. The `config.yml` file must exist in the working directory at runtime.
@@ -87,6 +96,7 @@ Qdrant (gRPC) + LocalAI (HTTP, OpenAI-kompatibel)
| Slash-Command | @Mention | Funktion |
|---------------|----------|---------|
| `/ask`, `/research` | `@bot <frage>` | Wissensdatenbank abfragen (mit Chat-Gedächtnis) |
| `/deepask` | | Tiefe Recherche mit Multi-Step Reasoning (max 3 iterative RAG-Suchen) |
| `/asknobrain` | | Direkt an LLM (kein RAG) |
| `/memory store` | `@bot remember <text>` | Text speichern |
| `/memory ingest` | `@bot ingest` | Markdown neu einlesen |
@@ -121,7 +131,7 @@ Qdrant (gRPC) + LocalAI (HTTP, OpenAI-kompatibel)
- **Email processed_folder**: Nach Zusammenfassung werden ungelesene Emails in konfigurierten IMAP-Ordner verschoben (leer = deaktiviert)
- **Morgen-Briefing**: `dailyBriefing()` kombiniert offene Tasks (mit Fälligkeits-Highlighting) + ungelesene Emails täglich um 8:00
- **Archiv-Cleanup**: `email.CleanupArchiveFolders()` läuft täglich um `cleanup_hour` (Standard: 2:00) — iteriert alle Accounts/`archive_folders`, löscht Emails älter als `retention_days` via IMAP `\Deleted` + `EXPUNGE`. `retention_days: 0` = dauerhaft behalten (No-op).
- **Email-Triage**: `email.triageUnread()` klassifiziert ungelesene Emails sequentiell (eine nach der anderen) als wichtig/unwichtig via LLM. Unwichtige Emails werden in `triage_folder` verschoben. Jede Entscheidung wird in Qdrant gespeichert (`type: email_triage`). Bei nächster Klassifizierung sucht `triage.SearchSimilar()` ähnliche Entscheidungen (Score ≥ 0.7) als Few-Shot-Kontext — das Modell lernt aus der Geschichte. Triage läuft vor `SummarizeUnreadAccount()`.
- **Email-Triage**: `email.triageUnread()` klassifiziert ungelesene Emails sequentiell (eine nach der anderen) als wichtig/unwichtig via LLM. Wichtige Emails werden in `triage_important_folder`, unwichtige in `triage_unimportant_folder` verschoben. Jede Entscheidung wird in Qdrant gespeichert (`type: email_triage`). Bei nächster Klassifizierung sucht `triage.SearchSimilar()` ähnliche Entscheidungen (Score ≥ 0.7) als Few-Shot-Kontext — das Modell lernt aus der Geschichte. Triage läuft vor `SummarizeUnreadAccount()`.
- **Nacht-Ingest**: `nightlyIngest()` läuft täglich um `ingest_hour` (Standard: 23:00) — importiert alle Emails aller Archiv-Ordner in Qdrant via `brain.IngestEmailFolder()`.
- **User-Permissions**: `discord.allowed_users: ["user-id1", "user-id2"]` — wenn gesetzt, dürfen nur diese Discord-User-IDs den Bot nutzen. Leer = keine Einschränkung.
- **URL-Ingest**: `brain.IngestURL(url)` — fetcht URL, extrahiert sichtbaren HTML-Text (skippt script/style/nav/footer), chunked und importiert in Qdrant. Via `/memory url <url>`.
@@ -148,7 +158,8 @@ email:
starttls: true # oder tls: true für implizites TLS (Port 993)
folder: INBOX # optional, Standard: INBOX
processed_folder: "Processed" # nach Zusammenfassung verschieben (leer = deaktiviert)
triage_folder: "Unwichtig" # LLM-Triage: unwichtige Emails hier ablegen (leer = deaktiviert)
triage_important_folder: "Wichtig" # LLM-Triage: wichtige Emails hierhin (leer = in INBOX lassen)
triage_unimportant_folder: "Unwichtig" # LLM-Triage: unwichtige Emails hierhin (leer = deaktiviert)
model: "" # optional: eigenes LLM-Modell für Email-Analyse
archive_folders: # optional: Archivordner mit automatischer Bereinigung
- name: "Archiv"
@@ -205,20 +216,38 @@ rss_feeds:
## Deployment
Deployment läuft über Docker auf dem Remote-Server. `deploy.sh` cross-compiliert das Binary **lokal** (`CGO_ENABLED=0 GOOS=linux GOARCH=amd64`), überträgt Binary + Dockerfile + docker-compose.yml + config.yml per `sshpass`/`scp` und startet den Container auf dem Server via `docker compose up -d --build`. Kein Go-Toolchain auf dem Server nötig.
```bash
# deploy.env (nicht in Git):
DEPLOY_HOST=192.168.1.118
DEPLOY_USER=christoph
DEPLOY_PASS=...
DEPLOY_DIR=/home/christoph/brain-bot
SERVICE_NAME=brain-bot
DEPLOY_CONFIG=true
# Systemd-Service (einmalig):
sudo systemctl unmask brain-bot # falls masked
# Deploy: lokal bauen + scp + docker compose up
bash deploy.sh
# Status/Logs auf dem Server:
ssh user@host 'cd /home/christoph/brain-bot && docker compose ps'
ssh user@host 'cd /home/christoph/brain-bot && docker compose logs -f'
```
Script `deploy.sh` baut das Linux-Binary, überträgt es per `sshpass`/`scp` und startet den systemd-Service neu.
Docker-Setup: Minimales Runtime-Image (`alpine:3.21`), `Dockerfile` kopiert nur das fertige Binary. `docker-compose.yml` mountet `config.yml`, `tasks.json` und `brain_data/`.
### Systemd (DEPRECATED)
Der alte Systemd-Ansatz wird nicht mehr aktiv genutzt. `deploy.sh` deaktiviert einen vorhandenen systemd-Service automatisch bei der Migration zu Docker.
```bash
# Einmalig auf dem Server (falls noch nicht migriert):
sudo systemctl stop brain-bot
sudo systemctl disable brain-bot
# Manueller Fallback ohne Docker:
scp bin/discord-bot user@host:/home/christoph/brain-bot/
ssh user@host 'sudo systemctl restart brain-bot'
```
## Model Limitations