Lebenszyklus des Voice Overlay (macOS)
Zielgruppe: Mitwirkende an der macOS-App. Ziel: das Sprach-Overlay vorhersehbar halten, wenn Wake-Word und Push-to-Talk sich überschneiden.Aktuelle Absicht
- Wenn das Overlay bereits durch das Wake-Word sichtbar ist und der Benutzer den Hotkey drückt, übernimmt die Hotkey-Sitzung den vorhandenen Text, anstatt ihn zurückzusetzen. Das Overlay bleibt sichtbar, solange der Hotkey gedrückt gehalten wird. Wenn der Benutzer loslässt: senden, wenn getrimmter Text vorhanden ist, andernfalls schließen.
- Nur das Wake-Word sendet weiterhin bei Stille automatisch; Push-to-Talk sendet sofort beim Loslassen.
Implementiert (9. Dez. 2025)
- Overlay-Sitzungen tragen jetzt für jede Erfassung ein Token (Wake-Word oder Push-to-Talk). Teil-/End-/Sende-/Schließen-/Pegel-Updates werden verworfen, wenn das Token nicht übereinstimmt, um veraltete Callbacks zu vermeiden.
- Push-to-Talk übernimmt sichtbaren Overlay-Text als Präfix (sodass beim Drücken des Hotkeys, während das Wake-Overlay sichtbar ist, der Text erhalten bleibt und neue Sprache angehängt wird). Es wartet bis zu 1,5 s auf ein endgültiges Transkript, bevor es auf den aktuellen Text zurückfällt.
- Chime-/Overlay-Logging wird auf
infoin den Kategorienvoicewake.overlay,voicewake.pttundvoicewake.chimeausgegeben (Sitzungsstart, Teil, Ende, Senden, Schließen, Chime-Grund).
Nächste Schritte
- VoiceSessionCoordinator (actor)
- Verwaltet genau eine
VoiceSessiongleichzeitig. - API (tokenbasiert):
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Verwirft Callbacks, die veraltete Token enthalten (verhindert, dass alte Recognizer das Overlay erneut öffnen).
- Verwaltet genau eine
- VoiceSession (model)
- Felder:
token,source(wakeWord|pushToTalk), bestätigter/temporärer Text, Chime-Flags, Timer (automatisches Senden, Inaktivität),overlayMode(display|editing|sending), Cooldown-Deadline.
- Felder:
- Overlay-Bindung
VoiceSessionPublisher(ObservableObject) spiegelt die aktive Sitzung in SwiftUI.VoiceWakeOverlayViewrendert nur über den Publisher; es verändert niemals direkt globale Singletons.- Benutzeraktionen im Overlay (
sendNow,dismiss,edit) rufen über das Sitzungs-Token den Coordinator zurück.
- Vereinheitlichter Sendepfad
- Bei
endCapture: wenn getrimmter Text leer ist → schließen; andernfallsperformSend(session:)(spielt einmal den Sende-Chime ab, leitet weiter, schließt). - Push-to-Talk: keine Verzögerung; Wake-Word: optionale Verzögerung für automatisches Senden.
- Nach Abschluss von Push-to-Talk einen kurzen Cooldown auf die Wake-Runtime anwenden, damit das Wake-Word nicht sofort erneut auslöst.
- Bei
- Logging
- Der Coordinator gibt
.info-Logs im Subsystemai.openclawund in den Kategorienvoicewake.overlayundvoicewake.chimeaus. - Zentrale Ereignisse:
session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
- Der Coordinator gibt
Checkliste zur Fehlerbehebung
-
Logs streamen, während ein hängendes Overlay reproduziert wird:
- Prüfen, dass nur ein aktives Sitzungs-Token vorhanden ist; veraltete Callbacks sollten vom Coordinator verworfen werden.
-
Sicherstellen, dass das Loslassen von Push-to-Talk immer
endCapturemit dem aktiven Token aufruft; wenn der Text leer ist,dismissohne Chime oder Senden erwarten.
Migrationsschritte (empfohlen)
VoiceSessionCoordinator,VoiceSessionundVoiceSessionPublisherhinzufügen.VoiceWakeRuntimeso refaktorieren, dass Sitzungen erstellt/aktualisiert/beendet werden, anstattVoiceWakeOverlayControllerdirekt zu verändern.VoicePushToTalkso refaktorieren, dass bestehende Sitzungen übernommen werden und beim LoslassenendCaptureaufgerufen wird; Runtime-Cooldown anwenden.VoiceWakeOverlayControllermit dem Publisher verbinden; direkte Aufrufe aus Runtime/PTT entfernen.- Integrationstests für Sitzungsübernahme, Cooldown und Schließen bei leerem Text hinzufügen.