음성 Wake 및 Push-to-Talk
모드
- Wake 단어 모드 (기본값): 항상 켜져 있는 음성 인식기가 트리거 토큰 (
swabbleTriggerWords)을 기다립니다. 일치하면 캡처를 시작하고 부분 텍스트와 함께 오버레이를 표시하며 침묵 후 자동으로 전송합니다. - Push-to-talk (오른쪽 Option 키 누르기): 오른쪽 Option 키를 눌러 즉시 캡처합니다. 트리거가 필요하지 않습니다. 오버레이는 눌린 상태에서 표시됩니다. 해제하면 짧은 지연 후 최종화되고 전달되므로 텍스트를 조정할 수 있습니다.
런타임 동작 (wake 단어)
- 음성 인식기는
VoiceWakeRuntime에 있습니다. - 트리거는 wake 단어와 다음 단어 사이에 의미 있는 휴지 (~0.55초 간격)가 있을 때만 발동합니다. 명령이 시작되기 전에도 휴지에서 오버레이/차임이 시작될 수 있습니다.
- 침묵 창: 음성이 흐를 때 2.0초, 트리거만 들린 경우 5.0초.
- 하드 스톱: 폭주 세션을 방지하기 위해 120초.
- 세션 간 디바운스: 350ms.
- 오버레이는 커밋된/휘발성 색상으로
VoiceWakeOverlayController를 통해 구동됩니다. - 전송 후 인식기가 다음 트리거를 수신하기 위해 깨끗하게 재시작됩니다.
라이프사이클 불변성
- 음성 Wake가 활성화되어 있고 권한이 부여된 경우 wake 단어 인식기가 수신 대기 중이어야 합니다 (명시적 push-to-talk 캡처 중 제외).
- X 버튼을 통한 수동 닫기를 포함한 오버레이 가시성은 인식기 재개를 방해하지 않아야 합니다.
고착된 오버레이 실패 모드 (이전)
이전에는 오버레이가 표시된 상태로 고착되어 수동으로 닫으면 런타임의 재시작 시도가 오버레이 가시성으로 인해 차단될 수 있었고 이후 재시작이 예약되지 않아 Voice Wake가 "죽은" 것처럼 보일 수 있었습니다.
강화:
- Wake 런타임 재시작이 더 이상 오버레이 가시성으로 차단되지 않습니다.
- 오버레이 닫기 완료가
VoiceSessionCoordinator를 통해VoiceWakeRuntime.refresh(...)를 트리거하므로 수동 X 닫기가 항상 수신 대기를 재개합니다.
Push-to-talk 세부 사항
- 핫키 감지는 오른쪽 Option (
keyCode 61+.option)에 대한 글로벌.flagsChanged모니터를 사용합니다. 이벤트만 관찰합니다 (삼키지 않음). - 캡처 파이프라인은
VoicePushToTalk에 있습니다: 즉시 음성을 시작하고, 부분을 오버레이로 스트리밍하며, 해제 시VoiceWakeForwarder를 호출합니다. - Push-to-talk이 시작되면 두 개의 오디오 탭이 경쟁하지 않도록 wake 단어 런타임을 일시 중지합니다. 해제 후 자동으로 재시작됩니다.
- 권한: 마이크 + 음성이 필요합니다. 이벤트를 보려면 접근성/입력 모니터링 승인이 필요합니다.
- 외부 키보드: 일부는 오른쪽 Option을 예상대로 노출하지 않을 수 있습니다. 사용자가 누락을 보고하면 대체 단축키를 제공하십시오.
사용자 대면 설정
- Voice Wake 토글: wake 단어 런타임을 활성화합니다.
- Cmd+Fn을 눌러 말하기: push-to-talk 모니터를 활성화합니다. macOS < 26에서는 비활성화됩니다.
- 언어 및 마이크 선택기, 실시간 레벨 미터, 트리거 단어 테이블, 테스터 (로컬 전용; 전달하지 않음).
- 마이크 선택기는 기기가 연결 해제되면 마지막 선택을 유지하고 연결 해제 힌트를 표시하며 돌아올 때까지 시스템 기본값으로 일시적으로 대체됩니다.
- 소리: 트리거 감지 및 전송 시 차임. 기본값은 macOS "Glass" 시스템 소리. 각 이벤트에 대해
NSSound로 로드 가능한 파일 (예: MP3/WAV/AIFF)을 선택하거나 소리 없음을 선택할 수 있습니다.
전달 동작
- 음성 Wake가 활성화되면 전사가 활성 게이트웨이/에이전트 (앱의 나머지가 사용하는 동일한 로컬 vs 원격 모드)로 전달됩니다.
- 응답은 마지막으로 사용된 메인 공급자 (WhatsApp/Telegram/Discord/WebChat)로 전달됩니다. 전달이 실패하면 오류가 로깅되고 실행은 WebChat/세션 로그를 통해 여전히 표시됩니다.
전달 페이로드
VoiceWakeForwarder.prefixedTranscript(_:)는 전송 전에 머신 힌트를 앞에 추가합니다. wake 단어와 push-to-talk 경로 간에 공유됩니다.
빠른 확인
- Push-to-talk을 켜고 Cmd+Fn을 누르고, 말하고, 해제합니다: 오버레이가 부분을 표시한 다음 전송해야 합니다.
- 누르는 동안 메뉴 바 귀가 확대 상태를 유지해야 합니다 (
triggerVoiceEars(ttl:nil)사용). 해제 후 축소됩니다.