OpenClawSkills
GitHub
平台 • 5 分钟阅读

语音覆盖层

唤醒词和按住说话重叠时的语音覆盖层生命周期

受众:macOS 应用贡献者。目标:在唤醒词和按住说话重叠时保持语音覆盖层可预测。

#

Tutorial.step

当前意图

- 如果覆盖层已因唤醒词而可见,并且用户按下热键,热键会话将采用现有文本而不是重置它。覆盖层在按住热键时保持显示。当用户释放时:如果有修剪后的文本则发送,否则关闭。

- 仅唤醒词仍然在静音时自动发送;按住说话在释放时立即发送。

#

Tutorial.step

已实现(2025 年 12 月 9 日)

- 覆盖层会话现在为每次捕获(唤醒词或按住说话)携带一个令牌。当令牌不匹配时,部分/最终/发送/关闭/级别更新将被丢弃,避免过时的回调。

- 按住说话采用任何可见的覆盖层文本作为前缀(因此在唤醒覆盖层显示时按下热键会保留文本并追加新的语音)。它会等待最多 1.5 秒以获取最终转录,然后回退到当前文本。

- 铃声/覆盖层日志在类别 ''voicewake.chime''、''voicewake.overlay'' 和 ''voicewake.ptt'' 中以 ''voicewake.chime'' 级别发出(会话开始、部分、最终、发送、关闭、铃声原因)。

#

Tutorial.step

后续步骤

1. VoiceSessionCoordinator(参与者)

- 一次只拥有一个 ''VoiceSession''。

- API(基于令牌):''beginWakeCapture''、''beginPushToTalk''、''updatePartial''、''endCapture''、''cancel''、''applyCooldown''。

- 丢弃携带过时令牌的回调(防止旧识别器重新打开覆盖层)。

2. VoiceSession(模型)

- 字段:''token''、''source''(wakeWord|pushToTalk)、已提交/易失性文本、铃声标志、计时器(自动发送、空闲)、''overlayMode''(display|editing|sending)、冷却截止时间。

3. 覆盖层绑定

- ''VoiceSessionPublisher''(''ObservableObject'')将活动会话镜像到 SwiftUI。

- ''VoiceWakeOverlayView'' 仅通过发布者渲染;它从不直接改变全局单例。

- 覆盖层用户操作(''sendNow''、''dismiss''、''edit'')使用会话令牌回调到协调器。

4. 统一发送路径

- 在 ''endCapture'' 上:如果修剪后的文本为空 → 关闭;否则 ''performSend(session:)''(播放发送铃声一次、转发、关闭)。

- 按住说话:无延迟;唤醒词:自动发送的可选延迟。

- 在按住说话完成后对唤醒运行时应用短冷却,以便唤醒词不会立即重新触发。

5. 日志记录

- 协调器在子系统 ''voicewake.chime''、类别 ''bot.molt'' 和 ''voicewake.overlay'' 中发出 ''voicewake.chime'' 日志。

- 关键事件:''session_started''、''adopted_by_push_to_talk''、''partial''、''finalized''、''send''、''dismiss''、''cancel''、''cooldown''。

#

Tutorial.step

调试清单

- 在重现粘性覆盖层时流式传输日志:

''''`bash", "p3": "sudo log stream --predicate 'subsystem == "bot.molt" AND category CONTAINS "voicewake"' --level info --style compact", "p4": "''''`

sudo log stream --predicate 'subsystem == "bot.molt" AND category CONTAINS "voicewake"' --level info --style compact

''''`

- 验证只有一个活动会话令牌;过时的回调应该被协调器丢弃。

- 确保按住说话释放始终使用活动令牌调用 ''endCapture'';如果文本为空,则期望 ''dismiss'' 而没有铃声或发送。

#

Tutorial.step

迁移步骤(建议)

1. 添加 ''VoiceSessionCoordinator''、''VoiceSession'' 和 ''VoiceSessionPublisher''。

2. 重构 ''VoiceWakeRuntime'' 以创建/更新/结束会话,而不是直接接触 ''VoiceWakeOverlayController''。

3. 重构 ''VoicePushToTalk'' 以采用现有会话并在释放时调用 ''endCapture'';应用运行时冷却。

4. 将 ''VoiceWakeOverlayController'' 连接到发布者;从运行时/PTT 中删除直接调用。

5. 添加会话采用、冷却和空文本关闭的集成测试。