> ## Documentation Index
> Fetch the complete documentation index at: https://openclaw.veiseule.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Spraakoverlay

# Levenscyclus van de spraakoverlay (macOS)

Doelgroep: macOS-appbijdragers. Doel: de spraakoverlay voorspelbaar houden wanneer wake-woord en push-to-talk overlappen.

## Huidige intentie

* Als de overlay al zichtbaar is door het wake-woord en de gebruiker de sneltoets indrukt, *adopteert* de sneltoetssessie de bestaande tekst in plaats van deze te resetten. De overlay blijft zichtbaar zolang de sneltoets wordt ingedrukt. Wanneer de gebruiker loslaat: verzenden als er getrimde tekst is, anders sluiten.
* Alleen het wake-woord verzendt nog steeds automatisch bij stilte; push-to-talk verzendt direct bij loslaten.

## Geïmplementeerd (9 dec 2025)

* Overlay-sessies dragen nu per opname (wake-woord of push-to-talk) een token. Updates voor partial/final/send/dismiss/level worden genegeerd wanneer het token niet overeenkomt, om verouderde callbacks te voorkomen.
* Push-to-talk adopteert alle zichtbare overlaytekst als prefix (dus het indrukken van de sneltoets terwijl de wake-overlay actief is, behoudt de tekst en voegt nieuwe spraak toe). Het wacht tot 1,5 s op een definitief transcript voordat wordt teruggevallen op de huidige tekst.
* Chime-/overlaylogging wordt uitgezonden bij `info` in categorieën `voicewake.overlay`, `voicewake.ptt` en `voicewake.chime` (sessiestart, partial, final, verzenden, sluiten, reden van chime).

## Volgende stappen

1. **VoiceSessionCoordinator (actor)**
   * Beheert exact één `VoiceSession` tegelijk.
   * API (token-gebaseerd): `beginWakeCapture`, `beginPushToTalk`, `updatePartial`, `endCapture`, `cancel`, `applyCooldown`.
   * Negeert callbacks met verouderde tokens (voorkomt dat oude recognizers de overlay opnieuw openen).
2. **VoiceSession (model)**
   * Velden: `token`, `source` (wakeWord|pushToTalk), vastgelegde/vluchtige tekst, chime-vlaggen, timers (automatisch verzenden, inactiviteit), `overlayMode` (display|editing|sending), cooldown-deadline.
3. **Overlay-binding**
   * `VoiceSessionPublisher` (`ObservableObject`) spiegelt de actieve sessie naar SwiftUI.
   * `VoiceWakeOverlayView` rendert uitsluitend via de publisher; het muteert nooit direct globale singletons.
   * Overlay-gebruikersacties (`sendNow`, `dismiss`, `edit`) roepen terug naar de coordinator met het sessietoken.
4. **Eenvoudig verzendpad**
   * Bij `endCapture`: als getrimde tekst leeg is → sluiten; anders `performSend(session:)` (speelt het verzendgeluid één keer af, stuurt door, sluit).
   * Push-to-talk: geen vertraging; wake-woord: optionele vertraging voor automatisch verzenden.
   * Pas een korte cooldown toe op de wake-runtime nadat push-to-talk is beëindigd, zodat het wake-woord niet direct opnieuw triggert.
5. **Logging**
   * De coordinator emitteert `.info`-logs in subsysteem `bot.molt`, categorieën `voicewake.overlay` en `voicewake.chime`.
   * Sleutelgebeurtenissen: `session_started`, `adopted_by_push_to_talk`, `partial`, `finalized`, `send`, `dismiss`, `cancel`, `cooldown`.

## Debugging-checklist

* Stream logs terwijl je een vastzittende overlay reproduceert:

  ```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
  sudo log stream --predicate 'subsystem == "bot.molt" AND category CONTAINS "voicewake"' --level info --style compact
  ```

* Verifieer dat er slechts één actief sessietoken is; verouderde callbacks moeten door de coordinator worden genegeerd.

* Zorg ervoor dat het loslaten van push-to-talk altijd `endCapture` aanroept met het actieve token; als de tekst leeg is, verwacht `dismiss` zonder chime of verzending.

## Migratiestappen (aanbevolen)

1. Voeg `VoiceSessionCoordinator`, `VoiceSession` en `VoiceSessionPublisher` toe.
2. Refactor `VoiceWakeRuntime` om sessies te maken/bij te werken/te beëindigen in plaats van `VoiceWakeOverlayController` direct aan te raken.
3. Refactor `VoicePushToTalk` om bestaande sessies te adopteren en bij loslaten `endCapture` aan te roepen; pas runtime-cooldown toe.
4. Verbind `VoiceWakeOverlayController` met de publisher; verwijder directe aanroepen vanuit runtime/PTT.
5. Voeg integratietests toe voor sessie-adoptie, cooldown en sluiten bij lege tekst.
