- README.md : bandeau POC, date 14 avril 2026, retrait claims "production-ready 77%" (alignement code/doc post-audit) - docs/STATUS.md : état réel par module (opérationnel/alpha/en cours) - docs/DEV_SETUP.md : gestion worktrees Claude - QUICK_START.md : gemma4:latest au lieu de qwen3-vl:8b - deploy/build_package.sh : +9 fichiers dans REQUIRED_FILES (system_dialog_guard.py, persistent_buffer.py, grounding.py, etc.) - agent_v0/deploy_windows.py : marqué OBSOLÈTE (legacy) - .gitignore : ajout data/, .hypothesis, .deps_installed, buffer/, instance/*.db, caches SQLite Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
245 lines
8.5 KiB
Python
245 lines
8.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
deploy_windows.py — Script de packaging du client Windows pour Agent V1.
|
|
|
|
⚠️ OBSOLÈTE (avril 2026)
|
|
Le build officiel du package Windows passe par ``deploy/build_package.sh``
|
|
(à la racine du repo) qui lit directement ``agent_v0/agent_v1/`` et évite
|
|
les clones intermédiaires. Ce script est conservé pour référence mais son
|
|
manifeste ``FILE_MANIFEST`` est incomplet : il n'inclut pas
|
|
``system_dialog_guard.py``, ``persistent_buffer.py``, ``recovery.py``,
|
|
``uia_helper.py``, ``grounding.py``, ``policy.py``,
|
|
``vision/blur_sensitive.py``, ``vision/system_info.py``,
|
|
``ui/chat_window.py``, ``ui/capture_server.py``, ``ui/shared_state.py``.
|
|
Ne PAS l'utiliser pour un packaging réel.
|
|
|
|
Copie uniquement les fichiers nécessaires au fonctionnement de l'agent
|
|
sur le PC cible (Windows), sans le serveur ni les dépendances lourdes.
|
|
|
|
Usage :
|
|
python deploy_windows.py # Crée le dossier deploy/windows_client/
|
|
python deploy_windows.py --zip # Idem + archive .zip
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import shutil
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
# Répertoire racine de agent_v0 (là où vit ce script)
|
|
AGENT_V0_DIR = Path(__file__).resolve().parent
|
|
|
|
# Répertoire de sortie
|
|
DEPLOY_DIR = AGENT_V0_DIR / "deploy" / "windows_client"
|
|
|
|
# ─────────────────────────────────────────────────────────
|
|
# Manifeste des fichiers à déployer
|
|
# Chaque entrée : (source relative à agent_v0, destination relative à windows_client)
|
|
# ─────────────────────────────────────────────────────────
|
|
FILE_MANIFEST: list[tuple[str, str]] = [
|
|
# === agent_v1 — package principal ===
|
|
("agent_v1/__init__.py", "agent_v1/__init__.py"),
|
|
("agent_v1/config.py", "agent_v1/config.py"),
|
|
("agent_v1/main.py", "agent_v1/main.py"),
|
|
("agent_v1/window_info.py", "agent_v1/window_info.py"),
|
|
("agent_v1/window_info_crossplatform.py", "agent_v1/window_info_crossplatform.py"),
|
|
|
|
# agent_v1/core
|
|
("agent_v1/core/__init__.py", "agent_v1/core/__init__.py"),
|
|
("agent_v1/core/captor.py", "agent_v1/core/captor.py"),
|
|
("agent_v1/core/executor.py", "agent_v1/core/executor.py"),
|
|
|
|
# agent_v1/network
|
|
("agent_v1/network/__init__.py", "agent_v1/network/__init__.py"),
|
|
("agent_v1/network/streamer.py", "agent_v1/network/streamer.py"),
|
|
|
|
# agent_v1/session
|
|
("agent_v1/session/__init__.py", "agent_v1/session/__init__.py"),
|
|
("agent_v1/session/storage.py", "agent_v1/session/storage.py"),
|
|
|
|
# agent_v1/ui — smart_tray (PAS tray.py, c'est l'ancien PyQt5)
|
|
("agent_v1/ui/__init__.py", "agent_v1/ui/__init__.py"),
|
|
("agent_v1/ui/notifications.py", "agent_v1/ui/notifications.py"),
|
|
("agent_v1/ui/smart_tray.py", "agent_v1/ui/smart_tray.py"),
|
|
|
|
# agent_v1/vision
|
|
("agent_v1/vision/__init__.py", "agent_v1/vision/__init__.py"),
|
|
("agent_v1/vision/capturer.py", "agent_v1/vision/capturer.py"),
|
|
|
|
# agent_v1/monitoring
|
|
("agent_v1/monitoring/__init__.py", "agent_v1/monitoring/__init__.py"),
|
|
|
|
# === lea_ui — communication chat/workflow (utilisée par smart_tray) ===
|
|
("lea_ui/__init__.py", "lea_ui/__init__.py"),
|
|
("lea_ui/server_client.py", "lea_ui/server_client.py"),
|
|
|
|
# === Racine agent_v0 — fichiers nécessaires à l'exécution ===
|
|
("__init__.py", "__init__.py"),
|
|
("config.py", "config.py"),
|
|
("agent_config.json", "agent_config.json"),
|
|
("run_agent_v1.py", "run_agent_v1.py"),
|
|
("setup_v1.bat", "setup.bat"),
|
|
("agent_v1/requirements.txt", "requirements.txt"),
|
|
]
|
|
|
|
# Contenu du fichier LISEZMOI.txt
|
|
LISEZMOI_CONTENT = """\
|
|
=== Agent V1 — RPA Vision — Client Windows ===
|
|
|
|
Installation :
|
|
1. Double-cliquer sur setup.bat
|
|
2. Configurer le serveur : éditer agent_config.json
|
|
ou définir la variable RPA_SERVER_HOST=192.168.1.x
|
|
3. Lancer : python run_agent_v1.py
|
|
|
|
L'agent apparaît dans la zone de notification (systray).
|
|
Clic droit pour accéder au menu : démarrer une session,
|
|
lancer un replay, voir les workflows appris, etc.
|
|
|
|
Léa communique par des notifications toast sur votre écran.
|
|
|
|
Prérequis :
|
|
- Python 3.10 ou plus récent
|
|
- Connexion réseau vers le serveur Linux
|
|
"""
|
|
|
|
|
|
def nettoyer_deploy_dir() -> None:
|
|
"""Supprime le répertoire de déploiement s'il existe déjà."""
|
|
if DEPLOY_DIR.exists():
|
|
print(f" Nettoyage de {DEPLOY_DIR} ...")
|
|
shutil.rmtree(DEPLOY_DIR)
|
|
|
|
|
|
def copier_fichiers() -> tuple[list[str], list[str]]:
|
|
"""
|
|
Copie tous les fichiers du manifeste vers le répertoire de déploiement.
|
|
|
|
Retourne :
|
|
(fichiers_copies, fichiers_manquants) — deux listes de chemins relatifs
|
|
"""
|
|
copies: list[str] = []
|
|
manquants: list[str] = []
|
|
|
|
for src_rel, dst_rel in FILE_MANIFEST:
|
|
src = AGENT_V0_DIR / src_rel
|
|
dst = DEPLOY_DIR / dst_rel
|
|
|
|
if not src.exists():
|
|
print(f" [ATTENTION] Fichier manquant, ignoré : {src_rel}")
|
|
manquants.append(src_rel)
|
|
continue
|
|
|
|
# Créer les répertoires parents si nécessaire
|
|
dst.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
shutil.copy2(src, dst)
|
|
copies.append(dst_rel)
|
|
|
|
return copies, manquants
|
|
|
|
|
|
def creer_lisezmoi() -> None:
|
|
"""Crée le fichier LISEZMOI.txt dans le répertoire de déploiement."""
|
|
lisezmoi_path = DEPLOY_DIR / "LISEZMOI.txt"
|
|
lisezmoi_path.write_text(LISEZMOI_CONTENT, encoding="utf-8")
|
|
print(f" LISEZMOI.txt créé")
|
|
|
|
|
|
def creer_archive_zip() -> Path:
|
|
"""
|
|
Crée une archive .zip du répertoire de déploiement.
|
|
|
|
Retourne le chemin de l'archive créée.
|
|
"""
|
|
horodatage = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
nom_archive = f"windows_client_{horodatage}"
|
|
chemin_archive = DEPLOY_DIR.parent / nom_archive
|
|
|
|
# shutil.make_archive ajoute automatiquement l'extension .zip
|
|
archive_path = shutil.make_archive(
|
|
str(chemin_archive),
|
|
"zip",
|
|
root_dir=str(DEPLOY_DIR.parent),
|
|
base_dir="windows_client",
|
|
)
|
|
return Path(archive_path)
|
|
|
|
|
|
def afficher_resume(copies: list[str], manquants: list[str], archive: Path | None) -> None:
|
|
"""Affiche un résumé des opérations effectuées."""
|
|
print()
|
|
print("=" * 55)
|
|
print(" Résumé du déploiement — Agent V1 Client Windows")
|
|
print("=" * 55)
|
|
print(f" Destination : {DEPLOY_DIR}")
|
|
print(f" Fichiers copiés : {len(copies)}")
|
|
|
|
if manquants:
|
|
print(f" Fichiers manquants : {len(manquants)}")
|
|
for f in manquants:
|
|
print(f" - {f}")
|
|
|
|
if archive:
|
|
taille_mo = archive.stat().st_size / (1024 * 1024)
|
|
print(f" Archive : {archive.name} ({taille_mo:.1f} Mo)")
|
|
|
|
print()
|
|
|
|
# Afficher l'arborescence simplifiée
|
|
print(" Arborescence :")
|
|
for f in sorted(copies):
|
|
print(f" {f}")
|
|
|
|
print()
|
|
print(" Terminé.")
|
|
print("=" * 55)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
description="Prépare le package de déploiement Windows pour Agent V1"
|
|
)
|
|
parser.add_argument(
|
|
"--zip",
|
|
action="store_true",
|
|
help="Créer aussi une archive .zip du package",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
print()
|
|
print("=== Déploiement Agent V1 — Client Windows ===")
|
|
print()
|
|
|
|
# Étape 1 : Nettoyage
|
|
nettoyer_deploy_dir()
|
|
|
|
# Étape 2 : Création du répertoire de déploiement
|
|
DEPLOY_DIR.mkdir(parents=True, exist_ok=True)
|
|
print(f" Répertoire créé : {DEPLOY_DIR}")
|
|
|
|
# Étape 3 : Copie des fichiers
|
|
print(" Copie des fichiers...")
|
|
copies, manquants = copier_fichiers()
|
|
|
|
# Étape 4 : Création du LISEZMOI.txt
|
|
creer_lisezmoi()
|
|
|
|
# Étape 5 : Archive .zip (optionnel)
|
|
archive = None
|
|
if args.zip:
|
|
print(" Création de l'archive .zip...")
|
|
archive = creer_archive_zip()
|
|
print(f" Archive créée : {archive}")
|
|
|
|
# Résumé
|
|
afficher_resume(copies, manquants, archive)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|