Initial commit
This commit is contained in:
347
geniusia2/gui/orchestrator_integration.py
Normal file
347
geniusia2/gui/orchestrator_integration.py
Normal file
@@ -0,0 +1,347 @@
|
||||
"""
|
||||
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_())
|
||||
Reference in New Issue
Block a user