Cầu nối Cordis
Cầu nối Cordis nhúng bộ máy DeepSeek Harness (DSH) vào backend của Libre WebUI. DSH chạy dưới dạng cây plugin trong môi trường Cordis do Libre WebUI lưu trú, nên các khả năng được cung cấp dưới dạng dịch vụ Cordis thay vì mô-đun được nhập trực tiếp.
Cầu nối tắt theo mặc định. Mọi hoạt động trên trang này chỉ diễn ra sau khi người vận hành bật nó (xem Cấu hình Cordis).
Vì sao dùng cầu nối thay vì tích hợp trực tiếp
Nhập các gói DSH từ dịch vụ của Libre WebUI sẽ ngắn hơn nhưng kém phù hợp hơn. Nhập trực tiếp biến bộ máy thành phụ thuộc lúc biên dịch, nên thay bộ điều hợp mô hình, thay vòng lặp tác nhân hoặc gỡ bộ máy đều yêu cầu sửa và triển khai lại Libre WebUI.
Cầu nối đảo ngược quan hệ đó. Libre WebUI phụ thuộc vào một hợp đồng trừu tượng duy nhất; tài liệu thành phần Cordis quyết định cách đáp ứng hợp đồng:
- Đổi đích mà không biên dịch lại. Cấu trúc thành phần là tệp YAML, nên chuyển bộ máy sang nhà cung cấp khác chỉ là đổi cấu hình.
- Cấu hình khả năng. Mỗi khả năng là một dòng Loader. Thay đổi do người vận hành quản lý có hiệu lực khi host khởi động lần tiếp theo.
- Gỡ sạch. Mỗi dịch vụ, trình lắng nghe và hiệu ứng mà bộ máy tạo đều thuộc fiber gốc. Giải phóng fiber này thu hồi tất cả, nên có thể dừng bộ máy mà không khởi động lại Libre WebUI.
Các lớp
Các phụ thuộc DSH cụ thể nằm trong backend/src/cordis/dsh/. Route và dịch vụ ứng dụng sử dụng hợp đồng của cầu nối. Driver Work có cấu trúc riêng trong bộ nhớ và không bao giờ nạp plugin hệ thống tệp của host.
Hợp đồng
Hợp đồng nằm tại backend/src/cordis/contracts.ts. Phạm vi được cố ý giới hạn ở các cấu trúc API Libre WebUI cần, không sử dụng thuật ngữ nội bộ của bộ máy.
| Hợp đồng | Mục đích |
|---|---|
DshEngine.status() | Trạng thái vòng đời từng dịch vụ (pending / ready / failed) |
DshEngine.modelConfiguration() | Mô hình và nhà cung cấp mặc định của cấu trúc đang chạy |
DshEngine.listSessions() | Tóm tắt phiên, mới nhất trước |
DshEngine.getSession(id) | Một phiên với các thông điệp được chiếu |
DshEngine.createSession(opts) | Dành trước mã phiên và thư mục làm việc |
DshEngine.updateSessionSettings(id, settings) | Lưu mô hình thực tế và chế độ quyền hệ thống tệp native khi phiên rảnh |
DshEngine.decideApproval(id, approvalId, decision) | Giải quyết một yêu cầu duyệt công cụ native đang chờ cho phiên sở hữu |
DshEngine.deleteSession(id) | Kết thúc phiên và giải phóng tác nhân |
DshEngine.listAgents() | Các tác nhân đang chạy, phân biệt gốc và con |
DshEngine.listTools() | Công cụ cung cấp cho mô hình mà bộ máy đã đăng ký |
DshEngine.sendMessage(id, txt) | Bắt đầu lượt và trả về handle luồng |
DshEngine.cancel(id) | Hủy lượt đang chạy của phiên |
Hợp đồng được công bố thành dịch vụ Cordis libreDshEngine. Bên sử dụng đọc qua ctx.get('libreDshEngine') và không nhập mô-đun cầu nối.
EngineStreamChunk mang text, reasoning, tool-call, tool-result, approval-request, approval-decision, error và done. Khung trực tiếp được định tuyến theo tác nhân và phiên sở hữu; thông điệp trợ lý lưu bền tương ứng không được phát lần thứ hai. sendMessage trả về handle có subscribe phát lại mọi dữ liệu đã gửi, nên token đầu tiên dù rất nhanh cũng không mất giữa lúc bộ máy bắt đầu lượt và HTTP handler gắn trình lắng nghe.
Trình tự một lượt chat
Dùng NDJSON thay WebSocket vì mỗi lượt là một chuỗi từ server đến client sau yêu cầu. Giữ trong POST tránh bắt tay, vé và giao thức kết nối lại thứ hai, đồng thời giữ cả lượt trong một yêu cầu đã xác thực.
DONE và PENDING
Cordis kích hoạt plugin khi các dịch vụ mà plugin khai báo đã có. Vì vậy dòng có thể ở trạng thái chưa chạy. Hai khái niệm khác nhau rất quan trọng; nhầm chúng là nguyên nhân phổ biến nhất khiến bộ máy im lặng.
Trạng thái dòng Loader. Loader theo dõi mỗi dòng qua PENDING → LOADING → ACTIVE hoặc FAILED. Dòng thiếu dịch vụ đã khai báo sẽ chờ vô hạn thay vì báo lỗi. Do đó cấu trúc thiếu thành phần có thể tạo bộ máy khởi động nhưng không phục vụ gì.
Tính sẵn có của dịch vụ. Host báo từng dịch vụ dự kiến như sau:
| Trạng thái | Ý nghĩa | Nguyên nhân |
|---|---|---|
pending | Chưa đăng ký trong ngữ cảnh | Dòng cung cấp chưa kích hoạt hoặc bị tắt |
ready | Đã đăng ký và sử dụng được | Dòng cung cấp đã kích hoạt |
failed | Đã khai báo nhưng không dùng được | Báo kèm chuỗi detail |
host.status() liệt kê mọi dịch vụ dự kiến cùng khả năng sử dụng và nêu tên dịch vụ bắt buộc còn thiếu. GET /api/cordis/health cung cấp cùng thông tin. Nếu cấu trúc bỏ sót dịch vụ bắt buộc, khởi động sẽ báo lỗi thay vì xuất bản bộ máy trả về danh sách rỗng.
Hai chuỗi phụ thuộc dễ cấu hình sai:
dsh-toolskhông thể khởi động thiếusystemPrompt.dsh-agent-loopchỉ khởi động khi có đủagents,sessions,llm,tools,systemPromptvàsessionProjections.
Thiếu một trong số đó sẽ tạo kho phiên hoạt động nhưng bộ máy không bao giờ trả lời thông điệp.
Cấu hình nhà cung cấp
Dòng libre-webui-llm-adapter đi kèm phục vụ các nhà cung cấp mô hình đã cấu hình trong Libre WebUI. Bộ chọn trên trang bộ máy chọn mô hình nhà cung cấp cho phiên mà không thay dòng này.
Thay đổi các dòng plugin có hiệu lực ở lần host khởi động tiếp theo. Khởi động lại backend hoặc tắt rồi bật Cordis khi công tắc quản trị không bị khóa. Phiên đã lưu vẫn trong kho cấu hình và tiếp tục qua cấu trúc hiện tại.
Mã tích hợp đáng tin cậy có thể dùng trực tiếp API vòng đời Cordis Loader. Cầu nối không cung cấp endpoint đổi adapter và không tự khôi phục adapter cũ nếu adapter thay thế thất bại.
Hoàn tác
Giải phóng fiber gốc của host gỡ toàn bộ những gì bộ máy cài đặt. Quan hệ sở hữu này là toàn bộ bảo đảm, vì:
- Plugin đăng ký dịch vụ nên dịch vụ được thu hồi cùng fiber.
- Đăng ký theo dõi
session/eventnằm trong constructor của cầu nối và thuộc fiber dòng cầu nối. - Cầu nối theo dõi handle tác nhân và giải phóng chúng trong hiệu ứng dọn dẹp.
- Host giải phóng ngữ cảnh gốc sở hữu mọi dòng.
stopCordisHost() có tính lũy đẳng và được gắn vào quy trình dừng backend, nên timer và handle tệp được giải phóng thay vì chờ tiến trình thoát.
Danh tính phiên và lưu trữ bền
Trang bộ máy dành trước một mã phiên không trong suốt khi tạo. Bật lưu trữ bền sẽ lưu header ngay, nên cả phiên rỗng cũng tồn tại sau khởi động lại. Cầu nối liệt kê phiên đã lưu và đang hoạt động, đọc log qua API lưu trữ được DSH kiểm tra và tiếp tục tác nhân bằng cùng mã phiên ở lượt sau. Thông điệp người dùng mới dùng constructor thông điệp có định danh của DSH.
Xóa phiên sẽ hủy và giải phóng tác nhân trước khi xóa artefact. Adapter xóa JSONL cục bộ kiểm tra đường dẫn kho và phiên, đồng thời từ chối liên kết tượng trưng. Backend lưu trữ tùy chỉnh không hỗ trợ xóa sẽ trả lỗi thay vì tuyên bố đã xóa dữ liệu.
Lệnh hủy truyền đến tác nhân native, yêu cầu mô hình và công việc công cụ. Client ngắt kết nối sẽ hủy lượt; thông điệp hoàn tất vẫn đọc được. Phát lại bộ đệm có giới hạn và giữ phản hồi nhanh trước khi bên đọc kết nối.
Bộ máy trên host là tính năng solo chỉ một bản sao. Triển khai team không thể nạp runtime JSONL cục bộ này. Work trong sandbox dùng các repository SQL hiện có cho tác vụ, lượt chạy, thông điệp, phê duyệt và sự kiện.
Giao diện HTTP
| Phương thức | Đường dẫn | Mục đích |
|---|---|---|
GET | /api/cordis/health | Trạng thái cầu nối; không xác thực |
GET | /api/cordis/sessions | Liệt kê phiên |
POST | /api/cordis/sessions | Tạo phiên |
GET | /api/cordis/sessions/:id | Đọc phiên cùng thông điệp |
DELETE | /api/cordis/sessions/:id | Kết thúc phiên |
POST | /api/cordis/sessions/:id/messages | Gửi thông điệp, truyền NDJSON |
POST | /api/cordis/sessions/:id/cancel | Hủy lượt đang chạy |
GET | /api/cordis/agents | Liệt kê tác nhân đang chạy |
GET | /api/cordis/tools | Liệt kê công cụ đã đăng ký |
Mọi route trừ /health đều yêu cầu phiên quản trị đã xác thực và trả 503 với code là CORDIS_DISABLED, CORDIS_STARTING hoặc CORDIS_UNAVAILABLE khi cầu nối chưa phục vụ được.

Trang là frontend/src/pages/CordisPage.tsx, truy cập tại /cordis từ thanh bên. Trang liệt kê phiên và công cụ, tạo phiên và truyền lượt vào hội thoại. Khi cầu nối tắt hoặc không khởi động được, trang hiển thị nguyên nhân thay vì danh sách rỗng, vì nếu không thì “không có phiên” sẽ giống “không có bộ máy”.
Client trình duyệt là frontend/src/utils/api/cordisApi.ts. Nó chỉ giao tiếp với giao diện này, không nhập kiểu backend hay gói @deepseek-ai/*, nên có thể thay bộ máy mà không sửa frontend. Lượt được đọc bằng sendMessage(sessionId, text, { onChunk }); client tự phân tích JSON theo dòng và chấp nhận chunk bị chia giữa nhiều lần đọc mạng.
Điều khiển chat của bộ máy
Trang bộ máy hiển thị Markdown, bảng và khối mã tô cú pháp, với thao tác sao chép phản hồi và mã. Prompt hệ thống và ngữ cảnh runtime được chèn nằm trong phần Ngữ cảnh phiên đang thu gọn, không được trình bày như thông điệp của người dùng. Suy luận hiển thị và hoạt động công cụ có các phần riêng, và kết quả vẫn ghép đúng thao tác sau tải lại.
Chọn mô hình nhà cung cấp thực trong ô soạn thảo. Bộ chọn dùng các mô hình cục bộ và plugin có sẵn cho quản trị viên đăng nhập, kèm danh tính nhà cung cấp. Lựa chọn persona và tác nhân trong Chat không phải mã mô hình và không đưa chỉ dẫn vào cuộc hội thoại bộ máy. Header persona-model cũ bị lỗi được bỏ qua khi tìm mặc định mà không sửa log đã lưu.
Mỗi phiên có lựa chọn Chỉ đọc hoặc Ghi trong không gian làm việc, được thực thi bởi chính sách hệ thống tệp DSH và giới hạn workspace theo đường dẫn chuẩn của cầu nối. Ô soạn thảo cho biết phạm vi workspace. Cài đặt lưu thành sự kiện phiên native và tồn tại qua khởi động lại; thay đổi bị từ chối khi lượt đang chạy.
Yêu cầu nâng quyền native xuất hiện như thẻ Cho phép một lần / Từ chối gắn với thao tác. Phê duyệt chỉ áp dụng cho yêu cầu đó, không đổi chế độ quyền thường trực. Yêu cầu cũ hoặc đã hủy không thể được duyệt. Chat không có giao diện sẽ từ chối câu hỏi không thể hiển thị. Cầu nối không cấp quyền host không giới hạn.
Các endpoint bổ sung cho quản trị viên:
| Phương thức | Đường dẫn | Mục đích |
|---|---|---|
GET | /api/cordis/models | Mô hình nhà cung cấp khả dụng và mô hình thực mặc định hiện tại |
PATCH | /api/cordis/sessions/:id/settings | Đặt mô hình và/hoặc chế độ quyền của phiên |
POST | /api/cordis/sessions/:id/approvals/:approvalId | Quyết định yêu cầu chờ bằng allowed-once hoặc rejected |
Dùng bộ máy trong Chat
Bật cả Quyền truy cập và chính sách → Mô hình tác tử CLI và Công cụ Cordis. Quản trị viên sau đó có thể chọn DeepSeek Harness trong Chat. Mỗi yêu cầu nhận một phiên bộ máy tạm mới chứa bản hội thoại được gửi cùng yêu cầu Chat. Cơ sở dữ liệu Chat thông thường vẫn có thẩm quyền; hội thoại không liên quan, nhánh và lần thử lại không thể dùng chung lịch sử bộ máy vô hình. Log tạm bị xóa sau hoàn tất hoặc hủy và không xuất hiện trên trang bộ máy.
Cấu trúc nhà cung cấp tiêu chuẩn cũng liệt kê DeepSeek Harness · mô hình (nhà cung cấp) trong nhóm Tác nhân. Mã đã lưu bọc cùng route nhà cung cấp đầy đủ mà trang bộ máy dùng: dsh:lwui:ollama:<model> hoặc dsh:lwui:plugin:<plugin>:<model>, với từng thành phần nhà cung cấp được mã hóa phần trăm. Kết nối DSH native cục bộ tùy chọn thêm dsh:native:<provider>:<model> từ danh mục trực tiếp của instance đó. Chúng dùng lại cấu hình và thông tin xác thực nhà cung cấp native. Cài gói Apache-2.0 độc lập từ libre-webui/dsh-native-provider, hoặc chuẩn bị bundle từ bản phân phối Libre WebUI. Cả hai dùng tên @libre-webui/dsh-native-provider và giữ khóa nhà cung cấp trong DSH native. Kết nối cần cùng host Unix và tài khoản hệ điều hành, với Unix socket riêng; nó không cô lập các ứng dụng dùng chung tài khoản. Chỉ suy luận mô hình được cung cấp, không có phiên tác nhân hay thực thi công cụ native. Xem hướng dẫn cấu hình về cài đặt, khởi động lại profile, nâng cấp và gỡ bỏ. Thiếu kết nối hay mô hình đã chọn sẽ báo lỗi mà không đổi nhà cung cấp. Lượt gọi native cũng xuất hiện trong Mức sử dụng nhà cung cấp với mô hình, token báo cáo, độ trễ và trạng thái. Profile gốc dsh giữ mô hình mặc định của cấu trúc đang chạy. Cấu trúc adapter tùy chỉnh cung cấp profile gốc mà không quảng bá lựa chọn thay nhà cung cấp Libre WebUI không hỗ trợ.
Tiêu đề và tóm tắt suy nghĩ phân giải lựa chọn DSH về nhà cung cấp bên dưới, rồi gửi yêu cầu văn bản trực tiếp không công cụ hay phiên tác nhân. Yêu cầu profile gốc đọc mặc định của bộ máy đang chạy, gồm ghi đè ở dòng cầu nối, thay vì đoán từ danh mục. Adapter tùy chỉnh cần một mô hình tác vụ Ollama hoặc plugin được cấu hình rõ ràng. Nhà cung cấp đã chọn không khả dụng sẽ gây lỗi thông thường hoặc bản xem trước tiêu đề cục bộ, không chuyển sang nhà cung cấp khác.
Yêu cầu sử dụng cấu hình và thông tin xác thực của quản trị viên đã xác thực. Không chọn ngầm thông tin của quản trị viên khác. Workspace Cordis đã cấu hình vẫn là mặc định; Chat không thay bằng thư mục nhà của người dùng server.
Work trong sandbox
Khi Cordis được bật, Work có mục Bộ máy riêng với Libre WebUI và DeepSeek Harness. Bộ chọn giữ tên mô hình và danh tính nhà cung cấp thông thường. Lựa chọn DSH được lưu nội bộ thành dsh:<model> với nhà cung cấp LWUI. Lựa chọn native lưu providerType: dsh, mã nhà cung cấp native chính xác và mã mô hình nguyên gốc. Các kiểm tra công cụ và quyền truy cập vẫn áp dụng; thông tin xác thực native yêu cầu thêm quản trị viên đang hoạt động.
Mỗi lượt chạy tạo vòng lặp tác nhân DSH cô lập trong bộ nhớ. Adapter nhận hội thoại Work hiện tại, metadata nhà cung cấp, ảnh và schema công cụ. Phần thân công cụ chỉ chờ kết quả do Work trả về; không thể đọc tệp hay khởi chạy tiến trình host.
Work tiếp tục chịu trách nhiệm kiểm tra tham số, yêu cầu phê duyệt, chạy công cụ trong runtime workspace, lưu kết quả và trạng thái phát lại của nhà cung cấp trong SQL, áp ngân sách và phát sự kiện. Công cụ bị từ chối tạo kết quả từ chối bình thường. Hủy sẽ giải phóng DSH và theo quy trình dọn container Work. Sau phục hồi worker, driver DSH mới nhận ngữ cảnh đã khôi phục mà không lặp hiệu ứng công cụ đã hoàn tất.
Tích hợp Work không cần cấu trúc bộ máy host hay kho phiên JSONL. Nó theo quy tắc Docker/Kubernetes hiện tại của Work, bao gồm yêu cầu lưu trữ dùng chung của chế độ team.
Ranh giới bảo mật
Trang bộ máy và tác nhân Chat trên host chỉ dành cho quản trị viên. Phiên bộ máy là bảng điều khiển quản trị dùng chung, kể cả prompt hệ thống, không phải workspace riêng theo người dùng. Tài khoản thường không thể đọc, tạo, sửa hay hủy qua API.
Công cụ hệ thống tệp host đi kèm giới hạn đọc/ghi trong workspace bằng cách kiểm tra đích chuẩn, gồm phân giải liên kết tượng trưng. Thư mục làm việc riêng của phiên phải nằm trong giới hạn đó. Chính sách thay đổi native DSH và quyết định duyệt một lần vẫn áp dụng. Plugin cấu trúc do người vận hành cài là mã server đáng tin cậy và có thể cấp thêm khả năng. Phê duyệt bộ máy tách biệt với phê duyệt và chạy container của Work.
Driver DSH của Work tách riêng: không nạp plugin hệ thống tệp, shell hay lưu trữ của host và chỉ thực thi qua quyền cùng sandbox hiện có của Work. Nhà cung cấp từ xa vẫn là lựa chọn chủ động, dùng route cấu hình của tài khoản đã chọn.