15 KiB
Préparation validation réelle — flux finalize → proposition utilisateur → replay-session
Date : 2026-05-20
Mission : Claude 5 (lecture seule)
Périmètre : agent_v0/deploy/windows_client/**, agent_v0/agent_v1/**, scripts SCP, docs déploiement
Branche : backup/post-demo-2026-05-19 (HEAD 5ea4960e6, 5 fichiers uncommitted + 1 untracked)
Constat
Le câblage agent-side du contrat enrichi /finalize est déjà fait et présent dans la branche locale :
streamer.py:96-103, 627-635— attribut_on_finalize_result, setterset_on_finalize_result, invocation aprèsresp.ok(catch d'erreur du callback en log warning).main.py:31— importdispatch_finalize_result.main.py:222— wireself.streamer.set_on_finalize_result(self._on_finalize_result)dansstart_session.main.py:445-448—_on_finalize_result(payload)dispatche viadispatch_finalize_result(self.ui, payload, replay_name)avecreplay_name = self._last_recording_name.finalize_contract.py(untracked) — module pur,dispatch_finalize_result(ui, payload, replay_name)route selonreplay_launch.status(started/failed) etreplay_ready + replay_request.smart_tray.py:577-599—offer_finalize_replay(replay_request, replay_name): notification toast + dialog_ask_consentArticle 14, puis_launch_replay_request(replay_request, replay_name)si accepté.
Le contrat attendu côté serveur s'appelle replay_launch (status started/failed), pas launch_replay comme supposé en mission 4. Les 3 clés consommées : replay_ready: bool, replay_request: dict (doit contenir session_id), replay_launch: dict {status}.
Synchro vers Léa Windows : aucun script SCP automatique présent dans le repo. Le canal réel est un sshpass scp manuel fichier par fichier vers dom@192.168.1.11:C:/rpa_vision/agent_v1/<chemin> (cf. memory/feedback_scp_auto_modif_client_windows.md + handoff 2026-05-16). Le dossier agent_v0/deploy/windows_client/ existe mais sert au setup initial (setup.bat), pas au déploiement incrémental — ses fichiers miroirs sont obsolètes de 2 à 7 semaines par rapport à la source.
Le BUILD_DEPLOY_GUIDE.md (24 novembre 2025) parle de l'ancien agent_v0/ mode upload chiffré — obsolète pour le flux agent_v1 streaming actuel.
Fichiers à déployer
Tableau fichier / déploiement / motif
| Fichier source | Doit être déployé ? | Pourquoi |
|---|---|---|
agent_v0/agent_v1/main.py |
✅ OUI | Lignes 31 (import), 222 (wire), 445-448 (_on_finalize_result) ajoutées — sans ce fichier, le callback n'est pas wired |
agent_v0/agent_v1/network/streamer.py |
✅ OUI | Lignes 96-103 + 627-635 ajoutées — sans ce fichier, le payload /finalize est jeté dans un log comme avant |
agent_v0/agent_v1/ui/smart_tray.py |
✅ OUI | Méthode offer_finalize_replay (577-599) ajoutée — sans elle, finalize_contract.py log "UI indisponible" et abandonne |
agent_v0/agent_v1/finalize_contract.py |
✅ OUI (NOUVEAU FICHIER) | Untracked en git, n'existe nulle part sur Léa Windows → ImportError au démarrage de l'agent si oublié (import ligne main.py:31) |
agent_v0/agent_v1/vision/capturer.py |
✅ OUI | Fix monitor missions 2/2b (garde dims aberrantes + fallback) — pertinent pour la fiabilité de la session enregistrée qui alimente le replay_request |
agent_v0/agent_v1/core/executor.py |
🟡 Si modifié séparément | Apparaît dans git status (modifié dans session antérieure), à vérifier avec git diff avant SCP pour ne pas pousser un changement non validé |
agent_v0/agent_v1/ui/smart_tray.py (méthode _launch_replay_request) |
✅ Inclus dans smart_tray.py | Référencée par offer_finalize_replay, ligne 507 |
agent_v0/agent_v1/config.py |
⚫ Non | Pas modifié par les missions récentes |
agent_v0/agent_v1/ui/chat_window.py |
⚫ Non | Pas modifié par mission 4 |
agent_v0/agent_v1/ui/shared_state.py |
⚫ Non | Pas modifié |
agent_v0/agent_v1/network/persistent_buffer.py |
⚫ Non | Pas modifié |
agent_v0/agent_v1/network/feedback_bus.py |
⚫ Non | Pas modifié |
agent_v0/lea_ui/server_client.py |
⚫ Non | Pas modifié, et probablement non utilisé au runtime actuel (main a son propre poll loop) |
agent_v0/deploy/windows_client/** |
⚫ Non | Miroir obsolète, sert au setup initial, ne fait pas partie du canal de déploiement incrémental |
La synchro actuelle couvre-t-elle ?
| Fichier | Couvert par synchro auto ? | Statut |
|---|---|---|
agent_v0/agent_v1/network/streamer.py |
❌ NON | Aucun script auto — SCP manuel obligatoire |
agent_v0/agent_v1/ui/smart_tray.py |
❌ NON | Aucun script auto — SCP manuel obligatoire |
agent_v0/agent_v1/main.py |
❌ NON | Aucun script auto — SCP manuel obligatoire |
agent_v0/agent_v1/finalize_contract.py |
❌ NON (cas critique) | Fichier NEUF, untracked git, absent partout sur Léa → ImportError garanti si oublié |
Conclusion synchro : il faut SCP les 4 fichiers manuellement. Le risque principal est d'oublier finalize_contract.py (nouveau) car il n'apparaîtra pas dans un diff incrémental classique — le réflexe "je SCP les fichiers modifiés" ne le couvre pas. Doit être SCP en premier.
Commandes SCP de référence
SSHPASS='loli' sshpass -e scp -o StrictHostKeyChecking=no \
/home/dom/ai/rpa_vision_v3/agent_v0/agent_v1/finalize_contract.py \
dom@192.168.1.11:C:/rpa_vision/agent_v1/finalize_contract.py
SSHPASS='loli' sshpass -e scp -o StrictHostKeyChecking=no \
/home/dom/ai/rpa_vision_v3/agent_v0/agent_v1/network/streamer.py \
dom@192.168.1.11:C:/rpa_vision/agent_v1/network/streamer.py
SSHPASS='loli' sshpass -e scp -o StrictHostKeyChecking=no \
/home/dom/ai/rpa_vision_v3/agent_v0/agent_v1/ui/smart_tray.py \
dom@192.168.1.11:C:/rpa_vision/agent_v1/ui/smart_tray.py
SSHPASS='loli' sshpass -e scp -o StrictHostKeyChecking=no \
/home/dom/ai/rpa_vision_v3/agent_v0/agent_v1/main.py \
dom@192.168.1.11:C:/rpa_vision/agent_v1/main.py
SSHPASS='loli' sshpass -e scp -o StrictHostKeyChecking=no \
/home/dom/ai/rpa_vision_v3/agent_v0/agent_v1/vision/capturer.py \
dom@192.168.1.11:C:/rpa_vision/agent_v1/vision/capturer.py
Checklist smoke
Pré-requis machine (à valider une fois)
| Item | Vérification |
|---|---|
Léa Windows installée à C:\rpa_vision\ |
dir C:\rpa_vision\agent_v1\main.py doit répondre |
Venv .venv ou .venv_v1_win présent avec dépendances |
C:\rpa_vision\.venv\Scripts\python.exe -c "import pystray, pynput, mss, plyer; print('ok')" |
| Token API exporté côté Windows | echo %RPA_API_TOKEN% (ou variable session) — sinon set RPA_API_TOKEN=<token> |
| Serveur Linux accessible | depuis Windows : curl -H "Authorization: Bearer %RPA_API_TOKEN%" http://192.168.1.40:5005/health |
rpa-streaming actif côté Linux |
systemctl --user status rpa-streaming |
| VWB backend actif (port 5002) | optionnel — la mission 5 ne le requiert pas |
| Léa Windows actuellement quittée | tray icône absente |
Déploiement (≈ 1 min)
- SCP
finalize_contract.pyEN PREMIER (fichier neuf, sinon ImportError au prochainpython run_agent_v1.py). - SCP
streamer.py,smart_tray.py,main.py,capturer.py(ordre indifférent). - Côté Léa Windows : ouvrir le dossier
C:\rpa_vision\agent_v1\et confirmer les 5 fichiers ont la date du jour. - Lancer Léa : double-clic raccourci ou
C:\rpa_vision\.venv\Scripts\pythonw.exe run_agent_v1.py. - Vérifier qu'aucune fenêtre console n'apparaît avec une stack trace
ImportError: finalize_contract. Si oui → relancer avecpython.exe(paspythonw.exe) pour voir l'erreur, ou re-SCPfinalize_contract.py. - Vérifier l'icône systray apparaît (cercle gris/orange selon connexion serveur).
Test nominal (≈ 2 min)
| # | Action utilisateur | Logs Léa Windows attendus | Logs serveur Linux attendus | Comportement attendu |
|---|---|---|---|---|
| 1 | Clic droit tray → "Apprenez-moi une tâche" | agent_v0.agent_v1.ui.shared_state Enregistrement demarre : ... + agent_v1.network.streamer Streamer pour sess_... démarré |
[REGISTER] session sess_... machine=desktop-58d5cac |
Notif "C'est parti !" |
| 2 | Saisir nom "test_finalize_replay", confirmer | idem | idem | Tray icône passe rouge |
| 3 | Faire 3-5 clics dans une app simple (calculatrice, notepad) | Action capturée : mouse_click × N |
événements + screenshots reçus dans /event /image |
Compteur "X étapes mémorisées" augmente dans le menu tray |
| 4 | Clic droit tray → "C'est terminé" | Enregistrement arrete : test_finalize_replay (N actions) puis Streamer ... arrêté puis Session finalisée: {...replay_ready: true, replay_request: {session_id: sess_..., ...}, replay_launch: {status: ...}} |
[FINALIZE] sess_... → workflow construit, replay_request retourné |
Notif "Merci ! J'ai bien mémorisé vos N actions." |
| 5 | (auto) | agent_v1.ui.smart_tray.offer_finalize_replay : proposition test 'test_finalize_replay' |
rien | Notif toast "J'ai compris la tâche 'test_finalize_replay'. Voulez-vous la tester ?" |
| 6 | Dialog tkinter Yes/No s'ouvre, cliquer Oui | agent_v1.ui.smart_tray Replay demarre pour workflow ... |
[REPLAY_START] replay_id=replay_..., workflow=... puis actions enqueues |
Tray icône passe bleu (replay actif), notification Article 50 "Le système d'intelligence artificielle exécute la tâche..." |
| 7 | Observer Léa rejouer les clics | Replay action received : click ... × N puis Replay terminé — retour en mode capture |
actions dispatchées via /replay/next, résultats via /replay/result |
Les clics sont rejoués à l'écran. Tray icône revient vert. Notif "C'est fait !" |
Critère succès global : 7 étapes en ≤ 5 min, sans intervention manuelle entre 4 et 7 autre que le dialog _ask_consent.
Test d'échec (variantes à essayer après le nominal)
| Variante | Action | Comportement attendu |
|---|---|---|
| Refus utilisateur | Étape 6 : cliquer Non | _launch_replay_request non appelé, aucun POST /replay/start, log Léa silencieux après offer_finalize_replay, retour mode capture sans replay |
Serveur ne renvoie pas replay_ready |
Couper le câblage côté serveur pour qu'il renvoie juste {} |
Léa log Session finalisée: {}, aucune notif, pas de dialog. Comportement = backward-compat parfaite |
Serveur renvoie replay_launch.status=started |
Test serveur déjà lance le replay | Log Léa Replay direct déjà lancé par le serveur après finalize, dialog NON affiché (logique dispatch_finalize_result:20-22) |
Serveur renvoie replay_launch.status=failed |
Idem | Log warning Auto-replay serveur échoué après finalize, proposition manuelle, dialog affiché (fallback) |
finalize_contract.py absent |
Ne pas SCP ce fichier, relancer Léa | ImportError: cannot import name 'dispatch_finalize_result' au démarrage, agent ne démarre pas |
offer_finalize_replay absent (smart_tray ancien) |
Ne pas SCP smart_tray.py, relancer | Log UI indisponible pour proposer un test immédiat, pas de dialog, replay non lancé |
| Network coupé pendant finalize | Débrancher Wi-Fi pile au "C'est terminé" | Log Léa Finalisation échouée: <exception>, callback non invoqué, aucune notif. Session reste localement, retry implicite au prochain run (buffer SQLite) |
| Replay impossible (workflow vide ou bug) | Faire 0 clic pendant l'enregistrement avant Stop | Selon serveur : si replay_ready=false, dispatch silencieux ligne 24. Pas de dialog, comportement attendu = ne pas proposer un test inutile |
Signes d'échec à surveiller
- Stack trace au démarrage Léa →
finalize_contract.pymanquant ou syntax error - Aucun log
Session finalisée:après "C'est terminé" → streamer n'arrive pas à appeler/finalize(réseau ? auth ? port ?) - Log
Session finalisée: {...}MAIS pas de notif Léa → soit le payload ne contient pasreplay_ready/replay_request, soitoffer_finalize_replayn'est pas sur smart_tray (ancien fichier) - Notif affichée mais pas de dialog Yes/No → bug tkinter (rare) ou thread bloqué (vérifier
_ask_consentqui crée son propre Tk()) - Dialog accepté mais aucun POST
/replay/startcôté serveur →_launch_replay_requestmal câblé oureplay_requestinvalide (session_id absent)
Risques / points ouverts
finalize_contract.pyjamais committé —git statusle marque untracked. Risque : disparition silencieuse au prochaingit stashougit checkout. À committer avant la session de test.- Le SCP des 5 fichiers n'est pas atomique — si Léa est relancée entre le SCP de 2 fichiers, état incohérent possible. Mitigation : SCP les 5 fichiers d'abord, puis relancer Léa, jamais l'inverse.
- Le miroir
agent_v0/deploy/windows_client/agent_v1/est obsolète de 7 semaines — risque de confusion si quelqu'un essaie de redéployer un poste neuf viasetup.bat. Hors scope mission 5 mais à signaler pour le prochain client. _last_recording_namepeut être vide sistart_sessionest appelé avec une chaîne vide —_on_finalize_resultfallback sur "la tâche que vous venez d'enregistrer", testé dansfinalize_contract.py:38. OK mais l'UX dégrade.- Le contrat serveur n'est pas encore validé — la mission concerne le côté agent. Vérifier côté serveur que
/finalizeretourne bien{replay_ready, replay_request, replay_launch}AVANT de smoke-tester. Si le serveur retourne encore l'ancien payload, le test nominal s'arrêtera après étape 4 sans crash mais sans proposition (variante 2 du test d'échec). - Token API
RPA_API_TOKENcôté Windows — si la variable n'est pas définie dans la session Windows actuelle, leregisteret lefinalizeretourneront 401 silencieusement (cf.streamer.py:573-600). Sympôme : log LéaEnregistrement session échoué: 401. - Pas de test d'idempotence — si l'utilisateur enchaîne 2 enregistrements rapidement et accepte le test du premier, le
_replay_activepourrait masquer un secondoffer_finalize_replay. À surveiller mais hors scope ici. - Article 14 / Article 50 — le dialog
_ask_consentcouvre l'Article 14 (contrôle humain avant lancement auto). La notification Article 50 (transparence "le système IA exécute...") est déjà câblée dans_launch_replay_requestréutilisé. Conforme.
Méthode d'audit
- Lecture intégrale :
finalize_contract.py(40 lignes),LISEZMOI.txtdeploy,setup.bat. - Lecture déjà réalisée (audits précédents 2026-05-19/20) :
streamer.py,main.py,smart_tray.pycomplets,vision/capturer.py. - Lecture ciblée :
BUILD_DEPLOY_GUIDE.md(constate obsolescence),feedback_scp_auto_modif_client_windows.md, handoff 2026-05-16 (commandes SCP de référence). - Grep : consumers
dispatch_finalize_result,offer_finalize_replay,_launch_replay_request,_last_recording_name. - Diff dates source vs miroir deploy/windows_client pour valider obsolescence.
git diff agent_v0/agent_v1/network/streamer.pypour confirmer la nature exacte des modifs.- Aucune modification de code, aucune action VWB, aucune modif de script — conformément aux interdits.