- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
164 lines
5.0 KiB
Python
164 lines
5.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Exemple d'utilisation du RPA Vision V3
|
|
|
|
Ce script montre comment :
|
|
1. Charger un workflow existant
|
|
2. Démarrer l'exécution en mode supervisé
|
|
3. Observer la progression
|
|
4. Arrêter proprement
|
|
|
|
Usage:
|
|
python examples/run_rpa.py --workflow <workflow_id> --mode supervised
|
|
"""
|
|
|
|
import argparse
|
|
import logging
|
|
import time
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Ajouter le répertoire racine au path
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from core.pipeline import WorkflowPipeline, create_pipeline
|
|
from core.execution import ExecutionLoop, ExecutionMode, ExecutionState, create_execution_loop
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def on_step_complete(result):
|
|
"""Callback appelé après chaque étape."""
|
|
status = "✓" if result.success else "✗"
|
|
logger.info(
|
|
f"{status} Step: node={result.node_id}, "
|
|
f"confidence={result.match_confidence:.2f}, "
|
|
f"duration={result.duration_ms:.0f}ms"
|
|
)
|
|
|
|
|
|
def on_state_change(new_state):
|
|
"""Callback appelé lors des changements d'état."""
|
|
logger.info(f"State changed to: {new_state.value}")
|
|
|
|
|
|
def on_error(error_type, exception):
|
|
"""Callback appelé en cas d'erreur."""
|
|
logger.error(f"Error [{error_type}]: {exception}")
|
|
|
|
|
|
def confirmation_callback(message, action_info):
|
|
"""Callback pour demander confirmation (mode supervisé)."""
|
|
print(f"\n{'='*60}")
|
|
print(f"ACTION REQUIRED: {message}")
|
|
print(f"Details: {action_info}")
|
|
print(f"{'='*60}")
|
|
|
|
response = input("Execute? [y/N]: ").strip().lower()
|
|
return response == 'y'
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="RPA Vision V3 Runner")
|
|
parser.add_argument("--workflow", "-w", required=True, help="Workflow ID to execute")
|
|
parser.add_argument(
|
|
"--mode", "-m",
|
|
choices=["observation", "coaching", "supervised", "automatic"],
|
|
default="supervised",
|
|
help="Execution mode"
|
|
)
|
|
parser.add_argument("--data-dir", "-d", default="data", help="Data directory")
|
|
parser.add_argument("--list", "-l", action="store_true", help="List available workflows")
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Créer le pipeline
|
|
logger.info("Initializing RPA Vision V3...")
|
|
pipeline = create_pipeline(
|
|
data_dir=args.data_dir,
|
|
use_gpu=False,
|
|
enable_ui_detection=True
|
|
)
|
|
|
|
# Lister les workflows si demandé
|
|
if args.list:
|
|
workflows = pipeline.list_workflows()
|
|
if not workflows:
|
|
print("No workflows found.")
|
|
else:
|
|
print("\nAvailable workflows:")
|
|
for wf in workflows:
|
|
print(f" - {wf['workflow_id']}: {wf['name']} ({wf['learning_state']})")
|
|
return
|
|
|
|
# Créer la boucle d'exécution
|
|
loop = create_execution_loop(pipeline, capture_interval_ms=500)
|
|
|
|
# Enregistrer les callbacks
|
|
loop.on_step_complete(on_step_complete)
|
|
loop.on_state_change(on_state_change)
|
|
loop.on_error(on_error)
|
|
|
|
# Déterminer le mode
|
|
mode_map = {
|
|
"observation": ExecutionMode.OBSERVATION,
|
|
"coaching": ExecutionMode.COACHING,
|
|
"supervised": ExecutionMode.SUPERVISED,
|
|
"automatic": ExecutionMode.AUTOMATIC
|
|
}
|
|
mode = mode_map[args.mode]
|
|
|
|
# Démarrer l'exécution
|
|
logger.info(f"Starting workflow '{args.workflow}' in {args.mode} mode...")
|
|
|
|
if mode == ExecutionMode.SUPERVISED:
|
|
# En mode supervisé, utiliser le callback de confirmation
|
|
loop.confirmation_callback = confirmation_callback
|
|
|
|
success = loop.start(args.workflow, mode=mode)
|
|
|
|
if not success:
|
|
logger.error("Failed to start execution")
|
|
return
|
|
|
|
# Boucle principale - afficher la progression
|
|
try:
|
|
while loop.get_state() in [ExecutionState.RUNNING, ExecutionState.PAUSED, ExecutionState.WAITING_CONFIRMATION]:
|
|
progress = loop.get_progress()
|
|
|
|
# Afficher la progression
|
|
print(
|
|
f"\rProgress: {progress['steps_executed']} steps, "
|
|
f"{progress['steps_succeeded']} succeeded, "
|
|
f"{progress['steps_failed']} failed, "
|
|
f"node: {progress['current_node'] or 'N/A'}",
|
|
end="", flush=True
|
|
)
|
|
|
|
time.sleep(1)
|
|
|
|
except KeyboardInterrupt:
|
|
logger.info("\nStopping execution...")
|
|
loop.stop()
|
|
|
|
finally:
|
|
# Afficher le résumé
|
|
print("\n")
|
|
final_progress = loop.get_progress()
|
|
logger.info(f"Execution finished: {final_progress['status']}")
|
|
logger.info(f" Steps executed: {final_progress['steps_executed']}")
|
|
logger.info(f" Steps succeeded: {final_progress['steps_succeeded']}")
|
|
logger.info(f" Steps failed: {final_progress['steps_failed']}")
|
|
logger.info(f" Duration: {final_progress['duration_seconds']:.1f}s")
|
|
|
|
# Nettoyer
|
|
loop.cleanup()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|