feat(chat): màn giới thiệu khi hội thoại còn rỗng

Bấm "Cuộc trò chuyện mới" trước đây để lại một khung trắng: không có gì nói
người dùng đang làm trong project nào, thư mục có bao nhiêu tệp, hay bắt đầu từ
đâu. Đây là trạng thái RỖNG — một trong bốn trạng thái mà mọi khung dữ liệu phải
có, và là trạng thái duy nhất người dùng nhìn thấy trước khi gõ chữ đầu tiên.

Gồm lời chào theo tên, dòng bối cảnh (project · số tệp · số skill đang bật), và
bốn thẻ gợi ý.

Hai quyết định:
- Thẻ ĐIỀN câu gợi ý vào ô nhập chứ không gửi luôn. Câu gợi ý là điểm bắt đầu;
  người dùng gần như luôn cần thêm chi tiết của riêng họ, và gửi ngay sẽ tiêu
  một lượt gọi model cho một câu hỏi chung chung.
- Dấu phía trên lời chào không bấm được — nó là dấu hiệu thị giác. Một nút không
  làm gì tệ hơn không có nút.

Dòng bối cảnh phân biệt KHÔNG BIẾT với 0: đếm được 0 tệp thì hiện "0 tệp", còn
không đọc được thư mục thì bỏ hẳn mảnh đó — hiện "0 tệp" khi người dùng vừa thấy
có tệp trong thư mục còn tệ hơn là thiếu một mảnh.

show_welcome() được móc ở ba chỗ: new_session(), load_conversation() (theo số
tin nhắn đã lưu), và TRƯỚC mọi nhánh add_user trong turn runner — đặt sau từng
add_user() thì dễ sót đúng một nhánh, và nhánh đó sẽ hiện cả hai thứ cùng lúc.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 19:55:43 +09:00
co-authored by Claude Opus 5
parent b2e2791ff6
commit 64900a2504
7 changed files with 460 additions and 0 deletions
+4
View File
@@ -65,6 +65,10 @@ class ChatTurnRunnerMixin:
attachments = attachments or []
typed = text
prefix, request, info = self._apply_skill_command(text)
# Moi duong tra ve som duoi day cung them mot bong nguoi dung vao khung,
# nen man gioi thieu phai nhuong cho ngay tai day — dat sau tung
# add_user() thi de sot dung mot nhanh, va nhanh do se hien ca hai thu.
self.show_welcome(False)
if info is not None:
# A local /skill command (list / select / error) — answer inline.
self.chat_view.add_user(typed)