Vòng đời Lớp phủ Giọng nói (macOS)
Audience: macOS app contributors. Goal: keep the voice overlay predictable when wake-word and push-to-talk overlap.Ý định hiện tại
- If the overlay is already visible from wake-word and the user presses the hotkey, the hotkey session adopts the existing text instead of resetting it. The overlay stays up while the hotkey is held. When the user releases: send if there is trimmed text, otherwise dismiss.
- Chỉ dùng từ đánh thức vẫn tự động gửi khi im lặng; nhấn‑để‑nói gửi ngay khi thả.
Đã triển khai (9 Thg 12, 2025)
- Overlay sessions now carry a token per capture (wake-word or push-to-talk). Partial/final/send/dismiss/level updates are dropped when the token doesn’t match, avoiding stale callbacks.
- Push-to-talk adopts any visible overlay text as a prefix (so pressing the hotkey while the wake overlay is up keeps the text and appends new speech). It waits up to 1.5s for a final transcript before falling back to the current text.
- Ghi log chuông/lớp phủ được phát tại
infotrong các danh mụcvoicewake.overlay,voicewake.pttvàvoicewake.chime(bắt đầu phiên, partial, final, send, dismiss, lý do chuông).
Bước tiếp theo
- VoiceSessionCoordinator (actor)
- Sở hữu đúng một
VoiceSessiontại một thời điểm. - API (dựa trên token):
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Bỏ các callback mang token cũ (ngăn các bộ nhận dạng cũ mở lại lớp phủ).
- Sở hữu đúng một
- VoiceSession (model)
- Trường:
token,source(wakeWord|pushToTalk), văn bản committed/volatile, cờ chuông, bộ hẹn giờ (tự động gửi, nhàn rỗi),overlayMode(display|editing|sending), thời hạn cooldown.
- Trường:
- Liên kết lớp phủ
VoiceSessionPublisher(ObservableObject) phản chiếu phiên đang hoạt động vào SwiftUI.VoiceWakeOverlayViewchỉ render thông qua publisher; không bao giờ thay đổi trực tiếp các singleton toàn cục.- Các hành động người dùng trên lớp phủ (
sendNow,dismiss,edit) gọi ngược vào coordinator với token của phiên.
- Luồng gửi hợp nhất
- Khi
endCapture: nếu văn bản đã cắt gọn rỗng → đóng; nếu không thìperformSend(session:)(phát chuông gửi một lần, chuyển tiếp, đóng). - Nhấn‑để‑nói: không trì hoãn; từ đánh thức: có thể trì hoãn để tự động gửi.
- Áp dụng một cooldown ngắn cho runtime từ đánh thức sau khi nhấn‑để‑nói kết thúc để từ đánh thức không kích hoạt lại ngay.
- Khi
- Ghi log
- Coordinator phát log
.infotrong subsystembot.molt, các danh mụcvoicewake.overlayvàvoicewake.chime. - Các sự kiện chính:
session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
- Coordinator phát log
Danh sách kiểm tra gỡ lỗi
-
Stream log trong khi tái hiện lớp phủ bị “dính”:
- Xác minh chỉ có một token phiên đang hoạt động; các callback cũ phải bị coordinator bỏ.
-
Đảm bảo việc thả nhấn‑để‑nói luôn gọi
endCapturevới token đang hoạt động; nếu văn bản rỗng, kỳ vọngdismissmà không có chuông hoặc gửi.
Các bước di chuyển (đề xuất)
- Thêm
VoiceSessionCoordinator,VoiceSessionvàVoiceSessionPublisher. - Tái cấu trúc
VoiceWakeRuntimeđể tạo/cập nhật/kết thúc phiên thay vì chạm trực tiếp vàoVoiceWakeOverlayController. - Tái cấu trúc
VoicePushToTalkđể kế thừa các phiên hiện có và gọiendCapturekhi thả; áp dụng cooldown runtime. - Kết nối
VoiceWakeOverlayControllervới publisher; loại bỏ các lời gọi trực tiếp từ runtime/PTT. - Thêm các bài kiểm thử tích hợp cho việc kế thừa phiên, cooldown và đóng khi văn bản rỗng.