Files
Geniusia_v2/geniusia2/gui/orchestrator_integration.py
2026-03-05 00:20:25 +01:00

348 lines
11 KiB
Python

"""
Intégration Orchestrator ↔ GUI
Module pour connecter l'Orchestrator à l'interface graphique
"""
import logging
from typing import Optional
from .human_logger import HumanLogger
from .signals import GUISignals
from .improved_gui import ImprovedGUI
class OrchestratorGUIBridge:
"""
Pont entre l'Orchestrator et la GUI.
Facilite la communication bidirectionnelle:
- Orchestrator → GUI : Logs, stats, changements de mode
- GUI → Orchestrator : Commandes (start, stop, pause)
Attributes:
orchestrator: Instance de l'Orchestrator
gui: Instance de l'ImprovedGUI
human_logger: Instance du HumanLogger
signals: Signaux Qt pour communication
"""
def __init__(self, orchestrator, gui: Optional[ImprovedGUI] = None):
"""
Initialise le pont Orchestrator-GUI.
Args:
orchestrator: Instance de l'Orchestrator
gui: Instance de l'ImprovedGUI (optionnel, sera créée si None)
"""
self.logger = logging.getLogger(__name__)
self.orchestrator = orchestrator
# Créer ou utiliser la GUI fournie
if gui is None:
self.gui = ImprovedGUI(orchestrator)
else:
self.gui = gui
# Créer le HumanLogger
self.human_logger = HumanLogger()
# Utiliser les signaux de la GUI
self.signals = self.gui.signals
# Connecter les signaux
self._connect_gui_to_orchestrator()
self._inject_logging_into_orchestrator()
self.logger.info("OrchestratorGUIBridge initialisé")
def _connect_gui_to_orchestrator(self):
"""Connecte les signaux de la GUI à l'Orchestrator."""
# Boutons de contrôle
self.gui.start_requested.connect(self._on_start_requested)
self.gui.stop_requested.connect(self._on_stop_requested)
self.gui.pause_requested.connect(self._on_pause_requested)
self.logger.info("Signaux GUI → Orchestrator connectés")
def _inject_logging_into_orchestrator(self):
"""Injecte le système de logging dans l'Orchestrator."""
# Ajouter les attributs nécessaires à l'Orchestrator
self.orchestrator.human_logger = self.human_logger
self.orchestrator.gui_signals = self.signals
# Ajouter des méthodes helper à l'Orchestrator
self.orchestrator.log_to_gui = self.log_to_gui
self.orchestrator.update_gui_stats = self.update_gui_stats
self.orchestrator.change_mode_gui = self.change_mode_gui
self.logger.info("Logging injecté dans l'Orchestrator")
def _on_start_requested(self):
"""Gestionnaire de demande de démarrage."""
self.logger.info("Démarrage demandé depuis la GUI")
if hasattr(self.orchestrator, 'start'):
try:
self.orchestrator.start()
self.signals.emit_status_change(True)
self.log_to_gui("👀", "Système démarré en mode Observation", "success")
except Exception as e:
self.logger.error(f"Erreur au démarrage: {e}")
self.log_to_gui("", f"Erreur au démarrage: {str(e)}", "error")
def _on_stop_requested(self):
"""Gestionnaire de demande d'arrêt."""
self.logger.info("Arrêt demandé depuis la GUI")
if hasattr(self.orchestrator, 'stop'):
try:
self.orchestrator.stop()
self.signals.emit_status_change(False)
self.log_to_gui("", "Système arrêté", "info")
except Exception as e:
self.logger.error(f"Erreur à l'arrêt: {e}")
self.log_to_gui("", f"Erreur à l'arrêt: {str(e)}", "error")
def _on_pause_requested(self):
"""Gestionnaire de demande de pause."""
self.logger.info("Pause demandée depuis la GUI")
if hasattr(self.orchestrator, 'pause'):
try:
self.orchestrator.pause()
is_paused = getattr(self.orchestrator, 'is_paused', False)
if is_paused:
self.log_to_gui("", "Système en pause", "warning")
else:
self.log_to_gui("", "Système repris", "success")
except Exception as e:
self.logger.error(f"Erreur à la pause: {e}")
self.log_to_gui("", f"Erreur à la pause: {str(e)}", "error")
def log_to_gui(self, emoji: str, message: str, level: str = "info"):
"""
Envoie un log à la GUI.
Args:
emoji: Emoji à afficher
message: Message de log
level: Niveau du log ('info', 'success', 'warning', 'error')
Examples:
>>> bridge.log_to_gui("👀", "Action observée", "info")
"""
self.signals.emit_log(emoji, message, level)
def update_gui_stats(self, **stats):
"""
Met à jour les statistiques de la GUI.
Args:
**stats: Statistiques à mettre à jour
(actions_count, patterns_count, workflows_count, etc.)
Examples:
>>> bridge.update_gui_stats(
... actions_count=12,
... patterns_count=2,
... workflows_count=1
... )
"""
self.signals.emit_stats_update(stats)
def change_mode_gui(self, mode: str):
"""
Change le mode affiché dans la GUI.
Args:
mode: Nouveau mode ('shadow', 'assist', 'copilot', 'auto')
Examples:
>>> bridge.change_mode_gui("assist")
"""
self.signals.emit_mode_change(mode)
def show(self):
"""Affiche la GUI."""
self.gui.show()
def hide(self):
"""Masque la GUI."""
self.gui.hide()
# Fonctions helper pour faciliter l'intégration
def setup_gui_for_orchestrator(orchestrator) -> OrchestratorGUIBridge:
"""
Configure la GUI pour un Orchestrator.
Fonction helper qui crée et configure automatiquement
le pont entre l'Orchestrator et la GUI.
Args:
orchestrator: Instance de l'Orchestrator
Returns:
Instance du OrchestratorGUIBridge configuré
Examples:
>>> from geniusia2.core import Orchestrator
>>> from geniusia2.gui import setup_gui_for_orchestrator
>>>
>>> orchestrator = Orchestrator()
>>> bridge = setup_gui_for_orchestrator(orchestrator)
>>> bridge.show()
>>>
>>> # Dans l'Orchestrator, utiliser:
>>> orchestrator.log_to_gui("👀", "Message", "info")
>>> orchestrator.update_gui_stats(actions_count=12)
"""
bridge = OrchestratorGUIBridge(orchestrator)
return bridge
def add_gui_logging_to_orchestrator(orchestrator, signals: GUISignals):
"""
Ajoute le logging GUI à un Orchestrator existant.
Fonction helper pour ajouter uniquement le logging
sans créer de nouvelle GUI.
Args:
orchestrator: Instance de l'Orchestrator
signals: Signaux GUI à utiliser
Examples:
>>> orchestrator = Orchestrator()
>>> gui = ImprovedGUI(orchestrator)
>>> add_gui_logging_to_orchestrator(orchestrator, gui.signals)
>>>
>>> # Maintenant l'orchestrator peut logger:
>>> orchestrator.log_to_gui("👀", "Message", "info")
"""
human_logger = HumanLogger()
orchestrator.human_logger = human_logger
orchestrator.gui_signals = signals
# Méthodes helper
def log_to_gui(emoji: str, message: str, level: str = "info"):
signals.emit_log(emoji, message, level)
def update_gui_stats(**stats):
signals.emit_stats_update(stats)
def change_mode_gui(mode: str):
signals.emit_mode_change(mode)
orchestrator.log_to_gui = log_to_gui
orchestrator.update_gui_stats = update_gui_stats
orchestrator.change_mode_gui = change_mode_gui
if __name__ == "__main__":
"""Test de l'intégration Orchestrator-GUI"""
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QTimer
# Mock Orchestrator pour les tests
class MockOrchestrator:
def __init__(self):
self.is_running = False
self.is_paused = False
self.actions_count = 0
self.patterns_count = 0
self.workflows_count = 0
def start(self):
print("MockOrchestrator: start()")
self.is_running = True
def stop(self):
print("MockOrchestrator: stop()")
self.is_running = False
def pause(self):
print("MockOrchestrator: pause()")
self.is_paused = not self.is_paused
def simulate_action(self):
"""Simule une action observée"""
self.actions_count += 1
self.log_to_gui("👀", f"Action #{self.actions_count} observée", "info")
self.update_gui_stats(
actions_count=self.actions_count,
patterns_count=self.patterns_count,
workflows_count=self.workflows_count
)
app = QApplication(sys.argv)
print("=" * 60)
print("Test de l'intégration Orchestrator-GUI")
print("=" * 60)
# Créer un mock orchestrator
orchestrator = MockOrchestrator()
# Configurer la GUI
bridge = setup_gui_for_orchestrator(orchestrator)
bridge.show()
print("\n✓ GUI créée et affichée")
print("✓ Orchestrator connecté")
# Simuler des événements
def simulate_workflow():
print("\n📝 Simulation d'événements...")
# Démarrer
QTimer.singleShot(1000, lambda: [
print(" 1. Démarrage"),
orchestrator.start(),
bridge.signals.emit_status_change(True),
bridge.log_to_gui("", "Système démarré", "success")
])
# Actions
QTimer.singleShot(2000, lambda: [
print(" 2. Action 1"),
orchestrator.simulate_action()
])
QTimer.singleShot(3000, lambda: [
print(" 3. Action 2"),
orchestrator.simulate_action()
])
QTimer.singleShot(4000, lambda: [
print(" 4. Action 3"),
orchestrator.simulate_action()
])
# Pattern détecté
QTimer.singleShot(5000, lambda: [
print(" 5. Pattern détecté"),
setattr(orchestrator, 'patterns_count', 1),
bridge.log_to_gui("🎯", "Pattern détecté !", "success"),
bridge.update_gui_stats(
actions_count=orchestrator.actions_count,
patterns_count=1,
workflows_count=0
)
])
# Changement de mode
QTimer.singleShot(6000, lambda: [
print(" 6. Changement de mode"),
bridge.change_mode_gui("assist"),
bridge.log_to_gui("", "Mode Suggestions activé", "success")
])
QTimer.singleShot(500, simulate_workflow)
print("\nTestez les boutons de la GUI:")
print(" - Pause")
print(" - Arrêter")
print(" - System tray")
sys.exit(app.exec_())