macOS companion app
Overlay suara
Siklus Hidup Overlay Suara (macOS)
Audiens: kontributor aplikasi macOS. Tujuan: menjaga overlay suara tetap dapat diprediksi saat kata pemicu dan push-to-talk tumpang tindih.
Maksud saat ini
- Jika overlay sudah terlihat dari kata pemicu dan pengguna menekan hotkey, sesi hotkey mengadopsi teks yang sudah ada alih-alih mengatur ulangnya. Overlay tetap tampil selama hotkey ditahan. Saat pengguna melepas: kirim jika ada teks yang sudah dipangkas, jika tidak tutup.
- Kata pemicu saja tetap mengirim otomatis saat senyap; push-to-talk mengirim langsung saat dilepas.
Diimplementasikan (9 Des 2025)
- Sesi overlay kini membawa token per penangkapan (kata pemicu atau push-to-talk). Pembaruan parsial/final/kirim/tutup/level dibuang saat token tidak cocok, sehingga menghindari callback lama.
- Push-to-talk mengadopsi teks overlay apa pun yang terlihat sebagai prefiks (jadi menekan hotkey saat overlay pemicu aktif akan mempertahankan teks dan menambahkan ucapan baru). Ini menunggu hingga 1,5 dtk untuk transkrip final sebelum kembali memakai teks saat ini.
- Pencatatan chime/overlay dipancarkan pada
infodalam kategorivoicewake.overlay,voicewake.ptt, danvoicewake.chime(awal sesi, parsial, final, kirim, tutup, alasan chime).
Langkah berikutnya
- VoiceSessionCoordinator (aktor)
- 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 ulang overlay).
- Memiliki tepat satu
- VoiceSession (model)
- Field:
token,source(wakeWord|pushToTalk), teks committed/volatile, flag chime, timer (kirim otomatis, idle),overlayMode(display|editing|sending), tenggat cooldown.
- Field:
- Pengikatan overlay
VoiceSessionPublisher(ObservableObject) mencerminkan sesi aktif ke SwiftUI.VoiceWakeOverlayViewmerender hanya melalui publisher; ini tidak pernah memutasi singleton global secara langsung.- Tindakan pengguna overlay (
sendNow,dismiss,edit) memanggil kembali coordinator dengan token sesi.
- Jalur kirim terpadu
- Pada
endCapture: jika teks yang dipangkas kosong → tutup; jika tidakperformSend(session:)(memutar chime kirim sekali, meneruskan, menutup). - Push-to-talk: tanpa jeda; kata pemicu: jeda opsional untuk kirim otomatis.
- Terapkan cooldown singkat ke runtime pemicu setelah push-to-talk selesai agar kata pemicu tidak langsung terpicu lagi.
- Pada
- Pencatatan
- Coordinator memancarkan log
.infodalam subsistemai.openclaw, kategorivoicewake.overlaydanvoicewake.chime. - Peristiwa kunci:
session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
- Coordinator memancarkan log
Daftar periksa debug
-
Streaming log saat mereproduksi overlay yang macet:
sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact -
Verifikasi hanya ada satu token sesi aktif; callback lama harus dibuang oleh coordinator.
-
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
VoiceWakeRuntimeuntuk membuat/memperbarui/mengakhiri sesi alih-alih menyentuhVoiceWakeOverlayControllersecara langsung. - Refactor
VoicePushToTalkuntuk mengadopsi sesi yang ada dan memanggilendCapturesaat dilepas; terapkan cooldown runtime. - Hubungkan
VoiceWakeOverlayControllerke publisher; hapus panggilan langsung dari runtime/PTT. - Tambahkan pengujian integrasi untuk adopsi sesi, cooldown, dan penutupan teks kosong.