Hiện trạng 27 màn hình · đề xuất sắp xếp lại theo UI/UX kiểu Claude · bảng màu Visual Studio Code · dựng lúc 21:26 15/08/2026
Phần 1 — Điều hướng · Phần 2 — Luồng người dùng · Phần 3 — 27 màn hình · Phần 4 — Màn chết
Dashboard Schedule Task Workspace ▼ ← nhánh accordion, tab strip bên trong BỊ ẨN Project Cowork ← TỰ ẨN khi chưa chọn project Co4E Folder GraphRAG ← TỰ ẨN khi chưa chọn project Monitoring ▼ ← nhánh accordion, tab strip BỊ ẨN Tổng quan Sự kiện bảo mật Lịch sử gọi MCP Nhật ký hành động Trạng thái Agent Agents Admin Công cụ Icon
[ + Đoạn chat mới ] ← hành động chính, trên cùng ────────────── Project ← màn đầu, giữ nguyên Cowork ← luôn hiện (mờ đi nếu chưa chọn project) Co4E Folder GraphRAG ← luôn hiện (mờ đi nếu chưa chọn project) Schedule Task ────────────── RECENTS ← History dời từ pane giữa lên đây · thread gần nhất… ────────────── (ghim đáy — nhóm phụ trợ) Dashboard ← vẫn 1 cú nhấp như cũ Monitoring ← BỎ ẨN dải tab, đủ 8 mục nằm ngang trong trang: [Tổng quan] [Sự kiện bảo mật] [Lịch sử gọi MCP] [Nhật ký hành động] [Trạng thái Agent] [Agents Admin] [Công cụ] [Icon] 👤 local · Provider ▾ ← gom Provider/Language/Theme/Settings
| Vấn đề | Chi tiết |
|---|---|
| Accordion 2 cấp, không phẳng | app.py:170 ghi là \“Claude-style\” nhưng là QTreeWidget accordion. Claude dùng danh sách phẳng. |
| Mục tự biến mất | workspace_tab.py:485 ẩn Cowork và GraphRAG khi chưa chọn project. |
| Tab strip bị ẩn | hide_tab_bar() ẩn dải tab có sẵn → menu là đường duy nhất. |
| History chỉ có ở tab Cowork | workspace_tab.py:169. Điểm làm tốt phải giữ: lịch sử đã gom theo project — lưu trong <project>/.cowork_history (config.py:590), hiển thị gom nhóm ở sidebar.py:193. |
| Monitoring gom 5 việc rời rạc | Chi phí · log bảo mật · quản trị agent · cấu hình tool · thư viện icon. |
| Dashboard trùng Monitoring ▸ Tổng quan | Cùng bộ StatCard + BudgetCard. |
| Top bar giữ thiết lập | Provider/Ngôn ngữ/Giao diện ở topbar, tách khỏi Cài đặt. |
| Header không đổi theo màn | Mọi sub-tab đều hiện \“Workspace — Projects\”. |
| LỖI: bấm mục con Workspace, menu nhảy về mục cha | _goto gọi refresh() (app.py:726) → subtabs_changed vô điều kiện (workspace_tab.py:497) → takeChildren() (app.py:691) huỷ mục vừa bấm.Đo được: 5/5 mục Workspace mất highlight, 0/8 mục Monitoring bị. |
Không thuộc màn nào nên liệt kê riêng.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| — | cây | lambda cur, _prev: self._navigate(cur); self._on_nav_click | app.py:175 | giữ nguyên tại chỗ |
| MENU | nút | self._toggle_nav | app.py:218 | Giữ — nút MENU gập sidebar (150↔54px) |
| — | droplist | self._on_provider_changed | app.py:559 | → menu tài khoản ở đáy sidebar |
| — | droplist | self._on_language_changed | app.py:568 | → menu tài khoản ở đáy sidebar |
| Cài đặt | nút | self._open_settings | app.py:586 | → menu tài khoản ở đáy sidebar |
| self._tray_open_act | menu chuột phải | — | app.py:329 | giữ nguyên tại chỗ |
| self._tray_quit_act | menu chuột phải | — | app.py:330 | giữ nguyên tại chỗ |
| _icon(icon_name | menu chuột phải | — | app.py:625 | giữ nguyên tại chỗ |
App có 11 chỗ gập được. Thiết kế mới giữ đủ cả 11.
| Chỗ gập được | Cách dùng | Nguồn | Thiết kế mới |
|---|---|---|---|
| Thanh menu chính | MENU ‹ ở đầu thanh — gập còn dải icon (150px → 54px) | app.py:409 | giữ |
| Pane Project | chevron ‹ trên đầu danh sách project | workspace_tab.py:368 | giữ |
| Pane Lịch sử | chevron trên đầu History, gập thành dải mỏng | sidebar.py:167 · workspace_tab.py:247 | giữ |
| Pane Tệp trong chat | chevron › — gập panel Files bên phải khung chat | chat_panel.py:709 | giữ |
| Panel Hỏi đáp GraphRAG | chevron › — gập panel agent bên phải đồ thị | structure_graph_view.py:615 | giữ |
| Panel cấu hình bước Co4E | nút gập panel phải của canvas | co4e_tab.py:767 | giữ |
| Panel Tin nhắn Co4E | gập khung log dưới canvas — mặc định đang gập | co4e_tab.py:894 | giữ |
| Terminal trong Thư mục | bấm thanh tiêu đề để mở/gập — mặc định đang gập | terminal_panel.py:156 | giữ |
| Panel AI sửa tệp | nút ✨ bật/tắt panel — mặc định đang ẩn | folder_tab.py:777 | giữ |
| Đồ thị ⇄ Tin nhắn (GraphRAG) | nút đổi nội dung pane trái | structure_graph_view.py:416 | giữ — đổi thành cặp tab |
| Khối kết quả công cụ trong chat | bấm tiêu đề để mở/gập output dài | chat_view.py:253 | giữ |
Không màn nào bị bỏ. Giám sát (Dashboard + 8 màn Monitoring) ở nhóm phụ trợ đáy sidebar, mở ra thấy đủ 8 tab.
| Màn hình | Hiện tại ở đâu | Sau khi sửa ở đâu | Chức năng |
|---|---|---|---|
| Màn hình làm việc | |||
| Workspace ▸ Project | Menu ▸ Workspace (mở nhánh) ▸ Project | Sidebar ▸ Project — lên cấp 1, bớt 1 lần mở nhánh | giữ nguyên |
| Workspace ▸ Cowork | Menu ▸ Workspace ▸ Cowork — biến mất nếu chưa chọn project | Sidebar ▸ Cowork — luôn thấy, mờ khi chưa chọn | giữ nguyên |
| Workspace ▸ Co4E | Menu ▸ Workspace ▸ Co4E | Sidebar ▸ Co4E | giữ nguyên |
| Workspace ▸ Folder (“Thư mục”) | Menu ▸ Workspace ▸ Thư mục | Sidebar ▸ Folder | giữ nguyên |
| Workspace ▸ GraphRAG | Menu ▸ Workspace ▸ GraphRAG — biến mất nếu chưa chọn project | Sidebar ▸ GraphRAG — luôn thấy | giữ nguyên |
| Schedule Task — Kanban | Menu ▸ Schedule Task | Sidebar ▸ Schedule Task ▸ tab Kanban | giữ nguyên |
| Schedule Task — Lịch | Menu ▸ Schedule Task ▸ combo đổi sang “Lịch” | Sidebar ▸ Schedule Task ▸ tab Lịch — combo thành tab, dễ thấy hơn | giữ nguyên |
| Giám sát & vận hành — phần bạn hỏi | |||
| Dashboard | Menu ▸ Dashboard (cấp 1) | Sidebar ▸ vùng đáy — vẫn 1 cú nhấp | giữ nguyên |
| Monitoring ▸ Tổng quan | Menu ▸ Monitoring (mở nhánh) ▸ Tổng quan | Sidebar ▸ Monitoring ▸ tab Tổng quan | giữ nguyên |
| Monitoring ▸ Sự kiện bảo mật | Menu ▸ Monitoring ▸ Sự kiện bảo mật | Sidebar ▸ Monitoring ▸ tab Sự kiện bảo mật | giữ nguyên |
| Monitoring ▸ Lịch sử gọi MCP | Menu ▸ Monitoring ▸ Lịch sử gọi MCP | Sidebar ▸ Monitoring ▸ tab Lịch sử gọi MCP | giữ nguyên |
| Monitoring ▸ Nhật ký hành động | Menu ▸ Monitoring ▸ Nhật ký hành động | Sidebar ▸ Monitoring ▸ tab Nhật ký hành động | giữ nguyên |
| Monitoring ▸ Trạng thái Agent | Menu ▸ Monitoring ▸ Trạng thái Agent | Sidebar ▸ Monitoring ▸ tab Trạng thái Agent | giữ nguyên |
| Monitoring ▸ Agents Admin | Menu ▸ Monitoring ▸ Agents Admin | Sidebar ▸ Monitoring ▸ tab Agents Admin | giữ nguyên |
| Monitoring ▸ Công cụ | Menu ▸ Monitoring ▸ Công cụ ▸ tab con Tool | Connector | Sidebar ▸ Monitoring ▸ tab Công cụ ▸ Tool | Connector | giữ nguyên |
| Monitoring ▸ Icon | Menu ▸ Monitoring ▸ Icon | Sidebar ▸ Monitoring ▸ tab Icon | giữ nguyên |
| Thành phần bị dời chỗ | |||
| History (lịch sử chat) | Pane giữa, chỉ ở tab Cowork. Đã gom theo project. | Sidebar ▸ RECENTS — vẫn gom theo project + “Tất cả project…” | giữ, dễ tới hơn |
| Bộ chọn project | Pane trái, chỉ ở tab Project | Thanh chọn đầu trang, dùng chung mọi màn | giữ, dễ tới hơn |
| Provider · Ngôn ngữ · Giao diện | Thanh trên cùng (topbar) | Menu tài khoản ở đáy sidebar — gom cùng chỗ với Cài đặt | giữ nguyên |
| Nút Cài đặt | Thanh trên cùng | Menu tài khoản ở đáy sidebar | giữ nguyên |
| Hộp thoại & lớp phủ | |||
| 11 hộp thoại | Mở từ nút trên các màn tương ứng | Không đổi — vẫn mở từ đúng những nút đó | giữ nguyên |
| Robot trợ giúp · Terminal · Composer | Lớp phủ / panel thu gọn | Không đổi | giữ nguyên |
Đầy đủ, kể cả nhóm không hiện ra màn hình.
| Nhóm | SL | Các mục | Nhìn thấy? | Nguồn |
|---|---|---|---|---|
| Thanh menu trái | 4 mục | Dashboard · Schedule Task · Workspace · Monitoring | có | app.py:154 |
| Workspace ▸ mục con | 5 mục | Project · Cowork · Co4E · Folder · GraphRAG | không — hide_tab_bar(), và Cowork/GraphRAG còn tự ẩn khi chưa chọn project | workspace_tab.py:43 |
| Monitoring ▸ mục con | 8 mục | Tổng quan · Sự kiện bảo mật · Lịch sử gọi MCP · Nhật ký hành động · Trạng thái Agent · Agents Admin · Công cụ · Icon | không — hide_tab_bar() | monitoring_tab.py:215 |
| Công cụ ▸ tab con | 2 tab | Tool · Connector | có — màn duy nhất còn hiện dải tab | tools_admin_tab.py:91 |
| Schedule ▸ chế độ xem | 2 chế độ | Kanban · Lịch | là combo, không phải tab | schedule_task_tab.py:171 |
| Kanban ▸ lane trạng thái | 7 lane | backlog · scheduled · running · waiting_input · done · failed · paused | cắt ở mép phải, phải cuộn ngang | tasks.py:24 |
| Co4E ▸ sidebar | 3 tab icon | Workflows · Agents · Skills | chỉ có icon, tên nằm trong tooltip | co4e_tab.py:426 |
| Co4E ▸ dải tab flow | 1 + N | Flow Status (ghim) + mỗi workflow đang mở một tab | có, kiểu trình duyệt | co4e_tab.py:556 |
| Folder ▸ trình xem | 5 trang | trống · mã nguồn · HTML · tài liệu · ảnh (+ bảng tính) | tự đổi theo đuôi tệp, không có tab | folder_tab.py:322 |
| GraphRAG ▸ khung trái | 2 trang | Đồ thị · Tin nhắn | là nút bấm, không phải tab | structure_graph_view.py:217 |
| Dialog Tạo task bằng AI | 2 tab | Sinh bằng AI · Nhập từ Excel | có | schedule_task_tab.py:530 |
| Dialog Kết nối ngoài | 2 chế độ | MCP (stdio) · REST API | là combo đổi trang | ext_connector_dialog.py:23 |
| Dialog Đăng nhập (màn chết) | 3 trang | Khởi tạo lần đầu · Đăng nhập · Dự phòng offline | không tới được | login_dialog.py:74 |
| Dialog Flow Builder (màn chết) | 3 tab | Flow · Agents · Skills | không tới được | flow_dialog.py:247 |
| Luồng | Hiện tại | Sau khi sửa |
|---|---|---|
| Khởi động → màn đầu | python -m cowork_local → MainWindow → Workspace ▸ Project Không có bước đăng nhập (LoginDialog bị bỏ qua) | Giữ nguyên đích đến. Sidebar phẳng nên Project là mục đầu, không còn nằm dưới nhánh Workspace. |
| Tạo project → chat | Nav ▸ Workspace (mở nhánh) → Project → “+” → điền form → Lưu → chọn project → nav ▸ Cowork (mục vừa mới xuất hiện) → gõ | Sidebar ▸ Project → “+” → Lưu → sidebar ▸ Cowork (luôn nhìn thấy) → gõ. Bớt 1 bước mở nhánh, và menu không đổi hình giữa chừng. |
| Co4E: tạo → chạy → xem run | Nav ▸ Workspace ▸ Co4E → “+” trên dải tab → kéo agent từ sidebar → chọn node → sửa ở panel phải → Lưu → Chạy → bấm tab Flow Status để xem | Sidebar ▸ Co4E → “+ Workflow” trong danh sách trái → kéo → sửa phải → Lưu → Chạy. Trạng thái run là một mục trong danh sách trái, không phải tab riêng. |
| Tạo & chạy scheduled task | Nav ▸ Schedule → “+ Task” → form 5 group → Lưu → kéo thẻ vào lane Running (chạy ngay, không hỏi) | Sidebar ▸ Schedule Task → “+ Task” → form 3 tab → Lưu → kéo vào Running (lane có viền cảnh báo). |
| Duyệt tệp → AI sửa | Nav ▸ Workspace ▸ Folder → chọn tệp → bấm ✨ mở panel AI → gõ lệnh → xem plan → xem diff → Apply | Sidebar ▸ Folder → chọn tệp → ✨ mở lớp phủ AI → gõ → plan → diff → Apply. Luồng giữ nguyên; panel không còn chiếm chỗ cố định. |
| Khía cạnh | Giao diện cũ | Giao diện mới | Có đồng bộ không |
|---|---|---|---|
| Số lối vào | 1 — nút “Cuộc trò chuyện mới” trên toolbar Cowork (cowork_tab.py:34) | 2 — nút sidebar + nút toolbar cũ giữ nguyên | Tôi vẽ thêm nút sidebar mà chưa nói gì về nút cũ. Giữ cả hai (bỏ nút cũ là xoá chức năng), cùng gọi một hàm. |
| Thấy được khi nào | Chỉ khi đang ở tab Cowork — mà tab này tự ẩn khi chưa chọn project | Luôn thấy trên sidebar | Mới dễ tới hơn. Chưa chọn project thì nút mờ đi. |
| Chat mới thuộc project nào | Project đang mở, ngầm định — không hiển thị ở đâu | Bộ chọn project ngay trên nút, trong sidebar | Cùng hành vi — vẫn là project đang mở (ctx.active_project_id), nhưng nay nhìn thấy và đổi được tại chỗ. |
| Đổi project trước khi tạo | Phải rời Cowork → về tab Project → chọn dòng trong danh sách → quay lại Cowork → bấm nút. 4 bước. | Bấm droplist ngay trên nút → chọn → bấm nút. 2 bước, không rời màn. | Ít bước hơn, không thêm chức năng — vẫn là chọn project rồi tạo chat. |
| Bấm từ màn khác | Không xảy ra được — nút chỉ có trên Cowork | Chuyển sang Cowork rồi tạo chat mới | Hành vi mới, cần thiết vì nút giờ ở mọi màn. |
| Việc thực sự làm | new_session() (chat_panel.py:1653): xoá messages · sinh session_id mới · dọn view, composer, plan, tệp vào/ra · turn đang chạy vẫn chạy nền | Giữ y nguyên | Không đổi. |
| Lưu chat cũ | Tự lưu; History refresh qua history_changed | Giữ y nguyên — RECENTS refresh | Không đổi. |
sidebar.py:68 khai báo tín hiệu
new_chat và workspace_tab.py:241 đã nối nó vào
_on_sidebar_new — nhưng không nơi nào phát tín hiệu này
(grep new_chat.emit → rỗng). Tức pane Lịch sử vốn được thiết kế để có nút
“chat mới” nhưng nút đó chưa bao giờ được thêm. Đề xuất đưa nút lên sidebar chính là
hoàn thiện ý định sẵn có trong code, không phải thêm mới.Token đã tiêu và chi phí quy ra tiền, theo kỳ.
Header: kỳ · granularity · metric · tiền tệ · 6 thẻ: Total · In · Out · Cache · Cost · Ngân sách · Biểu đồ: spline + đường so sánh kỳ trước · Thói quen: top task tốn token
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| Kỳ trước | nút | self._chart_prev | ui\dashboard_tab.py:59 | giữ nguyên tại chỗ |
| Kỳ sau | nút | self._chart_next | ui\dashboard_tab.py:67 | giữ nguyên tại chỗ |
| — | droplist | self._on_gran_changed | ui\dashboard_tab.py:71 | giữ nguyên tại chỗ |
| — | droplist | self._refresh_chart | ui\dashboard_tab.py:75 | giữ nguyên tại chỗ |
| Tiền tệ hiển thị (tỉ giá USD→VND/JPY cố định, sửa được trong | droplist | self._on_currency_changed | ui\dashboard_tab.py:84 | giữ nguyên tại chỗ |
| nút | self.refresh | ui\dashboard_tab.py:91 | → lên sidebar cùng RECENTS | |
| AI phân tích | nút | self._ai_analyze | ui\dashboard_tab.py:145 | giữ nguyên tại chỗ |
| Áp dụng chiến lược tiết kiệm | nút | self._apply_saving_strategy | ui\dashboard_tab.py:150 | giữ nguyên tại chỗ |
| f'{arrow} {self._title} ({self._count} | nút | self._toggle; self._toggle | ui\widgets.py:254 | giữ nguyên tại chỗ |
| — | danh sách | self._emit | ui\widgets.py:261 | giữ nguyên tại chỗ |
Kanban các tác vụ hẹn giờ. Bộ lập lịch chạy nền dù màn này đóng.
Lane: một cột mỗi trạng thái · Thẻ: kéo đổi lane · double-click sửa · chuột phải: Chạy ngay / Lịch sử
core.tasks.STATUSES — không gộp, không giấu lane nào. Lane hẹp lại để vừa một màn, hết cuộn ngang.| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| Thêm Task | nút | self._add_task | ui\schedule_task_tab.py:88 | giữ nguyên tại chỗ |
| AI tạo Task | nút | self._ai_create | ui\schedule_task_tab.py:92 | giữ nguyên tại chỗ |
| — | droplist | self._on_view_changed | ui\schedule_task_tab.py:95 | → đổi thành cặp tab Kanban | Lịch |
| len(runs | bảng | self._open_artifact | ui\schedule_task_tab.py:436 | giữ nguyên tại chỗ |
| QDialogButtonBox.Close | nút hộp thoại | — | ui\schedule_task_tab.py:461 | giữ nguyên tại chỗ |
| Project/workspace mà agent của task này sẽ chạy trong đó — á | droplist | — | ui\schedule_task_tab.py:523 | giữ nguyên tại chỗ |
| vd: Mỗi thứ 2 lúc 9h, dùng Code đọc dữ liệu CAE mới tạo báo | ô nhập nhiều dòng | — | ui\schedule_task_tab.py:537 | giữ nguyên tại chỗ |
| Đường dẫn tệp local, cách nhau bằng ; | ô nhập | — | ui\schedule_task_tab.py:544 | giữ nguyên tại chỗ |
| Chọn tệp… | nút | self._ai_pick_files | ui\schedule_task_tab.py:546 | giữ nguyên tại chỗ |
| https://… các link, cách nhau bằng ; | ô nhập | — | ui\schedule_task_tab.py:553 | giữ nguyên tại chỗ |
| Tạo kế hoạch | nút | self._generate | ui\schedule_task_tab.py:557 | giữ nguyên tại chỗ |
| Tạo template Excel… | nút | self._export_template | ui\schedule_task_tab.py:571 | giữ nguyên tại chỗ |
| Chọn file… | nút | self._pick_import_file | ui\schedule_task_tab.py:576 | giữ nguyên tại chỗ |
| QDialogButtonBox.Ok | QDialogButtonBox.Cancel | nút hộp thoại | — | ui\schedule_task_tab.py:592 | giữ nguyên tại chỗ |
| Chạy ngay | menu chuột phải | — | ui\schedule_task_tab.py:309 | giữ nguyên tại chỗ |
| Sửa task | menu chuột phải | — | ui\schedule_task_tab.py:310 | giữ nguyên tại chỗ |
| Nhân bản task | menu chuột phải | — | ui\schedule_task_tab.py:311 | giữ nguyên tại chỗ |
| schedtask.menu_resume' if paused else 'schedtask.menu_pause | menu chuột phải | — | ui\schedule_task_tab.py:313 | giữ nguyên tại chỗ |
| Xem log | menu chuột phải | — | ui\schedule_task_tab.py:314 | giữ nguyên tại chỗ |
| Lịch sử chạy… | menu chuột phải | — | ui\schedule_task_tab.py:315 | giữ nguyên tại chỗ |
| Tạo task tiếp theo từ output | menu chuột phải | — | ui\schedule_task_tab.py:316 | giữ nguyên tại chỗ |
| Xóa task | menu chuột phải | — | ui\schedule_task_tab.py:318 | giữ nguyên tại chỗ |
| schedtask.menu_delete_selected', n=len(selected | menu chuột phải | — | ui\schedule_task_tab.py:348 | giữ nguyên tại chỗ |
schedule_task_tab.py:265), không cảnh báo.Cùng dữ liệu Kanban, xếp theo ngày.
Ô ngày: nút + tạo task lúc 09:00 ngày đó
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| + | nút | lambda: self.add_requested.emit(self._date_str) | ui\calendar_view.py:43 | giữ nguyên tại chỗ |
| — | danh sách | self._on_item_clicked | ui\calendar_view.py:49 | giữ nguyên tại chỗ |
| Trước | nút | lambda: self._shift(-1) | ui\calendar_view.py:100 | giữ nguyên tại chỗ |
| Hôm nay | nút | self._go_today | ui\calendar_view.py:103 | giữ nguyên tại chỗ |
| Sau | nút | lambda: self._shift(1) | ui\calendar_view.py:105 | giữ nguyên tại chỗ |
| — | droplist | self._on_granularity_changed | ui\calendar_view.py:110 | giữ nguyên tại chỗ |
| — | danh sách | lambda item: self.show_month(self.anchor.year, item.data(Qt.UserRole)) | ui\calendar_view.py:213 | giữ nguyên tại chỗ |
Khai báo project — đơn vị gom nhóm của app. Mỗi project có sandbox riêng và Instructions chèn vào mọi chat. Đây là bộ chọn project duy nhất.
Trái: danh sách project — chỉ hiện ở tab này · Phải: Tên · Mô tả · Instructions · thư mục
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| Thu gọn danh sách project | nút | lambda: self._set_projects_collapsed(True) | ui\workspace_tab.py:90 | giữ nguyên tại chỗ |
| — | danh sách | self._on_select | ui\workspace_tab.py:97 | → giữ ở màn Quản lý project + thêm thanh chọn đầu trang |
| Project mới | nút | self._create | ui\workspace_tab.py:101 | giữ nguyên tại chỗ |
| Xóa | nút | self._delete | ui\workspace_tab.py:105 | giữ nguyên tại chỗ |
| — | dải tab | self._on_tab_changed | ui\workspace_tab.py:129 | giữ nguyên tại chỗ |
| project.name | ô nhập | — | ui\workspace_tab.py:193 | giữ nguyên tại chỗ |
| project.description | ô nhập | — | ui\workspace_tab.py:194 | giữ nguyên tại chỗ |
| vd: "Trả lời bằng tiếng Việt. Team đang xây tool báo cáo X; | ô nhập nhiều dòng | — | ui\workspace_tab.py:203 | giữ nguyên tại chỗ |
| Đổi thư mục… | nút | self._pick_folder | ui\workspace_tab.py:211 | giữ nguyên tại chỗ |
| Mở thư mục | nút | self._open_workspace | ui\workspace_tab.py:214 | giữ nguyên tại chỗ |
| Lưu project | nút | self._save | ui\workspace_tab.py:223 | giữ nguyên tại chỗ |
workspace_tab.py:310-338): Project → danh sách project, Cowork → History, còn lại → trống.Chat với agent. Agent đọc/ghi tệp trong sandbox, chạy lệnh, gọi MCP.
Lịch sử: chat gom theo project; nhãn đậm = tên project, chỉ là nhãn · Hội thoại: bong bóng theo trục thời gian · Files: tệp đầu ra, gập được · Composer: Enter gửi · /skill · /agent · Hàng dưới: thư mục sandbox (chỗ thứ 2 lộ project) · model · Định tuyến · Tự chạy
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| Skills | nút | self._open_skills_manager | ui\cowork_tab.py:30 | giữ nguyên tại chỗ |
| Cuộc trò chuyện mới | nút | self.new_session | ui\cowork_tab.py:34 | giữ nguyên tại chỗ |
| Thư mục Local… | nút | self._pick_output_folder | ui\cowork_tab.py:48 | giữ nguyên tại chỗ |
| Model/agent riêng cho tab này — độc lập với tab kia | droplist | self._on_agent_changed | ui\chat_panel.py:165 | giữ nguyên tại chỗ |
| Nén | nút | self._compress_messages | ui\chat_panel.py:177 | giữ nguyên tại chỗ |
| Thu gọn bảng Files | nút | lambda: self._set_io_collapsed(True) | ui\chat_panel.py:239 | giữ nguyên tại chỗ |
| app_icon('link | menu chuột phải | — | ui\chat_panel.py:439 | giữ nguyên tại chỗ |
| app_icon('edit | menu chuột phải | — | ui\chat_panel.py:440 | giữ nguyên tại chỗ |
| Nhấp đúp để xoá một tin nhắn khỏi hàng đợi | danh sách | self._remove_queue_item | ui\composer.py:406 | giữ nguyên tại chỗ |
| Bấm trên thẻ để gỡ tệp đính kèm nhầm | danh sách | self._remove_attachment | ui\composer.py:420 | giữ nguyên tại chỗ |
| nút | self._pick_attachments | ui\composer.py:443 | giữ nguyên tại chỗ | |
| composer.queue_btn') if self._busy else 'composer.send | nút | self._on_submit | ui\composer.py:446 | giữ nguyên tại chỗ |
| Dừng | nút | self.stop_requested.emit | ui\composer.py:450 | giữ nguyên tại chỗ |
| Gỡ tệp này (đính kèm nhầm | nút | lambda _=False, path=p: self._remove_attachment_path(path) | ui\composer.py:599 | giữ nguyên tại chỗ |
| Thu gọn bảng Lịch sử | nút | self.collapse_requested.emit | ui\sidebar.py:104 | giữ nguyên tại chỗ |
| Tìm theo tiêu đề hoặc nội dung… | ô nhập | self.refresh; self.refresh | ui\sidebar.py:119 | giữ nguyên tại chỗ |
| nút | self.refresh | ui\sidebar.py:123 | → lên sidebar cùng RECENTS | |
| — | cây | self._on_item; self._context_menu | ui\sidebar.py:132 | giữ nguyên tại chỗ |
| Làm mới | nút | self.refresh_requested.emit | ui\sidebar.py:147 | giữ nguyên tại chỗ |
| sidebar.menu.unpin') if pinned else 'sidebar.menu.pin | menu chuột phải | — | ui\sidebar.py:305 | giữ nguyên tại chỗ |
| Đổi tên… | menu chuột phải | — | ui\sidebar.py:306 | giữ nguyên tại chỗ |
| Xóa | menu chuột phải | — | ui\sidebar.py:307 | giữ nguyên tại chỗ |
| sidebar.menu.delete_selected', n=len(selected | menu chuột phải | — | ui\sidebar.py:332 | giữ nguyên tại chỗ |
| title | nút | self._toggle_body | ui\chat_view.py:228 | giữ nguyên tại chỗ |
| Tự động định tuyến model cho khung chat này. Tắt: luôn dùng | droplist | self._on_changed | ui\routing_toggle.py:66 | giữ nguyên tại chỗ |
| Tự chạy | ô tick | self._on_toggled | ui\routing_toggle.py:133 | giữ nguyên tại chỗ |
chat_panel.py:142-181).workspace_tab.py:323).ctx.active_project_id), không phải của riêng màn nào.Xưởng dựng workflow node-graph. Lưu toàn cục, không theo project.
Sidebar: 3 tab icon: Workflows · Agents · Skills — kéo thả được · Dải tab: Flow Status ghim + mỗi workflow một tab · Canvas: node và cạnh · Phải: cấu hình bước đang chọn
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| — | danh sách | lambda _i: self._accept() | ui\co4e_tab.py:144 | giữ nguyên tại chỗ |
| × | nút | lambda: self._close_flow_tab_button(btn) | ui\co4e_tab.py:341 | giữ nguyên tại chỗ |
| Chạy | nút | self._run_selected_in_background | ui\co4e_tab.py:459 | giữ nguyên tại chỗ |
| Mới | nút | self._new_agent | ui\co4e_tab.py:476 | giữ nguyên tại chỗ |
| Quản lý skill… | nút | self._manage_skills | ui\co4e_tab.py:493 | giữ nguyên tại chỗ |
| tip_key | nút | slot | ui\co4e_tab.py:502 | giữ nguyên tại chỗ |
| — | dải tab | self._on_flow_tab_changed; self._close_flow_tab | ui\co4e_tab.py:556 | → bỏ; chọn workflow từ danh sách trái |
| + | nút | self._new_workflow | ui\co4e_tab.py:582 | giữ nguyên tại chỗ |
| self._wf.name | ô nhập | self._on_name_changed | ui\co4e_tab.py:631 | giữ nguyên tại chỗ |
| Thêm | nút | self._add_blank_step | ui\co4e_tab.py:636 | giữ nguyên tại chỗ |
| Lưu | nút | lambda: self._save(as_template=False) | ui\co4e_tab.py:639 | giữ nguyên tại chỗ |
| Auto = mỗi bước tự lập kế hoạch rồi chạy · Plan = chỉ lập kế | droplist | self._on_mode_changed | ui\co4e_tab.py:645 | giữ nguyên tại chỗ |
| Chạy | nút | self._on_run_clicked | ui\co4e_tab.py:650 | giữ nguyên tại chỗ |
| short | nút | self._open_workspace_folder | ui\co4e_tab.py:693 | giữ nguyên tại chỗ |
| Dừng | nút | self._stop_selected_run | ui\co4e_tab.py:701 | giữ nguyên tại chỗ |
| Đổi tên | nút | self._rename_selected_run | ui\co4e_tab.py:706 | giữ nguyên tại chỗ |
| Xóa | nút | self._delete_selected_run | ui\co4e_tab.py:710 | giữ nguyên tại chỗ |
| Xóa đã xong | nút | lambda: self.manager.clear_finished() | ui\co4e_tab.py:714 | giữ nguyên tại chỗ |
| 0 | bảng | self._open_run_from_table; self._runs_context_menu | ui\co4e_tab.py:722 | giữ nguyên tại chỗ |
| Thu gọn bảng cấu hình | nút | self._toggle_config | ui\co4e_tab.py:747 | giữ nguyên tại chỗ |
| Mở rộng khung tin nhắn | nút | self._toggle_messages | ui\co4e_tab.py:841 | giữ nguyên tại chỗ |
| Gửi | nút | self._chat_send | ui\co4e_tab.py:873 | giữ nguyên tại chỗ |
| icon('edit | menu chuột phải | — | ui\co4e_tab.py:1014 | giữ nguyên tại chỗ |
| icon('edit | menu chuột phải | — | ui\co4e_tab.py:1015 | giữ nguyên tại chỗ |
| icon('branch | menu chuột phải | — | ui\co4e_tab.py:1016 | giữ nguyên tại chỗ |
| icon('play | menu chuột phải | — | ui\co4e_tab.py:1017 | giữ nguyên tại chỗ |
| icon('trash | menu chuột phải | — | ui\co4e_tab.py:1018 | giữ nguyên tại chỗ |
| Mở flow | menu chuột phải | — | ui\co4e_tab.py:1400 | giữ nguyên tại chỗ |
| Mở thư mục output | menu chuột phải | — | ui\co4e_tab.py:1404 | giữ nguyên tại chỗ |
| Đổi tên | menu chuột phải | — | ui\co4e_tab.py:1405 | giữ nguyên tại chỗ |
| Xóa | menu chuột phải | — | ui\co4e_tab.py:1406 | giữ nguyên tại chỗ |
| step.label | ô nhập | self._on_edit | ui\co4e_config_panel.py:44 | giữ nguyên tại chỗ |
| step.role | ô nhập | self._on_edit | ui\co4e_config_panel.py:48 | giữ nguyên tại chỗ |
| — | ô nhập nhiều dòng | self._on_edit | ui\co4e_config_panel.py:60 | giữ nguyên tại chỗ |
| Soạn bằng AI | nút | self._ai_draft | ui\co4e_config_panel.py:63 | giữ nguyên tại chỗ |
| Thông tin/ngữ cảnh bổ sung cho agent hoặc step này (thêm vào | ô nhập nhiều dòng | self._on_edit | ui\co4e_config_panel.py:77 | giữ nguyên tại chỗ |
| Tải danh sách model | nút | self._load_models | ui\co4e_config_panel.py:87 | giữ nguyên tại chỗ |
| — | droplist | self._on_edit | ui\co4e_config_panel.py:97 | giữ nguyên tại chỗ |
| Tự kiểm tra | ô tick | self._on_edit | ui\co4e_config_panel.py:104 | giữ nguyên tại chỗ |
| — | ô số | self._on_edit | ui\co4e_config_panel.py:106 | giữ nguyên tại chỗ |
| Đính kèm tệp | nút | self._add_attachment | ui\co4e_config_panel.py:125 | giữ nguyên tại chỗ |
| Bỏ | nút | self._del_attachment | ui\co4e_config_panel.py:128 | giữ nguyên tại chỗ |
| — | danh sách | self._edit_subagent | ui\co4e_config_panel.py:141 | giữ nguyên tại chỗ |
| Thêm | nút | self._add_subagent | ui\co4e_config_panel.py:144 | giữ nguyên tại chỗ |
| Bỏ | nút | self._del_subagent | ui\co4e_config_panel.py:147 | giữ nguyên tại chỗ |
| Chạy | nút | lambda: self.run_node.emit(self._node_id) | ui\co4e_config_panel.py:159 | giữ nguyên tại chỗ |
| Chạy từ đây | nút | lambda: self.run_from.emit(self._node_id) | ui\co4e_config_panel.py:163 | giữ nguyên tại chỗ |
| Xóa bước | nút | lambda: self.delete_node.emit(self._node_id) | ui\co4e_config_panel.py:166 | giữ nguyên tại chỗ |
| + Add next step | menu chuột phải | — | ui\co4e_canvas.py:188 | giữ nguyên tại chỗ |
| → Connect from here | menu chuột phải | — | ui\co4e_canvas.py:189 | giữ nguyên tại chỗ |
| 🗑 Delete step | menu chuột phải | — | ui\co4e_canvas.py:190 | giữ nguyên tại chỗ |
| 🗑 Delete connection | menu chuột phải | — | ui\co4e_canvas.py:368 | giữ nguyên tại chỗ |
Duyệt tệp + nhờ AI sửa. AI không ghi đè — đề xuất diff, bấm Apply mới ghi.
Cây trái: hệ thống tệp thật · Viewer: code / HTML / PDF / ảnh / bảng tính · Panel AI: yêu cầu → plan → diff → Apply · Terminal: shell thật, không qua sandbox
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| self._root | ô nhập | — | ui\folder_tab.py:265 | giữ nguyên tại chỗ |
| Mở thư mục | nút | self._pick_root | ui\folder_tab.py:267 | giữ nguyên tại chỗ |
| folder.edit') if not self.mode_btn.isChecked() else 'folder. | nút | self._toggle_edit_mode | ui\folder_tab.py:299 | giữ nguyên tại chỗ |
| AI Edit | nút | self._toggle_ai_panel | ui\folder_tab.py:304 | giữ nguyên tại chỗ |
| Lưu | nút | self._save | ui\folder_tab.py:309 | giữ nguyên tại chỗ |
| Mở bằng app ngoài | nút | self._open_external | ui\folder_tab.py:315 | giữ nguyên tại chỗ |
| len(rows | bảng | — | ui\folder_tab.py:534 | giữ nguyên tại chỗ |
| Mô tả chỉnh sửa… (vd: thêm xử lý lỗi | ô nhập | self._ai_send | ui\folder_tab.py:736 | giữ nguyên tại chỗ |
| Gửi | nút | self._ai_send | ui\folder_tab.py:740 | giữ nguyên tại chỗ |
| Hủy | nút | self._ai_discard | ui\folder_tab.py:752 | giữ nguyên tại chỗ |
| Áp dụng | nút | self._ai_apply | ui\folder_tab.py:755 | giữ nguyên tại chỗ |
| terminal.expand_tooltip') if self._collapsed else 'terminal. | nút | self.toggle | ui\terminal_panel.py:85 | giữ nguyên tại chỗ |
| — | ô nhập nhiều dòng | — | ui\terminal_panel.py:105 | giữ nguyên tại chỗ |
| Chạy | nút | self._run_current | ui\terminal_panel.py:130 | giữ nguyên tại chỗ |
| Mở bằng LibreOffice | nút | self._open_external | ui\libreoffice_view.py:97 | giữ nguyên tại chỗ |
Đồ thị tri thức về cấu trúc mã/tài liệu + agent hỏi đáp trên đó.
Đồ thị: node theo loại, cạnh có nhãn quan hệ · Phải: hỏi đáp dựa trên đồ thị
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| sctx.config.cowork_output_dir( | ô nhập | — | ui\structure_graph_view.py:220 | giữ nguyên tại chỗ |
| Browse… | nút | self._pick | ui\structure_graph_view.py:222 | giữ nguyên tại chỗ |
| Khóa phạm vi quét vào đúng thư mục sandbox của 1 project — p | droplist | self._on_project_changed | ui\structure_graph_view.py:226 | giữ nguyên tại chỗ |
| Scan | nút | self._scan | ui\structure_graph_view.py:228 | giữ nguyên tại chỗ |
| Xem mọi message hội thoại nhóm theo ngày (dạng JSON). | nút | self._toggle_messages | ui\structure_graph_view.py:242 | giữ nguyên tại chỗ |
| Xuất PNG | nút | self._export | ui\structure_graph_view.py:248 | giữ nguyên tại chỗ |
| — | cây | self._show_msg_json | ui\structure_graph_view.py:268 | giữ nguyên tại chỗ |
| Thu gọn bảng Agent | nút | lambda: self._set_agent_collapsed(True) | ui\structure_graph_view.py:288 | giữ nguyên tại chỗ |
| vd. cái gì gọi hàm main? file nào định nghĩa class? | ô nhập | self._ask | ui\structure_graph_view.py:299 | giữ nguyên tại chỗ |
| Hỏi | nút | self._ask | ui\structure_graph_view.py:301 | giữ nguyên tại chỗ |
Chi phí, tài nguyên máy, sandbox, nhật ký gần đây.
Trái: Token & chi phí · Hoạt động · Tài nguyên · Bảng giá model · Phải: Sandbox · Quyền · Audit log
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| Làm mới | nút | self.refresh | ui\monitoring_tab.py:149 | → lên sidebar cùng RECENTS |
| 0 | bảng | — | ui\monitoring_tab.py:175 | giữ nguyên tại chỗ |
| Lọc dòng (hoặc gõ câu hỏi rồi bấm )… | ô nhập | table.apply_filter | ui\monitoring_tab.py:347 | giữ nguyên tại chỗ |
| AI | nút | lambda: self._ai_filter(search, ai_btn) | ui\monitoring_tab.py:350 | giữ nguyên tại chỗ |
| — | droplist | self._reload_pricing_table | ui\monitoring_tab.py:486 | giữ nguyên tại chỗ |
| Nhập | nút | self._import_pricing | ui\monitoring_tab.py:496 | giữ nguyên tại chỗ |
| Mẫu | nút | self._export_pricing | ui\monitoring_tab.py:498 | giữ nguyên tại chỗ |
| Thêm | nút | self._add_pricing_row | ui\monitoring_tab.py:500 | giữ nguyên tại chỗ |
| Tự lấy | nút | self._autolink_pricing | ui\monitoring_tab.py:502 | giữ nguyên tại chỗ |
| Xóa | nút | self._delete_pricing_row | ui\monitoring_tab.py:504 | giữ nguyên tại chỗ |
| 0 | bảng | — | ui\monitoring_tab.py:510 | giữ nguyên tại chỗ |
| Sửa | nút | self._open_settings_and_refresh | ui\monitoring_tab.py:547 | giữ nguyên tại chỗ |
| Sửa | nút | self._open_settings_and_refresh | ui\monitoring_tab.py:573 | giữ nguyên tại chỗ |
| Xem tất cả | nút | lambda: self.tabs.setCurrentIndex(self.tabs.indexOf(self.action_page)) | ui\monitoring_tab.py:586 | giữ nguyên tại chỗ |
Nhật ký lần agent chạm thứ nhạy cảm: lệnh bị chặn, truy cập ngoài sandbox.
Trên: 4 thẻ KPI · Giữa: ô tìm + nút ✨AI, lọc Agent/Hành động/Thời gian · Dưới: bảng cột Hành động dạng badge màu (thay cho ✕/✓ luôn giống nhau) + phân trang, nhấp dòng mở panel chi tiết bên phải.
| ☐ | Thời gian | Agent | Tài khoản | Máy | Hành động | Chi tiết chặn |
|---|
audit_log.record("security_block",…) luôn truyền ok=False — dư thừa, không phân biệt được gì.ui/monitoring_tab.py:_wrap_with_filter).name thật (prompt/run_command/install_package).ui/monitoring_tab.py trước khi hiện thực, và 2/4 loại "Hành động" (path ngoài sandbox, mạng chặn) chưa có nguồn ghi log thật.Mọi lần agent gọi MCP server ngoài.
Trên: 4 thẻ KPI · Giữa: ô tìm + nút ✨AI, lọc Server/Kết quả/Thời gian · Dưới: bảng có badge Kết quả (✓/✕ phân biệt thật theo ok) + phân trang, nhấp dòng mở panel chi tiết bên phải. Bảng hiện tại (ảnh trên) không có ô lọc/tìm kiếm nào — khác biệt không chủ đích so với 2 màn log kia.
| Thời gian | Agent | Tài khoản | Máy | Tool | Kết quả | Chi tiết |
|---|
ui/monitoring_tab.py:166-168 tạo thẳng self.mcp_table = _EventTable() rồi thêm vào tab, không bọc qua _wrap_with_filter như Sự kiện bảo mật/Nhật ký hành động — đúng như đã ghi ở ảnh Hiện tại.ui/monitoring_tab.py:_EventTable).core/mcp_client.py — server thật phụ thuộc Admin đã cấu hình connector nào ở Settings, không có sẵn mặc định.ui/monitoring_tab.py trước khi hiện thực; danh sách server chỉ minh hoạ, không phải cấu hình mặc định.Nhật ký cấp ứng dụng: ai đổi cấu hình, ai chạy task.
| Thời gian | Agent | Loại | Máy | Hành động | Kết quả | Chi tiết |
|---|---|---|---|---|---|---|
| 15/08 · 09:42 | CACowork Agent | Gọi MCP | DESKTOP-DEMO | ms365__send_mail | ✓ Thành công | Đã gửi email đến nam.pdt@company.com — chủ đề "Báo cáo tuần Q3". |
| 15/08 · 09:38 | CACowork Agent | Công cụ | DESKTOP-DEMO | read_file | ✓ Thành công | Đã đọc ./docs/installation.md (172 dòng). |
| 15/08 · 09:31 | SASecurity Agent | Chặn bảo mật | DESKTOP-DEMO | dangerous_command | ✕ Thất bại | Chặn lệnh: rm -rf / --no-preserve-root |
| 15/08 · 09:20 | CACowork Agent | Quyền | DESKTOP-DEMO | path_outside_sandbox | ✕ Thất bại | Chặn đọc C:\Users\NamPDT\Documents\personal.xlsx — ngoài sandbox. |
| 15/08 · 08:55 | SASecurity Agent | Gọi MCP | DESKTOP-DEMO | brave__web_search | ✓ Thành công | Trả về 8 kết quả cho "CVE-2026-1234". |
| 14/08 · 17:45 | SCschedule | Công cụ | DESKTOP-DEMO | run_command | ✓ Thành công | python scripts/report.py — thoát mã 0. |
ui/monitoring_tab.py:_EventTable) gộp cả 4 loại sự kiện (tool_call/mcp_call/security_block/permission) vào tab này nhưng không có cột phân loại — phải tự suy ra loại hành động từ cột "Tên"._wrap_with_filter) chỉ có 1 ô tìm + nút ✨AI; 3 dropdown Loại/Trạng thái/Thời gian, 4 thẻ KPI, phân trang và nút Xuất CSV trong 12.ui-redesign-action-logs.html đều là tính năng mới, chưa có trong code._MAX_ROWS dòng mới nhất và không phân trang — không biết còn bao nhiêu sự kiện bị ẩn..pill đã áp cho Sự kiện bảo mật (mục 10).ui/monitoring_tab.py trước khi hiện thực — hiện bảng thật chỉ lọc bằng 1 ô tìm text.Agent nào đang bật và nguồn định nghĩa.
| Agent | Trạng thái | Nguồn |
|---|---|---|
| 👤Cowork Agent | ● Rảnh | Lượt đang chạy của tab Cowork |
| ⏱Task Agent | ● Rảnh | Task đang chạy trong Schedule Task |
| ◈Knowledge Agent | ● Rảnh | Ô hỏi của GraphRAG |
| ▦Planner Agent | — | Một giai đoạn trong lượt Cowork/Task đang chạy (update_plan) — không theo dõi riêng |
| ⬡Reasoning Agent | — | Luồng suy luận (reasoning) của model trong lượt đang chạy — không theo dõi riêng |
| 🛡Security Agent | ● Bật | Kiểm duyệt prompt/đính kèm/lệnh của Agent Security — chạy inline trong lượt đang chạy |
ui/monitoring_tab.py:_refresh_agent_status) chỉ dùng chữ/icon đơn cho trạng thái — khó quét nhanh dòng nào đang chạy khi bảng dài.Quản trị agent hệ thống. Cũng là nơi chọn model cho robot trợ giúp.
Nút Kiểm tra: probe provider thật
| Tên | Vai trò | Model | Kích hoạt | Trạng thái | Cập nhật | |
|---|---|---|---|---|---|---|
| SASecurity Agent | Bảo mật | Ollama — qwen2.5:7b | OK | 11/08 09:30 | ✎ 🗑 | |
| GAGraphRAG Agent | Tri thức | Ollama — qwen2.5:14b | OK | 10/08 14:22 | ✎ 🗑 | |
| MAMonitor Agent | Giám sát | Mặc định — qwen2.5:7b | Kiểm tra… | 09/08 11:05 | ✎ 🗑 | |
| HAHelp Assistant | Hỗ trợ | Mặc định — qwen2.5:7b | Chưa kiểm tra | 08/08 16:40 | ✎ 🗑 |
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| agent.name if agent else | ô nhập | — | ui\agents_admin_tab.py:55 | giữ nguyên tại chỗ |
| agent.prompt if agent else | ô nhập nhiều dòng | — | ui\agents_admin_tab.py:65 | giữ nguyên tại chỗ |
| — | droplist | self._refresh_model_combo | ui\agents_admin_tab.py:70 | → menu tài khoản ở đáy sidebar |
| Lấy danh sách model thực tế của provider này để chọn từ drop | nút | self._load_live_models | ui\agents_admin_tab.py:89 | giữ nguyên tại chỗ |
| Kích hoạt | ô tick | — | ui\agents_admin_tab.py:98 | giữ nguyên tại chỗ |
| QDialogButtonBox.Save | QDialogButtonBox.Cancel | nút hộp thoại | — | ui\agents_admin_tab.py:101 | giữ nguyên tại chỗ |
| 0 | bảng | — | ui\agents_admin_tab.py:169 | giữ nguyên tại chỗ |
| Thêm | nút | self._add | ui\agents_admin_tab.py:178 | giữ nguyên tại chỗ |
| Sửa | nút | self._edit | ui\agents_admin_tab.py:182 | giữ nguyên tại chỗ |
| Xóa | nút | self._delete | ui\agents_admin_tab.py:185 | giữ nguyên tại chỗ |
| Kiểm tra | nút | self._check_all | ui\agents_admin_tab.py:188 | giữ nguyên tại chỗ |
_check_all trong ui/agents_admin_tab.py) — cần chỗ khác để gọi (icon riêng theo dòng, hoặc menu ⋯).monitoring.refresh toàn màn hình) và + Thêm (giống nút agents_admin.add_btn thật) — Sửa/Xoá đã dời vào từng dòng nên không cần ở đây nữa.Bật/tắt công cụ dựng sẵn và khai báo kết nối ngoài. Màn duy nhất còn hiện dải tab bên trong.
Tool: công cụ dựng sẵn + tự kiểm tra Internet · Connector: MCP · REST · MS365 · Jira
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| — | ô tick | on_toggle | ui\tools_admin_tab.py:32 | giữ nguyên tại chỗ |
| 0 | bảng | — | ui\tools_admin_tab.py:57 | giữ nguyên tại chỗ |
| Kiểm tra Internet | nút | self._test_internet | ui\tools_admin_tab.py:72 | giữ nguyên tại chỗ |
| Làm mới | nút | self.refresh | ui\tools_admin_tab.py:80 | → lên sidebar cùng RECENTS |
| Dán bất kỳ link Jira nào — tự điền Base URL | ô nhập | self._on_paste | ui\connectors_panel.py:42 | giữ nguyên tại chỗ |
| jira.get('base_url', | ô nhập | — | ui\connectors_panel.py:46 | giữ nguyên tại chỗ |
| jira.get('email', | ô nhập | — | ui\connectors_panel.py:48 | giữ nguyên tại chỗ |
| jira.get('api_token', | ô nhập | — | ui\connectors_panel.py:49 | giữ nguyên tại chỗ |
| Kiểm tra kết nối | nút | self._test | ui\connectors_panel.py:58 | giữ nguyên tại chỗ |
| Lưu | nút | self._save_close | ui\connectors_panel.py:60 | giữ nguyên tại chỗ |
| Kết nối tới connector bên ngoài | ô tick | self._on_connect_external_toggled | ui\connectors_panel.py:133 | giữ nguyên tại chỗ |
| — | cây | lambda *_: self._ext_edit() | ui\connectors_panel.py:144 | giữ nguyên tại chỗ |
| Thêm connector… | nút | self._ext_add | ui\connectors_panel.py:155 | giữ nguyên tại chỗ |
| Sửa | nút | self._ext_edit | ui\connectors_panel.py:159 | giữ nguyên tại chỗ |
| Xóa | nút | self._ext_delete | ui\connectors_panel.py:162 | giữ nguyên tại chỗ |
core/tools.py:TOOL_SPECS) dạng chữ phẳng (☑/☐) — không thấy ngay tool nào đang bật khi lướt nhanh.ui/connectors_panel.py) — phải bung từng nhóm mới thấy có gì bên trong._ext_edit/_ext_delete thật; Jira (built-in) chỉ có ✎ Sửa (mở dialog cấu hình riêng, không xóa được); OneDrive/SharePoint (built-in MS365) không có nút nào — thật cũng chỉ bật/tắt, không sửa/xóa.tools_admin_tab.py:_fetch_url_desc_cell — nút này gắn với khả năng fetch_url, không phải một hành động chung của cả tab.Thư viện icon, dùng lại khi đặt icon cho agent Co4E.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| Tìm icon có sẵn… | ô nhập | self._reload_builtin | ui\icons_admin_tab.py:43 | giữ nguyên tại chỗ |
| Thêm tệp SVG | nút | self._add_icon | ui\icons_admin_tab.py:58 | giữ nguyên tại chỗ |
| Dán SVG | nút | self._add_from_svg_text | ui\icons_admin_tab.py:60 | giữ nguyên tại chỗ |
| Xóa tùy chỉnh | nút | self._delete_icon | ui\icons_admin_tab.py:62 | giữ nguyên tại chỗ |
Thiết lập toàn app. Cuộn dọc, không mục lục.
5 nhóm: Ngôn ngữ · Provider · Bảo mật (khoá mật khẩu) · Tham số · Routing
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| Giữ chạy nền trong khay hệ thống khi đóng cửa sổ | ô tick | — | ui\settings_dialog.py:56 | giữ nguyên tại chỗ |
| Hiện thông báo khay hệ thống khi tác vụ xong hoặc lỗi | ô tick | — | ui\settings_dialog.py:59 | giữ nguyên tại chỗ |
| — | droplist | self._on_provider_edit_changed | ui\settings_dialog.py:70 | → menu tài khoản ở đáy sidebar |
| conf.get('base_url', | ô nhập | — | ui\settings_dialog.py:77 | giữ nguyên tại chỗ |
| ô nhập | — | ui\settings_dialog.py:103 | giữ nguyên tại chỗ | |
| Unlock | nút | self._sandbox_unlock | ui\settings_dialog.py:107 | giữ nguyên tại chỗ |
| Xác nhận trước khi Cowork chạy lệnh | ô tick | — | ui\settings_dialog.py:121 | giữ nguyên tại chỗ |
| Chặn mạng cho lệnh do agent chạy | ô tick | — | ui\settings_dialog.py:126 | giữ nguyên tại chỗ |
| Enable Agent Security (command validation | ô tick | — | ui\settings_dialog.py:136 | giữ nguyên tại chỗ |
| AI check commands | ô tick | — | ui\settings_dialog.py:142 | giữ nguyên tại chỗ |
| Số tệp tối đa đính kèm vào một tin nhắn. | ô số | — | ui\settings_dialog.py:178 | giữ nguyên tại chỗ |
| Giới hạn nội dung mỗi tệp đính kèm đưa vào prompt; phần vượt | ô số | — | ui\settings_dialog.py:183 | giữ nguyên tại chỗ |
| Giới hạn số node trong đồ thị Cấu trúc (0 = không giới hạn). | ô số | — | ui\settings_dialog.py:194 | giữ nguyên tại chỗ |
| Giới hạn số cạnh trong đồ thị Cấu trúc (0 = không giới hạn). | ô số | — | ui\settings_dialog.py:200 | giữ nguyên tại chỗ |
| routing.get('judge_model', | ô nhập | — | ui\settings_dialog.py:279 | giữ nguyên tại chỗ |
| Đánh giá lại ngay | nút | self._routing_reassess_now | ui\settings_dialog.py:282 | giữ nguyên tại chỗ |
| QDialogButtonBox.Save | QDialogButtonBox.Cancel | nút hộp thoại | — | ui\settings_dialog.py:299 | giữ nguyên tại chỗ |
| value | ô nhập | — | ui\settings_dialog.py:316 | giữ nguyên tại chỗ |
| Tải | nút | lambda: self._load_models(self.provider_combo.currentData(), combo, st | ui\settings_dialog.py:368 | giữ nguyên tại chỗ |
| Test kết nối | nút | lambda: self._test_connection(self.provider_combo.currentData(), statu | ui\settings_dialog.py:374 | giữ nguyên tại chỗ |
| code | ô nhập | — | ui\settings_dialog.py:496 | giữ nguyên tại chỗ |
| Copy mã | nút | lambda: QGuiApplication.clipboard().setText(code) | ui\settings_dialog.py:503 | giữ nguyên tại chỗ |
| Mở link | nút | lambda: webbrowser.open(flow.get('verification_uri_complete') or url) | ui\settings_dialog.py:506 | giữ nguyên tại chỗ |
settings_dialog.py:115).ui/settings_dialog.py, chỉ đổi cách trình bày chứ không đổi dữ liệu.Khai báo tác vụ hẹn giờ: nội dung, lịch lặp, phụ thuộc, thông báo.
5 nhóm: Cơ bản · Lịch · Đầu vào · Phụ thuộc · Thực thi
Cùng 1 dialog TaskEditorDialog cho cả Thêm task và Sửa task — chỉ đổi tiêu đề (Thêm/Sửa), bố cục dưới đây dùng chung cho cả hai. Layout theo đúng kiểu màn Cài đặt: danh sách 5 nhóm bên trái thay cho 3 tab wizard, đúng 5 QGroupBox thật (không phải 3 bước tự đặt ra).
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| self.task.get('title', | ô nhập | — | ui\task_editor_dialog.py:96 | giữ nguyên tại chỗ |
| self.task.get('description', | ô nhập nhiều dòng | — | ui\task_editor_dialog.py:100 | giữ nguyên tại chỗ |
| nút | self._gen_prompt_from_description | ui\task_editor_dialog.py:102 | giữ nguyên tại chỗ | |
| — | droplist | self._refresh_model_combo | ui\task_editor_dialog.py:135 | → menu tài khoản ở đáy sidebar |
| Tải danh sách model của provider này | nút | self._load_live_models | ui\task_editor_dialog.py:147 | giữ nguyên tại chỗ |
| AI agent = chạy một agent Cowork với model đã chọn. Co4E flo | droplist | self._on_run_kind_changed | ui\task_editor_dialog.py:170 | giữ nguyên tại chỗ |
| Flow Co4E đã lưu mà task này sẽ chạy (có sẵn hoặc của bạn). | droplist | — | ui\task_editor_dialog.py:176 | giữ nguyên tại chỗ |
| Thông thường = chạy một lần (hoặc thủ công). Tự động = cronj | droplist | self._on_task_mode_changed | ui\task_editor_dialog.py:188 | giữ nguyên tại chỗ |
| Bật lịch chạy | ô tick | — | ui\task_editor_dialog.py:217 | giữ nguyên tại chỗ |
| — | droplist | self._on_repeat_changed | ui\task_editor_dialog.py:232 | giữ nguyên tại chỗ |
| sched.get('cron_expression') or | ô nhập | — | ui\task_editor_dialog.py:238 | giữ nguyên tại chỗ |
| Chọn một lịch mẫu — sẽ điền đúng cú pháp vào ô cron. | droplist | self._on_cron_sample | ui\task_editor_dialog.py:242 | giữ nguyên tại chỗ |
| Chỉ ngày làm việc (bỏ T7/CN | ô tick | — | ui\task_editor_dialog.py:258 | giữ nguyên tại chỗ |
| Bỏ qua ngày nghỉ lễ | ô tick | — | ui\task_editor_dialog.py:260 | giữ nguyên tại chỗ |
| sched.get('holiday_country', 'VN') or 'VN | ô nhập | — | ui\task_editor_dialog.py:262 | giữ nguyên tại chỗ |
| — | droplist | self._on_notify_changed | ui\task_editor_dialog.py:274 | giữ nguyên tại chỗ |
| ex_sched.get('notify_email', '') or | ô nhập | — | ui\task_editor_dialog.py:280 | giữ nguyên tại chỗ |
| inp.get('manual_text') or | ô nhập nhiều dòng | — | ui\task_editor_dialog.py:313 | giữ nguyên tại chỗ |
| — | nút | self._add_files | ui\task_editor_dialog.py:324 | giữ nguyên tại chỗ |
| — | nút | lambda: self._remove_selected(self.files_list) | ui\task_editor_dialog.py:328 | giữ nguyên tại chỗ |
| — | nút | self._add_link | ui\task_editor_dialog.py:349 | giữ nguyên tại chỗ |
| — | nút | lambda: self._remove_selected(self.links_list) | ui\task_editor_dialog.py:353 | giữ nguyên tại chỗ |
| — | droplist | self._check_chain | ui\task_editor_dialog.py:376 | giữ nguyên tại chỗ |
| Dùng output task này làm input task sau | ô tick | — | ui\task_editor_dialog.py:385 | giữ nguyên tại chỗ |
| Cần phê duyệt (không tự chạy theo lịch; chờ bấm Chạy ngay | ô tick | — | ui\task_editor_dialog.py:421 | giữ nguyên tại chỗ |
| QDialogButtonBox.Save | QDialogButtonBox.Cancel | nút hộp thoại | — | ui\task_editor_dialog.py:430 | giữ nguyên tại chỗ |
QGroupBox thật (Cơ bản · Lịch · Đầu vào · Phụ thuộc · Thực thi, xem ui/task_editor_dialog.py), luôn thấy đang ở nhóm nào và còn bao nhiêu nhóm nữa — nhất quán với cách điều hướng ở Cài đặt thay vì mỗi màn một kiểu.Quản lý skill — khối hướng dẫn tái dùng, gõ /skill để chèn.
Ô tick: chính là bật/tắt skill
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| skill.name if skill else | ô nhập | — | ui\skills_dialog.py:34 | giữ nguyên tại chỗ |
| skill.description if skill else | ô nhập | — | ui\skills_dialog.py:39 | giữ nguyên tại chỗ |
| Tạo từ mô tả | nút | self._gen_instructions | ui\skills_dialog.py:44 | giữ nguyên tại chỗ |
| skill.instructions if skill else | ô nhập nhiều dòng | — | ui\skills_dialog.py:50 | giữ nguyên tại chỗ |
| QDialogButtonBox.Save | QDialogButtonBox.Cancel | nút hộp thoại | — | ui\skills_dialog.py:55 | giữ nguyên tại chỗ |
| Tự động tạo | nút | self._auto_generate | ui\skills_dialog.py:127 | giữ nguyên tại chỗ |
| Từ file template… | nút | self._from_template | ui\skills_dialog.py:132 | giữ nguyên tại chỗ |
| Nhập… | nút | self._import | ui\skills_dialog.py:136 | giữ nguyên tại chỗ |
| Xuất .md | nút | self._export_md | ui\skills_dialog.py:140 | giữ nguyên tại chỗ |
| Nhân bản | nút | self._duplicate | ui\skills_dialog.py:144 | giữ nguyên tại chỗ |
| Sửa | nút | self._edit | ui\skills_dialog.py:148 | giữ nguyên tại chỗ |
| Xóa | nút | self._delete | ui\skills_dialog.py:151 | giữ nguyên tại chỗ |
| Đóng | nút | self.accept | ui\skills_dialog.py:154 | giữ nguyên tại chỗ |
Soạn skill: tên, mô tả, hướng dẫn.
✨: sinh hướng dẫn từ mô tả ngắn
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
Xem và nhờ AI sửa tệp, mở từ panel Files trong chat.
Tệp nhị phân: trích văn bản, chỉ đọc · Lưu: tạo .bak trước khi ghi
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| sp | ô nhập | — | ui\file_edit_dialog.py:66 | giữ nguyên tại chỗ |
| Mở file khác… | nút | self._browse | ui\file_edit_dialog.py:68 | giữ nguyên tại chỗ |
| Tải lại từ đĩa | nút | self._reload | ui\file_edit_dialog.py:73 | giữ nguyên tại chỗ |
| Mở một file để xem hoặc chỉnh sửa. | ô nhập nhiều dòng | — | ui\file_edit_dialog.py:84 | giữ nguyên tại chỗ |
| Nói cho AI cách sửa file này (vd: 'sửa lỗi chính tả', 'dịch | ô nhập | self._ai_edit | ui\file_edit_dialog.py:94 | giữ nguyên tại chỗ |
| Sửa bằng AI | nút | self._ai_edit | ui\file_edit_dialog.py:97 | giữ nguyên tại chỗ |
| Lưu | nút | self._save | ui\file_edit_dialog.py:106 | giữ nguyên tại chỗ |
| Đóng | nút | self.reject | ui\file_edit_dialog.py:110 | giữ nguyên tại chỗ |
Định nghĩa agent Co4E: tính cách, quyền, model, skill.
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| agent.name | ô nhập | — | ui\co4e_agent_dialog.py:32 | giữ nguyên tại chỗ |
| agent.role or 'AGENT | ô nhập | — | ui\co4e_agent_dialog.py:34 | giữ nguyên tại chỗ |
| agent.instructions | ô nhập nhiều dòng | — | ui\co4e_agent_dialog.py:42 | giữ nguyên tại chỗ |
| Soạn bằng AI | nút | self._ai_draft | ui\co4e_agent_dialog.py:46 | giữ nguyên tại chỗ |
| getatagent, 'context', | ô nhập nhiều dòng | — | ui\co4e_agent_dialog.py:59 | giữ nguyên tại chỗ |
| Tải danh sách model | nút | self._load_models | ui\co4e_agent_dialog.py:68 | giữ nguyên tại chỗ |
| Đính kèm tệp | nút | self._add_attachment | ui\co4e_agent_dialog.py:99 | giữ nguyên tại chỗ |
| Bỏ | nút | self._del_attachment | ui\co4e_agent_dialog.py:102 | giữ nguyên tại chỗ |
| QDialogButtonBox.Save | QDialogButtonBox.Cancel | nút hộp thoại | — | ui\co4e_agent_dialog.py:113 | giữ nguyên tại chỗ |
Khai báo kết nối ngoài, 2 chế độ.
MCP (stdio): lệnh + tham số · REST: URL · key · header · Test: thử kết nối thật
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| — | droplist | self._apply_preset | ui\ext_connector_dialog.py:35 | giữ nguyên tại chỗ |
| connector.get('name', | ô nhập | — | ui\ext_connector_dialog.py:43 | giữ nguyên tại chỗ |
| — | droplist | lambda i: self.stack.setCurrentIndex(self.mode_combo.currentData() != | ui\ext_connector_dialog.py:47 | giữ nguyên tại chỗ |
| connector.get('command', | ô nhập | — | ui\ext_connector_dialog.py:59 | giữ nguyên tại chỗ |
| '.join(connector.get('args', []) or [] | ô nhập | — | ui\ext_connector_dialog.py:62 | giữ nguyên tại chỗ |
| connector.get('base_url', | ô nhập | — | ui\ext_connector_dialog.py:69 | giữ nguyên tại chỗ |
| connector.get('api_key', | ô nhập | — | ui\ext_connector_dialog.py:72 | giữ nguyên tại chỗ |
| connector.get('auth_header', 'Authorization | ô nhập | — | ui\ext_connector_dialog.py:75 | giữ nguyên tại chỗ |
| connector.get('auth_scheme', 'Bearer | ô nhập | — | ui\ext_connector_dialog.py:77 | giữ nguyên tại chỗ |
| Kiểm tra kết nối | nút | self._test_connection | ui\ext_connector_dialog.py:90 | giữ nguyên tại chỗ |
| QDialogButtonBox.Save | QDialogButtonBox.Cancel | nút hộp thoại | — | ui\ext_connector_dialog.py:103 | giữ nguyên tại chỗ |
Chốt chặn cuối trước khi agent làm việc có hậu quả. Bật Tự chạy thì bỏ qua bước này.
Xem trước: lệnh sắp chạy hoặc diff sắp ghi
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
Soạn agent hệ thống: gắn vào chức năng nào, provider/model gì.
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
Màn đăng nhập — đã dựng xong nhưng không nơi nào gọi. App khởi động thẳng với user \“local\”, quyền admin.
3 trang: Khởi tạo · Đăng nhập · Offline
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| Thoát | nút | self.reject | ui\login_dialog.py:87 | giữ nguyên tại chỗ |
| self.ctx.config.shared_dir | ô nhập | — | ui\login_dialog.py:121 | giữ nguyên tại chỗ |
| Chọn… | nút | self._bs_browse | ui\login_dialog.py:122 | giữ nguyên tại chỗ |
| Tạo tài khoản Admin | nút | self._bs_create_admin | ui\login_dialog.py:137 | giữ nguyên tại chỗ |
| cached_code | ô nhập | — | ui\login_dialog.py:186 | giữ nguyên tại chỗ |
| self.ctx.config.auth.get('last_department', | ô nhập | — | ui\login_dialog.py:199 | giữ nguyên tại chỗ |
| Đăng nhập | nút | lambda: self._do_login(shared_dir) | ui\login_dialog.py:209 | giữ nguyên tại chỗ |
| login.offline_btn', role=role | nút | lambda: self._finish_login(Account(username=username, role=role, code= | ui\login_dialog.py:256 | giữ nguyên tại chỗ |
| Thử lại | nút | self._retry | ui\login_dialog.py:263 | giữ nguyên tại chỗ |
Robot trợ giúp nổi, có mặt trên mọi màn. Cố tình không có công cụ.
3 trạng thái: tab mép → huy hiệu → panel chat
Giữ nguyên bố cục bên trong; chỉ đổi thanh menu sang danh sách phẳng.
| Nhãn | Loại | Hàm xử lý | Nguồn | Sau khi sửa |
|---|---|---|---|---|
| self | nút | self._show_launcher | ui\help_agent_widget.py:169 | giữ nguyên tại chỗ |
| self | nút | self._hide_to_edge | ui\help_agent_widget.py:178 | giữ nguyên tại chỗ |
| header | nút | self._collapse | ui\help_agent_widget.py:214 | giữ nguyên tại chỗ |
| row | ô nhập | self._send | ui\help_agent_widget.py:236 | giữ nguyên tại chỗ |
| row | nút | self._send | ui\help_agent_widget.py:241 | giữ nguyên tại chỗ |
Sáu màn có trong code nhưng không tới được — tổng 64 control (accounts 18 · flow_dialog 28 · agent_manager 7 · skill_manager 7 · mcp_servers 4). Không nằm trong kiểm kê phía trên vì không có đường nào tới; chỉ ghi nhận, không đề xuất gỡ.
| Thành phần | Vị trí | Tình trạng |
|---|---|---|
| AccountsTab | ui/accounts_tab.py:153 | Quản lý tài khoản/nhóm đầy đủ, nhưng không được gắn vào MonitoringTab. |
| LoginDialog | ui/login_dialog.py:57 | Màn đăng nhập hoàn chỉnh; app.py:860 bỏ qua, hard-code user “local”. |
| FlowBuilderDialog | ui/flow_dialog.py:34 | Bị Co4E thay thế; không nơi nào gọi. |
| AgentManagerTab | ui/agent_manager_tab.py:28 | Chỉ dùng bởi FlowBuilderDialog → cũng không tới được. |
| SkillManagerTab | ui/skill_manager_tab.py | Chỉ dùng bởi FlowBuilderDialog → cũng không tới được. |
| McpServerEditDialog | ui/mcp_servers_dialog.py:15 | Bị ExtConnectorEditDialog thay thế. |
settings_dialog.py:115 hard-code mật khẩu
Sandbox; hai lớp cùng tên CustomAgent
(custom_agents.py:23 · co4e.py:117).