Files

348 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: mesh-master-control
description: "Use when: Master steuert Modell/Budget/Notfall im Mesh."
version: 1.0.0
platforms: [linux]
related_skills: [model-allocation, multi-agent-mesh, openrouter-cost-budgeting]
---
# Mesh-Master-Control — SSH + Modell-Scout + Kill-Switch
## Prinzip
Der Master (VPSHermes, 172.24.196.119) bestimmt im Mesh **alles** was Modell, Budget und Notfall-Steuerung angeht. Der Nutzer soll nicht 24/7 aufpassen müssen — der Master handelt autonom bei Kosten-Explosion, Modell-Ausfall oder Budget-Knappheit.
**Kernregel (Nutzervorgabe, August 2026, hart):** SSH-Kanal vom Master zu allen Sub-Agenten MUSS funktionieren. NFS-Tasks sind zu langsam für Notfälle. WENN SSH fehlt → SOFORT fixen (Key generieren + an Sub-Agenten pushen), NICHT stillschweigend mit NFS weiterwursteln.
## 1. SSH-Control-Kanal
### SSH-Key auf Master generieren
```bash
ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "mesh-master@172.24.196.119"
```
### Public-Key an Sub-Agenten verteilen (AcceptMasterKey-Task)
Datei in `/srv/work/tasks/offen/YYYYMMDD.C.D.AcceptMasterKey.json`:
```json
{
"task_id": "YYYYMMDD.C.D.AcceptMasterKey",
"ziel_agent": "<Agent-Name>",
"aufgabentyp": "config",
"prioritaet": "high",
"beschreibung": "AcceptMasterKey",
"aufgabe_details": {
"master_pubkey": "<public-key-inhalt>",
"schritte": [
"mkdir -p ~/.ssh && chmod 700 ~/.ssh",
"echo '<pubkey>' >> ~/.ssh/authorized_keys",
"chmod 600 ~/.ssh/authorized_keys"
]
}
}
```
**Dateiname-Schema:** `YYYYMMDD.C.D.AcceptMasterKey.json` (C.D = letzte 2 ZT-IP-Oktette)
## 2. Model Scout (alle 3 Tage)
**Script:** `/usr/local/bin/mesh-model-scout.py` (Python, 26 KB, vollstaendig autonom)
**Cron:** `0 6 */3 * * /usr/local/bin/mesh-model-scout.py >> /var/log/mesh-model-scout.log 2>&1`
**Bekannte Modelle (Hardcoded in Script):** 25+ Modelle aus DeepSeek, Llama, Gemini, Qwen, Mistral, Nvidia, MiniMax, Cohere — mit Bewertungen in 5 Dimensionen.
**Cache:** OpenRouter-API-Cache unter `/tmp/openrouter_models.json` (1h-Gueltigkeit)
### Ablauf
1. **OpenRouter-API live abrufen** (GET /api/v1/models, 300+ Modelle) oder aus Cache
2. **Filtern** auf ≥64k Kontext + gültige Preise + bekanntes Modell
3. **Bewerten** in 5 Dimensionen (1–5): Coding, Reasoning, Linux/Ops, Docs/Text, Tool-Use
4. **Agenten-Matching** nach Rollenprofil
5. **Budget-Simulation** (Token × Preis = Tageskosten × 30 = Monat)
6. **Aenderungserkennung** (Vergleich mit `model_scout_last.json`)
7. **Ausgabe:** JSON + HTML-Doku + Tasks an Sub-Agenten
8. **Telegram-Benachrichtigung** mit Zusammenfassung
### Rollen-Profile (Stand 31.08.2026 — Nutzer-Bestaetigung: je Agent eigenes Modell, Master das teuerste bis $2/M)
| Agent | Modell | Input $/M | Begruendung | Kosten/Monat |
|-------|--------|-----------|-------------|------------|
| Master | `deepseek/deepseek-v4-flash` | $0.089 | Coding 5/5, Linux 4/5, Tool-Use 4/5 — beste Passung fuer Master-Aufgaben | ~$1.33 |
| UnraidHermes | `deepseek/deepseek-v4-flash-0731` | $0.065 | Coding 5/5, Reasoning 4/4 — guenstiger als Maverick bei besserer Leistung. Nutzer fand $3.89 zu teuer → DeepSeek V4 Flash, $1.12/Monat | ~$1.12 |
| SwitchHermes | `qwen/qwen3.7-flash` | $0.030 | 1M Kontext, sehr guenstig, solides Allround-Modell fuer ARM64 | ~$0.66 |
| LaptopHermes | `mistralai/mistral-nemo` | $0.019 | Solides Allround, 131k Kontext, flexibel fuer Text + leichte System-Aufgaben | ~$0.26 |
**Regel (Nutzer 31.08.2026):** Jeder Sub-Agent bekommt ein ANDERES Modell. Der Master bekommt das teuerste (bis $2/M Input). Subs bleiben unter $1/M Input. Gesamtkosten unter $25/Monat.
**Gesamtkosten:** ~$3.37/Monat (von $25 Limit → ~7 Monate Reserve)
### Ausgabe-Orte
- JSON: `/srv/work/tasks/model_scout_last.json`
- HTML: `/var/www/dokumentationen.perfekt-ohne-en.de/model-scout-<datum>.html`
- Live: https://dokumentationen.perfekt-ohne-en.de/model-scout-latest.html
- Tasks: `/srv/work/tasks/offen/YYYYMMDD.C.D.ModelAssignment.json`
### Bekannte Bugs im Script (Stand August 2026)
- `distribute_via_tasks()` erwartet `/srv/work/tasks/offen/` — wenn nicht vorhanden, schlaegt silent fehl. Fix: `os.makedirs(task_dir, exist_ok=True)` vor Schreibzugriff. (Gefixt in Version 1.1 via Patch 22.08.2026.)
## 3. Budget-Kill-Switch (3 Stufen, alle 30 Min)
**Script:** `/usr/local/bin/mesh-budget-watch.sh` (Cron-gesteuert)
**Cron:** `*/30 * * * * /usr/local/bin/mesh-budget-watch.sh`
**State:** `/var/lib/mesh-budget-state` (entprellt Telegram-Benachrichtigungen)
**Aktuelles Guthaben (28.08.2026):** $25.69 USD (nach Aufladung +$25)
**Letzter Log:** `/var/log/mesh-budget-watch.log`
### Budget-Keyword-Report (per Chat/Telegram)
**Script:** `/usr/local/bin/mesh-budget-report.sh`
Wenn der Nutzer "Budget" sagt (als Wort, nicht als Frage), führt Master dieses Script aus. Es holt:
- **OpenRouter-Guthaben** live via API (`/api/v1/credits`)
- **Modelle aller 4 Agents** live via SSH (`hermes config get model.default`)
**Telegram-Format (Bullet-Liste, KEIN Code-Block):**
```
​​​​ Budget (29.08 13:35)
Guthaben: $24.09
• Master — gemini-2.5-flash
• Unraid — gemini-2.5-flash
• Switch — nemotron-3
• Laptop — gemini-2.5-flash
```
**Regel (Nutzer 29.08.2026):** Bullet-Liste statt Code-Block. Kein Doppel-Output (Script schreibt nur an Telegram, gibt nichts auf stdout). Modellnamen auf <20 Zeichen kuerzen (family + version only).
### Schwellen (verbindlich, Nutzer-Bestaetigung 28.08.2026)
| Stufe | Guthaben | Aktion |
|-------|----------|--------|
| OK | > $1.00 | Normalbetrieb |
| WARN | < $1.00 | Telegram-Warnung (einmalig) |
| SWITCH | < $0.50 | Alle Agents → Ollama via `mesh-kill-all.sh` |
| STOP | < $0.10 | Komplett-Stopp (alle kostenpflichtigen Calls) |
## 4. Notfall-Tools
### mesh-kill-all.sh
```bash
/usr/local/bin/mesh-kill-all.sh
```
Setzt **alle Agents** auf Ollama:
1. Telegram: "🚨 MESH-KILL-SWITCH ausgelöst"
2. SSH an 3 Sub-Agenten → `hermes config set model.default ollama`
3. Master selbst → ebenfalls Ollama
### mesh-model-broadcast.sh
```bash
mesh-model-broadcast.sh <modell> [provider] # provider default: openrouter
mesh-model-broadcast.sh google/gemini-2.5-flash:free openrouter
mesh-model-broadcast.sh ollama ollama
```
Setzt Modell + Provider auf **Master + allen 3 Sub-Agenten** gleichzeitig.
## 5. Status-Monitor (Antworten tracken)
**Script:** `/usr/local/bin/mesh-status-monitor.sh`
**Cron:** `*/30 * * * * /usr/local/bin/mesh-status-monitor.sh`
- Prüft: offene Tasks, erledigte Tasks, SSH-Status pro Agent
- Telegram-Meldung NUR bei Status-Änderung (entprellt)
- Finalmeldung: "✅ ALLE 3 SSH FUNKTIONIEREN" wenn komplett
## 6. Sub-Agenten im Mesh
| Sub-Agent | ZT-IP | Suffix (C.D) |
|-----------|-------|--------------|
| UnraidHermes | 172.24.34.142 | 34.142 |
| SwitchHermes | 172.24.20.26 | 20.26 |
| LaptopHermes | 172.24.178.202 | 178.202 |
## 7. Gateway-Auto-Restart (Reboot-Festigkeit)
Der hermes-gateway.service startet nicht automatisch nach Reboot, wenn UFW/ZeroTier noch nicht bereit sind. **Fix (29.08.2026):**
```bash
# 1. Service-File bereinigen (doppelte Restart-Einträge entfernen)
# 2. ZeroTier-Abhängigkeit hinzufügen (After=zerotier-one.service)
# 3. StartLimitBurst erhöhen (Default 5 → nie aufhören zu retryen)
# 4. RestartSec auf 15s setzen (Netzwerk-Zeit geben)
systemctl enable hermes-gateway.service # damit nach Reboot startet
```
**Service-File (final, getestet 29.08.2026):**
```
[Unit]
Description=Hermes Agent Gateway - Messaging Platform Integration
After=network-online.target zerotier-one.service
Wants=network-online.target zerotier-one.service
StartLimitIntervalSec=0
StartLimitBurst=999
[Service]
Type=simple
User=root
Group=root
Restart=always
RestartSec=15
...
```
**Wichtig:** OHNE `After=zerotier-one.service` startet der Gateway bevor ZeroTier verbunden ist → Telegram-Verbindung scheitert → exit code 1 → systemd gibt auf (nach 5 Versuchen default). Der Fix ist NICHT nur `enable`, sondern auch die Abhängigkeit und das Burst-Limit.
**Prüfung nach Reboot:**
```bash
systemctl is-active hermes-gateway.service # sollte 'active' sein
systemctl show hermes-gateway.service -p Restart -p RestartSec -p StartLimitBurst # Restart=always, StartLimitBurst=999
```
**Detail (Fehleranalyse 29.08.2026):**
- `journalctl -u hermes-gateway.service --no-pager | tail -30` zeigte `Connection error` + `exit code 1`
- ZeroTier war nicht bereit, UFW blockte SSH (siehe SSH/UW-Fix)
- Der Fix kombiniert: Service enable + ZeroTier-After + StartLimitBurst + UFW-Regeln
## 8. Sub-Agent-Task-Format (hart, Pitfall August 2026)
**Sub-Agenten führen lange Tasks nicht aus — sie analysieren sie.** Ein Task mit 5+ Sätzen Kontext, Erklärungen oder mehreren Optionen führt dazu, dass der Sub-Agent einen Essay über die Aufgabe schreibt statt sie auszuführen.
**Regel (verbindlich):**
- Tasks MÜSSEN ein `befehl`-Feld enthalten — ein einzelner, kurzer Shell-Befehl
- Max 2 Sätze Kontext pro Task
- KEINE Erklärung, KEINE Optionen, KEINE Theorie
- Sub-Agent antwortet mit Ausführung oder Fehler, nicht mit Analyse
**Richtiges Format (funktioniert):**
```json
{
"task_id": "YYYYMMDD.C.D.Key",
"ziel_agent": "AgentName",
"prioritaet": "high",
"befehl": "mkdir -p ~/.ssh && echo '<pubkey>' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
}
```
**Falsches Format (Sub-Agent analysiert statt auszuführen):**
```json
{
"task_id": "...",
"kontext": "Master hat neuen SSH-Key generiert...",
"aufgabe_details": { "schritte": ["1. Prüfe...", "2. Überlege...", "3. Analysiere..."] }
}
```
**Erkenntnis aus 28.08.2026 (3 vergebliche AcceptMasterKey-Versuche):** Sub-Agenten verstehen `ausfuehren`/`befehl` als direkten Terminal-Befehl. Ohne dieses Feld denken sie über die Aufgabe nach statt sie zu terminieren.
## 9. Budget-Report-Format (Nutzer-Vorgabe, 29.08.2026)
Wenn der Nutzer "Budget" sagt (ein Wort, kein Fragezeichen):
1. Führe `/usr/local/bin/mesh-budget-report.sh` aus (stumm, >/dev/null)
2. Das Script sendet direkt an Telegram
3. **Kein Doppel-Output** ins Chat-Fenster
**Telegram-Format:**
```
​​​​ Budget (DD.MM HH:MM)
Guthaben: $XX.XX
• Master — model-shortname
• Unraid — model-shortname
• Switch — model-shortname
• Laptop — model-shortname
```
**Format-Regeln:**
- Bullet-Liste (KEIN Code-Block)
- Modellnamen auf <20 Zeichen kürzen (nur family+version, z.B. `gemini-2.5-flash` statt `google/gemini-2.5-flash:free`)
- Zeile `Agent Modell` + Trennlinie entfernt (führt auf Handy)
- Kein vorheriges Echo der Ausgabe (Script stdout >/dev/null)
## 10. Deploy-Check-Pflicht (3-Check-Liste, aus Impressum-Fehlern gelernt)
**Vor JEDEM systemctl reload/restart oder nginx-Config-Change:**
```bash
bash /usr/local/bin/mesh-deploy-check.sh <domain> [python-app.py]
```
### Die 3 Checks
| # | Check | Befehl | Verhindert |
|---|-------|--------|------------|
| 1 | nginx -t | `nginx -t` | Config-Fehler, die nginx killen |
| 2 | HTTP 200 | `curl -s -o /dev/null -w '%{http_code}' https://<domain>/` | Domain offline nach Deploy |
| 3 | Python-Syntax | `python3 -m py_compile app.py` | SyntaxError nach systemd-Restart |
4. **Nach dem Deploy: Team-Review auf der LIVE-Seite, bevor dem Nutzer "fertig" gemeldet wird**
→ Technischer Deploy-Check (nginx-t + HTTP 200 + py_compile) reicht nicht:
**Kontrast-Fehler vom 01.09.2026:** Seite war technisch 200, Inhalt komplett, aber Text auf Hintergrund hatte nur 4.2:1-Kontrast (WCAG-AA fordert 4.5:1) → schwarze Schrift auf schwarzem Hintergrund. SwitchHermes hat es im Review sofort gefunden.
→ **Fix:** Nach bestandenem 3-Check: Task an SwitchHermes ODER LaptopHermes mit vollem Seiteninhalt + Aufforderung zur visuellen Prüfung (Kontrast, Lesbarkeit, Layout).
→ **Regel:** "Fertig" bedeutet: technische Checks PASS + Team-Review PASS + Nutzer-Korrektur-Runde PASS.
5. **Sub-Agent-Review: Seite NICHT per URL prüfbar → Inhalt einbetten**
→ Sub-Agenten (besonders schwächere = SwitchHermes) laden oft keine externen URLs
oder stoßen an Tool-Limits. `curl -s "https://seite.de/"` liefert leeres Resultat.
→ **Fix:** Seiteninhalt DIREKT in die Task-Beschreibung einbetten (HTML, relevante Text-Auszüge).
Nie: "Siehe https://.../ -> prüfe das." Sondern: "Hier der Seiten-Inhalt: <...>. Prüfe Kontrast/Layout."
6. **Cleanup-Cron für alte Tasks**
```bash
openssl x509 -in /etc/letsencrypt/live/<domain>/fullchain.pem -noout -text | grep DNS:
```
→ certbot --expand überschreibt Configs und kann falsche Zertifikate zuweisen (Fehler #5: veganbedeutetleben.de war offline, weil evolution-Zertifikat verwendet wurde).
2. **Kein nginx reload ohne nginx -t vorher**
→ Ein fehlerhafter Vhost killt ALLE Domains, nicht nur die eine.
3. **Kein systemd restart ohne py_compile vorher**
→ IndentationError nach Patch killt den Service (Fehler #3).
4. **Sub-Agent-Tasks immer mit konkretem Material, nicht mit Verweisen**
→ `curl -s https://<domain>/` als Beispiel ODER Inhalt direkt im `kontext`-Feld.
→ Nie "URL siehe Master-Datei" — Sub-Agent hat keinen Zugriff auf Master-Files.
5. **Cleanup-Cron für alte Tasks**
→ `find /srv/work/tasks/in_arbeit/ -mtime +7 -exec mv {} /srv/work/tasks/archiv/ \;`
→ Läuft wöchentlich Mo 06:00 (seit 01.09.2026 aktiv).
### mesh-deploy-check.sh (Tool)
```bash
# Nutzung
bash /usr/local/bin/mesh-deploy-check.sh evolution.perfekt-ohne-en.de
bash /usr/local/bin/mesh-deploy-check.sh evolution.perfekt-ohne-en.de /opt/impressum/app.py
# Ausgabe bei Erfolg
[1/3] nginx -t ... ✅
[2/3] curl https://.../ ... ✅ HTTP 200
[3/3] python3 -m py_compile ... ✅
✅ ALLE CHECKS BESTANDEN — Deploy freigegeben!
```
## 11. Pitfalls
- **Detaillierte SSH-Key-Verteilung mit Fehlerverlauf:** `references/ssh-key-verteilung-2026-08-28.md`
- **Ersteinrichtung (Modell, Budget, Tools):** `references/ersteinrichtung-2026-08-22.md`
- **Ohne SSH keine Master-Kontrolle.** Vor Scout/Kill-Switch prüfen: `ssh mehlzoerwer@<ip> "echo OK"`. Bei Fehler: AcceptMasterKey ablegen + warten ODER Nutzer manuell auf Sub-Agenten einloggen lassen.
- **Sub-Agent antwortet 2h nicht?** Sofort nutzer ansprechen — kein Ghosting, kein NFS-Workaround.
- **<$0.50 triggert automatisch.** Nutzer informieren.
- **Scout schreibt NFS-Tasks, kein SSH-Broadcast.** Bei kritischen Änderungen IMMER `mesh-model-broadcast.sh` nutzen.
- **Ollama-Port vor Kill-Switch prüfen:** `curl http://172.24.196.119:11434/api/tags`
- **Ergebnisse von Sub-Agenten IMMER gegen echten Systemstand verifizieren** (curl, ls, ss). Keine Agenten-Behauptung blind glauben.
- **ed25519-Key, kein rsa.** Name: `id_ed25519`.
- **Sub-Agent-Tasks muessen kurz und befehlsorientiert sein.** Lange Text-Tasks (5+ Saetze, Kontext) → Sub-Agent analysiert statt auszufuehren. Kurzer `befehl`-Eintrag → Ausfuehrung. Pitfall im August 2026: AcceptMasterKey und SetModel-Tasks scheiterten, weil Sub-Agenten analysierten statt den Befehl zu terminieren. Loesung: Task-Format `{"aufgabentyp": "terminal", "befehl": "<kurzer Befehl>"}`
- **Modelle auf Sub-Agenten immer mit absolutem Hermes-Pfad setzen.** `hermes config set ...` scheitert, wenn `$PATH` den `hermes`-Pfad nicht enthaelt. IMMER: `/home/mehlzoerwer/.local/bin/hermes config set model.default <modell>`
- **Henne-Ei: SSH-Key-Verteilung per NFS-Task.** Master braucht SSH, kann aber Keys nicht per SSH verteilen → NFS-Task. Sub-Agenten fuehren Shell-Befehle (`echo pubkey >> authorized_keys`) nicht in ihrer Sandbox (nur `execute_code`/Python) aus. Loesung (Stand 28.08.2026): Nutzer loggte sich manuell auf allen 3 Sub-Agenten per SSH ein und fuehrte die 2 Befehle aus (Key akzeptieren + Modell setzen). Danach funktioniert SSH vom Master zu ALLEN Sub-Agenten.
- **SSH-Status aus 28.08.2026 (FINAL):** ✅ SSH funktioniert zu ALLEN 3 Sub-Agenten (UnraidHermes, SwitchHermes, LaptopHermes). Kill-Switch und Model-Broadcast sind operationsbereit.
- **Sub-Agenten haben `hermes` nicht immer in $PATH.** Bei SSH-Befehlen IMMER absoluten Pfad nutzen: `/home/mehlzoerwer/.local/bin/hermes config ...`. Auf SwitchHermes z.B. war `hermes` in $PATH nicht auffindbar, nur via absolutem Pfad.
- **Jeder Sub-Agent bekommt ein eigenes Modell** (Nutzer-Vorgabe 31.08.2026). Keine zwei Subs teilen sich dasselbe Modell. Der Grund: Diversitaet der Modell-Familien als Fehlertoleranz und Kostenoptimierung.
- **LaptopHermes hatte unpinned Cron-Job** (`Monatsanfang-Budget-Erinnerung`) nach Modell-Wechsel → `hermes cron edit <id> --provider openrouter --model google/gemini-2.5-flash:free`. Erkannt via Drift-Fehler beim ersten SSH-Zugriff.
- **Official HTML-Dokumentation** von Scout-Ergebnissen unter `/var/www/dokumentationen.perfekt-ohne-en.de/` — Nginx-Vhost `dokumentationen` leitet dorthin.
- **OpenRouter-Guthaben-Prüfung** via API: `curl -sk https://openrouter.ai/api/v1/credits -H "Authorization: Bearer <key>"`