Sari la conținutul principal

Puntea Cordis

Puntea integrează DeepSeek Harness (DSH) în backendul Libre WebUI. DSH rulează ca arbore de pluginuri într-un runtime Cordis găzduit de LWUI, astfel încât capacitățile sosesc ca servicii Cordis, nu module importate.

Puntea este oprită implicit. Comportamentul descris începe numai după activarea de către operator; vedeți Configurarea Cordis.

De ce punte, nu integrare directă

Importul direct al pachetelor DSH ar fi mai scurt, dar mai slab: motorul devine dependență la compilare. Schimbarea adaptorului, buclei agentului sau eliminarea motorului ar cere modificarea și redistribuirea Libre WebUI.

Puntea inversează relația. LWUI depinde de un contract abstract; documentul de compoziție alege implementarea:

  • Altă destinație fără reconstruire. Compoziția YAML permite schimbarea furnizorului prin configurare.
  • Configurarea capacităților. Fiecare este un rând Loader; schimbările operatorului se aplică la următoarea pornire a gazdei.
  • Eliminare curată. Fibra rădăcină deține toate serviciile, listenerele și efectele. Eliberarea ei retrage tot, fără restartul Libre WebUI.

Straturi

Dependențele concrete DSH rămân în backend/src/cordis/dsh/. Rutele și serviciile folosesc contractele punții. Driverul Work are compoziție separată în memorie și nu montează niciodată pluginuri de fișiere ale gazdei.

Contracte

Contractul din backend/src/cordis/contracts.ts cuprinde intenționat numai formele necesare API-ului, fără vocabular intern al motorului.

ContractScop
DshEngine.status()Ciclul de viață al serviciilor (pending / ready / failed)
DshEngine.modelConfiguration()Modelul și furnizorul implicite ale compoziției active
DshEngine.listSessions()Rezumatul sesiunilor, cele noi întâi
DshEngine.getSession(id)Sesiune cu mesajele proiectate
DshEngine.createSession(opts)Rezervarea ID-ului și directorului
DshEngine.updateSessionSettings(id, settings)Salvarea modelului real și permisiunilor native în repaus
DshEngine.decideApproval(id, approvalId, decision)Rezolvarea aprobării pentru sesiunea proprietară
DshEngine.deleteSession(id)Încheierea sesiunii și eliberarea agentului
DshEngine.listAgents()Agenți activi, rădăcină sau copii
DshEngine.listTools()Instrumente înregistrate vizibile modelului
DshEngine.sendMessage(id, txt)Începerea turei și returnarea handle-ului de flux
DshEngine.cancel(id)Anularea turei active

Este publicat ca serviciu Cordis libreDshEngine; consumatorul citește ctx.get('libreDshEngine'), fără importarea modulului punții.

EngineStreamChunk transportă text, reasoning, tool-call, tool-result, approval-request, approval-decision, error și done. Cadrele sunt rutate prin agentul și sesiunea proprietare; mesajul durabil corespunzător nu este emis din nou. sendMessage întoarce un handle al cărui subscribe reia datele deja emise, astfel încât primul token rapid nu se pierde înaintea atașării listenerului HTTP.

Secvența unei ture de chat

Se folosește NDJSON deoarece o tură este o singură secvență server–client după cerere. Păstrarea pe POST evită încă un handshake, ticket și protocol de reconectare și menține tura într-o cerere autentificată.

DONE și PENDING

Cordis activează pluginul când există serviciile declarate, deci un rând trece și prin stări anterioare rulării. Confundarea următoarelor concepte este cauza frecventă a motorului tăcut.

Starea intrării Loader. Rândul trece prin PENDING → LOADING → ACTIVE sau FAILED. Lipsa serviciilor îl lasă în așteptare permanentă, nu în eroare; o compoziție incompletă poate porni fără să servească nimic.

Disponibilitatea serviciului. Gazda raportează fiecare serviciu astfel:

StareSemnificațieCauză
pendingNeînregistrat în contextRândul furnizor nu s-a activat sau e oprit
readyÎnregistrat și utilizabilRândul furnizor s-a activat
failedDeclarat, dar inutilizabilRaportat cu text detail

host.status() arată disponibilitatea și cerințele lipsă; GET /api/cordis/health expune aceleași informații. Un serviciu obligatoriu lipsă provoacă eroare de pornire, nu publicarea unui motor cu liste goale.

Două lanțuri sunt ușor de greșit:

  • dsh-tools nu pornește fără systemPrompt.
  • dsh-agent-loop așteaptă agents, sessions, llm, tools, systemPrompt și sessionProjections.

Lipsa oricăruia poate lăsa stocarea funcțională, dar motorul nu răspunde niciunui mesaj.

Configurarea furnizorului

Rândul libre-webui-llm-adapter servește furnizorii configurați în LWUI. Selectorul Engine alege modelul sesiunii fără a înlocui rândul.

Schimbările compoziției se aplică la următoarea pornire. Reporniți backendul sau dezactivați/reactivați Cordis dacă comutatorul este deblocat. Sesiunile durabile rămân în depozit și reiau prin compoziția curentă.

Codul de integrare de încredere poate folosi direct API-urile lifecycle ale Loaderului. Puntea nu are endpoint de schimbare a adaptorului și nu restaurează automat vechiul adaptor dacă înlocuitorul eșuează.

Revenire

Eliberarea fibrei rădăcină elimină tot ce a instalat motorul. Această proprietate este garanția completă:

  • Serviciile înregistrate de pluginuri sunt retrase odată cu fibra.
  • Abonările session/event apar în constructorul punții și aparțin fibrei rândului său.
  • Puntea urmărește handle-urile agenților și le eliberează în efectul de închidere.
  • Gazda eliberează contextul rădăcină care deține toate rândurile.

stopCordisHost() este idempotent și legat de oprirea backendului; timerele și fișierele sunt eliberate, nu abandonate până la ieșirea procesului.

Identitatea și persistența sesiunilor

Engine rezervă un ID opac la creare. Cu persistență activă, antetul este stocat imediat, deci și o sesiune goală supraviețuiește restartului. Puntea listează sesiuni active și salvate, citește logurile prin API-ul validat DSH și reia agentul pe același ID pentru continuare. Mesajele noi folosesc constructorul DSH cu identificator.

Ștergerea anulează și eliberează agentul înaintea artefactului. Adaptorul JSONL validează depozitul și căile și refuză legături simbolice. Un backend personalizat fără ștergere întoarce eroare, nu pretinde că datele au dispărut.

Anularea ajunge la agent, model și instrumente. Deconectarea clientului anulează tura; mesajele finalizate rămân lizibile. Bufferul limitat păstrează răspunsul rapid dinaintea atașării cititorului.

Motorul gazdei este o funcție solo cu o singură replică. Team nu poate monta runtime-ul JSONL local. Work izolat folosește în schimb depozitele SQL existente pentru sarcini, execuții, mesaje, aprobări și evenimente.

Interfața HTTP

MetodăCaleScop
GET/api/cordis/healthStarea punții; fără autentificare
GET/api/cordis/sessionsListarea sesiunilor
POST/api/cordis/sessionsCrearea sesiunii
GET/api/cordis/sessions/:idCitirea sesiunii și mesajelor
DELETE/api/cordis/sessions/:idÎncheierea sesiunii
POST/api/cordis/sessions/:id/messagesMesaj și flux NDJSON
POST/api/cordis/sessions/:id/cancelAnularea turei active
GET/api/cordis/agentsListarea agenților activi
GET/api/cordis/toolsListarea instrumentelor

Toate rutele în afară de /health cer sesiune autentificată de administrator. Cât timp puntea nu poate servi, răspund 503 cu code CORDIS_DISABLED, CORDIS_STARTING sau CORDIS_UNAVAILABLE.

Pagina Cordis Engine cu sesiuni, instrumente înregistrate și conversație în flux.

Pagina frontend/src/pages/CordisPage.tsx este la /cordis din bara laterală. Listează și creează sesiuni, arată instrumente și transmite tura în conversație. Când puntea este oprită sau nu pornește, explică motivul în locul unei liste goale; altfel „fără sesiuni” și „fără motor” ar arăta identic.

Clientul frontend/src/utils/api/cordisApi.ts folosește numai această interfață, fără tipuri backend sau pachete @deepseek-ai/*. Motorul rămâne înlocuibil fără schimbări frontend. sendMessage(sessionId, text, { onChunk }) consumă tura; clientul parsează JSON pe linii și suportă fragmente împărțite între citiri de rețea.

Controalele chatului Engine

Pagina redă Markdown, tabele și cod evidențiat, cu copiere de răspuns și cod. Prompturile de sistem și contextul injectat stau în Session context, închis implicit, nu ca mesaje ale utilizatorului. Raționamentul expus și instrumentele au secțiuni separate; rezultatele rămân asociate operației corecte după reîncărcare.

Alegeți un model real al furnizorului dintre cele locale și plugin disponibile administratorului, păstrând identitatea furnizorului. Personele și agenții Chat nu sunt ID-uri de model și nu injectează instrucțiuni aici. Antetele vechi persona-model sunt ignorate ca indicii implicite fără schimbarea logului.

Fiecare sesiune are Read-only sau Workspace write, aplicate de politica DSH și granița canonică. Composerul arată domeniul. Setările sunt evenimente native durabile, valabile după restart; modificările în timpul turei sunt refuzate.

Cererea nativă de escaladare apare la operație ca Allow once / Deny. Aprobarea este doar pentru acea cerere și nu modifică modul permanent. Cererile expirate/anulate nu se aprobă, iar Chat headless refuză întrebările pe care nu le poate afișa. Puntea nu oferă acces nelimitat la gazdă.

Endpointuri administrative suplimentare:

MetodăCaleScop
GET/api/cordis/modelsModele disponibile și modelul real implicit curent
PATCH/api/cordis/sessions/:id/settingsSetarea modelului ori permisiunilor sesiunii
POST/api/cordis/sessions/:id/approvals/:approvalIdDecizie cu allowed-once sau rejected

Folosirea motorului în Chat

Activați Access & policies → Agent CLI models și Cordis Engine. Administratorii pot alege DeepSeek Harness în Chat. Fiecare cerere primește o sesiune nouă tranzitorie cu transcrierea furnizată. Baza Chat rămâne autoritatea; conversațiile distincte, ramurile și reîncercările nu împart istoric invizibil. Logul tranzitoriu este șters la finalizare/anulare și nu apare în Engine.

Compoziția standard oferă și DeepSeek Harness · model (provider) în Agents. ID-urile învelesc aceleași rute calificate ca pagina Engine: dsh:lwui:ollama:<model> sau dsh:lwui:plugin:<plugin>:<model>, cu componente codificate procentual. Conexiunea locală DSH nativă adaugă opțional dsh:native:<provider>:<model> din catalogul curent, refolosind setările și acreditările native.

Instalați pachetul Apache-2.0 din libre-webui/dsh-native-provider, sau pregătiți un bundle din distribuția LWUI. Ambele folosesc @libre-webui/dsh-native-provider și păstrează cheile în DSH. Cer aceeași gazdă Unix și același cont OS, cu socket privat; nu izolează aplicații care împart contul. Expun doar inferență, fără sesiuni agent sau instrumente native. Ghidul de configurare descrie instalarea, restartul profilului, actualizarea și eliminarea. Conexiunea sau modelul lipsă eșuează fără înlocuirea furnizorului. Apelurile native apar și în Provider Usage, cu model, tokenuri raportate, latență și rezultat.

Profilul de bază dsh păstrează modelul implicit al compoziției active. Adaptoarele personalizate oferă doar această bază, fără a promite suprascrieri LWUI nesuportate.

Titlurile și rezumatele de gândire rezolvă alegerea la furnizor și cer direct text fără instrumente ori sesiune agent. Baza citește implicitele motorului activ, inclusiv rândul punții, nu ghicește catalogul. Adaptoarele proprii necesită un model de sarcini Ollama sau plugin explicit. Furnizorul indisponibil produce eroarea obișnuită ori previzualizarea locală a titlului, nu apel către alt furnizor.

Cererea folosește setările și acreditările administratorului autentificat, niciodată implicit ale altuia. Spațiul Cordis configurat rămâne implicit; Chat nu îl înlocuiește cu directorul personal al utilizatorului serverului.

Work izolat

Cordis activ adaugă în Work Engine, cu Libre WebUI și DeepSeek Harness. Numele modelelor și identitățile furnizorilor rămân normale. Pentru furnizorii LWUI, DSH se salvează ca dsh:<model>; nativul păstrează providerType: dsh, ID-ul exact al furnizorului și modelul brut. Verificările de acces și instrumente rămân; acreditările native cer administrator activ.

Fiecare rulare creează buclă DSH izolată în memorie. Adaptorul primește conversația Work actuală, metadata furnizorului, imagini și scheme. Corpurile instrumentelor doar așteaptă rezultatele Work; nu citesc fișiere gazdă și nu pornesc procese gazdă.

Work validează argumente, cere aprobări, execută în spațiul configurat, salvează rezultate și replay provider în SQL, aplică bugete și publică evenimente. Refuzul produce rezultatul normal de refuz. Anularea eliberează DSH și urmează curățarea containerului Work. După recuperarea workerului, un driver nou primește contextul restaurat fără repetarea efectelor finalizate.

Nu sunt necesare compoziția gazdei sau JSONL. Se aplică regulile Work Docker/Kubernetes și de implementare, inclusiv persistența partajată team.

Granița de securitate

Engine și agentul Chat pe gazdă sunt numai pentru administratori. Sesiunile sunt o consolă comună inclusiv prompturile sistem, nu spații per utilizator. Conturile obișnuite nu le pot citi, crea, modifica sau anula prin API.

Instrumentele livrate limitează citirea/scrierea la spațiul configurat prin ținte canonice și rezolvarea symlinkurilor. Directorul alternativ al sesiunii trebuie să rămână în interior. Politica nativă DSH și aprobările unice rămân valabile. Pluginurile operatorului sunt cod server de încredere și pot adăuga capacități. Aprobările Engine sunt distincte de aprobările și containerele Work.

Driverul Work este separat: fără pluginuri de fișiere, shell sau persistență ale gazdei și numai cu autorizarea/sandboxul Work. Furnizorii externi rămân opționali și folosesc ruta configurată a contului selectat.