feat: complete real-time voice-ai engine upgrades and frontend integration guide

This commit is contained in:
2026-09-03 12:34:55 +05:30
parent c23d979338
commit 37440993f7
56 changed files with 2521 additions and 3040 deletions
+34 -22
View File
@@ -460,36 +460,32 @@ def _stage_for_missing(missing_field: str) -> str:
def _pick_best_question(missing_list: List[str], lang: str, is_psych: bool = False) -> str:
if not missing_list:
if lang.startswith("ta"):
return "சரிங்க, எல்லா விவரத்தையும் டாக்டர்கிட்ட குடுத்துடுறேன். ரொம்ப நன்றிங்க!"
return "அனைத்து விபரங்களும் பதிவு செய்யப்பட்டது!"
elif lang.startswith("hi"):
return "ठीक है जी, मैं यह सारी जानकारी डॉक्टर साहब को दे देती हूँ। शुक्रिया!"
return "सभी विवरण दर्ज कर लिए।"
elif lang.startswith("te"):
return "చాలా ధన్యవాదాలు! మీ వివరాలన్నీ డాక్టర్ గారికి అందిస్తాను."
return "అన్ని వివరాలు నమోదు చేయబడ్డాయి. ధన్యవాదాలు!"
elif lang.startswith("kn"):
return "ಸರಿ, ಈ ಎಲ್ಲಾ ವಿವರಗಳನ್ನು ಡಾಕ್ಟರ್‌ಗೆ ತಿಳಿಸ್ತೀನಿ. ಧನ್ಯವಾದಗಳು!"
return "ಎಲ್ಲಾ ವಿವರಗಳನ್ನು ದಾಖಲಿಸಲಾಗಿದೆ. ಧನ್ಯವಾದಗಳು!"
else:
return "Got it. I have compiled all these details for the doctor. Thank you!"
return "All details recorded. Thank you!"
field = missing_list[0]
# Tamil
# Tamil (Max 5 words)
if lang.startswith("ta"):
if field == "reason_for_visit" or field == "symptoms":
return "வணக்கம், உங்களுக்கு என்ன உடம்பு பிரச்சனை இருக்குன்னு சொல்ல முடியுமா?"
return "உங்களுக்கு என்ன உடம்பு பிரச்சனை?"
elif field == "duration":
if is_psych:
return "புரியுதுங்க. இந்த மன அழுத்தம் அல்லது கவலை எப்போலிருந்து இருக்குன்னு சொல்ல முடியுமா?"
return "சரிங்க, இந்த பிரச்சனை எத்தனை நாளா இருக்குன்னு சொல்ல முடியுமா?"
return "எத்தனை நாளாக இந்த பிரச்சனை?"
elif field == "medical_history":
if is_psych:
return "புரியுதுங்க. இதுக்கு முன்னாடி மன அழுத்தம் அல்லது தூக்கமின்மைக்காக சிகிச்சை எடுத்திருக்கீங்களா?"
return "சரிங்க. உங்களுக்கு பிபி, சுகர், ஆஸ்துமா போன்ற வேறு ஏதேனும் உடம்பு பிரச்சனை இருக்கா?"
return "வேறு ஏதேனும் நோய் இருக்கிறதா?"
elif field == "medications":
return "சரிங்க, இதுக்காக இல்ல வேறு ஏதேனும் பிரச்சனைக்காக வழக்கமா மாத்திரை சாப்பிடுறீங்களா?"
return "தினமும் ஏதேனும் மாத்திரை சாப்பிடுகிறீர்களா?"
elif field == "allergies":
return "புரியுதுங்க. உங்களுக்கு ஏதேனும் மருந்து அல்லது உணவு அலர்ஜி இருக்கா?"
return "ஏதேனும் மருந்து அலர்ஜி இருக்கா?"
# Hindi
# Hindi (Max 5 words)
elif lang.startswith("hi"):
if field == "reason_for_visit" or field == "symptoms":
return "नमस्ते, आपको क्या स्वास्थ्य समस्या हो रही है?"
@@ -702,10 +698,6 @@ class AIOrchestrator:
"""
from app.ai.prompts import build_system_prompt
api_key = self.gemini.api_key
if not api_key or api_key in ["your_gemini_key", "your_gemini_api_key", ""]:
return None
patient = {
"name": getattr(session, "first_name", "Patient"),
"age": getattr(session, "age", ""),
@@ -724,9 +716,25 @@ class AIOrchestrator:
system_prompt = build_system_prompt(context)
raw_text = await self.gemini.generate_response(system_prompt, user_message)
raw_text = None
# Priority 1: OpenAI (if user paid for key)
if self.openai.api_key and self.openai.api_key.strip() not in ["your_openai_key", "your_openai_api_key", ""]:
try:
raw_text = await self.openai.generate_response(system_prompt, user_message)
except Exception as e:
print(f"[AIOrchestrator] OpenAI LLM call failed: {e}")
# Parse JSON from Gemini response
# Priority 2: Gemini fallback
if not raw_text and self.gemini.api_key and self.gemini.api_key.strip() not in ["your_gemini_key", "your_gemini_api_key", ""]:
try:
raw_text = await self.gemini.generate_response(system_prompt, user_message)
except Exception as e:
print(f"[AIOrchestrator] Gemini LLM call failed: {e}")
if not raw_text:
return None
# Parse JSON from response
cleaned = raw_text.strip()
if cleaned.startswith("```"):
cleaned = cleaned.split("\n", 1)[-1]
@@ -739,6 +747,10 @@ class AIOrchestrator:
# Validate it has required keys
if "reply" not in parsed or not isinstance(parsed.get("reply"), str):
return None
# Clean reply string generated directly by OpenAI
parsed["reply"] = parsed["reply"].strip()
if "state_updates" not in parsed or not isinstance(parsed.get("state_updates"), dict):
parsed["state_updates"] = {}
if "completed" not in parsed: