Initial: Mesh-Configs vom 03.09.2026 01:23
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
---
|
||||
name: openrouter-cost-budgeting
|
||||
description: OpenRouter-Usage deckeln und Agents automatisch bremsen.
|
||||
related_skills: [model-allocation, multi-agent-mesh]
|
||||
---
|
||||
|
||||
# OpenRouter Kosten-Tracking & Budget-Bremse
|
||||
|
||||
Kosten für eine Gruppe von Agents (Master + Sub-Agents) über OpenRouter überwachen,
|
||||
begrenzen und bei Limit automatisch pausieren. Ergänzt `model-allocation` (Modell-Wahl)
|
||||
um die reine **Kosten-Überwachung + Durchsetzung**.
|
||||
|
||||
## NUTZER-BUDGET-MODELL (verbindlich)
|
||||
|
||||
- **Hartes Tageslimit: 1$ pro Tag und Agent.**
|
||||
- **Solange OpenRouter-Credits (Guthaben) vorhanden sind, wird gearbeitet — kein Monats-Cap.**
|
||||
- Aufladung ~1. des Monats, evtl. am 15. nochmal — nicht garantiert.
|
||||
- Kein "Team-Monats-Stopp": die einzige harte Grenze ist das 1$/Tag/Agent-Tageslimit plus
|
||||
technischer Stop, wenn das Guthaben auf 0 fällt.
|
||||
|
||||
## OpenRouter-Kosten-API (echte USD)
|
||||
|
||||
- `GET /api/v1/credits` → `total_usage` (kumuliert USD über das ganze Konto-Leben) + `total_credits`.
|
||||
Verfügbar = `total_credits - total_usage`.
|
||||
- `GET /api/v1/auth/key` → `usage` (dieselbe kumulierte Größe, pro Schlüssel). Alle Keys eines
|
||||
Accounts zeigen dieselben `/credits`, aber unterschiedliche `/auth/key usage`.
|
||||
- Header `X-OR-Usage-Cost-USD` ist NICHT verlässlich; der Body liefert stattdessen
|
||||
`usage.cost` (USD) pro Antwort — verwende das für request-genaue Kosten.
|
||||
|
||||
## WICHTIG: Kumulativ vs. Perioden-Delta
|
||||
|
||||
`total_usage` ist über das **ganze Konto-Leben** kumuliert. Für Tages-/Monatsbudget IMMER ein
|
||||
**Delta** rechnen (sonst meldet ein laufendes Konto dauerhaft "über Budget"):
|
||||
|
||||
- **Tages-Delta** = letzter Wert des Tages − letzter Wert des Vortags (tagübergreifend,
|
||||
NICHT innerhalb desselben Tages — sonst entsteht eine Mitternachts-Lücke + Einzel-Tag=0).
|
||||
- **Monats-Basis** = letzter Eintrag des **Vormonats** (fallback: erster Eintrag dieses Monats,
|
||||
fallback: row[0]). NIE `row[0]` als Basis allein — das zählte das ganze Konto-Leben.
|
||||
- **Counter-Reset** abfangen: negatives Delta → 0 (kein falsches "Sparen").
|
||||
- 7-Tage-Kumulativ zusätzlich prüfen (Agent bleibt täglich <Deckel, summiert aber Wochen-Limit).
|
||||
|
||||
## Budget-Bremse / Kill-Switch
|
||||
|
||||
1. **Erfassen** (stündlicher Cron): `cost-track` ruft für alle Agents (Master lokal + je
|
||||
Sub-Agent per SSH, Key bleibt auf dem Agenten, nur Zahl wird zurückgeschickt) die `/credits`
|
||||
und `/auth/key usage` ab und hängt an eine Zeitreihe `costs.jsonl` an.
|
||||
2. **Prüfen** (gleicher Cron): `cost-break` vergleicht Deltas gegen Limits (budget.yaml) und
|
||||
schreibt **`kill_switches.json`** — welche Agents `PAUSED` sind.
|
||||
3. **Durchsetzen** (auf jedem Sub-Agent-Poller): vor Task-Übernahme prüft der Agent per SSH,
|
||||
ob sein Name in `kill_switches.json` `PAUSED` ist → wenn ja, keine Tasks übernehmen, kein Geld.
|
||||
4. **Master (VPSHermes) wird NIE hart pausiert** — er muss sein eigenes System und den Nutzer
|
||||
weiter betreuen. Nur Sub-Agents werden pausiert.
|
||||
|
||||
## Modell-Hart-Sperre (stärkster Kostenhebel)
|
||||
|
||||
Wenn EIN Modell den Großteil der Kosten verursacht (z.B. 64% bei einem teuren Pro-Modell),
|
||||
blockiere es hart — es ist dann gar nicht mehr ladbar:
|
||||
|
||||
```bash
|
||||
hermes config set model.providers.openrouter.blocked_models '["<modell>"]'
|
||||
# Prüfen: <modell> erscheint nicht mehr in: hermes models list
|
||||
```
|
||||
|
||||
`model.` (Singular), NICHT `models.` — und Hermes-Config NIE per patch/editor ändern, immer
|
||||
`hermes config set` (patch wird abgelehnt).
|
||||
|
||||
## Konfig (budget.yaml — Beispiel)
|
||||
|
||||
```yaml
|
||||
limits:
|
||||
tageslimit_agent_usd: 1.0 # harte Grenze pro Tag und Agent
|
||||
tageslimit_gesamt_usd: 4.0 # pragmatisches Gesamt-Cap (4 Agents x 1$)
|
||||
modelle:
|
||||
erlaubt: [...]
|
||||
blockiert: [ ".../v4-pro" ]
|
||||
bremse:
|
||||
kill_switch_file: /srv/work/costs/kill_switches.json
|
||||
```
|
||||
|
||||
## Werkzeuge (Referenz-Implementierung)
|
||||
|
||||
Siehe `references/cost-brake-ops.md` (betriebliche Details, Python-Call, Fehler-Chronologie):
|
||||
|
||||
- `scripts/cost-track.sh` — Zeitreihe erfassen (alle Agents)
|
||||
- `scripts/cost-break.py` — Limits prüfen → kill_switches.json
|
||||
- `scripts/cost-report.sh` → HTML-Fragment (USD-Gesamt + Bremse-Status) für Doku-Website
|
||||
|
||||
## Doku-Anbindung
|
||||
|
||||
Kosten-Sektion in der Live-Panel-Website: zeigt `total_usage_usd`, ob Agents pausiert sind,
|
||||
und den aktuellen Bremsen-Status. So behält der Master den Gesamtüberblick wie vom Nutzer
|
||||
gewünscht ("alles überschauen und bremsen").
|
||||
|
||||
## Live-Implementierung (mesh-master-control Skill)
|
||||
|
||||
Seit August 2026 laeuft auf dem Master der **mesh-budget-watch.sh** Cron (alle 30 Min):
|
||||
- Ruft `/api/v1/credits` via `curl` ab (echtes Guthaben, nicht kumulativ)
|
||||
- 3-Stufen-System: Warnung bei <$1, Auto-Switch auf Ollama bei <$0.50, Komplett-Stopp bei <$0.10
|
||||
- Telegram-Benachrichtigung bei Stufen-Ueberschreitung (entprellt via STATE-File)
|
||||
- Integriert `mesh-kill-all.sh` fuer den Ollama-Switch
|
||||
|
||||
Weitere Details im **mesh-master-control Skill** (`devops/mesh-master-control`).
|
||||
@@ -0,0 +1,75 @@
|
||||
# Kosten-Bremse — Betriebsreferenz (Session 2026-08)
|
||||
|
||||
Ergebnis einer kompletten Nachbaustufe: Kosten-Überwachung + automatisches Bremsen
|
||||
über OpenRouter in einem Multi-Agent-Mesh (Master + 3 Sub-Agents).
|
||||
|
||||
## Tatsächliche OpenRouter-Endpoints (verifiziert 08.08)
|
||||
|
||||
```bash
|
||||
# Konto-weit, USD, kumulativ über Kontoleben:
|
||||
GET https://openrouter.ai/api/v1/credits
|
||||
# -> data.total_credits, data.total_usage (total_credits - total_usage = verfügbar)
|
||||
|
||||
# Pro-Key:
|
||||
GET https://openrouter.ai/api/v1/auth/key
|
||||
# -> data.usage (gleiche kumulierte Größe pro Schlüssel)
|
||||
```
|
||||
|
||||
- Zwei Messe: `/credits` (verbindlich, account-weit) + `/auth/key` (pro-Agent-Verteilung).
|
||||
- Alle Keys desselben Accounts liefern in `/credits` dieselbe Zahl; `/auth/key usage` differiert.
|
||||
- `X-OR-Usage-Cost-USD` Response-Header war NICHT vorhanden → stattdessen
|
||||
`chat-completions` Body `usage.cost` (USD) liefert exakte Pro-Request-Kosten.
|
||||
|
||||
## Python-Call für Kosten-Abfrage (Key bleibt lokal)
|
||||
|
||||
```python
|
||||
import json,re,urllib.request
|
||||
e=open('/root/.hermes/.env').read()
|
||||
key=re.search(r'OPENROUTER_API_KEY=([A-Za-z0-9_.\-]+)',e).group(1)
|
||||
h={"Authorization":f"Bearer {key}"}
|
||||
c=json.load(urllib.request.urlopen(urllib.request.Request(
|
||||
"https://openrouter.ai/api/v1/credits",headers=h),timeout=15))["data"]
|
||||
print(c.get("total_credits"), round(c.get("total_usage",0),2))
|
||||
```
|
||||
|
||||
Für Sub-Agents per SSH ausführen, Key bleibt auf dem Agenten, nur die Zahl kommt zurück.
|
||||
|
||||
## Delta-Logik (die Kern-Korrektur aus dem Team-Review)
|
||||
|
||||
`total_usage` ist KONTOLEBEN-kumulativ. Falsch war: `total_usage > Cap` (pausiert dauerhaft)
|
||||
und `letzte-heute − erste-heute` (Mitternachts-Lücke, Einzel-Tag=0, Reset negativ).
|
||||
|
||||
Korrigiert:
|
||||
- Tages-Delta tagübergreifend: `letzter-Wert-heute − letzter-Wert-vortag`
|
||||
- Monats-Basis = letzter Eintrag des VORMONATS (fallback Monatsanfang, fallback row[0])
|
||||
- negative Werte → 0
|
||||
- 7-Tage-Kumulativ-Summe als Zweit-Check
|
||||
|
||||
## Kill-Switch-Durchsetzung (Poller-Guard)
|
||||
|
||||
In `mesh-agent-poller.sh` vor der Task-Übernahme:
|
||||
|
||||
```bash
|
||||
KILL_CHECK=$($SSH_CMD "python3 -c \"
|
||||
import json
|
||||
try: d=json.load(open('/srv/work/costs/kill_switches.json'))
|
||||
except Exception: d={}
|
||||
sw=d.get('kill_switches',{}).get('$MEINE_ID',{})
|
||||
print('PAUSED' if sw and sw.get('status')=='PAUSED' else 'OK')" 2>/dev/null")
|
||||
if [ "$KILL_CHECK" = "PAUSED" ]; then log "Budget-BREMSE aktiv"; exit 0; fi
|
||||
```
|
||||
|
||||
## Modell-Block (Hermes)
|
||||
|
||||
`hermes config set model.providers.openrouter.blocked_models '["deepseek/deepseek-v4-pro"]'`
|
||||
(Key `model.` Singular). Danach taucht es nicht mehr in `hermes models list` auf.
|
||||
|
||||
## Chronologie der Fehler (saubere Lektionen)
|
||||
|
||||
1. Erst 25$ Monats-Cap → zu aggressiv → Nutzer korrigierte: Wallet-Modell (1$/Tag/Agent,
|
||||
kein Monats-Stopp, solange Guthaben da arbeiten).
|
||||
2. `total_usage` kumulativ mit Cap verglichen → dauerhafter Fehlalarm → Team (Switch) meldete
|
||||
row[0]-Basis-Problem → auf Vormonats-Basis korrigiert.
|
||||
3. Unser eigenes Sup-Tool-Test überschrieb `costs.jsonl` mit Testdaten → Echte-Daten wiederherstellen
|
||||
via frischem cost-track-Lauf (kein Test-Artefakt zurücklassen).
|
||||
4. `models.` vs `model.` Config-Key → Singular.
|
||||
Reference in New Issue
Block a user