# -*- coding: utf-8 -*- """ Conversation Extension Points. Extension Points für STT, TTS, NLP und Intent-Handler. """ from abc import abstractmethod from typing import Any, TYPE_CHECKING from trixy_core.plugins.extensions.extension import Extension from trixy_core.plugins.extensions.extension_point import ExtensionPoint, get_global_registry # Extension Point IDs INTENT_HANDLER_POINT = "conversation.intent_handler" STT_POINT = "conversation.stt" TTS_POINT = "conversation.tts" NLP_POINT = "conversation.nlp" class IntentHandlerExtension(Extension): """ Extension für Intent-Handler. Ermöglicht Plugins, neue Intents zu verarbeiten: - Smart-Home-Steuerung - Kalender-Integration - E-Mail-Verarbeitung - Benutzerdefinierte Befehle Beispiel: class SmartHomeIntentExtension(IntentHandlerExtension): def __init__(self, plugin_name: str): super().__init__( "smarthome_intents", "Smart-Home Steuerung", plugin_name, intents=["turn_on_light", "turn_off_light", "set_temperature"], ) async def create_instance(self, config): return SmartHomeIntentHandler(config) """ def __init__( self, extension_id: str, name: str, plugin_name: str = "", intents: list[str] | None = None, priority: int = 0, description: str = "", ) -> None: """ Initialisiert die IntentHandler Extension. Args: extension_id: Eindeutige ID name: Anzeigename plugin_name: Plugin-Name intents: Liste der verarbeiteten Intents priority: Priorität (höher = wird zuerst gefragt) description: Beschreibung """ super().__init__(extension_id, name, plugin_name) self._info.description = description self._info.extension_point = INTENT_HANDLER_POINT self._info.priority = priority self._info.metadata["intents"] = intents or [] @property def intents(self) -> list[str]: """Verarbeitete Intents.""" return self._info.metadata.get("intents", []) def handles_intent(self, intent: str) -> bool: """Prüft ob dieser Handler einen Intent verarbeitet.""" return intent in self.intents or "*" in self.intents @abstractmethod async def create_instance(self, config: dict[str, Any]): """Erstellt die IntentHandler-Instanz.""" pass class STTExtension(Extension): """ Extension für Speech-to-Text. Ermöglicht Plugins, neue STT-Engines hinzuzufügen: - Google Speech-to-Text - Amazon Transcribe - Azure Speech - Whisper (lokal) - Vosk (offline) Beispiel: class WhisperSTTExtension(STTExtension): def __init__(self, plugin_name: str): super().__init__( "whisper_stt", "OpenAI Whisper", plugin_name, engine="whisper", languages=["de", "en", "fr", "es"], offline=True, ) async def create_instance(self, config): return WhisperSTT(model=config.get("model", "base")) """ def __init__( self, extension_id: str, name: str, plugin_name: str = "", engine: str = "", languages: list[str] | None = None, offline: bool = False, description: str = "", ) -> None: """ Initialisiert die STT Extension. Args: extension_id: Eindeutige ID name: Anzeigename plugin_name: Plugin-Name engine: Engine-Name languages: Unterstützte Sprachen offline: Funktioniert offline description: Beschreibung """ super().__init__(extension_id, name, plugin_name) self._info.description = description self._info.extension_point = STT_POINT self._info.metadata["engine"] = engine self._info.metadata["languages"] = languages or ["en"] self._info.metadata["offline"] = offline @property def engine(self) -> str: """Engine-Name.""" return self._info.metadata.get("engine", "") @property def languages(self) -> list[str]: """Unterstützte Sprachen.""" return self._info.metadata.get("languages", []) @property def is_offline(self) -> bool: """Funktioniert offline.""" return self._info.metadata.get("offline", False) @abstractmethod async def create_instance(self, config: dict[str, Any]): """Erstellt die STT-Engine-Instanz.""" pass class TTSExtension(Extension): """ Extension für Text-to-Speech. Ermöglicht Plugins, neue TTS-Engines hinzuzufügen: - Google TTS - Amazon Polly - Azure Speech - Coqui TTS (lokal) - eSpeak (offline) Beispiel: class CoquiTTSExtension(TTSExtension): def __init__(self, plugin_name: str): super().__init__( "coqui_tts", "Coqui TTS", plugin_name, engine="coqui", voices=["thorsten", "karlsson"], offline=True, ) async def create_instance(self, config): return CoquiTTS(voice=config.get("voice", "thorsten")) """ def __init__( self, extension_id: str, name: str, plugin_name: str = "", engine: str = "", voices: list[str] | None = None, languages: list[str] | None = None, offline: bool = False, description: str = "", ) -> None: """ Initialisiert die TTS Extension. Args: extension_id: Eindeutige ID name: Anzeigename plugin_name: Plugin-Name engine: Engine-Name voices: Verfügbare Stimmen languages: Unterstützte Sprachen offline: Funktioniert offline description: Beschreibung """ super().__init__(extension_id, name, plugin_name) self._info.description = description self._info.extension_point = TTS_POINT self._info.metadata["engine"] = engine self._info.metadata["voices"] = voices or [] self._info.metadata["languages"] = languages or ["en"] self._info.metadata["offline"] = offline @property def engine(self) -> str: """Engine-Name.""" return self._info.metadata.get("engine", "") @property def voices(self) -> list[str]: """Verfügbare Stimmen.""" return self._info.metadata.get("voices", []) @property def languages(self) -> list[str]: """Unterstützte Sprachen.""" return self._info.metadata.get("languages", []) @property def is_offline(self) -> bool: """Funktioniert offline.""" return self._info.metadata.get("offline", False) @abstractmethod async def create_instance(self, config: dict[str, Any]): """Erstellt die TTS-Engine-Instanz.""" pass class NLPExtension(Extension): """ Extension für Natural Language Processing. Ermöglicht Plugins, neue NLP-Engines hinzuzufügen: - OpenAI GPT - Anthropic Claude - Llama (lokal) - Rasa NLU - spaCy Beispiel: class ClaudeNLPExtension(NLPExtension): def __init__(self, plugin_name: str): super().__init__( "claude_nlp", "Anthropic Claude", plugin_name, engine="claude", capabilities=["intent", "entity", "conversation"], ) async def create_instance(self, config): return ClaudeNLP(api_key=config["api_key"]) """ def __init__( self, extension_id: str, name: str, plugin_name: str = "", engine: str = "", capabilities: list[str] | None = None, offline: bool = False, description: str = "", ) -> None: """ Initialisiert die NLP Extension. Args: extension_id: Eindeutige ID name: Anzeigename plugin_name: Plugin-Name engine: Engine-Name capabilities: NLP-Fähigkeiten (intent, entity, sentiment, etc.) offline: Funktioniert offline description: Beschreibung """ super().__init__(extension_id, name, plugin_name) self._info.description = description self._info.extension_point = NLP_POINT self._info.metadata["engine"] = engine self._info.metadata["capabilities"] = capabilities or [] self._info.metadata["offline"] = offline @property def engine(self) -> str: """Engine-Name.""" return self._info.metadata.get("engine", "") @property def capabilities(self) -> list[str]: """NLP-Fähigkeiten.""" return self._info.metadata.get("capabilities", []) @property def is_offline(self) -> bool: """Funktioniert offline.""" return self._info.metadata.get("offline", False) @abstractmethod async def create_instance(self, config: dict[str, Any]): """Erstellt die NLP-Engine-Instanz.""" pass def setup_conversation_extension_points() -> dict[str, ExtensionPoint]: """ Richtet alle Conversation Extension Points ein. Returns: Dict mit allen erstellten Extension Points """ registry = get_global_registry() points = {} # Intent-Handler points[INTENT_HANDLER_POINT] = registry.create_point( id=INTENT_HANDLER_POINT, name="Intent-Handler", description="Erweiterung um neue Intent-Verarbeitung", category="conversation", allows_multiple=True, ) # Speech-to-Text points[STT_POINT] = registry.create_point( id=STT_POINT, name="Speech-to-Text Engines", description="Erweiterung um neue STT-Engines (Whisper, Google, etc.)", category="conversation", allows_multiple=True, ) # Text-to-Speech points[TTS_POINT] = registry.create_point( id=TTS_POINT, name="Text-to-Speech Engines", description="Erweiterung um neue TTS-Engines (Coqui, Polly, etc.)", category="conversation", allows_multiple=True, ) # NLP points[NLP_POINT] = registry.create_point( id=NLP_POINT, name="NLP Engines", description="Erweiterung um neue NLP-Engines (GPT, Claude, Llama, etc.)", category="conversation", allows_multiple=True, ) return points