Siklus Hidup Overlay Suara (macOS)
Audiens: kontributor app macOS. Tujuan: menjaga overlay suara tetap dapat diprediksi saat wake-word dan push-to-talk saling tumpang tindih.Tujuan saat ini
- Jika overlay sudah terlihat karena wake-word dan pengguna menekan hotkey, sesi hotkey mengadopsi teks yang ada alih-alih meresetnya. Overlay tetap tampil selama hotkey ditekan. Saat pengguna melepaskannya: kirim jika ada teks yang sudah di-trim, jika tidak tutup.
- Wake-word saja tetap mengirim otomatis saat senyap; push-to-talk langsung mengirim saat dilepas.
Sudah diimplementasikan (9 Des 2025)
- Sesi overlay sekarang membawa token per capture (wake-word atau push-to-talk). Update partial/final/send/dismiss/level dibuang saat token tidak cocok, untuk menghindari callback lama.
- Push-to-talk mengadopsi teks overlay yang terlihat sebagai prefix (jadi menekan hotkey saat overlay wake aktif akan mempertahankan teks dan menambahkan ucapan baru). Ini menunggu hingga 1,5 detik untuk transkrip final sebelum fallback ke teks saat ini.
- Logging chime/overlay dikirim pada level
infodalam kategorivoicewake.overlay,voicewake.ptt, danvoicewake.chime(awal sesi, partial, final, send, dismiss, alasan chime).
Langkah selanjutnya
- VoiceSessionCoordinator (actor)
- Memiliki tepat satu
VoiceSessionpada satu waktu. - API (berbasis token):
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Membuang callback yang membawa token lama (mencegah recognizer lama membuka kembali overlay).
- Memiliki tepat satu
- VoiceSession (model)
- Field:
token,source(wakeWord|pushToTalk), teks committed/volatile, flag chime, timer (auto-send, idle),overlayMode(display|editing|sending), tenggat cooldown.
- Field:
- Binding overlay
VoiceSessionPublisher(ObservableObject) mencerminkan sesi aktif ke SwiftUI.VoiceWakeOverlayViewhanya merender melalui publisher; ini tidak pernah memutasi singleton global secara langsung.- Tindakan pengguna overlay (
sendNow,dismiss,edit) melakukan callback ke koordinator dengan token sesi.
- Jalur kirim terpadu
- Pada
endCapture: jika teks yang sudah di-trim kosong → tutup; jika tidakperformSend(session:)(memutar chime kirim sekali, meneruskan, menutup). - Push-to-talk: tanpa penundaan; wake-word: penundaan opsional untuk auto-send.
- Terapkan cooldown singkat pada runtime wake setelah push-to-talk selesai agar wake-word tidak langsung terpicu lagi.
- Pada
- Logging
- Koordinator mengirim log
.infodalam subsystemai.openclaw, kategorivoicewake.overlaydanvoicewake.chime. - Event kunci:
session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
- Koordinator mengirim log
Checklist debugging
-
Streaming log saat mereproduksi overlay yang macet:
- Verifikasi hanya ada satu token sesi aktif; callback lama harus dibuang oleh koordinator.
-
Pastikan pelepasan push-to-talk selalu memanggil
endCapturedengan token aktif; jika teks kosong, harapkandismisstanpa chime atau pengiriman.
Langkah migrasi (disarankan)
- Tambahkan
VoiceSessionCoordinator,VoiceSession, danVoiceSessionPublisher. - Refactor
VoiceWakeRuntimeagar membuat/memperbarui/mengakhiri sesi alih-alih menyentuhVoiceWakeOverlayControllersecara langsung. - Refactor
VoicePushToTalkagar mengadopsi sesi yang ada dan memanggilendCapturesaat dilepas; terapkan cooldown runtime. - Hubungkan
VoiceWakeOverlayControllerke publisher; hapus panggilan langsung dari runtime/PTT. - Tambahkan integration test untuk adopsi sesi, cooldown, dan penutupan saat teks kosong.