Cordis-brug
De Cordis-brug integreert DeepSeek Harness (DSH) in de backend van Libre WebUI. DSH draait als pluginboom in een door Libre WebUI gehoste Cordis-runtime. Mogelijkheden worden zo Cordis-services in plaats van geïmporteerde modules.
De brug staat standaard uit. Niets op deze pagina gebeurt voordat een operator haar inschakelt; zie Cordis-configuratie.
Waarom een brug in plaats van directe integratie
DSH-pakketten rechtstreeks vanuit Libre WebUI-services importeren zou korter maar minder geschikt zijn. Het maakt de engine een afhankelijkheid bij compilatie: een modeladapter of agentlus vervangen of de engine verwijderen vereist dan Libre WebUI aanpassen en opnieuw uitrollen.
De brug keert dit om. Libre WebUI gebruikt één abstract contract; een Cordis-compositiedocument bepaalt wat dat invult:
- Andere bestemming zonder herbouw. De compositie is YAML; een andere provider kiezen is een configuratiewijziging.
- Mogelijkheden configureren. Elke mogelijkheid is een Loader-rij. Wijzigingen aan de operatorcompositie gelden bij de volgende hoststart.
- Schoon verwijderen. Alle geïnstalleerde services, listeners en effecten behoren aan de rootfiber. Die opruimen draait alles terug, zodat de operator de engine kan stoppen zonder Libre WebUI te herstarten.
Lagen
Concrete DSH-afhankelijkheden blijven binnen backend/src/cordis/dsh/. Routes en applicatieservices gebruiken de brugcontracten. De Work-driver heeft een afzonderlijke compositie in het geheugen en laadt nooit hostbestandssysteemplugins.
Contracten
Het contract staat in backend/src/cordis/contracts.ts. Het bevat bewust alleen de vormen die Libre WebUI’s API nodig heeft, zonder interne engineterminologie.
| Contract | Doel |
|---|---|
DshEngine.status() | Levenscyclusstatus van elke engineservice (pending / ready / failed) |
DshEngine.modelConfiguration() | Model- en providerstandaarden van de draaiende compositie |
DshEngine.listSessions() | Sessiesamenvattingen, nieuwste eerst |
DshEngine.getSession(id) | Eén sessie met geprojecteerde berichten |
DshEngine.createSession(opts) | Sessie-ID en werkmap reserveren |
DshEngine.updateSessionSettings(id, settings) | Echt model en native bestandssysteemrechten opslaan wanneer inactief |
DshEngine.decideApproval(id, approvalId, decision) | Een native toolgoedkeuring voor de bijbehorende sessie afhandelen |
DshEngine.deleteSession(id) | Sessie beëindigen en agent opruimen |
DshEngine.listAgents() | Actieve agents, aangeduid als hoofd- of subagent |
DshEngine.listTools() | Voor het model zichtbare geregistreerde tools |
DshEngine.sendMessage(id, txt) | Beurt starten en streamhandle teruggeven |
DshEngine.cancel(id) | Actieve beurt van een sessie annuleren |
Het contract wordt als Cordis-service libreDshEngine gepubliceerd. Consumenten lezen die met ctx.get('libreDshEngine'), zonder de brugmodule te importeren.
EngineStreamChunk bevat text, reasoning, tool-call, tool-result, approval-request, approval-decision, error en done. Live frames volgen hun eigenaaragent en sessie; het bijbehorende duurzame assistentbericht verschijnt niet nogmaals. sendMessage geeft een handle terug waarvan subscribe al verzonden inhoud opnieuw afspeelt. Een snel eerste token gaat daardoor niet verloren voordat de HTTP-handler zijn listener aansluit.
Volgorde van één chatbeurt
NDJSON wordt gebruikt omdat een beurt na het verzoek één reeks van server naar client is. De reeks op de POST houden voorkomt een tweede handshake, ticket en herverbindingsprotocol en houdt de hele beurt binnen één geauthenticeerd verzoek.
DONE en PENDING
Cordis activeert een plugin zodra de gedeclareerde services beschikbaar zijn. Een rij doorloopt dus ook toestanden vóór uitvoering. Verwarring tussen de volgende twee begrippen is de gebruikelijkste oorzaak van een stille engine.
Loader-toestand. Iedere rij doorloopt PENDING → LOADING → ACTIVE of FAILED. Ontbrekende gedeclareerde services laten de rij onbeperkt wachten in plaats van falen. Een onvolledige compositie kan daarom starten zonder iets te bedienen.
Servicebeschikbaarheid. De host rapporteert iedere verwachte service als:
| Status | Betekenis | Oorzaak |
|---|---|---|
pending | Niet geregistreerd in de context | De leverende rij is niet geactiveerd of uitgeschakeld |
ready | Geregistreerd en bruikbaar | De leverende rij is geactiveerd |
failed | Gedeclareerd maar onbruikbaar | Gemeld met een detail-tekenreeks |
host.status() noemt beschikbaarheid en ontbrekende vereiste services; GET /api/cordis/health geeft dezelfde informatie. Een ontbrekende verplichte service laat de start mislukken in plaats van een engine te publiceren die lege lijsten retourneert.
Twee afhankelijkheidsketens zijn gemakkelijk verkeerd in te stellen:
dsh-toolsstart niet zondersystemPrompt.dsh-agent-loopstart pas alsagents,sessions,llm,tools,systemPromptensessionProjectionsbestaan.
Ontbreekt een van deze, dan kan de sessieopslag werken terwijl de engine nooit antwoord geeft.
Providerconfiguratie
De meegeleverde rij libre-webui-llm-adapter bedient de in Libre WebUI ingestelde providers. De modelkiezer op de Engine-pagina kiest een providermodel per sessie zonder die rij te vervangen.
Wijzigingen in compositierijen gelden bij de volgende hoststart. Herstart de backend of schakel Cordis uit en in wanneer de beheerdersschakelaar ontgrendeld is. Duurzame sessies blijven in de ingestelde opslag en hervatten via de huidige compositie.
Vertrouwde integratiecode kan de lifecycle-API’s van de Cordis Loader rechtstreeks gebruiken. De brug biedt geen adapterwisselendpoint en herstelt de vorige adapter niet automatisch wanneer een vervanger faalt.
Rollback
De rootfiber opruimen verwijdert alles wat de engine heeft geïnstalleerd. Deze eigendomsrelatie is de volledige garantie:
- Plugins registreren services; die worden met hun fiber teruggetrokken.
session/event-abonnementen worden in de brugconstructor geregistreerd en behoren aan de fiber van de brugrij.- De brug houdt agenthandles bij en ruimt ze op in haar teardowneffect.
- De host ruimt de rootcontext op, die alle rijen bezit.
stopCordisHost() is idempotent en aangesloten op het afsluiten van de backend. Timers en bestandshandles worden vrijgegeven in plaats van aan het einde van het proces overgelaten.
Sessie-identiteit en opslag
De Engine-pagina reserveert bij creatie een ondoorzichtig sessie-ID. Met persistentie wordt de header direct opgeslagen, zodat ook een lege sessie herstart overleeft. De brug toont opgeslagen en actieve sessies, leest logs via DSH’s gevalideerde opslag-API en hervat de agent met hetzelfde ID voor vervolgberichten. Nieuwe gebruikersberichten gebruiken DSH’s constructor voor geïdentificeerde berichten.
Verwijderen annuleert en ruimt de agent op vóór het sessiebestand wordt verwijderd. De lokale JSONL-adapter valideert opslag- en sessiepaden en weigert symlinks. Aangepaste opslagbackends zonder verwijderondersteuning geven een fout in plaats van te beweren dat gegevens verwijderd zijn.
Annulering bereikt de native agent, modelaanvraag en tooluitvoering. Een verbroken clientverbinding annuleert de beurt; voltooide berichten blijven leesbaar. Gebufferde streamherhaling is begrensd en bewaart snelle antwoorden vóór aansluiting van een lezer.
De hostengine is een solo-functie met één replica. Team-implementaties kunnen haar lokale JSONL-runtime niet laden. Geïsoleerde Work-uitvoering gebruikt de bestaande SQL-repositories voor taken, runs, berichten, goedkeuringen en events.
HTTP-interface
| Methode | Pad | Doel |
|---|---|---|
GET | /api/cordis/health | Brugstatus; zonder authenticatie |
GET | /api/cordis/sessions | Sessies opsommen |
POST | /api/cordis/sessions | Sessie maken |
GET | /api/cordis/sessions/:id | Sessie met berichten lezen |
DELETE | /api/cordis/sessions/:id | Sessie beëindigen |
POST | /api/cordis/sessions/:id/messages | Bericht sturen, NDJSON streamen |
POST | /api/cordis/sessions/:id/cancel | Actieve beurt annuleren |
GET | /api/cordis/agents | Actieve agents opsommen |
GET | /api/cordis/tools | Geregistreerde tools opsommen |
Alle routes behalve /health vereisen een geauthenticeerde beheerderssessie. Zolang de brug geen verzoeken kan verwerken, antwoorden ze met 503 en een code van CORDIS_DISABLED, CORDIS_STARTING of CORDIS_UNAVAILABLE.

De pagina is frontend/src/pages/CordisPage.tsx, bereikbaar via /cordis in de zijbalk. Ze toont sessies en tools, maakt sessies en streamt een beurt naar het gesprek. Als de brug uitstaat of niet start, verschijnt de reden in plaats van een lege lijst: anders zien “geen sessies” en “geen engine” er hetzelfde uit.
De browserclient is frontend/src/utils/api/cordisApi.ts. Die gebruikt alleen deze interface, zonder backendtypes of @deepseek-ai/*-pakketten te importeren; de engine blijft vervangbaar zonder frontendwijziging. Een beurt gebruikt sendMessage(sessionId, text, { onChunk }). De client verwerkt zelf newline-gescheiden JSON en verdraagt frames die over meerdere netwerklezingen zijn verdeeld.
Chatbediening van de Engine
De pagina toont Markdown, tabellen en code met syntaxiskleuring, met kopieerknoppen voor antwoorden en code. Systeemprompts en ingevoegde runtimecontext staan onder aanvankelijk ingeklapte Sessiecontext, niet als gebruikersberichten. Getoonde redeneerstappen en toolactiviteit hebben eigen uitklapsecties; resultaten blijven na herladen aan de juiste bewerking gekoppeld.
Kies een echt providermodel in de opsteller. De lijst gebruikt beschikbare lokale en pluginmodellen van de aangemelde beheerder, inclusief provideridentiteit. Chatpersonas en agents zijn geen model-ID’s en voegen hun instructies niet toe aan een Engine-gesprek. Oude mislukte persona-modelheaders worden als standaardhint genegeerd zonder het opgeslagen log te wijzigen.
Elke sessie heeft Alleen lezen of Schrijven in werkruimte, afgedwongen door DSH’s bestandssysteembeleid en de canonieke werkruimtegrens. De opsteller toont het bereik. Instellingen worden als native sessie-events opgeslagen en overleven herstart; wijzigen tijdens een actieve beurt wordt geweigerd.
Een native verzoek om extra rechten verschijnt als Eén keer toestaan / Weigeren bij de bewerking. Goedkeuring geldt alleen daarvoor en verandert de vaste rechtenmodus niet. Verouderde of geannuleerde verzoeken zijn niet meer goed te keuren; headless Chat weigert vragen die het niet kan tonen. De brug biedt geen onbeperkte hosttoegang.
Extra beheerderseindpunten:
| Methode | Pad | Doel |
|---|---|---|
GET | /api/cordis/models | Beschikbare providermodellen en de huidige echte modelstandaard |
PATCH | /api/cordis/sessions/:id/settings | Model en/of rechtenmodus van deze sessie instellen |
POST | /api/cordis/sessions/:id/approvals/:approvalId | Een openstaand verzoek beslissen met allowed-once of rejected |
De engine in Chat gebruiken
Schakel Toegang en beleid → CLI-agentmodellen en Cordis-engine in. Beheerders kunnen dan DeepSeek Harness in Chat kiezen. Elk verzoek krijgt een nieuwe tijdelijke enginesessie met het transcript van dat Chat-verzoek. De gewone Chat-database blijft leidend; onafhankelijke gesprekken, forks en herhalingen delen geen verborgen enginegeschiedenis. Het tijdelijke log wordt na voltooiing of annulering verwijderd en verschijnt niet op de Engine-pagina.
De standaardprovidercompositie biedt ook DeepSeek Harness · model (provider) in Agents. De opgeslagen ID’s omhullen dezelfde gekwalificeerde providerroute als de Engine-pagina: dsh:lwui:ollama:<model> of dsh:lwui:plugin:<plugin>:<model>, met procentcodering per providercomponent. De optionele lokale native DSH-verbinding voegt dsh:native:<provider>:<model> toe uit de actuele catalogus van die instantie en hergebruikt haar configuratie en referenties.
Installeer het zelfstandige Apache-2.0-pakket van libre-webui/dsh-native-provider, of maak een bundel vanuit Libre WebUI. Beide gebruiken @libre-webui/dsh-native-provider en houden providersleutels in native DSH. Beide processen vereisen dezelfde Unix-host en OS-account, met een private Unix-socket; toepassingen die die account delen worden niet geïsoleerd. Alleen modelinferentie wordt aangeboden, geen native agentsessies of tooluitvoering. De configuratiegids behandelt installatie, profielherstarts, upgrades en verwijdering. Ontbrekende verbindingen of modellen falen zonder van provider te wisselen. Native aanroepen staan ook bij Providergebruik, met model, gemelde tokens, latentie en resultaat.
Het basisprofiel dsh behoudt de modelstandaard van de actieve compositie. Aangepaste adaptercomposities bieden alleen dat basisprofiel en adverteren geen niet-ondersteunde LWUI-provideroverrides.
Titels en denksamenvattingen lossen de DSH-keuze op naar de onderliggende provider en sturen direct tekst zonder tools of agentsessie. Het basisprofiel leest de actieve enginestandaarden, inclusief overrides in de brugrij, in plaats van ze uit de catalogus te raden. Aangepaste adapters vereisen hiervoor een expliciet Ollama- of plugin-taakmodel. Een onbeschikbare provider veroorzaakt de gewone fout of lokale titelpreview, geen verzoek aan een andere provider.
Instellingen en referenties van de geauthenticeerde beheerder worden gebruikt. Andere beheerdersreferenties worden nooit impliciet geselecteerd. De ingestelde Cordis-werkruimte blijft de standaard; Chat vervangt die niet door de thuismap van de servergebruiker.
Geïsoleerde Work-uitvoering
Met Cordis biedt Work een aparte Engine-keuze tussen Libre WebUI en DeepSeek Harness. De modelkiezer behoudt gewone modelnamen en provideridentiteiten. Voor LWUI-providers wordt DSH intern opgeslagen als dsh:<model>; native keuzes bewaren providerType: dsh, het exacte native provider-ID en het ruwe model-ID. Normale toegang- en toolondersteuningscontroles blijven gelden; native referenties vereisen bovendien een actieve beheerder.
Elke run maakt een geïsoleerde DSH-agentlus in het geheugen. De adapter ontvangt het actuele Work-transcript, providermetadata, afbeeldingen en toolschema’s. Toolfuncties wachten alleen op resultaten van Work; ze kunnen geen hostbestanden lezen of hostprocessen starten.
Work valideert argumenten, vraagt goedkeuringen, voert tools uit in de werkruimteruntime, schrijft resultaten en provider-replaystaat naar SQL, handhaaft budgetten en publiceert events. Een geweigerde tool geeft het gewone weigeringsresultaat. Annulering ruimt DSH op en volgt Work’s containeropruiming. Na workerherstel ontvangt een nieuwe DSH-driver de herstelde context zonder voltooide tooleffecten te herhalen.
Deze integratie heeft geen hostenginecompositie of JSONL-opslag nodig. Ze volgt Work’s bestaande Docker/Kubernetes- en implementatieregels, inclusief gedeelde opslag in teammodus.
Beveiligingsgrens
De Engine-pagina en host-Chat-agent zijn alleen voor beheerders. Enginesessies vormen een gedeelde beheerdersconsole, inclusief systeemprompts, geen werkruimte per gebruiker. Gewone accounts kunnen ze niet via de API lezen, maken, wijzigen of annuleren.
De meegeleverde hostbestandstools beperken lezen en schrijven tot de ingestelde werkruimte via canonieke paden, inclusief symlinkresolutie. Afwijkende sessiewerkmappen moeten binnen die grens blijven. DSH’s wijzigingsbeleid en eenmalige goedkeuringen blijven gelden. Door operators geïnstalleerde compositieplugins zijn vertrouwde servercode en kunnen extra mogelijkheden bieden. Engine-goedkeuringen staan los van Work’s goedkeuring en containeruitvoering.
De Work-driver is afzonderlijk: geen hostbestandssysteem-, shell- of opslagplugins, en uitvoering alleen via Work’s bestaande autorisatie en sandbox. Externe modelproviders blijven optioneel en gebruiken de ingestelde route van de gekozen account.