Commit Graph
50 Commits
Author SHA1 Message Date
elton 3bbe0ffb17 Doku: Umstiegsrezept aufs Hausmuster ./data:/data umgestellt 2026-09-08 11:30:23 +02:00
elton fb3e37b208 Doku: Umstieg aufs Image geprueft, Rezept und Fallstricke ergaenzt 2026-09-08 11:12:07 +02:00
elton 99e90669f3 CI: Login-Kommentar berichtigen (401-Ursache waren vertauschte Secret-Werte)
llmrouter CI / bun test + build (push) Successful in 3s
llmrouter CI / Build and publish image (push) Successful in 36s
2026-09-08 10:22:28 +02:00
elton dcbcfc665b CI: Login mit Retry
llmrouter CI / bun test + build (push) Successful in 3s
llmrouter CI / Build and publish image (push) Failing after 14s
Beobachtet am 2026-09-08: Registry-Login ging durch, eine Minute später
401 vom selben Server (Anmelde-Stand unverändert, per Hand mit demselben
Konto verifizierbar). Drei Versuche mit 5s Abstand.
2026-09-08 09:53:47 +02:00
elton 32a2cc7d9c CI: SHA-Kürzung POSIX-sicher
llmrouter CI / bun test + build (push) Successful in 2s
llmrouter CI / Build and publish image (push) Failing after 3s
Die Job-Shell ist sh -e; ${GITHUB_SHA:0:7} ist bash-Expansion und bricht
mit Bad substitution. printf '%.7s' statt Slice.
2026-09-08 09:49:16 +02:00
elton 53dbcf65bb Gitea-Actions-CI nach live-Muster
llmrouter CI / bun test + build (push) Successful in 3s
llmrouter CI / Build and publish image (push) Failing after 17s
bun test + Build je Push/PR; Push nach main published
git.42i.org/spine/llmrouter:latest (+sha-Tag) und verifiziert den Pull per
/health im Container. Muster: dev-image.yml aus 42i/live (buildx, eigener
Builder, --privileged, DOCKER_API_VERSION 1.43, Verify-Pull).
2026-09-08 09:48:13 +02:00
elton 000b244541 Doku: Einstiegs-README, technische Referenz, Betriebsstand
README als Einstieg mit Docker-Schnellstart; die bisherige README lebt als
docs/referenz.md weiter, der Betriebsstand ist aus info nach docs/betrieb.md
portiert.
2026-09-08 09:48:13 +02:00
elton 1f99b73161 Docker-Image, Compose-Demo mit ./data-Mount
Alle Laufzeitdateien (config, ACLs, keys, state, aa-cache, log) gehen über
den Mount ./data:/data, weil logDir und ACLs relativ zum CONFIG_PATH
aufgelöst werden. Ohne Keys startet der Router trotzdem, /health bleibt
bedienbar.
2026-09-08 09:48:13 +02:00
elton 3c0a8ead85 openrouter-auswahl.ts vendored, Importpfade umgestellt
Der Router verlaesst 42i/agents: die gemeinsame Modellauswahl wandert als
eigenstaendige Kopie nach src/ (die llmlite-Fassung bleibt dort fuer den
Tier-Updater). Referenz-Stellen zu LiteLLM-Durchreiche und Parallelbetrieb
korrigiert (entfallen mit der Abschaltung 2026-09-07).
2026-09-08 09:48:13 +02:00
elton bf7bc2c0b9 Ausweich auch für Schwelle-Aliasse und bei 429/5xx
auto/mass:fast war als Endstation ohne Rückfall: ling-3.0-flash fiel
am 2026-09-07 nachts aus (5x 502 nach ~270 s hängendem Upstream,
117x 429), und der bisherige Ausweich griff nur bei fetch-Fehlern und
nur für fest-Ziele. Jetzt darf auch ein Schwelle-Alias ausweichen,
und der Ausweich löst bei 429/5xx aus — bevor das erste Byte an den
Client geht, also gefahrlos wiederholbar, weiterhin nur einmal.

auto/mass:fast weicht auf auto/coding:junior aus (ling erfüllt deren
Schwellen strukturell nie, der Rückfall landet also garantiert auf
einem tauglichen Modell). Die Container-Personas bekommen die
Kettenziele in die ACL — ohne sie schlägt der Fallback in
zielBestimmen still fehl und der ursprüngliche Fehler geht durch.

Verifiziert im lokalen End-to-End-Test gegen Schein-Upstreams:
Ausweich bei 429 (200 vom Ersatzmodell, Log-Zeile alias->ausweich),
Durchreichung von 429 ohne ACL-Freigabe, fetch-catch-Pfad unverändert
funktionierend.

Refs 42i/intern#1252
2026-09-08 09:07:34 +02:00
eltonandClaude Opus 5 16a6b98c51 Ticketnummer bis ins Router-Log durchreichen (42i/intern#1291)
Der Log wusste bisher WER gerufen hat (Key, Rolle), aber nicht WORAN gearbeitet
wurde. Damit liess sich "was kostet ein Vorgang" gar nicht bilden -- die
Voraussetzung fuer die Frage, ob die teuren Tickets die sind, die ein Mensch
wollte.

- server.ts liest den Header x-42i-ticket und legt ihn in den Log-Eintrag
- log.ts: Feld `ticket` in JSONL und SQLite; die Spalte wird per ALTER
  nachgezogen (Bestandstabellen haben sie nicht), dazu ein Index darauf.
  Das INSERT nennt jetzt Spaltennamen statt Positionen -- sonst haette die
  neue Spalte die Reihenfolge zerschossen.
- opencode.json und der Container-Entrypoint schicken den Header aus
  {env:AGENT_TICKET}; job.sh exportiert die Variable ohnehin seit 2026-09-02.

Wer keines mitschickt (Chat, Handbetrieb), steht als null im Log -- auch das
ist eine Auskunft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 22:22:19 +02:00
eltonandClaude Opus 5 2355981c67 VERSUCH: role/worker auf ling (auto/mass:fast)
Andreas 2026-09-07: 'stellen wir die worker mal auf ling um und schauen was
passiert.' Bewusst gegen meine Empfehlung aus #1252 (ling Coding 50,6 /
Agentic 21,1 gegen glm 71,5 / 51,5) -- und bewusst als Versuch: der Rueckweg
ist diese eine Zeile.

Nur role/worker. engineer, qa und perf bleiben auf auto/coding:junior, damit
der Vergleich sauber bleibt.

Zu beobachten ist nicht der Preis (der faellt sicher), sondern ob die
Ergebnisse die Abnahme des Teamleiters bestehen -- und wie oft er neu
delegieren muss. Ein Worker, der in Schleifen haengt, braucht am Ende mehr
Zuege als er spart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 20:27:13 +02:00
eltonandClaude Opus 5 948ab84afe llmrouter: Slot an das Verbindungssignal binden (cancel feuert nicht)
Gegenprobe am Produktivrouter nach dem ersten Fix: Ein abgebrochener Stream
gab den Slot WEITERHIN nicht frei -- cancel() im TransformStream wird von Bun
beim Verbindungsabbruch nicht aufgerufen. Immerhin griff die zweite Haerte:
statt zwei Stunden Stille gab es nach 30 s ein 503 mit Grund.

Jetzt haengt der Slot an req.signal, das beim Abbruch zuverlaessig feuert, plus
einem Sicherheitsnetz von 660 s (laenger als der Upstream-Timeout darf kein
Slot gehalten werden). Die Freigabe ist gegen Doppelaufruf gesichert, ein
spaeteres flush() schadet also nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 20:23:36 +02:00
eltonandClaude Opus 5 ff62e751ed llmrouter: Slot-Leak beheben (42i/intern#1283)
Ein abgebrochener Streaming-Aufruf gegen das lokale Qwen (maxParallel 1) hat
den einzigen Slot dauerhaft gefressen: die Freigabe hing allein im flush() des
TransformStreams, und der laeuft bei cancel() nie. Danach reihte sich jeder
weitere Aufruf UNBEGRENZT in die Warteschlange ein, statt zu scheitern --
auto/mass, role/ops (Buzz) und das small_model aller Container-Personas hingen
zwei Stunden, ohne dass irgendwo etwas rot wurde. Diagnose von Elton im
Selbstheilungslauf, dreimal in Folge belegt.

Drei Haerten:
- Die Freigabe ist gegen Doppelaufruf gesichert (Flag). Erst dadurch darf sie
  an mehreren Stellen stehen, ohne Slots zu erfinden.
- cancel() gibt jetzt frei, nicht nur flush(). Das ist der eigentliche Fehler:
  bricht der Client ab, laeuft flush() nie.
- Wer laenger als 30 s auf einen Slot wartet, bekommt 503 mit Grund. Ein
  Fehler, an dem der Aufrufer etwas aendern kann, ist besser als Stille.

Ausgeloest habe ich den Fall selbst: zwei eigene Testaufrufe gegen role/ops
liefen gegen 18:05 ins Timeout und wurden abgebrochen -- genau die Handlung,
die den Slot frisst. Der Fehler im Code ist aelter, der Ausloeser war meiner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 20:20:56 +02:00
eltonandClaude Opus 5 ae0c4ca4a6 Korrektur: Qwen MIT Denkstufe holt den Skill selbst -- Einbacken fuer buzz unnoetig
Andreas fragte nach ("bist du dir sicher? so ganz sicher?" / "versuch sonst mal
qwen mit reasoning") -- zu Recht. Ich hatte die Aussage "Qwen laedt den Skill
nicht" aus der Doku uebernommen, statt sie zu messen.

Gemessen 2026-09-07 an agent-buzz auf auto/mass (qwen36:35b, enable_thinking):
Er ruft context_get_context von selbst und nennt seinen Arbeitsweg korrekt
(Runbooks und geschlossene Tickets zuerst, Wissen sichern, Routinen woertlich).

Der alte Befund (klara 0/9, live/live#1171) galt fuer 42i/marvin-core:none --
Qwen OHNE Denkstufe. Der Unterschied ist die Denkstufe, nicht das Modell.
AGENT_SKILL_EINBACKEN bleibt als Notnagel im Entrypoint, ist fuer buzz aber
nicht gesetzt.

Belastbarkeit: ein Lauf, kein Dutzend. Fuer eine Regel reicht das nicht -- fuer
die Entscheidung, den Vorspann nicht vorsorglich zu verdoppeln, schon.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 17:41:09 +02:00
eltonandClaude Opus 5 6c3d73584d buzz auf das lokale Qwen (role/ops -> auto/mass), Skill fuer ihn eingebacken
Andreas 2026-09-07: "lass buzz auf 42i/mass laufen. Der macht nicht so viel,
das muss ein qwen koennen." Buzz ist der einzige ops-Agent, deshalb bleibt die
Rolle der richtige Ort statt eines Modellnamens im Container.

Dazu gehoert zwingend AGENT_SKILL_EINBACKEN=1 fuer buzz: Qwen holt den
Persona-Skill nicht von selbst (klara 0/9 Laeufe, live/live#1171) -- genau der
Fall, fuer den der Schalter heute gebaut wurde. Der Vorspann steigt fuer ihn
also wieder, dafuer kostet sein Modell nichts.

Ausserdem: start-buzz-web.sh haengt den Werkzeug-Hinweis nach seinem
`cat > AGENTS.md` wieder an. Buzz war der einzige Container ohne den Hinweis --
sein warmer Web-Server ueberschreibt die Datei, die der Entrypoint schreibt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 17:37:47 +02:00
eltonandClaude Opus 5 0ecf90e152 Altnamen wirksam machen und die XO-Runde drosseln
ALTNAMEN (Schadensbehebung): Bei der Umstellung heute Mittag starben fuenf
laufende Teamlaeufe, weil sie ihren Modellnamen aus der Session mittrugen und
der Router ihn nicht mehr kannte (Aktennotiz des XO an 42i/intern#1251). Das
Feld "altnamen" war seit jeher deklariert und validiert, aber im Server NIE
angewendet. Jetzt uebersetzt der Router alte Namen VOR ACL-Pruefung und
Aufloesung; 20 Eintraege fuer die 2608-Reihe und die praefixlosen LiteLLM-Namen.

DROSSELUNG der Runde (Andreas: Verbrauch senken). Gemessen am 07.09.: 32 Runden,
75-220 Zuege je Runde, 82k Kontext je Zug, 208 Mio. Token an einem Tag.
- Ereignis-Paket 4 -> 2: der Aufwand waechst quadratisch mit der Zuglaenge,
  zwei Runden mit je 110 Zuegen kosten rund ein Viertel einer mit 220. Keine
  Zeitgrenze, nichts wird abgebrochen (Andreas 2026-09-03).
- Prompt: die Rueckgabeformate von tool.sh stehen jetzt als Tabelle im Prompt --
  mehrere Zuege gingen dafuer drauf, sie zu erraten. Dazu die Regel, Kommandos
  zu buendeln (214 der 1359 Bash-Aufrufe waren reine cd) und keine breiten
  Verzeichnis-Dumps (groesstes Ergebnis des Tages: ein ls -la mit 14k Zeichen).

Nicht umgesetzt: die Vermutung, der XO fuehre delegierbare Arbeit selbst aus.
Die Messung widerlegt sie -- die Bash-Aufrufe sind ueberwiegend tool.sh-Aufrufe
(Tickets lesen, kommentieren, CI pruefen), also seine eigentliche Aufgabe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 14:05:35 +02:00
eltonandClaude Opus 5 32c54439c8 llmrouter: Messwerkzeug fuer Telefon-Latenz (Erstbyte mit Inkas Zuschnitt)
Anbieterstatistiken messen den Erstbyte ueber alle Nutzer und Prompts. Am
Telefon zaehlt die Zeit bis zum ersten gesprochenen Wort, mit unserem grossen
Systemprompt und ueber mehrere Zuege -- ein Modell mit Zwangs-Reasoning verliert
dort Sekunden, die in keiner Statistik stehen (42i/intern#1252).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 13:35:30 +02:00
elton 77c29266c9 llmrouter-README: Namensraum auto/ und die Rollen-Vorbelegung nachgezogen 2026-09-07 13:24:24 +02:00
eltonandClaude Opus 5 1513ca63d6 key-acls aufgeraeumt: nightjob und persona-inka-mx entfernt
nightjob hatte kein Token, keinen Konsumenten und keine Nutzung in den letzten
14 Tagen -- der Name stand nur noch in den ACL-Dateien. persona-inka-mx war ein
LiteLLM-key_alias; beide Inka-Tokens (Shim und Telefon-Front-End) laufen im
Router unter persona-inka. Der Alias in OpenBao (agents/inka/litellm) ist
mitkorrigiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 13:23:50 +02:00