""" Plugin Manager - Discovers and loads all backend plugins. """ from pathlib import Path from typing import Dict, List, Optional, Any import importlib.util import yaml import sys class PluginManager: """Manages all backend plugins.""" def __init__(self, plugin_dirs: List[Path]): """Initialize plugin manager.""" self.plugin_dirs = plugin_dirs self.plugins: Dict[str, Any] = {} self.discover_plugins() def discover_plugins(self): """Automatically discover and load all plugins.""" for plugin_dir in self.plugin_dirs: registry_path = plugin_dir / 'plugin_registry.yaml' if not registry_path.exists(): continue with open(registry_path) as f: registry = yaml.safe_load(f) for plugin_config in registry.get('plugins', []): if plugin_config.get('enabled', True): try: self.load_plugin(plugin_dir, plugin_config) except Exception as e: print(f"Failed to load plugin {plugin_config['name']}: {e}") def load_plugin(self, plugin_dir: Path, config: Dict): """Load a single plugin.""" plugin_name = config['name'] plugin_module = config['module'] plugin_class = config['class'] # Import plugin module module_path = plugin_dir / f"{plugin_module}.py" if not module_path.exists(): print(f"Plugin module not found: {module_path}") return spec = importlib.util.spec_from_file_location(plugin_module, module_path) module = importlib.util.module_from_spec(spec) sys.modules[plugin_module] = module spec.loader.exec_module(module) # Get plugin class PluginClass = getattr(module, plugin_class) # Find config path config_path = plugin_dir.parent.parent / 'tools' / plugin_name / 'config.yaml' # Instantiate plugin plugin = PluginClass(config_path) self.plugins[plugin_name] = plugin print(f"Loaded plugin: {plugin_name} v{plugin.version}") def get_plugin(self, name: str) -> Optional[Any]: """Get plugin by name.""" return self.plugins.get(name) def list_plugins(self) -> List[str]: """List all available plugins.""" return list(self.plugins.keys()) def get_available_backends(self) -> Dict[str, bool]: """Get all backends with health status.""" return { name: plugin.health_check() for name, plugin in self.plugins.items() }