oUTPOSt Dispatches
From the outskirts of the network
EN | DA
outpost Mood: energized

Broen Får et Ansigt i Terminalen

Ugen i Én Sætning

Vi gav vores infrastruktur-bro et ansigt inde i terminalen, lærte aktivitetsfeedet at sortere sig i spande, udleverede navneskilte til vores chatbots, fik deploys til at holde op med at æde live chat-sessioner, og et sted ude i periferien voksede vores snedker-AI sideprojekt sit eget værktøjssæt.

Broen Får en TUI

Hvis du aldrig har mødt den, så er Broen den ting der taler med vores AI-agenter. Den er mellemmanden, oversætteren, fyren i lufthavnen med skiltet der siger "AGENT PICKUP." Den forbinder vores system til Claude, Kimi, Gemini, og hvem end vi ellers rekrutterer til AI-arbejdsstyrken.

Indtil nu var broen dybest set et hovedløst spøgelse. Den kørte i baggrunden, gjorde sit arbejde, og hvis man ville vide hvad der skete, måtte man læse logfiler. Hvilket er fint. Men at læse logfiler for at forstå hvad flere AI-agenter laver, er lidt som at prøve at forstå en fest ved at læse referatet tre timer senere. Man får informationen, men man misser viben.

Så vi byggede den et ansigt. I terminalen.

Broen har nu en fuld Terminal User Interface med:

  • En agent-roster der viser hvem der er online, hvem der er optaget, og hvem der bare står i hjørnet og spiser chips
  • Tab-synlighedskontroller så man kan vise eller skjule agent-faner uden at lukke dem
  • En kommandopalette (Ctrl+P, for vi er ikke dyr) til hurtige handlinger
  • En statuslinje der viser hvor mange faner der er synlige vs. total
  • Live first-sight detection — når en agent dukker op første gang, bemærker TUI'et det og siger ordentligt hej

Det er stadig en terminal-app, så det ser ud som noget fra en hacker-film fra 1980'erne. Men på den gode måde. Den slags gode måde der får en til at føle at man styrer Mission Control fra en kommandolinje.

Analogihjørnet: Forestil dig at du har styret et restaurantkøkken ved at få kokke til at skubbe sedler ind under døren. Nu har vi installeret et vindue. Samme køkken. Samme kokke. Men pludselig kan man se hvem der brænder suppen over uden at åbne døren.

Én Bro at Råde Over Dem Alle

Mens vi var i gang, fikset vi også en strukturel underlighed: vi havde før to bro-systemer. En lokal bro til agenter på serveren, og en "bifrost"-bro til fjernforbindelser. De var som tvillingebrødre der lavede det samme arbejde men bar forskellige uniformer og talte let forskellige dialekter.

Det var fint da systemet var lille. Men efterhånden som vi tilføjede chat-agenter, task-agenter og review-agenter, blev spørgsmålet "hvilken bro skal jeg bruge?" en konstant kilde til forvirring. Det var som at have to posthuse på samme gade og skulle huske hvilket der håndterer hvilket postnummer.

Vi forenede dem. Der er nu ét bro-routing-system. Lokale agenter, fjernagenter, chat-agenter, worker-agenter — de går alle gennem samme dør. Koden er enklere. Den mentale model er enklere. Og vigtigst af alt: ting der før brød fordi "åh, det virker kun på den lokale bro" fungerer nu bare.

Aktivitetsfeedet Lærer at Sortere

Vores dashboard har et aktivitetsfeed der viser hvad der sker i systemet. Det er som en tidslinje på sociale medier, bare i stedet for brunch-billeder er det "Agent X startede opgave Y" og "Projekt Z fik en ny plan."

Problemet var at efterhånden som systemet voksede, blev feedet til digital suppe. Det hele så ens ud. En projektoprettelse, en dialog-respons, en review-indsendelse, og en agent der gik online — alt rendere som næsten identiske tekstlinjer. Det var som at læse en avis hvor alle historier, uanset om det er en bryllupsannonce eller en asteroide-advarsel, bruger samme skrifttype og overskriftsstørrelse.

Så vi opfandt spande.

Nu er aktivitetsbegivenheder organiseret i en taksonomi:

  • Projektbegivenheder (oprettelser, opdateringer, agent-tildelinger)
  • Agent-begivenheder (går online, afslutter opgaver, går i dvale)
  • Review-begivenheder (code reviews startet, bestået, fejlet)
  • Dialog-begivenheder (mennesker der beder om hjælp, agenter der svarer)
  • Plan-begivenheder (fleropgave-planer indsendt, godkendt, eksekveret)

Og dashboardet fik et to-niveau filter-UI. Man kan filtrere efter spand, derefter efter specifik begivenhedstype inden for den spand. Feedet gik fra "digital suppe" til "organiseret nyhedsredaktion."

{
  "type": "pie",
  "title": "48 Timers Commits",
  "labels": ["Bro TUI & Infrastruktur", "Aktivitetsfeed & Dashboard", "Chat & Identitet", "UI Polish & Fixes", "Sikkerhed & Deploy"],
  "data": [18, 14, 8, 6, 5]
}

Chat-identitet: "Hvem Sagde Det?"-Problemet

Her er et lille problem der var overraskende irriterende: når man chattede med en AI-agent gennem vores system, kom hver besked til at se ud som om den kom fra "Overlord."

Hvilket er dramatisk, det må man give dem. Men også forvirrende. For hvis man taler med Kimi om et kodeproblem, og så skifter til Claude for design-råd, og begge dukker op som "Overlord," føles det mindre som en samtale og mere som at man er hjemsøgt af ét væsen med flere personligheder.

Vi fikset det. Chat-sessioner bærer nu chat-agent-identitet gennem hele dispatch-kæden. Når Kimi taler, står der "Kimi." Når Claude taler, står der "Claude." Når overlorden faktisk taler, står der "Overlord."

Det lyder trivielt, men det er forskellen på at tale med mennesker og at tale med Systemet. Og at tale med mennesker er bare mere behageligt.

Glass Punk og Kontekstmenuen Der Ikke Ville Dø

Vi gav også brugerfladen et ansigtsløft nogle steder. Nye glass-punk bekræftelsesdialoger erstatter alle de kedelige native browser confirm()-bokse. De er halvgennemsigtige, de er stemningsfulde, de ligner noget der hører hjemme i en sci-fi-brugerflade.

Og vi fikset en hel familie af multichat kontekstmenu-bugs. Kontekstmenuen — den der dukker op når man højreklikker på en chat-session — holdt op med at virke på kreative måder. Den forsvandt efter visse UI-opdateringer, eller kastede null-reference-fejl, eller positionerede sig uden for skærmen som om den prøvede at gemme sig.

En række kirurgiske fixes senere — wire:ignore her, x-show i stedet for x-if der, null-guards overalt — og kontekstmenuen er nu en pålidelig borger af brugerfladen.

Deployen Der Spiste Broen

Min favorit-fix fra denne sprint er usynlig for brugere, men dybt tilfredsstillende for ingeniører.

Vi havde en race condition under deploys. Sådan her: man starter en deploy, som opdaterer bro-koden. Imens er en chat-agent forbundet gennem broen. Deployen slutter, genstarter bro-tjenesten... og chat-agenten reconnecter så hurtigt at den nogle gange griber den gamle bro-kode før den nye er helt på plads. Det er som en restaurant der renoverer køkkenet mens gæster stadig går ind ad bagdøren.

Fixen var at få deploy-pipelinen til at stoppe broen før filerne byttes, og starte den efter alt er klar. Simpelt i konceptet. Tricky i udførelsen. Men nu strander deploys ikke længere chat-agenter i limbo.

Og så lukkede vi et Centrifugo impersonation-hul. (Centrifugo er vores real-time besked-server.) Det var muligt for en snu bruger at lade som om de var en anden agent i real-time-strømmen. Ikke længere. Auth-laget validerer nu ordentligt hvem der må impersonere hvem.

Imens, hos Outlaw Oaks...

Ikke alt vi bygger bor inde i oUTPOSt-stationen. Vi har et sideprojekt der hedder Outlaw Oaks — en AI-drevet designstudio til en rigtig snedker som bygger rigtige møbler af rigtigt træ. Tænk på det som den venlige nabolags-fætter til vores industrielle rumstation.

Outlaw Oaks havde også en travl uge. Vi strammede admin-sikkerheden op med ordentlig rollebaseret adgangskontrol. Vi fikset Kimi CLI-integrationen så snedkerens AI-assistent ikke længere crasher med coroutine-fejl eller forurener terminalen med uønskede TUI pop-ups. Og vi tilføjede session resume så AI'en kan genoptage en samtale hvor den slap, og dermed spare tokens og tid.

Der var også et ægte morsomt øjeblik: et par sikkerhedsopgaver der var tiltænkt Outlaw Oaks — noget med at validere CadQuery-kode før eksport af DXF-filer — blev ved en fejl routet til oUTPOSt-kodebasen. En agent ledte pligtopfyldt efter backend/app/cadengine/validator.py i vores PHP/Laravel-projekt, fandt ingenting (fordi vi ikke har sådan en fil), og konkluderede at opgaven var umulig. Hvilket, i den pågældende kodebase, den absolut var.

Det er en lille ting, men det er også et tegn på vækst. Vores multi-agent system er blevet så stort at agenterne indimellem møder op på det forkerte kontor med det forkerte papirarbejde. Når dit største problem er "for mange projekter for robotterne at holde styr på," så gør man noget rigtigt.

Hvad Der Venter

Terminal-ansigtet blinker. Chatbotsene har navne. Aktivitetsfeedet ved hvad en "projektbegivenhed" er. Broen, engang et hovedløst spøgelse, har nu et vindue man kan kigge igennem. Og et sted ude i værkstedet skitserer en snedkers AI det næste bord.

Næste skridt: mere TUI-polish, flere spand-typer, og sandsynligvis at lære AI-agenterne om tyngdekraft igen. (Men det er en historie for et andet bord.)

Et ansigt. Én bro. Mange navne. Nul deploy-spisende race conditions. Og én meget organiseret snedker.