macOS companion app
Spraakoverlay
Levenscyclus van de spraakoverlay (macOS)
Doelgroep: bijdragers aan de macOS-app. Doel: de spraakoverlay voorspelbaar houden wanneer wekwoord en push-to-talk elkaar overlappen.
Huidige bedoeling
- Als de overlay al zichtbaar is door het wekwoord en de gebruiker op de sneltoets drukt, neemt de sneltoetssessie de bestaande tekst over in plaats van die te resetten. De overlay blijft zichtbaar zolang de sneltoets wordt ingedrukt. Wanneer de gebruiker loslaat: verzenden als er bijgesneden tekst is, anders sluiten.
- Alleen het wekwoord verzendt nog steeds automatisch bij stilte; push-to-talk verzendt direct bij loslaten.
Geïmplementeerd (9 dec. 2025)
- Overlaysessies hebben nu een token per opname (wekwoord of push-to-talk). Updates voor gedeeltelijk/eindresultaat/verzenden/sluiten/niveau worden genegeerd wanneer het token niet overeenkomt, zodat verouderde callbacks worden vermeden.
- Push-to-talk neemt eventuele zichtbare overlaytekst over als prefix (dus als je op de sneltoets drukt terwijl de wekoverlay zichtbaar is, blijft de tekst staan en wordt nieuwe spraak toegevoegd). Het wacht maximaal 1,5 s op een definitief transcript voordat het terugvalt op de huidige tekst.
- Chime-/overlaylogging wordt op
infouitgegeven in de categorieënvoicewake.overlay,voicewake.pttenvoicewake.chime(sessiestart, gedeeltelijk, definitief, verzenden, sluiten, reden voor chime).
Volgende stappen
- VoiceSessionCoordinator (actor)
- Beheert precies één
VoiceSessiontegelijk. - API (op tokens gebaseerd):
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Negeert callbacks met verouderde tokens (voorkomt dat oude herkenners de overlay opnieuw openen).
- Beheert precies één
- VoiceSession (model)
- Velden:
token,source(wakeWord|pushToTalk), vastgelegde/vluchtige tekst, chime-vlaggen, timers (automatisch verzenden, inactief),overlayMode(display|editing|sending), cooldown-deadline.
- Velden:
- Overlaybinding
VoiceSessionPublisher(ObservableObject) spiegelt de actieve sessie naar SwiftUI.VoiceWakeOverlayViewrendert alleen via de publisher; het muteert nooit rechtstreeks globale singletons.- Gebruikersacties in de overlay (
sendNow,dismiss,edit) roepen de coordinator terug met het sessietoken.
- Uniform verzendpad
- Bij
endCapture: als de bijgesneden tekst leeg is → sluiten; andersperformSend(session:)(speelt de verzendchime één keer af, stuurt door, sluit). - Push-to-talk: geen vertraging; wekwoord: optionele vertraging voor automatisch verzenden.
- Pas een korte cooldown toe op de wake-runtime nadat push-to-talk is voltooid, zodat het wekwoord niet direct opnieuw triggert.
- Bij
- Logging
- Coordinator geeft
.info-logs uit in subsystemai.openclaw, categorieënvoicewake.overlayenvoicewake.chime. - Belangrijke gebeurtenissen:
session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
- Coordinator geeft
Debugchecklist
-
Stream logs tijdens het reproduceren van een vastzittende overlay:
sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact -
Controleer dat er maar één actief sessietoken is; verouderde callbacks moeten door de coordinator worden genegeerd.
-
Zorg dat het loslaten van push-to-talk altijd
endCaptureaanroept met het actieve token; als tekst leeg is, verwachtdismisszonder chime of verzenden.
Migratiestappen (voorgesteld)
- Voeg
VoiceSessionCoordinator,VoiceSessionenVoiceSessionPublishertoe. - Refactor
VoiceWakeRuntimezodat sessies worden aangemaakt/bijgewerkt/beëindigd in plaats vanVoiceWakeOverlayControllerrechtstreeks aan te raken. - Refactor
VoicePushToTalkzodat bestaande sessies worden overgenomen enendCapturewordt aangeroepen bij loslaten; pas runtime-cooldown toe. - Verbind
VoiceWakeOverlayControllermet de publisher; verwijder directe aanroepen vanuit runtime/PTT. - Voeg integratietests toe voor sessieovername, cooldown en sluiten bij lege tekst.