Voice Wake & Push-to-Talk
Modi
- Wake-Word-Modus (Standard): Immer aktiver Speech-Recognizer wartet auf Trigger-Tokens (
swabbleTriggerWords). Bei Übereinstimmung startet die Erfassung, zeigt das Overlay mit partiellem Text und sendet automatisch nach Stille. - Push-to-Talk (Rechte Option halten): Halte die rechte Option-Taste, um sofort aufzunehmen — kein Trigger nötig. Das Overlay erscheint, solange die Taste gehalten wird; Loslassen finalisiert und leitet nach kurzer Verzögerung weiter, damit du den Text noch anpassen kannst.
Runtime-Verhalten (Wake-Word)
- Der Speech-Recognizer lebt in
VoiceWakeRuntime. - Der Trigger löst nur aus, wenn es eine bedeutsame Pause zwischen dem Wake-Word und dem nächsten Wort gibt (~0,55s Lücke). Das Overlay/der Chime kann bei der Pause starten, noch bevor der Befehl beginnt.
- Stille-Fenster: 2,0s wenn Sprache fließt, 5,0s wenn nur der Trigger gehört wurde.
- Harter Stopp: 120s um unkontrollierte Sessions zu verhindern.
- Debounce zwischen Sessions: 350ms.
- Das Overlay wird via
VoiceWakeOverlayControllermit Committed/Volatile-Einfärbung gesteuert. - Nach dem Senden startet der Recognizer sauber neu, um auf den nächsten Trigger zu lauschen.
Lebenszyklus-Invarianten
- Wenn Voice Wake aktiviert und Berechtigungen erteilt sind, sollte der Wake-Word-Recognizer lauschen (außer während einer expliziten Push-to-Talk-Erfassung).
- Die Overlay-Sichtbarkeit (einschließlich manuelles Schließen über den X-Button) darf niemals den Recognizer am Neustart hindern.
Hängendes Overlay — Fehlermodus (früher)
Früher konnte Voice Wake „tot” wirken, wenn das Overlay sichtbar hängen blieb und man es manuell schloss, weil der Neustart-Versuch der Runtime durch die Overlay-Sichtbarkeit blockiert werden konnte und kein weiterer Neustart geplant wurde.
Härtung:
- Der Wake-Runtime-Neustart wird nicht mehr durch die Overlay-Sichtbarkeit blockiert.
- Das Schließen des Overlays löst einen
VoiceWakeRuntime.refresh(...)viaVoiceSessionCoordinatoraus, sodass manuelles X-Schließen immer das Lauschen wieder aufnimmt.
Push-to-Talk — Details
- Hotkey-Erkennung nutzt einen globalen
.flagsChanged-Monitor für rechte Option (keyCode 61+.option). Wir beobachten nur Events (kein Schlucken). - Die Erfassungs-Pipeline lebt in
VoicePushToTalk: startet Speech sofort, streamt Partials ans Overlay und ruftVoiceWakeForwarderbeim Loslassen auf. - Wenn Push-to-Talk startet, pausieren wir die Wake-Word-Runtime, um duellierende Audio-Taps zu vermeiden; sie startet nach dem Loslassen automatisch wieder.
- Berechtigungen: erfordert Mikrofon + Spracherkennung; Events sehen braucht Bedienungshilfen/Input-Monitoring-Genehmigung.
- Externe Tastaturen: Manche stellen die rechte Option nicht wie erwartet bereit — biete eine Fallback-Tastenkombination an, falls Benutzer Probleme melden.
Benutzereinstellungen
- Voice Wake-Toggle: aktiviert die Wake-Word-Runtime.
- Cmd+Fn halten zum Sprechen: aktiviert den Push-to-Talk-Monitor. Deaktiviert auf macOS < 26.
- Sprach- & Mikrofon-Auswahl, Live-Pegelmeter, Trigger-Wort-Tabelle, Tester (nur lokal; leitet nicht weiter).
- Die Mikrofon-Auswahl behält die letzte Auswahl bei, wenn ein Gerät getrennt wird, zeigt einen Getrennt-Hinweis und fällt temporär auf den Systemstandard zurück, bis es wieder verfügbar ist.
- Sounds: Chimes bei Trigger-Erkennung und beim Senden; Standard ist der macOS-Systemsound „Glass”. Du kannst jede von
NSSoundladbare Datei (z. B. MP3/WAV/AIFF) für jedes Event wählen oder Kein Sound auswählen.
Weiterleitungsverhalten
- Wenn Voice Wake aktiviert ist, werden Transkripte an das aktive Gateway/den Agenten weitergeleitet (derselbe Lokal- vs. Remote-Modus wie der Rest der Mac-App).
- Antworten werden an den zuletzt genutzten Haupt-Provider (WhatsApp/Telegram/Discord/WebChat) geliefert. Falls die Zustellung fehlschlägt, wird der Fehler geloggt und der Run ist weiterhin via WebChat/Session-Logs sichtbar.
Weiterleitungs-Payload
VoiceWakeForwarder.prefixedTranscript(_:)stellt den Machine-Hint vor dem Senden voran. Wird zwischen Wake-Word- und Push-to-Talk-Pfaden geteilt.
Schnellprüfung
- Push-to-Talk aktivieren, Cmd+Fn halten, sprechen, loslassen: Das Overlay sollte Partials zeigen und dann senden.
- Während des Haltens sollten die Menüleisten-Ohren vergrößert bleiben (nutzt
triggerVoiceEars(ttl:nil)); sie fallen nach dem Loslassen ab.