docs: add POC specs, handoffs, and research notes
This commit is contained in:
158
docs/SMOKE_TEST_FINALIZE_REPLAY_2026-05-20.md
Normal file
158
docs/SMOKE_TEST_FINALIZE_REPLAY_2026-05-20.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# 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`, setter `set_on_finalize_result`, invocation après `resp.ok` (catch d'erreur du callback en log warning).
|
||||
- `main.py:31` — import `dispatch_finalize_result`.
|
||||
- `main.py:222` — wire `self.streamer.set_on_finalize_result(self._on_finalize_result)` dans `start_session`.
|
||||
- `main.py:445-448` — `_on_finalize_result(payload)` dispatche via `dispatch_finalize_result(self.ui, payload, replay_name)` avec `replay_name = self._last_recording_name`.
|
||||
- `finalize_contract.py` (untracked) — module pur, `dispatch_finalize_result(ui, payload, replay_name)` route selon `replay_launch.status` (`started`/`failed`) et `replay_ready + replay_request`.
|
||||
- `smart_tray.py:577-599` — `offer_finalize_replay(replay_request, replay_name)` : notification toast + dialog `_ask_consent` Article 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
|
||||
|
||||
```bash
|
||||
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)
|
||||
|
||||
1. **SCP `finalize_contract.py` EN PREMIER** (fichier neuf, sinon ImportError au prochain `python run_agent_v1.py`).
|
||||
2. SCP `streamer.py`, `smart_tray.py`, `main.py`, `capturer.py` (ordre indifférent).
|
||||
3. Côté Léa Windows : ouvrir le dossier `C:\rpa_vision\agent_v1\` et confirmer les 5 fichiers ont la date du jour.
|
||||
4. Lancer Léa : double-clic raccourci ou `C:\rpa_vision\.venv\Scripts\pythonw.exe run_agent_v1.py`.
|
||||
5. Vérifier qu'aucune fenêtre console n'apparaît avec une stack trace `ImportError: finalize_contract`. Si oui → relancer avec `python.exe` (pas `pythonw.exe`) pour voir l'erreur, ou re-SCP `finalize_contract.py`.
|
||||
6. 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.py` manquant 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 pas `replay_ready/replay_request`, soit `offer_finalize_replay` n'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_consent` qui crée son propre Tk())
|
||||
- **Dialog accepté mais aucun POST `/replay/start` côté serveur** → `_launch_replay_request` mal câblé ou `replay_request` invalide (session_id absent)
|
||||
|
||||
## Risques / points ouverts
|
||||
|
||||
1. **`finalize_contract.py` jamais committé** — `git status` le marque untracked. Risque : disparition silencieuse au prochain `git stash` ou `git checkout`. À committer avant la session de test.
|
||||
2. **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.
|
||||
3. **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 via `setup.bat`. Hors scope mission 5 mais à signaler pour le prochain client.
|
||||
4. **`_last_recording_name` peut être vide si `start_session` est appelé avec une chaîne vide** — `_on_finalize_result` fallback sur "la tâche que vous venez d'enregistrer", testé dans `finalize_contract.py:38`. OK mais l'UX dégrade.
|
||||
5. **Le contrat serveur n'est pas encore validé** — la mission concerne le côté agent. Vérifier côté serveur que `/finalize` retourne 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).
|
||||
6. **Token API `RPA_API_TOKEN` côté Windows** — si la variable n'est pas définie dans la session Windows actuelle, le `register` et le `finalize` retourneront 401 silencieusement (cf. `streamer.py:573-600`). Sympôme : log Léa `Enregistrement session échoué: 401`.
|
||||
7. **Pas de test d'idempotence** — si l'utilisateur enchaîne 2 enregistrements rapidement et accepte le test du premier, le `_replay_active` pourrait masquer un second `offer_finalize_replay`. À surveiller mais hors scope ici.
|
||||
8. **Article 14 / Article 50** — le dialog `_ask_consent` couvre 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_request` réutilisé. Conforme.
|
||||
|
||||
## Méthode d'audit
|
||||
|
||||
- Lecture intégrale : `finalize_contract.py` (40 lignes), `LISEZMOI.txt` deploy, `setup.bat`.
|
||||
- Lecture déjà réalisée (audits précédents 2026-05-19/20) : `streamer.py`, `main.py`, `smart_tray.py` complets, `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.py` pour confirmer la nature exacte des modifs.
|
||||
- **Aucune modification de code, aucune action VWB, aucune modif de script** — conformément aux interdits.
|
||||
Reference in New Issue
Block a user