Application compagnon macOS
Superposition vocale
Public : contributeurs de l'application macOS. Objectif : maintenir la superposition vocale prévisible lorsque la commande vocale et la pression-pour-parler se chevauchent.
Intention actuelle
- Si la superposition est déjà visible suite à une commande vocale et que l'utilisateur appuie sur la touche de raccourci, la session de la touche de raccourci adopte le texte existant au lieu de le réinitialiser. La superposition reste affichée tant que la touche est maintenue. Lorsque l'utilisateur relâche : envoyer s'il y a du texte tronqué, sinon fermer.
- La commande vocale seule envoie toujours automatiquement lors du silence ; la pression-pour-parler envoie immédiatement au relâchement.
Implémenté (9 déc. 2025)
- Les sessions de superposition portent désormais un jeton par capture (commande vocale ou pression-pour-parler). Les mises à jour partielles/finales/envoi/fermeture/niveau sont ignorées lorsque le jeton ne correspond pas, évitant ainsi les rappels obsolètes.
- La pression-pour-parler adopte tout texte visible de la superposition comme préfixe (ainsi, appuyer sur la touche de raccourci alors que la superposition de commande vocale est active conserve le texte et y ajoute la nouvelle parole). Elle attend jusqu'à 1,5 s pour une transcription finale avant de revenir au texte actuel.
- La journalisation des sons/superposition est émise au niveau
infodans les catégoriesvoicewake.overlay,voicewake.pttetvoicewake.chime(début de session, partiel, final, envoi, fermeture, raison du son).
Prochaines étapes
- VoiceSessionCoordinator (acteur)
- Possède exactement une
VoiceSessionà la fois. - API (basée sur jeton) :
beginWakeCapture,beginPushToTalk,updatePartial,endCapture,cancel,applyCooldown. - Ignore les rappels portant des jetons obsolètes (empêche les anciens reconnaisseurs de rouvrir la superposition).
- Possède exactement une
- VoiceSession (modèle)
- Champs :
token,source(wakeWord|pushToTalk), texte validé/volatil, indicateurs de son, minuteries (envoi automatique, inactivité),overlayMode(affichage|édition|envoi), échéance de temporisation.
- Champs :
- Liaison de superposition
VoiceSessionPublisher(ObservableObject) reflète la session active dans SwiftUI.VoiceWakeOverlayViews'affiche uniquement via l'éditeur ; il ne modifie jamais directement les singletons globaux.- Les actions utilisateur sur la superposition (
sendNow,dismiss,edit) rappellent le coordinateur avec le jeton de session.
- Chemin d'envoi unifié
- Sur
endCapture: si le texte tronqué est vide → fermer ; sinonperformSend(session:)(joue le son d'envoi une fois, transmet, ferme). - Pression-pour-parler : aucun délai ; commande vocale : délai optionnel pour l'envoi automatique.
- Appliquer une courte temporisation au runtime de commande vocale après la fin de la pression-pour-parler pour que la commande vocale ne se redéclenche pas immédiatement.
- Sur
- Journalisation
- Le coordinateur émet des logs
.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 logs
Liste de vérification pour le débogage
-
Diffuser les logs tout en reproduisant une superposition persistante :
Copier
sudo log stream --predicate 'subsystem == "ai.openclaw" AND category CONTAINS "voicewake"' --level info --style compact -
Vérifier qu'un seul jeton de session est actif ; les rappels obsolètes doivent être ignorés par le coordinateur.
-
S'assurer que le relâchement de la pression-pour-parler appelle toujours
endCaptureavec le jeton actif ; si le texte est vide, s'attendre à unedismisssans son ni envoi.
Étapes de migration (suggérées)
- Ajouter
VoiceSessionCoordinator,VoiceSessionetVoiceSessionPublisher. - Refactoriser
VoiceWakeRuntimepour créer/mettre à jour/terminer des sessions au lieu de manipuler directementVoiceWakeOverlayController. - Refactoriser
VoicePushToTalkpour adopter les sessions existantes et appelerendCaptureau relâchement ; appliquer la temporisation du runtime. - Connecter
VoiceWakeOverlayControllerà l'éditeur ; supprimer les appels directs depuis runtime/PTT. - Ajouter des tests d'intégration pour l'adoption de session, la temporisation et la fermeture sans texte.