| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- # -*- coding: utf-8 -*-
- """
- Wakeword-bezogene Netzwerk-Befehle.
- """
- from dataclasses import dataclass, field
- from datetime import datetime
- from trixy_core.network.cmd.base import CommandMessage
- @dataclass
- class WakewordDetected(CommandMessage):
- """
- Wakeword-Erkennung durch einen Satellite.
- Wird vom Satellite zum Server gesendet, wenn ein Wakeword erkannt wurde.
- Der Server führt dann die Arbitrierung durch (höchstes Audio-Level gewinnt).
- Enthält auch die Audio-Chunks mit dem Wakeword für Stimmenerkennung.
- """
- satellite_id: str = ""
- wakeword_type: str = "" # "custom" oder "system_command"
- wakeword_model: str = "" # Modell-Name (z.B. "hey_jarvis")
- confidence: float = 0.0 # Erkennungs-Confidence
- audio_level: float = 0.0 # RMS-Level für Arbitration
- audio_chunks: list[str] = field(default_factory=list) # Hex-encodierte Chunks
- timestamp: str = "" # ISO-Format Timestamp
- client_session_id: str = "" # Vom Client generierte Session-ID
- @dataclass
- class WakewordSelected(CommandMessage):
- """
- Satellite wurde für die Konversation ausgewählt.
- Wird vom Server zum ausgewählten Satellite gesendet.
- Enthält die Server-generierte Session-ID.
- """
- session_id: str = "" # Server-generierte Session-ID
- conversation_id: str = "" # Konversations-ID (= session_id)
- start_streaming: bool = True # Audio-Streaming starten
- max_duration_seconds: float = 60.0 # Max. Aufnahmedauer
- silence_timeout_seconds: float = 3.0 # Stille-Timeout
- @dataclass
- class WakewordAbort(CommandMessage):
- """
- Wakeword-Erkennung abbrechen.
- Wird gesendet, wenn ein anderer Satellite ausgewählt wurde
- oder die Erkennung abgebrochen werden soll.
- """
- reason: str = ""
- resume_detection: bool = True
- selected_satellite_id: str = "" # Welcher Satellite wurde stattdessen ausgewählt
- @dataclass
- class RecordingComplete(CommandMessage):
- """
- Audio-Aufnahme abgeschlossen.
- Wird vom Satellite zum Server gesendet, wenn die Aufnahme
- beendet wurde (durch Stille oder Timeout).
- """
- session_id: str = ""
- audio_data: str = "" # Hex-encodierte Audio-Daten
- duration_seconds: float = 0.0
- ended_by: str = "" # "silence", "timeout", "user", "error"
- speech_detected: bool = True # Wurde Sprache erkannt?
- peak_level: float = 0.0 # Peak Audio-Level
- vad_stats: dict = field(default_factory=dict) # VAD-Statistiken
- @dataclass
- class RecordingAck(CommandMessage):
- """
- Bestätigung für empfangene Aufnahme.
- Wird vom Server zum Satellite gesendet nach Empfang der Aufnahme.
- """
- session_id: str = ""
- received_bytes: int = 0
- processing: bool = True # Wird verarbeitet
- @dataclass
- class FollowUpRequest(CommandMessage):
- """
- Rückfrage vom Server an den Satellite.
- Der Assistent stellt eine Rückfrage und erwartet eine Antwort.
- """
- session_id: str = ""
- question: str = "" # Rückfrage-Text
- audio_data: str = "" # Hex-encodiertes TTS-Audio (optional)
- follow_up_number: int = 0 # Nummer der Rückfrage
- timeout_seconds: float = 60.0 # Timeout für Antwort
- audio_duration: float = 0.0 # TTS-Audio-Dauer in Sekunden (fuer Wait)
- @dataclass
- class FollowUpResponse(CommandMessage):
- """
- Antwort auf eine Rückfrage.
- Wird vom Satellite zum Server gesendet.
- """
- session_id: str = ""
- audio_data: str = "" # Hex-encodierte Audio-Antwort
- duration_seconds: float = 0.0
- follow_up_number: int = 0 # Welche Rückfrage wird beantwortet
- speech_detected: bool = True
- @dataclass
- class ConversationEnd(CommandMessage):
- """
- Konversation beenden.
- Kann vom Server oder Satellite gesendet werden.
- """
- session_id: str = ""
- reason: str = "" # "completed", "timeout", "cancelled", "error"
- final_response: str = "" # Letzte Antwort des Assistenten
- audio_data: str = "" # Hex-encodiertes TTS-Audio (optional)
- @dataclass
- class AssistantResponse(CommandMessage):
- """
- Assistenten-Antwort.
- Wird vom Server zum Satellite gesendet mit der Antwort.
- """
- session_id: str = ""
- text: str = "" # Antwort-Text
- audio_data: str = "" # Hex-encodiertes TTS-Audio
- is_final: bool = True # Ist dies die finale Antwort?
- has_follow_up: bool = False # Folgt eine Rückfrage?
- @dataclass
- class TranscriptionResult(CommandMessage):
- """
- Transkriptions-Ergebnis.
- Wird vom Server zum Satellite gesendet mit dem transkribierten Text.
- """
- session_id: str = ""
- text: str = "" # Transkribierter Text
- confidence: float = 0.0 # Transkriptions-Confidence
- language: str = "de" # Erkannte Sprache
- is_final: bool = True # Finale Transkription?
- @dataclass
- class IntentResult(CommandMessage):
- """
- Intent-Erkennungs-Ergebnis.
- Wird vom Server gesendet mit dem erkannten Intent.
- """
- session_id: str = ""
- intent: str = "" # Erkannter Intent
- confidence: float = 0.0
- entities: dict = field(default_factory=dict) # Extrahierte Entities
- handled_by: str = "" # Welches Plugin/Service handhabt den Intent
- @dataclass
- class TextInput(CommandMessage):
- """
- Text-Eingabe vom Client (Keyboard-Input).
- Wird als Alternative zu Spracheingabe verwendet.
- Startet eine neue Conversation oder setzt eine bestehende fort.
- Flow:
- 1. Client sendet TextInput an Server
- 2. Server erstellt/fortsetzt Conversation
- 3. Server emittiert speech_recognized Event
- 4. NLP verarbeitet Text
- 5. Bei Follow-Up: Server sendet FollowUpRequest zurück
- """
- satellite_id: str = ""
- text: str = "" # Eingegebener Text
- session_id: str = "" # Leer = neue Session, sonst Fortsetzung
- room_id: str = "" # Raum-ID
- language: str = "de" # Sprache
- is_follow_up: bool = False # Ist dies eine Antwort auf Follow-Up?
- follow_up_number: int = 0 # Welche Rückfrage wird beantwortet
- @dataclass
- class TextInputAck(CommandMessage):
- """
- Bestätigung für Text-Eingabe.
- Wird vom Server zum Client gesendet nach Empfang der Text-Eingabe.
- """
- session_id: str = "" # Zugewiesene Session-ID
- received: bool = True # Erfolgreich empfangen
- error: str = "" # Fehlermeldung falls nicht erfolgreich
- @dataclass
- class WakewordPause(CommandMessage):
- """Wakeword-Erkennung extern pausieren (Server → Satellite)."""
- reason: str = ""
- @dataclass
- class WakewordResume(CommandMessage):
- """Extern pausierte Wakeword-Erkennung fortsetzen (Server → Satellite)."""
- pass
- @dataclass
- class WakewordControlStop(CommandMessage):
- """Wakeword-Erkennung komplett stoppen (Server → Satellite)."""
- reason: str = ""
- @dataclass
- class WakewordControlStart(CommandMessage):
- """Wakeword-Erkennung starten (Server → Satellite)."""
- pass
|