Jembatan Cordis
Jembatan Cordis menanamkan mesin DeepSeek Harness (DSH) di backend Libre WebUI. DSH berjalan sebagai pohon plugin dalam runtime Cordis yang dihosting Libre WebUI. Kemampuannya tersedia sebagai layanan Cordis, bukan modul yang diimpor langsung.
Jembatan dinonaktifkan secara default. Fitur dalam halaman ini baru berjalan setelah operator mengaktifkannya. Lihat Konfigurasi Cordis.
Mengapa jembatan, bukan integrasi langsung
Mengimpor paket DSH langsung dari layanan Libre WebUI memang mempersingkat kode, tetapi menjadikan mesin dependensi saat kompilasi. Mengganti adaptor model atau siklus agen, maupun menghapus mesin, akan memerlukan perubahan dan penerapan ulang Libre WebUI.
Jembatan membalik hubungan itu. Libre WebUI bergantung pada satu kontrak abstrak, sedangkan dokumen komposisi Cordis memilih implementasinya:
- Mengganti tujuan tanpa membangun ulang. Komposisi berupa YAML; beralih penyedia cukup melalui konfigurasi.
- Mengatur kemampuan. Setiap kemampuan adalah baris Loader. Perubahan komposisi operator berlaku saat host berikutnya dimulai.
- Menghapus tanpa sisa. Semua layanan, pendengar, dan efek mesin dimiliki fiber akar. Membersihkannya membatalkan semuanya sehingga mesin dapat dihentikan tanpa memulai ulang Libre WebUI.
Lapisan
Dependensi DSH yang konkret tetap berada di backend/src/cordis/dsh/. Rute dan layanan aplikasi menggunakan kontrak jembatan. Driver Work memiliki komposisi terpisah dalam memori dan tidak pernah memasang plugin sistem berkas host.
Kontrak
Kontrak berada di backend/src/cordis/contracts.ts. Cakupannya sengaja sempit: data yang diperlukan API Libre WebUI, tanpa istilah internal mesin.
| Kontrak | Tujuan |
|---|---|
DshEngine.status() | Status siklus hidup setiap layanan (pending / ready / failed) |
DshEngine.modelConfiguration() | Default model dan penyedia komposisi yang berjalan |
DshEngine.listSessions() | Ringkasan sesi, terbaru terlebih dahulu |
DshEngine.getSession(id) | Satu sesi beserta proyeksi pesannya |
DshEngine.createSession(opts) | Memesan ID sesi dan direktori kerja |
DshEngine.updateSessionSettings(id, settings) | Menyimpan pilihan model nyata dan mode izin berkas native saat tidak aktif |
DshEngine.decideApproval(id, approvalId, decision) | Memutuskan satu persetujuan alat native tertunda untuk sesi pemilik |
DshEngine.deleteSession(id) | Mengakhiri sesi dan membersihkan agennya |
DshEngine.listAgents() | Agen aktif dengan penanda akar atau anak |
DshEngine.listTools() | Alat untuk model yang didaftarkan mesin |
DshEngine.sendMessage(id, txt) | Memulai giliran dan mengembalikan handle stream |
DshEngine.cancel(id) | Membatalkan giliran sesi yang sedang berjalan |
Kontrak dipublikasikan sebagai layanan Cordis libreDshEngine. Konsumen membacanya dengan ctx.get('libreDshEngine'), tanpa mengimpor modul jembatan.
EngineStreamChunk membawa text, reasoning, tool-call, tool-result, approval-request, approval-decision, error, dan done. Frame langsung diarahkan menurut agen dan sesi pemiliknya; pesan asisten persisten yang sama tidak dikirim lagi. Handle dari sendMessage memiliki subscribe yang memutar ulang data yang sudah dikirim, sehingga token pertama yang cepat tidak hilang sebelum handler HTTP memasang pendengarnya.
Urutan: satu giliran chat
Giliran adalah satu urutan dari server ke klien setelah permintaan, sehingga menggunakan NDJSON. Menempatkannya dalam POST menghindari handshake, tiket, dan protokol penyambungan kedua, serta menjaga seluruh giliran dalam satu permintaan terautentikasi.
DONE dan PENDING
Cordis mengaktifkan plugin ketika layanan yang dideklarasikan tersedia. Karena itu, sebuah baris dapat berada dalam status belum berjalan. Dua konsep berikut harus dibedakan; mencampurnya sering membuat mesin terlihat tidak merespons.
Status entri Loader. Loader melacak PENDING → LOADING → ACTIVE atau FAILED. Baris dengan layanan yang belum tersedia terus menunggu, bukan gagal. Akibatnya, komposisi tidak lengkap dapat memulai mesin tanpa menyediakan apa pun.
Ketersediaan layanan. Host melaporkan setiap layanan yang diharapkan sebagai:
| Status | Arti | Penyebab |
|---|---|---|
pending | Belum terdaftar pada konteks | Baris penyedia belum aktif atau dinonaktifkan |
ready | Terdaftar dan dapat digunakan | Baris penyedia sudah aktif |
failed | Dideklarasikan, tetapi tidak dapat digunakan | Alasan diberikan dalam string detail |
host.status() mencantumkan semua layanan dan ketersediaannya serta menyebutkan layanan wajib yang hilang. GET /api/cordis/health memberi informasi yang sama. Komposisi tanpa layanan wajib menyebabkan kegagalan awal, bukan menerbitkan mesin yang menjawab dengan daftar kosong.
Dua rantai dependensi yang mudah keliru:
dsh-toolstidak dapat dimulai tanpasystemPrompt.dsh-agent-loopmemerlukanagents,sessions,llm,tools,systemPrompt, dansessionProjectionssekaligus.
Jika satu saja hilang, penyimpanan sesi mungkin berfungsi, tetapi mesin tidak akan menjawab pesan.
Konfigurasi penyedia
Baris bawaan libre-webui-llm-adapter melayani penyedia model yang dikonfigurasi di Libre WebUI. Pemilih model halaman mesin memilih model penyedia untuk sesi tanpa mengganti baris itu.
Perubahan baris plugin berlaku pada awal host berikutnya. Mulai ulang backend atau nonaktifkan lalu aktifkan Cordis jika kontrol administrator tidak dikunci. Sesi tersimpan tetap berada di penyimpanan dan dilanjutkan melalui komposisi sekarang.
Kode integrasi tepercaya dapat memakai API siklus hidup Cordis Loader secara langsung. Jembatan tidak menyediakan endpoint penggantian adaptor atau memulihkan adaptor lama otomatis jika penggantian gagal.
Rollback
Membersihkan fiber akar host menghapus semua yang dipasang mesin. Kepemilikan tunggal ini menjamin bahwa:
- Layanan didaftarkan plugin, sehingga ditarik bersama fibernya.
- Langganan
session/eventdidaftarkan di constructor jembatan sendiri dan dimiliki fiber baris jembatan. - Jembatan melacak handle agen dan melepaskannya dalam efek pembersihan.
- Host membersihkan konteks akar pemilik seluruh baris.
stopCordisHost() bersifat idempoten dan terhubung ke proses penghentian backend. Timer serta handle berkas dilepas, bukan dibiarkan menunggu proses berakhir.
Identitas dan persistensi sesi
Halaman mesin memesan ID sesi opak saat pembuatan. Jika persistensi aktif, header langsung disimpan sehingga sesi kosong pun bertahan setelah restart. Jembatan menampilkan sesi tersimpan dan aktif, membaca log melalui API persistensi tervalidasi DSH, serta melanjutkan agen dengan ID sama untuk giliran berikutnya. Pesan pengguna baru memakai constructor pesan beridentitas DSH.
Menghapus sesi membatalkan dan membersihkan agen sebelum menghapus artefaknya. Adaptor penghapusan JSONL lokal memvalidasi jalur penyimpanan dan sesi serta menolak tautan simbolis. Backend persistensi khusus tanpa dukungan penghapusan mengembalikan kesalahan, bukan mengaku data telah dihapus.
Pembatalan diteruskan ke agen native, permintaan model, dan pekerjaan alat. Klien yang terputus membatalkan gilirannya; pesan selesai tetap dapat dibaca. Buffer pemutaran ulang memiliki batas dan mempertahankan respons cepat sebelum pembaca tersambung.
Mesin host merupakan fitur solo dengan satu replika. Penerapan team tidak dapat memasang runtime JSONL lokalnya. Work dalam sandbox memakai repositori SQL tugas, proses, pesan, persetujuan, dan event yang sudah ada.
Antarmuka HTTP
| Metode | Jalur | Tujuan |
|---|---|---|
GET | /api/cordis/health | Status jembatan; tanpa autentikasi |
GET | /api/cordis/sessions | Daftar sesi |
POST | /api/cordis/sessions | Membuat sesi |
GET | /api/cordis/sessions/:id | Membaca sesi beserta pesan |
DELETE | /api/cordis/sessions/:id | Mengakhiri sesi |
POST | /api/cordis/sessions/:id/messages | Mengirim pesan dan menerima stream NDJSON |
POST | /api/cordis/sessions/:id/cancel | Membatalkan giliran berjalan |
GET | /api/cordis/agents | Daftar agen aktif |
GET | /api/cordis/tools | Daftar alat terdaftar |
Setiap rute selain /health memerlukan sesi administrator terautentikasi. Saat jembatan tidak dapat melayani, responsnya 503 dengan code berupa CORDIS_DISABLED, CORDIS_STARTING, atau CORDIS_UNAVAILABLE.

Halaman berada di frontend/src/pages/CordisPage.tsx dan dibuka dari sidebar melalui /cordis. Halaman menampilkan sesi dan alat, membuat sesi, serta mengalirkan giliran ke percakapan. Jika jembatan mati atau tidak dapat dimulai, alasan ditampilkan alih-alih daftar kosong, agar ketiadaan sesi dapat dibedakan dari ketiadaan mesin.
Klien browser berada di frontend/src/utils/api/cordisApi.ts. Ia hanya memakai antarmuka ini, tanpa tipe backend atau paket @deepseek-ai/*, sehingga mesin dapat diganti tanpa perubahan frontend. Giliran dibaca melalui sendMessage(sessionId, text, { onChunk }). Klien mem-parsing JSON berbatas baris sendiri dan menerima chunk yang terpotong di antara pembacaan jaringan.
Kontrol chat mesin
Halaman mesin merender Markdown, tabel, dan kode dengan penyorotan sintaks serta kontrol salin. Prompt sistem dan konteks runtime dikelompokkan dalam Konteks sesi yang tertutup, bukan sebagai pesan pengguna. Penalaran terbuka dan aktivitas alat memiliki bagian terpisah; setelah muat ulang, hasil tetap berpasangan dengan operasi yang benar.
Pilih model penyedia nyata di komposer. Pemilih menggunakan model lokal dan plugin yang tersedia bagi administrator yang masuk, lengkap dengan identitas penyedia. Pilihan persona dan agen Chat bukan ID model dan tidak menyisipkan instruksinya ke percakapan mesin. Header persona-model lama yang gagal diabaikan sebagai petunjuk default, tanpa mengubah log tersimpan.
Setiap sesi memiliki Hanya baca atau Tulis di ruang kerja. Kebijakan berkas DSH dan batas kanonik ruang kerja menerapkannya. Komposer menunjukkan lingkup ruang. Pengaturan disimpan sebagai event native dan bertahan setelah restart; perubahan ditolak selama giliran aktif.
Permintaan peningkatan izin native muncul sebagai kartu Izinkan sekali / Tolak pada operasi. Persetujuan hanya berlaku untuk permintaan itu dan tidak mengubah mode izin tetap. Permintaan usang atau dibatalkan tidak bisa disetujui; Chat tanpa UI menolak pertanyaan yang tidak dapat ditampilkan. Jembatan tidak memberi akses host tanpa batas.
Endpoint administrator tambahan:
| Metode | Jalur | Tujuan |
|---|---|---|
GET | /api/cordis/models | Model penyedia tersedia dan default model nyata saat ini |
PATCH | /api/cordis/sessions/:id/settings | Mengatur model dan/atau mode izin sesi |
POST | /api/cordis/sessions/:id/approvals/:approvalId | Memutuskan satu permintaan dengan allowed-once atau rejected |
Menggunakan mesin di Chat
Aktifkan Akses dan kebijakan → Model agen CLI dan Mesin Cordis. Administrator lalu dapat memilih DeepSeek Harness di Chat. Setiap permintaan mendapat sesi mesin sementara baru yang hanya berisi percakapan dari permintaan tersebut. Database Chat tetap menjadi sumber otoritatif; percakapan, cabang, dan percobaan ulang berbeda tidak berbagi riwayat mesin tersembunyi. Log sementara dihapus setelah selesai atau dibatalkan dan tidak muncul di halaman mesin.
Komposisi standar juga menyediakan DeepSeek Harness · model (penyedia) dalam grup Agen. ID tersimpan membungkus rute terkualifikasi yang sama dengan halaman mesin: dsh:lwui:ollama:<model> atau dsh:lwui:plugin:<plugin>:<model>, dengan komponen yang dikodekan persen. Koneksi lokal DSH native opsional menambahkan dsh:native:<provider>:<model> dari katalog langsung instans, menggunakan konfigurasi dan kredensial penyedia aslinya. Pasang paket mandiri Apache-2.0 dari libre-webui/dsh-native-provider atau siapkan bundle dari distribusi Libre WebUI. Keduanya memakai nama @libre-webui/dsh-native-provider dan menyimpan kunci di DSH. Koneksi memerlukan host Unix dan akun OS yang sama melalui soket privat; aplikasi dengan akun sama tidak saling diisolasi. Hanya inferensi tersedia, tanpa sesi agen atau eksekusi alat native. Panduan konfigurasi menjelaskan pemasangan, restart profil, pembaruan, dan penghapusan. Koneksi atau model yang hilang menyebabkan kegagalan tanpa pergantian penyedia. Panggilan native juga tampil di Penggunaan Penyedia, dengan model, token yang dilaporkan, latensi, dan hasil. Profil dasar dsh mempertahankan default komposisi berjalan. Adaptor khusus hanya menawarkan profil dasar, tanpa pilihan override penyedia Libre WebUI yang tidak didukung.
Judul dan ringkasan penalaran menyelesaikan pilihan DSH menjadi penyedia dasarnya lalu meminta teks langsung tanpa alat atau sesi agen. Profil dasar membaca default mesin berjalan, termasuk override baris jembatan, bukan menebak dari katalog. Adaptor khusus memerlukan model tugas Ollama atau plugin yang ditentukan. Penyedia tidak tersedia menghasilkan kegagalan biasa atau pratinjau judul lokal, bukan permintaan ke penyedia lain.
Permintaan memakai konfigurasi dan kredensial administrator terautentikasi. Kredensial administrator lain tidak dipilih diam-diam. Ruang Cordis yang dikonfigurasi tetap menjadi default; Chat tidak menggantinya dengan direktori home pengguna server.
Work dalam sandbox
Saat Cordis aktif, Work menyediakan kontrol Mesin terpisah dengan Libre WebUI dan DeepSeek Harness. Pemilih mempertahankan nama model dan identitas penyedia. Untuk penyedia LWUI, pilihan DSH disimpan sebagai dsh:<model>. Pilihan native menyimpan providerType: dsh, ID penyedia native yang tepat, dan ID model asli. Pemeriksaan kemampuan alat serta akses biasa tetap berlaku; kredensial native menambahkan syarat administrator aktif.
Setiap proses membuat loop agen DSH terisolasi dalam memori. Adaptor menerima percakapan Work, metadata penyedia, gambar, dan skema alat. Implementasi alat hanya menunggu hasil Work; tidak dapat membaca berkas atau menjalankan proses host.
Work tetap bertanggung jawab memvalidasi argumen, meminta persetujuan, menjalankan alat dalam runtime ruang kerja, menyimpan hasil dan status replay penyedia di SQL, menerapkan anggaran, dan menerbitkan event. Alat yang ditolak memberi hasil penolakan biasa. Pembatalan membersihkan DSH dan mengikuti pembersihan kontainer Work. Setelah worker pulih, driver baru menerima konteks Work yang dipulihkan tanpa mengulang efek alat yang telah selesai.
Integrasi Work tidak memerlukan komposisi mesin host atau penyimpanan JSONL. Ia mengikuti aturan runtime dan penerapan Docker/Kubernetes Work, termasuk persistensi bersama untuk mode team.
Batas keamanan
Halaman mesin dan agen Chat di host hanya untuk administrator. Sesi mesin beserta prompt sistem merupakan konsol administrator bersama, bukan ruang per pengguna. Akun biasa tidak dapat membaca, membuat, mengubah, atau membatalkannya melalui API.
Alat berkas host bawaan membatasi baca dan tulis ke ruang yang dikonfigurasi memakai target kanonik, termasuk penyelesaian tautan simbolis. Override direktori sesi harus tetap di dalam ruang itu. Kebijakan perubahan native DSH dan persetujuan sekali jalan tetap berlaku. Plugin komposisi dari operator adalah kode server tepercaya yang dapat memberi kemampuan tambahan. Persetujuan mesin berbeda dari persetujuan dan eksekusi kontainer Work.
Driver DSH Work terpisah: tidak memasang plugin berkas, shell, atau persistensi host dan hanya mengeksekusi melalui otorisasi serta sandbox Work. Penyedia jarak jauh tetap memerlukan pilihan eksplisit dan memakai rute yang dikonfigurasi untuk akun terpilih.