Bỏ hai chế độ Off và Fallback ở ô định tuyến cạnh khung chat và ở mục Định
tuyến trong Cài đặt. Mặc định chuyển sang Auto.
- USER_ROUTING_MODES = ("auto", "manual"); giá trị off/fallback/lạ còn lưu trong
config hay project đều được hiểu là Auto (routing_mode_for,
project_routing_mode, set_*). Engine vẫn hiểu "off" khi truyền mode_override
tường minh.
- RoutingScheduler: định tuyến giờ luôn bật nên việc chấm điểm model định kỳ
luôn chạy; muốn tắt thì đặt reassess_interval_hours = 0.
- Cập nhật các test đang ghim hành vi "mặc định off".
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Thanh tiêu đề màn Cowork hiện "…tóm tắt từng tệ…" cho một câu dài 61 ký tự:
mốc cắt cứng ở 60 rơi đúng giữa chữ "tệp" và bỏ mất một chữ cái, đọc ra như lỗi
gõ chứ không như một câu bị rút gọn. Dấu ba chấm ở đó còn nói dối — nó báo còn
nhiều chữ nữa trong khi chỉ thiếu đúng một ký tự.
Thêm core.history.shorten_title: viết nốt từ đang dở thay vì cắt ngang nó, và
chỉ thêm dấu ba chấm khi thật sự có chữ bị bỏ. Từ dài bất thường (đường dẫn,
URL) thì lùi về ranh giới từ trước đó để một token dài không kéo tiêu đề dài ra
tuỳ ý.
Dùng chung cho cả hai nơi sinh tiêu đề (derive_title và ChatTurnRunnerMixin) để
tiêu đề trên thanh tiêu đề và tiêu đề lưu vào lịch sử không rút gọn theo hai
kiểu khác nhau.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Trước đây công tắc chỉ chặn tool mạng của agent; lệnh shell chỉ bị proxy
giả, còn M365, Teams, nút Test, MCP đang chạy, task script, link đính kèm
task, pip tự cài và tài nguyên web trong xem trước HTML vẫn ra mạng tự do.
- Cổng chung application/network/network_guard.py, nối vào cấu hình sống
ở Composition Root; nhà cung cấp AI (chat, danh sách model, thử model)
không đi qua cổng này.
- Lệnh shell của agent và task script chạy trong Windows AppContainer
không có quyền mạng (macOS: sandbox-exec, Linux: unshare --net);
không cô lập được thì từ chối chạy.
- Không cấp quyền kế thừa của AppContainer lên thư mục chứa PySide6:
Chromium không nạp được Qt6WebEngineCore.dll và tab Graph bị hỏng.
- Bật chặn thì dừng MCP đang chạy; tool OneDrive đồng bộ trên máy vẫn dùng.
- Mặc định tắt khi mở app lần đầu; nhãn và tooltip 3 ngôn ngữ cập nhật.
- Test: tests/test_network_guard_lanes.py (có bài AppContainer thật).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Thư mục làm việc vừa là sandbox (agent chỉ đọc/ghi bên trong nó) vừa là kho
kiến thức chung của project (file ở gốc được mọi đoạn chat tự đọc). Hai project
trỏ vào cùng một thư mục là đọc lẫn dữ liệu của nhau và ghi đè lên nhau — đúng
điều docstring đầu core/projects.py nói sandbox sinh ra để ngăn, nhưng không có
chỗ nào thực thi: cả ba nơi đặt thư mục đều gán thẳng output_dir rồi lưu.
Thêm core.projects.folder_conflict: so theo workspace_dir() chứ không theo
output_dir (project chưa đặt thư mục riêng vẫn đang chiếm thư mục quản lý sẵn),
chuẩn hoá đường dẫn bằng expanduser + abspath + normcase, và coi thư mục lồng
nhau là trùng — đứng ở thư mục cha vẫn với tới được file của project con.
Chặn tại cả ba nơi ghi output_dir: nút Đổi ở màn Project, thư mục mirror cloud,
và nút chọn thư mục trong tab Cowork. Chặn lúc CHỌN chứ không lúc Lưu, vì nút
Lưu chỉ ghi tên/mô tả/chỉ dẫn — chặn ở đó sẽ khoá luôn việc đổi tên một project
lỡ đang trùng thư mục.
Dữ liệu đã trùng sẵn không bị tự sửa: có nhãn cảnh báo ngay dưới ô Thư mục làm
việc, nói rõ trùng với project nào, để người dùng tự quyết.
Luật ở module riêng (presentation/workspace/project_folder_rules.py) vì nhét
vào project_editing.py sẽ đẩy file đó lên 435 dòng, vượt trần 400 của
scripts/check_loc.py.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>