macOS companion app
Sprach-Overlay
Lebenszyklus des Sprach-Overlays (macOS)
Zielgruppe: Mitwirkende an der macOS-App. Ziel: ein vorhersehbares Verhalten des Sprach-Overlays, wenn sich Aktivierungswort und Push-to-Talk überschneiden.
Verhalten
- Wenn das Overlay aufgrund des Aktivierungsworts bereits sichtbar ist und die Person die Tastenkombination drückt, übernimmt die Tastenkombinationssitzung den vorhandenen Text, statt ihn zurückzusetzen. Das Overlay bleibt sichtbar, solange die Tastenkombination gedrückt gehalten wird. Beim Loslassen: senden, wenn Text nach dem Entfernen umgebender Leerzeichen vorhanden ist, andernfalls schließen.
- Nur das Aktivierungswort führt bei Stille weiterhin zum automatischen Senden; Push-to-Talk sendet sofort beim Loslassen.
Implementierung
VoiceSessionCoordinator(apps/macos/Sources/OpenClaw/VoiceSessionCoordinator.swift) ist der alleinige Eigentümer der aktiven Sprachsitzung. Es handelt sich um einen@MainActor @Observable-Singleton, nicht um einen Actor. API:startSession,updatePartial,finalize,sendNow,dismiss,updateLevel,snapshot. Jede Sitzung enthält einUUID-Token; Aufrufe mit einem veralteten oder nicht übereinstimmenden Token werden verworfen.VoiceWakeOverlayController(VoiceWakeOverlayController+Session.swift) rendert das Overlay und leitet Benutzeraktionen (requestSend,dismiss) über das Sitzungstoken an den Koordinator zurück. Es verwaltet niemals selbst den Sitzungsstatus.- Push-to-Talk (
VoicePushToTalk.begin()) übernimmt jeglichen sichtbaren Overlay-Text alsadoptedPrefix(überVoiceSessionCoordinator.shared.snapshot()), sodass beim Drücken der Tastenkombination während der Anzeige des Aktivierungswort-Overlays der Text erhalten bleibt und neue Sprache angehängt wird. Beim Loslassen wartet es bis zu 1.5s auf ein endgültiges Transkript, bevor es auf den aktuellen Text zurückgreift. - Bei
dismissruft das OverlayVoiceSessionCoordinator.overlayDidDismissauf, wodurchVoiceWakeRuntime.refresh(state:)ausgelöst wird. So wird das Lauschen auf das Aktivierungswort nach dem manuellen Schließen über X, dem Schließen bei leerem Text und dem Schließen nach dem Senden jeweils fortgesetzt. - Einheitlicher Sendepfad: Wenn der Text nach dem Entfernen umgebender Leerzeichen leer ist, schließen; andernfalls spielt
sendNowden Sendeton einmal ab, leitet den Text überVoiceWakeForwarderweiter und schließt anschließend das Overlay.
Protokollierung
Das Sprachsubsystem ist ai.openclaw; jede Komponente protokolliert unter ihrer eigenen Kategorie:
| Kategorie | Komponente |
|---|---|
voicewake.coordinator |
VoiceSessionCoordinator |
voicewake.overlay |
VoiceWakeOverlayController/VoiceWakeOverlay |
voicewake.ptt |
Push-to-Talk-Tastenkombination und Aufnahme |
voicewake.runtime |
Aktivierungswort-Laufzeit |
voicewake.chime |
Wiedergabe des Signaltons |
voicewake.sync |
Globale Einstellungssynchronisierung |
voicewake.forward |
Transkriptweiterleitung |
voicewake.meter |
Mikrofonpegelüberwachung |
Checkliste zur Fehlerbehebung
-
Streamen Sie die Protokolle, während Sie ein hängen bleibendes Overlay reproduzieren:
bash sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact -
Vergewissern Sie sich, dass nur ein aktives Sitzungstoken vorhanden ist; veraltete Callbacks werden vom Koordinator verworfen.
-
Stellen Sie sicher, dass beim Loslassen von Push-to-Talk immer
end()mit dem aktiven Token aufgerufen wird; wenn der Text leer ist, muss das Overlay ohne Signalton oder Senden geschlossen werden.
Verwandte Themen
Was this useful?