voice-rag commited on
Commit
13015af
·
1 Parent(s): 80cecae

corrected language detection

Browse files
python-services/llm_server.py CHANGED
@@ -20,7 +20,8 @@ from pydantic import BaseModel
20
  # Internal Domain Layer Imports
21
  from client import groq, fireworks
22
  from conversation_manager import ConversationManager, ConversationSession
23
- from language_config import normalize_language, SUPPORTED_LANGUAGES
 
24
  from prompt_builder import build_system_prompt
25
  from summary import generate_summary
26
  from caller_info_extractor import extract_name_from_text, extract_phone_from_text
@@ -122,37 +123,47 @@ def _extract_sentences(buffer: str) -> tuple[list[str], str]:
122
  return sentences, buffer[last_end:]
123
 
124
 
125
- async def _fire_tts(sentence: str, language: str, gender: str) -> Optional[bytes]:
126
  """
127
  Asynchronously POST a single sentence to the deployed TTS Space.
128
- Endpoint: POST {TTS_SPACE_URL}/synthesise
129
- Payload: {"text": str, "language": str, "gender": str}
130
- Returns raw audio bytes (audio/mpeg) on success, None on any failure.
131
  """
132
  sentence = sentence.strip()
133
  if not sentence:
134
- return None
 
 
 
 
 
 
 
 
 
 
 
135
  try:
136
  async with httpx.AsyncClient(timeout=TTS_SYNTHESISE_TIMEOUT) as client:
137
  resp = await client.post(
138
  f"{TTS_SPACE_URL}/synthesise",
139
- json={"text": sentence, "language": language, "gender": gender},
140
  )
141
  if resp.status_code == 200:
142
- logger.info(f"TTS ✓ lang={language} chars={len(sentence)}")
143
- return resp.content
144
  logger.warning(
145
  f"TTS Space returned HTTP {resp.status_code}: {resp.text[:120]}"
146
  )
147
- return None
148
  except httpx.TimeoutException:
149
  logger.error(
150
  f"TTS request timed out ({TTS_SYNTHESISE_TIMEOUT}s): {sentence[:60]!r}"
151
  )
152
- return None
153
  except Exception as exc:
154
  logger.error(f"TTS request error: {exc}")
155
- return None
156
 
157
 
158
  def _start_groq_stream_thread(
@@ -534,13 +545,13 @@ async def chat_stream(req: ChatRequest):
534
  Fire TTS for one sentence.
535
  Returns a ready-to-yield SSE audio event string, or None if TTS failed.
536
  """
537
- audio_bytes = await _fire_tts(sentence, detected_language, tts_gender)
538
  if audio_bytes:
539
  return _sse({
540
  "type": "audio",
541
  "sentence": sentence,
542
  "audio_b64": base64.b64encode(audio_bytes).decode("utf-8"),
543
- "lang": detected_language,
544
  })
545
  return None
546
 
 
20
  # Internal Domain Layer Imports
21
  from client import groq, fireworks
22
  from conversation_manager import ConversationManager, ConversationSession
23
+ from utils import detect_language_from_content, SUPPORTED_LANGUAGES
24
+ from language_config import normalize_language
25
  from prompt_builder import build_system_prompt
26
  from summary import generate_summary
27
  from caller_info_extractor import extract_name_from_text, extract_phone_from_text
 
123
  return sentences, buffer[last_end:]
124
 
125
 
126
+ async def _fire_tts(sentence: str, language: str, gender: str) -> tuple[Optional[bytes], str]:
127
  """
128
  Asynchronously POST a single sentence to the deployed TTS Space.
129
+ Language is resolved from sentence content so Urdu/English never collide.
130
+ Returns (audio_bytes, tts_language) on success, (None, tts_language) on failure.
 
131
  """
132
  sentence = sentence.strip()
133
  if not sentence:
134
+ return None, normalize_language(language)
135
+
136
+ tts_lang = normalize_language(detect_language_from_content(sentence))
137
+ session_lang = normalize_language(language)
138
+ if tts_lang != session_lang:
139
+ logger.info(
140
+ "TTS lang from content: session=%s → sentence=%s preview=%r",
141
+ session_lang,
142
+ tts_lang,
143
+ sentence[:60],
144
+ )
145
+
146
  try:
147
  async with httpx.AsyncClient(timeout=TTS_SYNTHESISE_TIMEOUT) as client:
148
  resp = await client.post(
149
  f"{TTS_SPACE_URL}/synthesise",
150
+ json={"text": sentence, "language": tts_lang, "gender": gender},
151
  )
152
  if resp.status_code == 200:
153
+ logger.info(f"TTS ✓ lang={tts_lang} chars={len(sentence)}")
154
+ return resp.content, tts_lang
155
  logger.warning(
156
  f"TTS Space returned HTTP {resp.status_code}: {resp.text[:120]}"
157
  )
158
+ return None, tts_lang
159
  except httpx.TimeoutException:
160
  logger.error(
161
  f"TTS request timed out ({TTS_SYNTHESISE_TIMEOUT}s): {sentence[:60]!r}"
162
  )
163
+ return None, tts_lang
164
  except Exception as exc:
165
  logger.error(f"TTS request error: {exc}")
166
+ return None, tts_lang
167
 
168
 
169
  def _start_groq_stream_thread(
 
545
  Fire TTS for one sentence.
546
  Returns a ready-to-yield SSE audio event string, or None if TTS failed.
547
  """
548
+ audio_bytes, tts_lang = await _fire_tts(sentence, detected_language, tts_gender)
549
  if audio_bytes:
550
  return _sse({
551
  "type": "audio",
552
  "sentence": sentence,
553
  "audio_b64": base64.b64encode(audio_bytes).decode("utf-8"),
554
+ "lang": tts_lang,
555
  })
556
  return None
557
 
python-services/utils.py CHANGED
@@ -12,6 +12,8 @@ from language_config import (
12
  GURMUKHI,
13
  has_arabic_script,
14
  normalize_language,
 
 
15
  )
16
 
17
 
@@ -45,6 +47,11 @@ def detect_language_from_content(text: str) -> str:
45
  if detect_roman_urdu(text):
46
  return "ur"
47
 
 
 
 
 
 
48
  return "en"
49
 
50
 
 
12
  GURMUKHI,
13
  has_arabic_script,
14
  normalize_language,
15
+ SUPPORTED_LANGUAGES,
16
+ URDU_SHARED_PHRASES,
17
  )
18
 
19
 
 
47
  if detect_roman_urdu(text):
48
  return "ur"
49
 
50
+ text_lower = text.lower()
51
+ for phrase in URDU_SHARED_PHRASES:
52
+ if phrase.lower() in text_lower:
53
+ return "ur"
54
+
55
  return "en"
56
 
57