语音唤醒和按键说话

模式

  • 唤醒词模式(默认):始终开启的 Speech 识别器等待触发令牌(swabbleTriggerWords)。匹配时开始捕获,显示带有 partial 文本的叠加层,并在静默后自动发送。
  • 按键说话(按住右 Option):按住右 Option 键立即捕获——无需触发器。按住时显示叠加层;释放后最终确定并在短暂延迟后转发,以便你可以调整文本。

运行时行为(唤醒词)

  • Speech 识别器位于 VoiceWakeRuntime 中。
  • 仅当唤醒词和下一个词之间有有意义的停顿(约 0.55 秒间隔)时才触发。即使命令开始之前,叠加层/chime 也可以在停顿时启动。
  • 静默窗口:语音流动时 2.0 秒,如果仅听到触发器则 5.0 秒。
  • 硬停止:120 秒以防止失控会话。
  • 会话之间的去抖动:350 毫秒。
  • 叠加层通过 VoiceWakeOverlayController 驱动,带有已提交/易失着色。
  • 发送后,识别器干净重启以侦听下一个触发器。

生命周期不变性

  • 如果启用了 Voice Wake 并授予了权限,唤醒词识别器应该正在侦听(除了在显式按键说话捕获期间)。
  • 叠加层可见性(包括通过 X 按钮手动关闭)绝不能阻止识别器恢复。

粘性叠加层失败模式(之前)

以前,如果叠加层卡住可见,你手动关闭它,Voice Wake 可能看起来"死亡",因为运行时的重启尝试可能被叠加层可见性阻止,并且没有安排后续重启。

强化:

  • 唤醒运行时重启不再被叠加层可见性阻止。
  • 叠加层关闭完成通过 VoiceSessionCoordinator 触发 VoiceWakeRuntime.refresh(...),因此手动 X 关闭始终恢复侦听。

按键说话细节

  • 热键检测使用全局 .flagsChanged 监视器监视右 OptionkeyCode 61 + .option)。我们只观察事件(不吞咽)。
  • 捕获管道位于 VoicePushToTalk 中:立即启动 Speech,将 partial 流式传输到叠加层,并在释放时调用 VoiceWakeForwarder
  • 当按键说话启动时,我们暂停唤醒词运行时以避免音频 tap 冲突;它在释放后自动重启。
  • 权限:需要 Microphone + Speech;查看事件需要 Accessibility/Input Monitoring 批准。
  • 外部键盘:某些可能不会按预期公开右 Option——如果用户报告未命中,提供回退快捷方式。

面向用户的设置

  • Voice Wake 切换:启用唤醒词运行时。
  • Hold Cmd+Fn to talk:启用按键说话监视器。在 macOS < 26 上禁用。
  • 语言和麦克风选择器、实时电平计、触发词表、测试器(仅本地;不转发)。
  • 麦克风选择器在设备断开连接时保留最后的选择,显示断开连接提示,并临时回退到系统默认值直到返回。
  • Sounds:在触发检测和发送时发出 chime;默认为 macOS "Glass" 系统声音。你可以为每个事件选择任何 NSSound 可加载的文件(例如 MP3/WAV/AIFF)或选择 No Sound

转发行为

  • 当启用 Voice Wake 时,转录被转发到活动的 gateway/agent(mac 应用其余部分使用的相同本地与远程模式)。
  • 回复被传递到最后使用的主提供者(WhatsApp/Telegram/Discord/WebChat)。如果传递失败,错误将被记录,运行仍通过 WebChat/会话日志可见。

转发负载

  • VoiceWakeForwarder.prefixedTranscript(_:) 在发送前添加机器提示。在唤醒词和按键说话路径之间共享。

快速验证

  • 打开按键说话,按住 Cmd+Fn,说话,释放:叠加层应显示 partial 然后发送。
  • 按住时,菜单栏耳朵应保持放大(使用 triggerVoiceEars(ttl:nil));它们在释放后降下。