| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- # -*- coding: utf-8 -*-
- """
- Grundlegende Event-Datenklassen.
- Definiert häufig verwendete Events im Trixy-System.
- """
- from dataclasses import dataclass, field
- from typing import Any
- from trixy_core.events.event_data.base import EventData
- @dataclass
- class SatelliteConnected(EventData):
- """Event wenn ein Satellite sich verbindet."""
- satellite_id: str = ""
- room: str = ""
- alias: str = ""
- mac_address: str = ""
- ip_address: str = ""
- @dataclass
- class SatelliteDisconnected(EventData):
- """Event wenn ein Satellite die Verbindung trennt."""
- satellite_id: str = ""
- room: str = ""
- alias: str = ""
- reason: str = ""
- @dataclass
- class MusicSocketConnected(EventData):
- """Event wenn der Music-Socket eines Satellites verbunden ist."""
- satellite_id: str = ""
- alias: str = ""
- room: str = ""
- @dataclass
- class WakewordReceived(EventData):
- """Event wenn ein Wakeword erkannt wurde."""
- satellite_id: str = ""
- wakeword_model: str = ""
- confidence: float = 0.0
- audio_level: float = 0.0
- @dataclass
- class RawAudioInputReceived(EventData):
- """Event wenn rohe Audiodaten empfangen wurden."""
- satellite_id: str = ""
- audio_data: bytes = field(default=b"", repr=False)
- sample_rate: int = 16000
- duration_seconds: float = 0.0
- @dataclass
- class SpeechRecognized(EventData):
- """
- Event wenn Sprache erkannt wurde (STT-Ergebnis).
- Attributes:
- satellite_id: ID des Satellites
- room_id: Raum-ID des Satellites
- text: Erkannter Text
- confidence: Konfidenz der Erkennung (0.0-1.0)
- language: Sprache des Textes
- is_final: Ist dies das finale Ergebnis? (vs. Zwischen-Ergebnis)
- source: Quelle der Eingabe ("stt", "keyboard", etc.)
- alternatives: Alternative Erkennungen
- """
- satellite_id: str = ""
- room_id: str = ""
- text: str = ""
- confidence: float = 0.0
- language: str = "de"
- is_final: bool = True
- source: str = "stt" # "stt", "keyboard", "api"
- alternatives: list[str] = field(default_factory=list)
- @dataclass
- class IntentReceived(EventData):
- """
- Event wenn ein Intent erkannt wurde.
- Wird vom NLP-Provider emittiert nachdem Text verarbeitet wurde.
- Intent-Handler Plugins reagieren auf dieses Event.
- Flow:
- 1. NLP emittiert IntentReceived
- 2. Intent-Handler Plugin verarbeitet und emittiert IntentHandled
- 3. Falls keine Antwort: CreateOutputText wird emittiert
- 4. Response Generator erstellt Text und emittiert OutputTextCreated
- 5. TTS Plugin reagiert auf OutputTextCreated
- """
- satellite_id: str = ""
- intent: str = ""
- confidence: float = 0.0
- slots: dict[str, Any] = field(default_factory=dict)
- original_text: str = ""
- session_id: str = ""
- room_id: str = ""
- wakeword_type: str = "custom" # "custom" oder "system_command"
- is_authenticated: bool = False # Admin-Authentifizierung
- language: str = "de"
- metadata: dict[str, Any] = field(default_factory=dict)
- @dataclass
- class IntentHandled(EventData):
- """
- Event wenn ein Intent-Handler die Verarbeitung abgeschlossen hat.
- Wird vom Intent-Handler emittiert nach der Ausführung.
- Enthält das Ergebnis der Aktion.
- Attributes:
- satellite_id: ID des Satellites
- session_id: Konversations-Session-ID
- intent: Verarbeiteter Intent
- success: War die Verarbeitung erfolgreich?
- response_text: Optionaler Antworttext (falls Handler selbst antwortet)
- data: Ergebnisdaten der Aktion
- error: Fehlermeldung falls nicht erfolgreich
- needs_followup: Erwartet Rückfrage/Fortsetzung?
- suppress_response: Keine Antwort generieren?
- """
- satellite_id: str = ""
- session_id: str = ""
- room_id: str = ""
- intent: str = ""
- original_text: str = ""
- slots: dict[str, Any] = field(default_factory=dict)
- success: bool = True
- response_text: str = "" # Falls Handler eigene Antwort liefert
- data: dict[str, Any] = field(default_factory=dict) # Ergebnisdaten
- error: str = ""
- needs_followup: bool = False # Konversation fortsetzen?
- followup_prompt: str = "" # Rückfrage-Text
- suppress_response: bool = False # Keine Antwort generieren
- @dataclass
- class ConversationStarted(EventData):
- """Event wenn eine Konversation beginnt."""
- satellite_id: str = ""
- conversation_id: str = ""
- @dataclass
- class ConversationEnded(EventData):
- """Event wenn eine Konversation endet."""
- satellite_id: str = ""
- conversation_id: str = ""
- reason: str = "" # timeout, user_ended, error, completed
- @dataclass
- class PluginLoaded(EventData):
- """Event wenn ein Plugin geladen wurde."""
- plugin_name: str = ""
- plugin_version: str = ""
- @dataclass
- class PluginUnloaded(EventData):
- """Event wenn ein Plugin entladen wurde."""
- plugin_name: str = ""
- reason: str = ""
- @dataclass
- class SystemShutdown(EventData):
- """Event vor dem Herunterfahren des Systems."""
- reason: str = ""
- force: bool = False
- @dataclass
- class TTSRequest(EventData):
- """Event für TTS-Anfrage."""
- request_id: str = ""
- satellite_id: str = ""
- text: str = ""
- voice: str = "default"
- speed: float = 1.0
- volume: float = 1.0
- @dataclass
- class TTSCompleted(EventData):
- """Event wenn TTS abgeschlossen ist."""
- request_id: str = ""
- satellite_id: str = ""
- success: bool = True
- audio_duration: float = 0.0
- error: str = ""
- @dataclass
- class StreamStart(EventData):
- """Event zum Starten eines Audio-Streams."""
- satellite_id: str = ""
- source: str = ""
- volume: float = 1.0
- stream_type: str = "music" # "music", "audio", "tts"
- @dataclass
- class StreamStop(EventData):
- """Event zum Stoppen eines Audio-Streams."""
- satellite_id: str = ""
- stream_type: str = "all" # "music", "audio", "tts", "all"
- @dataclass
- class ProcessingResult(EventData):
- """Event mit Verarbeitungsergebnis (für Standalone-Modus)."""
- session_id: str = ""
- success: bool = True
- text: str = ""
- intent: str = ""
- response_text: str = ""
- error: str = ""
- @dataclass
- class CreateOutputText(EventData):
- """
- Event zur Generierung von Antworttext.
- Wird emittiert nach IntentHandled wenn:
- - Handler keine response_text geliefert hat
- - suppress_response nicht gesetzt ist
- Response-Generator Plugin reagiert und emittiert OutputTextCreated.
- Attributes:
- satellite_id: ID des Satellites
- session_id: Konversations-Session-ID
- room_id: Raum-ID
- intent: Erkannter Intent
- original_text: Ursprüngliche Benutzeranfrage
- slots: Extrahierte Slot-Werte
- handler_data: Ergebnisdaten des Intent-Handlers
- handler_success: War der Handler erfolgreich?
- handler_error: Fehlermeldung des Handlers
- language: Sprache für Antwort
- """
- satellite_id: str = ""
- session_id: str = ""
- room_id: str = ""
- intent: str = ""
- original_text: str = ""
- slots: dict[str, Any] = field(default_factory=dict)
- handler_data: dict[str, Any] = field(default_factory=dict)
- handler_success: bool = True
- handler_error: str = ""
- language: str = "de"
- @dataclass
- class OutputTextCreated(EventData):
- """
- Event wenn Antworttext generiert wurde.
- Wird vom Response-Generator emittiert.
- TTS Plugin reagiert darauf und spricht den Text.
- Conversation Service aktualisiert die Session.
- Attributes:
- satellite_id: ID des Satellites
- session_id: Konversations-Session-ID
- room_id: Raum-ID
- text: Generierter Antworttext
- intent: Ursprünglicher Intent
- is_followup: Ist dies eine Rückfrage?
- expects_response: Erwartet Benutzerantwort?
- """
- satellite_id: str = ""
- session_id: str = ""
- room_id: str = ""
- text: str = ""
- intent: str = ""
- is_followup: bool = False
- expects_response: bool = False
- @dataclass
- class FollowUpExpected(EventData):
- """
- Event wenn eine Rückfrage erwartet wird.
- Wird emittiert nachdem TTS abgeschlossen ist und der Benutzer
- antworten soll. Der Client soll ohne Wakeword-Erkennung
- direkt Audio streamen.
- Flow:
- 1. Handler setzt needs_followup=True
- 2. IntentDispatcher emittiert output_text_created mit expects_response=True
- 3. TTS spricht den Text
- 4. Nach TTS-Abschluss: followup_expected wird emittiert
- 5. Client wechselt in Follow-up-Modus (direktes STT ohne Wakeword)
- 6. Client streamt Audio bis Stille/Timeout
- 7. Server verarbeitet Audio → speech_recognized → NLP → ...
- Attributes:
- satellite_id: ID des Satellites
- session_id: Konversations-Session-ID
- room_id: Raum-ID
- timeout_seconds: Maximale Wartezeit auf Antwort
- followup_context: Kontext für die erwartete Antwort (Intent, Slots)
- """
- satellite_id: str = ""
- session_id: str = ""
- room_id: str = ""
- timeout_seconds: float = 30.0
- followup_context: dict[str, Any] = field(default_factory=dict)
- @dataclass
- class SatelliteRecordingStarted(EventData):
- """Event wenn server-gesteuerte Aufnahme gestartet wurde."""
- satellite_id: str = ""
- recording_id: str = ""
- timeout_seconds: float = 300.0
- @dataclass
- class SatelliteRecordingStopped(EventData):
- """Event wenn server-gesteuerte Aufnahme beendet wurde."""
- satellite_id: str = ""
- recording_id: str = ""
- reason: str = ""
- duration_seconds: float = 0.0
- audio_size_bytes: int = 0
- filename: str = ""
- @dataclass
- class SatelliteRecordingCleared(EventData):
- """Event wenn der Recording-Buffer geleert wurde."""
- satellite_id: str = ""
- recording_id: str = ""
- cleared_bytes: int = 0
- @dataclass
- class SatelliteStreamStarted(EventData):
- """Event wenn Live-Audio-Stream gestartet wurde."""
- satellite_id: str = ""
- target_satellite_id: str = ""
- stream_id: str = ""
- @dataclass
- class SatelliteStreamStopped(EventData):
- """Event wenn Live-Audio-Stream beendet wurde."""
- satellite_id: str = ""
- target_satellite_id: str = ""
- stream_id: str = ""
- reason: str = ""
- duration_seconds: float = 0.0
- bytes_forwarded: int = 0
- @dataclass
- class SatelliteStreamRecordStarted(EventData):
- """Event wenn Stream-Aufnahme in Datei gestartet wurde."""
- satellite_id: str = ""
- stream_id: str = ""
- filename: str = ""
- @dataclass
- class SatelliteStreamRecordStopped(EventData):
- """Event wenn Stream-Aufnahme beendet wurde."""
- satellite_id: str = ""
- stream_id: str = ""
- filename: str = ""
- reason: str = ""
- duration_seconds: float = 0.0
- file_size_bytes: int = 0
|