Superposition vocale
Cycle de vie de la superposition vocale (macOS)
Section intitulée « Cycle de vie de la superposition vocale (macOS) »Public : contributeurs à l’application macOS. Objectif : garder la superposition vocale prévisible lorsque le mot d’éveil et l’appui-parler se chevauchent.
Intention actuelle
Section intitulée « Intention actuelle »- Si la superposition est déjà visible suite à un mot d’éveil et que l’utilisateur appuie sur la touche de raccourci, la session de raccourci adopte le texte existant au lieu de le réinitialiser. La superposition reste active tant que la touche de raccourci est maintenue. Lorsque l’utilisateur relâche : envoyer s’il y a du texte rogné, sinon rejeter.
- Le mot d’éveil seul envoie toujours automatiquement en cas de silence ; l’appui-parler envoie immédiatement au relâchement.
Implémenté (9 déc. 2025)
Section intitulée « Implémenté (9 déc. 2025) »- Les sessions de superposition transportent désormais un jeton par capture (mot d’éveil ou appui-parler). Les mises à jour partielles/finales/envoi/rejet/niveau sont ignorées lorsque le jeton ne correspond pas, évitant ainsi les rappels obsolètes.
- L’appui-parler adopte tout texte visible de la superposition comme préfixe (ainsi, appuyer sur la touche de raccourci alors que la superposition d’éveil est active conserve le texte et ajoute la nouvelle parole). Il attend jusqu’à 1,5 s une transcription finale avant de revenir au texte actuel.
- La journalisation de la sonnerie/superposition est émise à
infodans les catégoriesvoicewake.overlay,voicewake.pttetvoicewake.chime(début de session, partiel, final, envoi, rejet, raison de la sonnerie).
Prochaines étapes
Section intitulée « Prochaines étapes »- VoiceSessionCoordinator (actor)
- Possède exactement un
VoiceSessionà la fois. - API (basée sur les jetons) :
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Ignore les rappels portant des jetons obsolètes (empêche les anciens reconnaissanceurs de rouvrir la superposition).
- Possède exactement un
- VoiceSession (model)
- Champs :
token,source(wakeWord|pushToTalk), texte validé/volatile, indicateurs de sonnerie, minuteurs (envoi auto, inactivité),overlayMode(affichage|édition|envoi), date limite de cooldown.
- Champs :
- Liaison de la superposition
VoiceSessionPublisher(ObservableObject) reflète la session active dans SwiftUI.VoiceWakeOverlayViewne s’affiche que via l’éditeur (publisher) ; il ne modifie jamais directement les singletons globaux.- Les actions utilisateur de la superposition (
sendNow,dismiss,edit) rappellent le coordinateur avec le jeton de session.
- Chemin d’envoi unifié
- Sur
endCapture: si le texte coupé est vide → fermer ; sinonperformSend(session:)(joue la sonnerie d’envoi une fois, transfère, ferme). - Push-to-talk : pas de délai ; mot de réveil : délai optionnel pour l’envoi automatique.
- Appliquez un court cooldown au runtime de réveil après la fin du push-to-talk pour que le mot de réveil ne se redéclenche pas immédiatement.
- Sur
- Journalisation
- Le coordinateur émet des journaux
.infodans le sous-systèmeai.openclaw, catégoriesvoicewake.overlayetvoicewake.chime. - Événements clés :
session_started,adopted_by_push_to_talk,partial,finalized,send,dismiss,cancel,cooldown.
- Le coordinateur émet des journaux
Liste de contrôle du débogage
Section intitulée « Liste de contrôle du débogage »-
Diffusez les journaux lors de la reproduction d’une superposition bloquée :
Fenêtre de terminal sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact -
Vérifiez qu’il n’y a qu’un seul jeton de session actif ; les rappels obsolètes doivent être ignorés par le coordinateur.
-
Assurez-vous que le relâchement du push-to-talk appelle toujours
endCaptureavec le jeton actif ; si le texte est vide, attendezdismisssans sonnerie ni envoi.
Étapes de migration (suggérées)
Section intitulée « Étapes de migration (suggérées) »- Ajoutez
VoiceSessionCoordinator,VoiceSessionetVoiceSessionPublisher. - Refactor
VoiceWakeRuntimeto create/update/end sessions instead of touchingVoiceWakeOverlayControllerdirectly. - Refactor
VoicePushToTalkto adopt existing sessions and callendCaptureon release; apply runtime cooldown. - Wire
VoiceWakeOverlayControllerto the publisher; remove direct calls from runtime/PTT. - Add integration tests for session adoption, cooldown, and empty-text dismissal.