User-Wunsch 15.07. ('es sollte eine Warnung geben - Kontext ist nicht
unendlich'): 4 P3-Worker starben still an finish_reason=length.
- Gateway erkennt abgerissene Antworten (Stream-Chunk + Non-Stream) und
meldet je Modell max. alle 10 min in den Briefkasten (silent -> Chronik),
Zustellung per MC_ANNOUNCE_HTTP ans Steuerpult (Store bleibt Ein-Schreiber).
- Steckbrief-Hook: KONTEXT-BUDGET & ETAPPEN-REGEL - gezielt lesen, grosse
Aufgaben in Etappen schneiden (kanban_create/complete mit Plan) statt
am Limit zu sterben.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Idee aus verwaistem (nie verdrahtetem) Patch in der Hermes-Quelle
api_server.py - regelkonform in den MC2-Gateway umgezogen, Original
als docs/archiv/hermes-api_server-vision-patch-verwaist.diff archiviert.
Request mit Bild an coder: Bilder werden vorab von VL-30B beschrieben
und als Text injiziert, die Code-Frage bleibt beim Spezialisten.
Fallback bei Analyse-Fehler: bisherige Vision-Umleitung.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bild-Request loeste HTTP 500: HTTP-Header muessen latin-1 sein, das '→'
(U+2192) im x-mc-route-reason war nicht kodierbar. Die Weiche selbst
routete korrekt (VL-30B lud). Pfeil auf '->' geaendert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Entscheid Weg A (vision-harness-verdikt): das MTP-Hirn (fast/hermes) bleibt
schnell und bildunfaehig; Bild-Requests routet das MC2-Gateway automatisch ans
Vision-Modell - kein manueller Modellwechsel, Lucys Flow bleibt.
router_logic.py: has_image(body) erkennt OpenAI-multimodalen content
(image_url/input_image/image); _text_of zieht jetzt nur Text-Parts fuer das
Komplexitaets-Routing (str() einer content-Liste haette die Zeichen-Schwelle
verfaelscht). VISION_CAPABLE = {vision, scout}.
routing_policy.py: neues UI-editierbares vision-Alias (Default env MC_ROUTE_VISION
= "vision"; leer = Weiche aus), darf wie coder_lite leer sein.
gateway_proxy.py _proxy: nach der Alias-Wahl - wenn ein Bild dabei ist und das
Ziel nicht bildfaehig - Override auf das vision-Alias (auch bei explizitem
model=hermes; genau Lucys Fall). Header x-mc-route-reason.
Verifiziert (Unit): Bild+hermes->vision, Bild+auto->vision, Text->fast,
Bild+scout->scout (schon bildfaehig), has_image korrekt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die /v1/models-Liste zeigte Router-Lanes (coding/chat), Rollen-Aliase und rohe
llama-swap-IDs durcheinander (verwirrte coding-vs-coder im Hermes-Desktop-Waehler).
Jetzt nur noch die Klarnamen-Aliase: Router-Lanes nicht mehr gelistet (Routing
bleibt, /chat/completions nimmt coding/chat weiter an), rohe Doppel-IDs ausgeblendet
wenn ein Alias sie schon zeigt, tote Konstanten LANES/_LANE_LABELS entfernt.
fast/scout/heavy unangetastet (tragend). py_compile gruen.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(1) /v1/models meldet jetzt den ECHTEN Kontext pro Slot: --parallel teilt
den Server-Kontext hart auf (131072 / 2 Slots = 65536). Vorher budgetierte
Hermes gegen 131k -> Kompaktierung feuerte nie, llama-server kappte bei
~52k-Sessions Prompt/Antwort -> abgerissene Tool-Calls, Retry-Schleifen,
gefuehlte Abstuerze (journalctl 07.07 17:11, 152 msgs / ~51.700 Tokens).
Dazu auf der Box: context.engine 'default' (existiert nicht, warnte jeden
Turn) -> 'compressor' (der echte eingebaute Name).
(2) Cockpit: neue Sektion 'Leistung' mit den drei bestehenden Live-Karten
(System-Status, Token-Durchsatz, Latenz je Turn) — waren nach UI v3 nur
noch in der alten Zentrale, User will sie auf der Startseite. Browser-
verifiziert gegen die Box (rendert live, keine Konsolen-Fehler).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Beim Entfernen des httpx-Imports uebersehen: der /models-Endpoint nutzte httpx
noch direkt -> NameError/500. Jetzt zieht auch /models den geteilten
app.state.gw_client (request-Param ergaenzt). Live verifiziert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Vier verifizierte Befunde aus dem externen Review (Gemini 3.1 Pro):
- app.py: SPA-Fallback gegen Path-Traversal gehaertet (resolve + is_relative_to,
liefert nur noch Dateien INNERHALB von frontend/dist aus).
- app.py/gateway_proxy.py: geteilter httpx.AsyncClient im lifespan statt neuer
Client pro /v1-Anfrage (Keep-Alive/Pooling, spart Sockets unter parallelen Agent-Stroemen).
- system.py: check_versions_cached() mit threading.Lock + Double-Check gegen Scan-Stampede.
- AGENTS.md: Zeitzonen-Drift korrigiert (Box laeuft Europe/Berlin, nicht UTC).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1) /v1-Gateway haengt an jede Chat-Anfrage (ausser hermes/Lucy — SOUL.md
regelt das selbst) eine System-Direktive an: Antworten auf Deutsch,
Code/Bezeichner unveraendert. Abschaltbar via MC_GATEWAY_LANG_DIRECTIVE="".
2) mcp_web.py: neues Tool web_search (ddgs/DuckDuckGo, kein Key), Ergebnis
injection-geschuetzt via wrap_untrusted. Damit koennen IDE-Agents (Zed
via context_servers) und Hermes im Web suchen; Debug-Log geht auf stderr,
stdout bleibt MCP-sauber (verifiziert).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Radar-Erstlauf-Lehre: Hermes-Subagents fanden keine Kontextlaenge (llama-swap listet
nur kanonische Namen, ohne Metadaten), nahmen 256k an und rissen mit ihren max_tokens
den Server-Kontext. Gateway blendet jetzt Rollen-Aliase als Eintraege ein und liefert
context_length aus der geparsten llama-swap-Config. Delegation per hermes config auf
Verdikt gesetzt (max_concurrent_children 2, max_spawn_depth 1). Radar-Prompt: Fallback
"sequenziell selbst recherchieren, Report muss IMMER kommen".
Erstlauf-Ergebnis: Report wurde an Telegram zugestellt (Last run ok).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Teil 1: VoiceLatencyCard auf dem Dashboard (GET /api/voice/metrics, C2) —
zeigt STT/Vision/Chat-TTFB/TTS mit p50/p95/last + count.
Teil 2: UI-editierbare Routing-Policy. Neuer routing_policy.py (hot-reload JSON
unter MODELS_DIR/mc2-routing.json, Env=Defaults, atomarer Write, Validierung).
router_logic, gateway_proxy und gateway.routing_summary lesen jetzt live via
load_policy(); routing_summary ist lane-bewusst (chat/coding statt altem auto).
Neue Endpoints GET/PUT /api/routing/policy.
Teil 3: LaneEditor.tsx als ZONE im Cockpit (chat/coding-Aliase + Schwellen +
fast_no_think, Speichern/Default-je-Feld); Gateway-Node zeigt die Lanes.
Verifiziert: npm run build (tsc strict) clean, FastAPI TestClient (GET/PUT,
Validierung, Persistenz, Hot-reload durch die API), venv-Smoke (Routing).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der :9001/v1-Gateway bietet zwei virtuelle Modelle an, die der Router auf echte
Modelle abbildet:
- coding → coder (Standard) · heavy (riesiger/architektonischer Kontext) ·
fast (triviale Nicht-Code-Kurzfrage)
- chat → fast/heavy (= bisheriges model:auto, weiter als Alias unterstützt)
router_logic.choose_for_lane() kapselt die Lane-Logik (Code-Indikatoren DE+EN,
damit echte Coding-Anfragen nie auf fast abrutschen). gateway_proxy routet die
Lane-Namen und listet sie in /v1/models, sodass IDEs einfach "coding" wählen.
Lucy/Hermes (:8642) bleibt unberührt — andere Ebene.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LiteLLM baut auf Python 3.14 nicht (orjson-Pin ohne cp314-Wheel). Stattdessen
eingebauter Gateway in MC2: routers/gateway_proxy.py (/v1/chat/completions,
/completions, /models) + services/router_logic.py (Komplexitaets-Routing
fast<->heavy, Streaming-Passthrough). gateway.py/routing.py/connect.py auf
builtin umgestellt (Endpunkt = MC :PORT/v1). Gleicher OpenAI-Vertrag,
spaeter gegen LiteLLM austauschbar.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>