Cycle de vie de la superposition vocale (macOS)
Public : contributeurs de l’application macOS. Objectif : maintenir une superposition vocale prévisible lorsque le mot d’activation et le push-to-talk se chevauchent.Intention actuelle
- Si la superposition est déjà visible via le mot d’activation et que l’utilisateur appuie sur le raccourci clavier, la session push-to-talk adopte le texte existant au lieu de le réinitialiser. La superposition reste affichée tant que le raccourci est maintenu. Au relâchement : envoyer s’il existe du texte tronqué, sinon fermer.
- Le mot d’activation seul envoie toujours automatiquement après le silence ; le push-to-talk envoie immédiatement au relâchement.
Implémenté (9 déc. 2025)
- Les sessions de superposition portent désormais un jeton par capture (mot d’activation ou push-to-talk). Les mises à jour partial/final/send/dismiss/level sont ignorées lorsque le jeton ne correspond pas, ce qui évite les rappels obsolètes.
- Le push-to-talk adopte tout texte de superposition visible comme préfixe (ainsi, appuyer sur le raccourci pendant que la superposition du mot d’activation est affichée conserve le texte et ajoute la nouvelle parole). Il attend jusqu’à 1,5 s un transcript final avant de revenir au texte courant.
- La journalisation des carillons/superpositions est émise à
infodans les catégoriesvoicewake.overlay,voicewake.pttetvoicewake.chime(début de session, partiel, final, envoi, fermeture, raison du carillon).
Prochaines étapes
- VoiceSessionCoordinator (actor)
- Détient exactement un
VoiceSessionà la fois. - API (basée sur des jetons) :
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Lâche les callbacks qui portent des jetons obsolètes (empêche les anciens reconnaissants de rouvrir le recouvrement).
- Détient exactement un
- VoiceSession (model)
- Champs :
token,source(wakeWord|pushToTalk), texte validé/volatile, indicateurs de carillon, minuteurs (envoi auto, inactivité),overlayMode(display|editing|sending), échéance de cooldown.
- Champs :
- Liaison de la superposition
VoiceSessionPublisher(ObservableObject) reflète la session active dans SwiftUI.VoiceWakeOverlayVieweffectue le rendu uniquement via l’éditeur ; il ne modifie jamais directement des singletons globaux.- Les actions utilisateur de la superposition (
sendNow,dismiss,edit) rappellent le coordinateur avec le jeton de session.
- Chemin d’envoi unifié
- À
endCapture: si le texte tronqué est vide → fermer ; sinonperformSend(session:)(joue le carillon d’envoi une fois, transfère, ferme). - Push-to-talk : pas de délai ; mot d’activation : délai optionnel pour l’envoi automatique.
- Appliquer un court cooldown à l’exécution du mot d’activation après la fin du push-to-talk afin que le mot d’activation ne se redéclenche pas immédiatement.
- À
- Journalisation
- Le coordinateur émet des journaux
.infodans le sous-systèmebot.molt, 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 vérification de débogage
-
Stream les logs tout en reproduisant une surcouche autocollante :
- 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, attendez-vous àdismisssans carillon ni envoi.
Étapes de migration (suggestions)
- Ajouter
VoiceSessionCoordinator,VoiceSessionetVoiceSessionPublisher. - Refactoriser
VoiceWakeRuntimepour créer/mettre à jour/terminer des sessions au lieu de toucher directementVoiceWakeOverlayController. - Refactoriser
VoicePushToTalkpour adopter les sessions existantes et appelerendCaptureau relâchement ; appliquer le cooldown d’exécution. - Connecter
VoiceWakeOverlayControllerà l’éditeur ; supprimer les appels directs depuis l’exécution/PTT. - Ajouter des tests d’intégration pour l’adoption de session, le cooldown et la fermeture lorsque le texte est vide.