petter2025 commited on
Commit
0198df0
·
verified ·
1 Parent(s): 6d6eff6

Delete voice_narrator.py

Browse files
Files changed (1) hide show
  1. voice_narrator.py +0 -183
voice_narrator.py DELETED
@@ -1,183 +0,0 @@
1
- """
2
- Voice Narration for Incident Alerts
3
- Supports multiple TTS providers with graceful fallback
4
- """
5
-
6
- import os
7
- import requests
8
- import logging
9
- from typing import Optional, Dict, Any
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
-
14
- class VoiceNarrator:
15
- """
16
- Narrate critical incidents using TTS API
17
-
18
- Supports:
19
- - Hathora Voice API (REST)
20
- - Generic TTS APIs
21
- - Graceful fallback (silent fail)
22
- """
23
-
24
- def __init__(self):
25
- # Check for API key (set in HF Secrets)
26
- self.api_key = os.environ.get("HATHORA_VOICE_API_KEY", "") or \
27
- os.environ.get("VOICE_API_KEY", "")
28
-
29
- # API endpoint (update with actual Hathora endpoint)
30
- self.api_endpoint = os.environ.get(
31
- "VOICE_API_ENDPOINT",
32
- "https://api.hathora.dev/v1/tts" # PLACEHOLDER
33
- )
34
-
35
- self.enabled = bool(self.api_key)
36
-
37
- if self.enabled:
38
- logger.info("✅ Voice narrator initialized with API key")
39
- else:
40
- logger.warning("⚠️ Voice narrator disabled (no API key found)")
41
-
42
- def narrate_incident(
43
- self,
44
- component: str,
45
- severity: str,
46
- latency: float,
47
- error_rate: float,
48
- root_cause: str = "Unknown",
49
- recovery_action: str = "Investigating"
50
- ) -> Optional[str]:
51
- """
52
- Generate voice narration for a critical incident
53
-
54
- Returns:
55
- Audio URL (str) if successful, None if failed
56
- """
57
-
58
- if not self.enabled:
59
- logger.debug("Voice narration skipped (disabled)")
60
- return None
61
-
62
- # Only narrate HIGH and CRITICAL incidents
63
- if severity not in ["HIGH", "CRITICAL"]:
64
- return None
65
-
66
- try:
67
- # Build dramatic narration text (30-60 seconds when spoken)
68
- narration_text = self._build_narration(
69
- component, severity, latency, error_rate, root_cause, recovery_action
70
- )
71
-
72
- # Call TTS API
73
- audio_url = self._call_tts_api(narration_text)
74
-
75
- if audio_url:
76
- logger.info(f"✅ Generated voice narration for {component}")
77
- return audio_url
78
- else:
79
- logger.warning("Voice API returned no audio URL")
80
- return None
81
-
82
- except Exception as e:
83
- # Silent fail - don't break the app
84
- logger.error(f"Voice narration failed: {e}", exc_info=True)
85
- return None
86
-
87
- def _build_narration(
88
- self,
89
- component: str,
90
- severity: str,
91
- latency: float,
92
- error_rate: float,
93
- root_cause: str,
94
- recovery_action: str
95
- ) -> str:
96
- """Build dramatic narration text"""
97
-
98
- # Format component name (remove dashes, capitalize)
99
- component_spoken = component.replace("-", " ").title()
100
-
101
- # Severity-specific intro
102
- if severity == "CRITICAL":
103
- intro = f"Critical alert. {component_spoken} is experiencing severe failure."
104
- else:
105
- intro = f"High priority alert. {component_spoken} degradation detected."
106
-
107
- # Metrics
108
- metrics = f"Latency: {int(latency)} milliseconds. Error rate: {error_rate*100:.0f} percent."
109
-
110
- # Root cause (if available)
111
- if root_cause and root_cause != "Unknown":
112
- cause = f"Root cause: {root_cause}."
113
- else:
114
- cause = "Root cause under investigation."
115
-
116
- # Recovery action
117
- action = f"Recovery action: {recovery_action}."
118
-
119
- # Combine into ~30-60 second narration
120
- full_text = f"{intro} {metrics} {cause} {action} Immediate attention required."
121
-
122
- logger.debug(f"Narration text: {full_text[:100]}...")
123
- return full_text
124
-
125
- def _call_tts_api(self, text: str) -> Optional[str]:
126
- """
127
- Call TTS API to generate audio
128
-
129
- GENERIC implementation - adapt to actual Hathora Voice API format
130
- """
131
-
132
- try:
133
- # Make REST API call
134
- response = requests.post(
135
- self.api_endpoint,
136
- headers={
137
- "Authorization": f"Bearer {self.api_key}",
138
- "Content-Type": "application/json"
139
- },
140
- json={
141
- "text": text,
142
- "voice": "en-US-neural",
143
- "speed": 1.0,
144
- "format": "mp3"
145
- },
146
- timeout=10.0
147
- )
148
-
149
- if response.status_code == 200:
150
- data = response.json()
151
-
152
- # Extract audio URL
153
- audio_url = data.get("audio_url") or \
154
- data.get("url") or \
155
- data.get("audioUrl")
156
-
157
- return audio_url
158
- else:
159
- logger.error(f"TTS API error: {response.status_code} - {response.text[:200]}")
160
- return None
161
-
162
- except requests.exceptions.Timeout:
163
- logger.warning("TTS API timeout")
164
- return None
165
- except Exception as e:
166
- logger.error(f"TTS API call failed: {e}")
167
- return None
168
-
169
-
170
- # Singleton instance
171
- _narrator = None
172
-
173
- def get_narrator() -> VoiceNarrator:
174
- """Get global narrator instance"""
175
- global _narrator
176
- if _narrator is None:
177
- _narrator = VoiceNarrator()
178
- return _narrator
179
-
180
-
181
- # Backward compatibility aliases
182
- VoiceHandler = VoiceNarrator
183
- get_voice_handler = get_narrator