backup: snapshot post-démo GHT 2026-05-19
Backup état complet après enregistrement vidéo démo de bout en bout. À utiliser comme point de référence pour la consolidation post-démo. Changements majeurs de la session 18-19 mai : - AIVA-URGENCE : page autonome avec preset URL + auto-focus chain - Workflow Demo_urgence_3_db : merge linux_db + steps AIVA + pause humaine NoMachine - Bypass LLM (static_result / static_text) dans replay_engine pour démos déterministes sans appel Ollama - Fix api_stream:3013 — replay_paused au premier polling /next - dag_execute : lift duration_ms vers top-level pour wait runtime - NPM bypass auth /aiva-urgence/ via location ^~ (proxy_host/10.conf hors git) - scripts/cancel-replays.sh — workaround Stop VWB qui ne purge pas la queue Anchors visuels (468) forcés dans le commit pour garantir restorabilité. DB workflows actuelle + ~12 .bak DB de la journée incluses. Sujets identifiés pour consolidation post-démo (TODO) : 1. Bug VWB recapture anchor ne régénère pas le PNG 2. Léa client accumule état mémoire (restart périodique requis) 3. Stop VWB ne purge pas la queue serveur (lien manquant vers /replay/cancel) 4. Bug coord client mss tronqué 2560x60 → mapping Y cassé 5. delay_before/delay_after ignorés au runtime (fix partiel duration_ms) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
53
scripts/cancel-replays.sh
Executable file
53
scripts/cancel-replays.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# Annule TOUS les replays actifs/en-pause côté streaming server.
|
||||
# À utiliser AVANT de relancer un replay quand le bouton Stop VWB
|
||||
# ne purge pas la queue (bug en cours d'investigation).
|
||||
#
|
||||
# Usage : ./scripts/cancel-replays.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ENV_FILE="/home/dom/ai/rpa_vision_v3/.env.local"
|
||||
STREAM_URL="http://localhost:5005"
|
||||
|
||||
if [[ ! -f "$ENV_FILE" ]]; then
|
||||
echo "❌ .env.local introuvable" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN=$(grep RPA_API_TOKEN "$ENV_FILE" | cut -d= -f2 | tr -d "'\"")
|
||||
if [[ -z "$TOKEN" ]]; then
|
||||
echo "❌ RPA_API_TOKEN vide" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Liste les replays actifs et les annule un par un.
|
||||
mapfile -t ACTIVE < <(
|
||||
curl -s -H "Authorization: Bearer $TOKEN" \
|
||||
"$STREAM_URL/api/v1/traces/stream/replay/list" \
|
||||
| python3 -c "
|
||||
import sys, json
|
||||
try:
|
||||
d = json.load(sys.stdin)
|
||||
for x in d.get('replays', []):
|
||||
if x.get('status') in ('running', 'paused_need_help', 'busy'):
|
||||
print(x['replay_id'])
|
||||
except Exception as e:
|
||||
sys.stderr.write(f'parse error: {e}\n')
|
||||
"
|
||||
)
|
||||
|
||||
if [[ ${#ACTIVE[@]} -eq 0 ]]; then
|
||||
echo "✓ Aucun replay actif"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Annulation de ${#ACTIVE[@]} replay(s) actif(s) :"
|
||||
for r in "${ACTIVE[@]}"; do
|
||||
echo -n " $r ... "
|
||||
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
||||
"$STREAM_URL/api/v1/traces/stream/replay/$r/cancel" > /dev/null
|
||||
echo "✓"
|
||||
done
|
||||
|
||||
echo "✓ Tous les replays annulés, queues purgées."
|
||||
70
scripts/paste_and_execute_linuxdb.sh
Executable file
70
scripts/paste_and_execute_linuxdb.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
# Déclenche manuellement le Ctrl+V puis Ctrl+Enter dans DBeaver de la VM via ydotool.
|
||||
# Contournement nécessaire car NoMachine en "passive grab" mange la touche Ctrl
|
||||
# envoyée par pynput depuis Léa Windows (les clics passent, pas les key combos).
|
||||
#
|
||||
# Pré-conditions (vérifiées + auto-réparées par ce script) :
|
||||
# - ydotoold tourne dans la VM avec socket /tmp/.ydotool_socket (perm 0666)
|
||||
# - Le gardien clipboard (prepare_clipboard_linuxdb.sh) maintient le INSERT
|
||||
# dans les clipboards Wayland + X11 de la VM
|
||||
#
|
||||
# Pré-condition manuelle (le script ne peut pas la vérifier) :
|
||||
# - DBeaver console <demo_95 2> a le focus dans la zone éditeur SQL
|
||||
#
|
||||
# Usage : lancer juste après les clics du workflow linux_db (entre ord 7 et ord 8).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
VM_HOST="dom@192.168.122.132"
|
||||
SSH_PASS="loli"
|
||||
SUDO_PASS="loli"
|
||||
YDOTOOL_SOCKET="/tmp/.ydotool_socket"
|
||||
|
||||
ssh_vm() {
|
||||
SSHPASS="$SSH_PASS" sshpass -e ssh -o StrictHostKeyChecking=no "$VM_HOST" "$@"
|
||||
}
|
||||
|
||||
# 1. Vérifier ydotoold (doit être lancé en amont par opérateur — voir handoff §5)
|
||||
# Le script ne tente PAS de le relancer car invoqué depuis le serveur systemd
|
||||
# qui n'a pas de TTY → sudo via stdin échoue silencieusement.
|
||||
if ! ssh_vm "test -S $YDOTOOL_SOCKET"; then
|
||||
echo "ERREUR: ydotoold (socket $YDOTOOL_SOCKET) absent dans la VM" >&2
|
||||
echo "Lance manuellement depuis terminal VM (TTY) :" >&2
|
||||
echo " sudo ydotoold --socket-path=$YDOTOOL_SOCKET --socket-perm=0666 &" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. Vérifier gardien clipboard, relancer si nécessaire
|
||||
GUARD_OK=$(ssh_vm "
|
||||
if [ -f /tmp/clipboard_guard.pid ]; then
|
||||
P=\$(cat /tmp/clipboard_guard.pid)
|
||||
kill -0 \$P 2>/dev/null && echo OK || echo DEAD
|
||||
else
|
||||
echo MISSING
|
||||
fi
|
||||
")
|
||||
if [ "$GUARD_OK" != "OK" ]; then
|
||||
echo "[setup] gardien clipboard absent/mort ($GUARD_OK), relance via prepare_clipboard_linuxdb.sh…"
|
||||
"$SCRIPT_DIR/prepare_clipboard_linuxdb.sh" || {
|
||||
echo "ERREUR: échec préparation clipboard" >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
# 3. Envoyer Ctrl+V (scan codes : Ctrl=29, V=47)
|
||||
echo "[ydotool] Ctrl+V"
|
||||
ssh_vm "YDOTOOL_SOCKET=$YDOTOOL_SOCKET ydotool key 29:1 47:1 47:0 29:0"
|
||||
|
||||
# 4. Délai pour que DBeaver finisse de coller (~1.6k chars)
|
||||
sleep 0.5
|
||||
|
||||
# 5. Envoyer Ctrl+Enter (scan codes : Ctrl=29, Enter=28)
|
||||
echo "[ydotool] Ctrl+Enter"
|
||||
ssh_vm "YDOTOOL_SOCKET=$YDOTOOL_SOCKET ydotool key 29:1 28:1 28:0 29:0"
|
||||
|
||||
echo ""
|
||||
echo "OK INSERT collé et exécuté dans DBeaver."
|
||||
echo ""
|
||||
echo "Pour vérifier en base demo_95 :"
|
||||
echo " sshpass -p $SSH_PASS ssh $VM_HOST \"python3 -c 'import sqlite3; c=sqlite3.connect(\\\"/home/dom/demo_95\\\"); print(list(c.execute(\\\"SELECT id,nom_patient,date_creation FROM requalification_urgence ORDER BY id DESC LIMIT 2\\\")))'\""
|
||||
9
scripts/payload_insert_morel.sql
Normal file
9
scripts/payload_insert_morel.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
INSERT INTO requalification_urgence (ipp, nom_patient, decision, sommes, resume, justification, workflow_id, date_creation) VALUES ('25003284', 'MOREL Catherine',
|
||||
'REQUALIFICATION_HOSPITALISATION', 1750, 'Patiente de 78 ans admise aux urgences pour dyspnée fébrile sur terrain asthmatique. Examen clinique retrouvant une polypnée à 28 par
|
||||
minute, saturation 88 pour cent en air ambiant, fièvre à 39 degrés. Radiographie thoracique montrant un foyer alvéolaire systématisé du lobe inférieur droit compatible avec une
|
||||
pneumopathie communautaire. Mise sous oxygénothérapie 3 litres par minute, antibiothérapie par amoxicilline acide clavulanique et nébulisations bronchodilatatrices. Surveillance
|
||||
prolongée en UHCD pendant 36 heures pour optimisation respiratoire et hémodynamique. Transfert en service de pneumologie pour poursuite de la prise en charge.', 'La décision
|
||||
REQUALIFICATION HOSPITALISATION est justifiée par plusieurs éléments concordants conformes au critère 3 de la grille PMSI ATIH. Premier critère : surveillance médicalisée prolongée
|
||||
supérieure à 6 heures avec oxygénothérapie et antibiothérapie intraveineuse. Deuxième critère : sévérité respiratoire initiale avec désaturation à 88 pour cent nécessitant un support
|
||||
continu non disponible en consultation simple. Troisième critère : transfert en service de pneumologie confirmant la nécessité de soins continus dépassant le forfait urgences. Ces
|
||||
éléments dépassent le périmètre du FORFAIT URGENCE et valident la valorisation en hospitalisation MCO.', 'wf_483910cdd851_1778750587', '2026-05-15');
|
||||
91
scripts/prepare_clipboard_linuxdb.sh
Executable file
91
scripts/prepare_clipboard_linuxdb.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
# Précharge le clipboard de la VM Ubuntu avec le INSERT SQL du workflow linux_db.
|
||||
# Contourne la lenteur du char-by-char NoMachine (bug paste:true).
|
||||
#
|
||||
# Source de vérité : scripts/payload_insert_morel.sql (extrait depuis workflows.db
|
||||
# backup du 2026-05-16_102755, avant transformation du step ord 8 en Ctrl+V).
|
||||
#
|
||||
# Wayland ne permet pas de "verrouiller" la sélection clipboard : wl-copy meurt
|
||||
# dès qu'un autre client (terminal, navigateur, DBeaver) prend le clipboard.
|
||||
# Solution : un GARDIEN qui re-pousse le payload toutes les 0.5s en boucle.
|
||||
# Le PID du gardien est sauvegardé dans /tmp/clipboard_guard.pid sur la VM
|
||||
# pour permettre un kill propre sans pkill -f (qui se tuerait lui-même).
|
||||
#
|
||||
# À lancer AVANT chaque run du workflow linux_db.
|
||||
# Le step ord 8 du workflow est désormais un Ctrl+V (et non plus le type_text).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PAYLOAD_FILE="$SCRIPT_DIR/payload_insert_morel.sql"
|
||||
VM_HOST="dom@192.168.122.132"
|
||||
SSH_PASS="loli"
|
||||
VM_PAYLOAD="/tmp/clipboard_payload.sql"
|
||||
VM_PIDFILE="/tmp/clipboard_guard.pid"
|
||||
|
||||
# 1. Vérifier le payload local
|
||||
if [ ! -s "$PAYLOAD_FILE" ]; then
|
||||
echo "ERREUR: payload introuvable ou vide : $PAYLOAD_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
BYTES=$(wc -c < "$PAYLOAD_FILE")
|
||||
echo "[1/3] Payload local : ${BYTES} bytes ($PAYLOAD_FILE)"
|
||||
|
||||
# 2. Pousser dans la VM via SSH (cat redirect)
|
||||
SSHPASS="$SSH_PASS" sshpass -e ssh -o StrictHostKeyChecking=no "$VM_HOST" \
|
||||
"cat > $VM_PAYLOAD" < "$PAYLOAD_FILE"
|
||||
REMOTE_BYTES=$(SSHPASS="$SSH_PASS" sshpass -e ssh -o StrictHostKeyChecking=no "$VM_HOST" \
|
||||
"wc -c < $VM_PAYLOAD")
|
||||
echo "[2/3] Fichier déployé : ${REMOTE_BYTES} bytes sur VM ($VM_PAYLOAD)"
|
||||
if [ "$REMOTE_BYTES" != "$BYTES" ]; then
|
||||
echo "ERREUR: taille fichier VM (${REMOTE_BYTES}) != local (${BYTES})" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. Lancer le gardien clipboard : boucle qui re-pousse le payload toutes les 0.5s.
|
||||
# Kill de l'ancien via /tmp/clipboard_guard.pid (PID file, PAS pkill -f
|
||||
# qui se tuerait lui-même car le pattern apparaît dans notre cmdline SSH).
|
||||
SSHPASS="$SSH_PASS" sshpass -e ssh -o StrictHostKeyChecking=no "$VM_HOST" \
|
||||
"export WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000
|
||||
# Kill ancien gardien si PID file existe et pointe vers un processus vivant
|
||||
if [ -f $VM_PIDFILE ]; then
|
||||
OLD_PID=\$(cat $VM_PIDFILE)
|
||||
if [ -n \"\$OLD_PID\" ] && kill -0 \"\$OLD_PID\" 2>/dev/null; then
|
||||
kill \"\$OLD_PID\" 2>/dev/null
|
||||
sleep 0.3
|
||||
fi
|
||||
fi
|
||||
# Lancer la boucle gardien : écrit sur LES DEUX clipboards.
|
||||
# - wl-copy : clipboard Wayland (apps natives Wayland)
|
||||
# - xsel : clipboard X11/XWayland (DBeaver/Java/GTK qui passe par XWayland)
|
||||
# Sans le double-write, DBeaver lit un clipboard X11 vide même si Wayland plein.
|
||||
# XAUTHORITY = cookie temporaire de mutter/XWayland (régénéré à chaque session)
|
||||
XAUTH=\$(ls /run/user/1000/.mutter-Xwaylandauth.* 2>/dev/null | head -1)
|
||||
if [ -z \"\$XAUTH\" ]; then
|
||||
echo 'WARN: mutter-Xwaylandauth introuvable, X11 paste ne marchera pas' >&2
|
||||
XAUTH=/home/dom/.Xauthority
|
||||
fi
|
||||
nohup setsid bash -c \"export DISPLAY=:0 XAUTHORITY=\$XAUTH; while true; do wl-copy < $VM_PAYLOAD; xsel --clipboard --input < $VM_PAYLOAD 2>/dev/null; sleep 0.5; done\" >/dev/null 2>&1 </dev/null &
|
||||
GUARD_PID=\$!
|
||||
echo \"\$GUARD_PID\" > $VM_PIDFILE
|
||||
sleep 0.7
|
||||
# Vérifier que le gardien tourne et que le clipboard est rempli
|
||||
if ! kill -0 \"\$GUARD_PID\" 2>/dev/null; then
|
||||
echo 'ERREUR: gardien mort juste après lancement' >&2
|
||||
exit 1
|
||||
fi
|
||||
CHECK=\$(wl-paste | wc -c)
|
||||
echo \"[3/3] gardien actif PID=\$GUARD_PID, clipboard=\$CHECK bytes\"
|
||||
# Tolérance ±1 byte (wl-paste ajoute parfois un newline final)
|
||||
DELTA=\$(( \$CHECK - $BYTES ))
|
||||
if [ \$DELTA -lt -1 ] || [ \$DELTA -gt 1 ]; then
|
||||
echo \"ERREUR: clipboard (\$CHECK) != payload ($BYTES) delta=\$DELTA\" >&2
|
||||
exit 1
|
||||
fi"
|
||||
|
||||
echo ""
|
||||
echo "OK clipboard VM verrouillé en boucle. Tu peux lancer le replay linux_db."
|
||||
echo "(le step ord 8 fera Ctrl+V, l'INSERT sera collé instantanément dans DBeaver)"
|
||||
echo ""
|
||||
echo "APRÈS LA DÉMO, tuer le gardien :"
|
||||
echo " SSHPASS=$SSH_PASS sshpass -e ssh ${VM_HOST} \"kill \\\$(cat $VM_PIDFILE)\""
|
||||
Reference in New Issue
Block a user