macOS companion app
Nakładka głosowa
Cykl życia nakładki głosowej (macOS)
Odbiorcy: kontrybutorzy aplikacji macOS. Cel: utrzymać przewidywalne działanie nakładki głosowej, gdy słowo wybudzające i tryb naciśnij, aby mówić nakładają się na siebie.
Obecny zamiar
- Jeśli nakładka jest już widoczna po słowie wybudzającym, a użytkownik naciśnie skrót klawiszowy, sesja skrótu klawiszowego przejmuje istniejący tekst zamiast go resetować. Nakładka pozostaje widoczna, dopóki skrót klawiszowy jest przytrzymywany. Gdy użytkownik go zwolni: wyślij, jeśli istnieje przycięty tekst, w przeciwnym razie odrzuć.
- Samo słowo wybudzające nadal wysyła automatycznie po ciszy; tryb naciśnij, aby mówić wysyła natychmiast po zwolnieniu.
Wdrożono (9 grudnia 2025)
- Sesje nakładki przenoszą teraz token dla każdego przechwytywania (słowo wybudzające lub tryb naciśnij, aby mówić). Aktualizacje częściowe/końcowe/wysyłania/odrzucania/poziomu są odrzucane, gdy token nie pasuje, co pozwala uniknąć nieaktualnych wywołań zwrotnych.
- Tryb naciśnij, aby mówić przejmuje każdy widoczny tekst nakładki jako prefiks (więc naciśnięcie skrótu klawiszowego, gdy nakładka wybudzania jest widoczna, zachowuje tekst i dopisuje nową wypowiedź). Czeka do 1,5 s na końcową transkrypcję, zanim awaryjnie użyje bieżącego tekstu.
- Logowanie dźwięku/nakładki jest emitowane na poziomie
infow kategoriachvoicewake.overlay,voicewake.pttivoicewake.chime(start sesji, część, finał, wysłanie, odrzucenie, powód dźwięku).
Następne kroki
- VoiceSessionCoordinator (aktor)
- Posiada dokładnie jedną
VoiceSessionnaraz. - API (oparte na tokenach):
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Odrzuca wywołania zwrotne przenoszące nieaktualne tokeny (zapobiega ponownemu otwieraniu nakładki przez stare rozpoznawacze).
- Posiada dokładnie jedną
- VoiceSession (model)
- Pola:
token,source(wakeWord|pushToTalk), zatwierdzony/ulotny tekst, flagi dźwięku, timery (automatyczne wysyłanie, bezczynność),overlayMode(display|editing|sending), termin końca okresu blokady.
- Pola:
- Powiązanie nakładki
VoiceSessionPublisher(ObservableObject) odzwierciedla aktywną sesję w SwiftUI.VoiceWakeOverlayViewrenderuje tylko przez publisher; nigdy nie modyfikuje globalnych singletonów bezpośrednio.- Akcje użytkownika nakładki (
sendNow,dismiss,edit) wywołują koordynator z tokenem sesji.
- Ujednolicona ścieżka wysyłania
- Przy
endCapture: jeśli przycięty tekst jest pusty → odrzuć; w przeciwnym razieperformSend(session:)(odtwarza dźwięk wysyłania raz, przekazuje dalej, odrzuca). - Tryb naciśnij, aby mówić: bez opóźnienia; słowo wybudzające: opcjonalne opóźnienie dla automatycznego wysyłania.
- Zastosuj krótki okres blokady do środowiska uruchomieniowego wybudzania po zakończeniu trybu naciśnij, aby mówić, aby słowo wybudzające nie uruchomiło się ponownie natychmiast.
- Przy
- Logowanie
- Koordynator emituje logi
.infow podsystemieai.openclaw, w kategoriachvoicewake.overlayivoicewake.chime. - Kluczowe zdarzenia:
session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
- Koordynator emituje logi
Lista kontrolna debugowania
-
Strumieniuj logi podczas odtwarzania zacinającej się nakładki:
sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact -
Zweryfikuj, że aktywny jest tylko jeden token sesji; nieaktualne wywołania zwrotne powinny być odrzucane przez koordynator.
-
Upewnij się, że zwolnienie w trybie naciśnij, aby mówić zawsze wywołuje
endCapturez aktywnym tokenem; jeśli tekst jest pusty, oczekujdismissbez dźwięku ani wysyłania.
Kroki migracji (sugerowane)
- Dodaj
VoiceSessionCoordinator,VoiceSessioniVoiceSessionPublisher. - Zrefaktoryzuj
VoiceWakeRuntime, aby tworzył/aktualizował/kończył sesje zamiast bezpośrednio dotykaćVoiceWakeOverlayController. - Zrefaktoryzuj
VoicePushToTalk, aby przejmował istniejące sesje i wywoływałendCapturepo zwolnieniu; zastosuj okres blokady środowiska uruchomieniowego. - Podłącz
VoiceWakeOverlayControllerdo publishera; usuń bezpośrednie wywołania ze środowiska uruchomieniowego/PTT. - Dodaj testy integracyjne dla przejmowania sesji, okresu blokady i odrzucania pustego tekstu.