Umbau Stufe 1-5: Governor v2 + OpenCode-Plugin + Subagenten-Mannschaft
Die Intelligenz sitzt nicht mehr NEBEN dem Coden, sondern DRIN. Alles auf der Box gemessen, nicht angenommen. Stufe 1 — Speicher-Haushalt (llama-swap-Config, nicht im Repo): Coder dauerwarm statt ttl 600 (Kaltstart 23 s -> 491 ms), Devstral als 'kritiker' verdrahtet, Swap 11 GB -> 0. Zwei Befunde: Kontext 131k->65k spart bei Qwen3-Next 0 GB (Hybrid-Attention), und llama-swap haelt nur EINE Gruppe resident -> alles Ko-Residente in dieselbe Gruppe. `persistent: true` verhindert dabei das Freiraeumen vor grossen Modellen -> ausgeloester Kernel-OOM, behoben durch persistent:false + TTLs (Vision laedt jetzt in 10 s statt 117 s + Absturz). Stufe 2 — Governor v2 (deploy/governor/): Steht jetzt IM Pfad (:8100 -> MC2 :9001) statt daneben. Zaehlt den GANZEN Anfragekoerper inkl. tools/tool_calls und kalibriert sich aus den echten usage.prompt_tokens jeder Antwort nach: Schaetzfehler 200 % -> 0,3 %. Soft-Einschub nur noch, wenn die Nachrichtenkette es erlaubt (kein Dazwischen- funken in offene tool_calls). Neuer Status-Endpunkt + systemd-Unit. Lucys Alltagsmodelle sind vom Schnitt ausgenommen. Stufe 3 — OpenCode-Plugin (deploy/opencode/plugin/mc2-governor.ts): Werkzeug-Zaun (git push, rm -rf, sudo, curl|sh — bewiesen), Pruef-Tor auf session.idle mit Selbstreparatur, Savepoint statt Kompression, Meldungen an Lucys Briefkasten mit eigenem Absender 'loop'. Stufe 4 — Mannschaft (opencode.json): plan+build -> coder (51,5 t/s) · explore -> hermes (69,6 t/s, warm, gratis) · review -> Devstral (15,0 t/s, FREMDE Modellfamilie gegen blinde Flecken). Der 63-GB-Planer faellt aus der Tagesrolle raus. Stufe 5 — ein Regelwerk, zwei Ausloeser: deploy/opencode-lauf.sh faehrt dieselbe Bau-Pruef-Schleife unbeaufsichtigt (die Schleife liegt hier UND im Plugin: bei `opencode run` endet der Prozess, bevor session.idle fertig ist — gemessen). Bricht ab, wenn der Governor fehlt. gitea-repo-create.sh saet jetzt VERIFY neben der CI-Ampel: jedes neue Repo wird mit Innen- UND Aussen-Pruefung geboren. Oberflaeche: Token-Waechter-Kachel im Cockpit (Fuellstand, Marken, Ehrlichkeits-Nachweis), /api/governor als gleichursprüngliches Fenster, Devstral im Modellkatalog, Rollen-Texte auf die neue Mannschaft aktualisiert. .gitattributes: deploy/**/*.py auf LF (deploy/*.py greift nur eine Ebene tief). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
"""Governor — Fenster auf den Token-Waechter (:8100).
|
||||
|
||||
Der Governor ist ein eigenstaendiger, absichtlich winziger Proxy ohne Datenbank: er
|
||||
sitzt zwischen den Coding-Agenten und diesem Gateway, zaehlt ehrlich mit (echte
|
||||
`usage.prompt_tokens` aus jeder Antwort) und zieht bei ueberlangen Sitzungen die
|
||||
Notbremse. Hier wird nichts Neues erhoben — nur sein Status-Endpunkt gleichursprünglich
|
||||
fuer die Oberflaeche verfuegbar gemacht, damit das Frontend nicht per CORS auf einen
|
||||
zweiten Port ausweichen muss.
|
||||
|
||||
Faellt der Governor aus, liefert dieser Router `ok: false` statt eines Fehlers: die
|
||||
Kachel zeigt dann „nicht erreichbar" und das Cockpit bleibt heil.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import httpx
|
||||
from fastapi import APIRouter
|
||||
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
GOVERNOR_URL = os.environ.get("MC_GOVERNOR_URL", "http://127.0.0.1:8100")
|
||||
|
||||
|
||||
@router.get("/governor")
|
||||
async def governor_status() -> dict:
|
||||
"""Momentaufnahme des Token-Waechters. Nie werfen — die Kachel darf nie das Cockpit reissen."""
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=3.0) as c:
|
||||
r = await c.get(f"{GOVERNOR_URL}/governor/status")
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
data["reachable"] = True
|
||||
return data
|
||||
except Exception as exc:
|
||||
return {
|
||||
"ok": False,
|
||||
"reachable": False,
|
||||
"error": f"{type(exc).__name__}: {exc}",
|
||||
"url": GOVERNOR_URL,
|
||||
}
|
||||
Reference in New Issue
Block a user