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 VoiceWakeOverlayController mit 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(...) via VoiceSessionCoordinator aus, 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 ruft VoiceWakeForwarder beim 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 NSSound ladbare 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.