import gradio as gr import os import torch import re from transformers import pipeline import google.generativeai as genai # ============================================ # API SETUP # ============================================ HF_TOKEN = os.getenv("HF_TOKEN") GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") genai.configure(api_key=GEMINI_API_KEY) if not HF_TOKEN: print("⚠️ WARNING: HF_TOKEN not set") if not GEMINI_API_KEY: print("⚠️ WARNING: GEMINI_API_KEY not set") # ============================================ # WORLD-CLASS SYSTEM PROMPT # ============================================ SYSTEM_PROMPT = """आप एक संवेदनशील, सहानुभूतिपूर्ण और ज्ञानवान महिला सशक्तिकरण परामर्शदाता हैं। आपका उद्देश्य भारतीय महिलाओं को उनकी समस्याओं में सहायता करना, प्रेरणा देना और व्यावहारिक समाधान प्रदान करना है। आपके विश्लेषण में निम्नलिखित बातें शामिल करें: 1. **भावनात्मक समझ (Emotional Recognition)** - महिला की आवाज़ में कौन सी भावनाएं हैं? (डर, गुस्सा, निराशा, आशा, दृढ़ निश्चय) - उसकी संवेदनशीलता और मजबूरियों को समझें - सहानुभूति के साथ स्वीकार करें: "आपकी भावनाएं बिल्कुल जायज़ हैं..." 2. **स्थिति का विश्लेषण (Sentiment Analysis)** - समस्या की गंभीरता: Emergency/Danger/Distress/Support Needed/Seeking Guidance/Positive - सामाजिक, आर्थिक, मानसिक पहलू - तुरंत खतरा है या लंबे समय की समस्या? 3. **भारतीय महिलाओं की सफल कहानियाँ (Inspiring Case Studies)** - समान परिस्थिति में से गुज़री महिलाओं की प्रामाणिक कहानियां - उदाहरण: * "शुषा वर्मा" - घरेलू हिंसा से मुक्ति, अब NGO चलाती हैं * "तारा शर्मा" - दहेज प्रताड़ना से निकलकर अब वकील * "प्रिया सिंह" - अपहरण से बचकर समाज सेविका बनीं * "निर्भया आंदोलन" - महिलाओं की सामूहिक शक्ति - हर कहानी में: संघर्ष → निर्णय → कार्रवाई → सफलता 4. **व्यावहारिक कदम (Actionable Steps)** - तुरंत करने योग्य 3-4 कदम - कानूनी विकल्प (IPC 498A, DV Act, महिला आयोग) - सुरक्षा प्रोटोकॉल - आर्थिक स्वतंत्रता के तरीके 5. **संसाधन और हेल्पलाइन** - राष्ट्रीय हेल्पलाइन: 181, 112, 1098 - राज्य-विशिष्ट संसाधन अगर पता हो - NGO संपर्क, कानूनी सहायता - आर्थिक सहायता योजनाएं 6. **सशक्तिकरण संदेश (Empowerment Message)** - उसकी क्षमता और शक्ति को दोहराएं - आत्मविश्वास बढ़ाएं - "आप अकेली नहीं हैं, हज़ारों महिलाएं इस यात्रा पर हैं" उत्तर का ढांचा (सादा टेक्स्ट, कोई Markdown नहीं): आपकी स्थिति समझी | Situation Understanding [संक्षिप्त पुनरावृत्ति + भावनात्मक स्वीकृति - 2-3 वाक्य] भावनाएं स्वीकार करते हैं | Emotional Validation [आपकी भावनाओं को वैध ठहराएं - 2-3 वाक्य] प्रेरक कहानी | Inspirational Story [एक समान केस स्टडी - कैसे किसी ने बाहर निकला - 4-5 वाक्य] तुरंत करें | Immediate Actions 1. [कदम 1 - स्पष्ट और व्यावहारिक] 2. [कदम 2 - स्पष्ट और व्यावहारिक] 3. [कदम 3 - स्पष्ट और व्यावहारिक] 4. [कदम 4 - स्पष्ट और व्यावहारिक] महत्वपूर्ण संपर्क | Important Contacts [हेल्पलाइन, NGO, कानूनी सहायता - संक्षिप्त सूची] याद रखें | Remember [सशक्तिकरण संदेश + आशा का संदेश - 2-3 वाक्य] महत्वपूर्ण निर्देश: - हमेशा आशावादी, सहायक और सशक्तिकरण पर ध्यान दें - कानूनी सलाह न दें - केवल कानूनी सहायता तक निर्देशित करें - भाषा: सरल हिंदी + अंग्रेजी मिश्रण, महिलाओं के दिल तक पहुंचे - कोई Markdown formatting नहीं - सादा टेक्स्ट ही उपयोग करें (कोई #, *, **, - नहीं) - उत्तर संक्षिप्त, स्पष्ट और व्यावहारिक होना चाहिए - प्रत्येक सेक्शन में पर्याप्त जानकारी दें लेकिन बहुत लंबा न हो""" # ============================================ # STT - WHISPER # ============================================ def transcribe_audio(audio_path): """Speech to Text using Whisper""" try: print("\n🎤 Transcribing audio...") whisper = pipeline( "automatic-speech-recognition", model="openai/whisper-small", token=HF_TOKEN ) result = whisper(audio_path) text = result.get("text", "").strip() print(f"✅ Transcribed: {text[:100]}...") return text except Exception as e: print(f"❌ STT Error: {e}") import traceback traceback.print_exc() return "" # ============================================ # LLM - GEMINI 2.0 FLASH # ============================================ def analyze_with_gemini(text): """Sentiment analysis, solutions & empowerment using Gemini 2.0 Flash""" try: print("\n🤖 Analyzing with Gemini 2.0 Flash...") prompt = f"""{SYSTEM_PROMPT} --- महिला का कथन | User's Statement: "{text}" --- अब उपरोक्त ढांचे के अनुसार संपूर्ण विश्लेषण और समाधान दें। सादा टेक्स्ट में लिखें - कोई Markdown formatting नहीं (कोई #, *, **, - नहीं)। प्रत्येक सेक्शन को स्पष्ट रूप से अलग करें।""" model = genai.GenerativeModel("gemini-2.0-flash") response = model.generate_content( prompt, generation_config={ "temperature": 0.8, "top_p": 0.95, "max_output_tokens": 1500, } ) analysis = response.text print(f"✅ Analysis complete: {len(analysis)} characters") return analysis except Exception as e: print(f"❌ Gemini Error: {e}") import traceback traceback.print_exc() return "सॉरी, इस समय विश्लेषण में समस्या आ रही है। कृपया पुनः प्रयास करें या 181 पर कॉल करें।" # ============================================ # MAIN PIPELINE # ============================================ def process_voice_input(audio): """Main pipeline: Audio → Text → Analysis → Empowerment""" if audio is None: return "कृपया अपनी आवाज़ रिकॉर्ड करें | Please record your voice\n\nमाइक्रोफोन बटन पर क्लिक करके अपनी आवाज़ रिकॉर्ड करें।\nClick the microphone button to record your voice." try: # STEP 1: Speech to Text print("\n" + "="*70) print("🔊 STEP 1: Speech to Text (Whisper)") print("="*70) text = transcribe_audio(audio) if not text or len(text.strip()) < 5: return """आवाज़ स्पष्ट नहीं सुनाई दी | Could Not Understand Clearly माफ़ कीजिए, आपकी आवाज़ स्पष्ट रूप से समझ नहीं आई। कृपया निम्नलिखित बातों का ध्यान रखें: शांत वातावरण में रिकॉर्ड करें स्पष्ट और धीरे-धीरे बोलें माइक्रोफोन के पास बोलें पुनः प्रयास करें Please ensure: Record in a quiet environment Speak clearly and slowly Stay close to the microphone Try again""" # STEP 2: Analysis & Empowerment print("\n" + "="*70) print("💡 STEP 2: Deep Analysis & Empowerment (Gemini 2.0 Flash)") print("="*70) analysis = analyze_with_gemini(text) # Clean markdown from analysis - remove all markdown formatting clean_analysis = re.sub(r'#{1,6}\s+', '', analysis) # Remove headers clean_analysis = re.sub(r'\*\*([^*]+)\*\*', r'\1', clean_analysis) # Remove bold clean_analysis = re.sub(r'\*([^*]+)\*', r'\1', clean_analysis) # Remove italic clean_analysis = re.sub(r'^\s*[-*+]\s+', '', clean_analysis, flags=re.MULTILINE) # Remove list markers clean_analysis = re.sub(r'^\s*\d+\.\s+', '', clean_analysis, flags=re.MULTILINE) # Remove numbered list markers # Format output with clean, plain text structure output = f"""महिला सशक्तिकरण सहायक | Women Empowerment Assistant आपने कहा | What You Said {text} विस्तृत विश्लेषण एवं समाधान | Comprehensive Analysis & Solutions {clean_analysis} आपातकालीन हेल्पलाइन | Emergency Helplines पुलिस आपातकाल | Police Emergency: 100 / 112 (24/7) महिला हेल्पलाइन | Women Helpline: 181 (24/7) बाल हेल्पलाइन | Child Helpline: 1098 (24/7) मानसिक स्वास्थ्य | Mental Health: 080-46110007 AASRA: 9820466726 कानूनी सहायता | Legal Aid: NALSA - 15100 (Free Legal Aid) वूमन पावर सेंटर | Women Power Center: अपने शहर का केंद्र Google पर खोजें आपके लिए महत्वपूर्ण | Important for You आप अकेली नहीं हैं - भारत में लाखों महिलाएं इसी यात्रा पर हैं आपकी आवाज़ मायने रखती है - सुनवाई करवाना आपका अधिकार है कानून आपके साथ है - IPC 498A, DV Act, दहेज निषेध अधिनियम सहायता उपलब्ध है - NGO, कानूनी, मानसिक स्वास्थ्य सेवाएं अगले कदम | Next Steps 1. विश्वसनीय व्यक्ति से बात करें - माता, बहन, या विश्वसनीय दोस्त को बताएं 2. हेल्पलाइन पर संपर्क करें - उपरोक्त हेल्पलाइन नंबरों पर तुरंत कॉल करें 3. दस्तावेज़ सुरक्षित रखें - सभी प्रासंगिक दस्तावेज़ और सबूत सुरक्षित स्थान पर रखें 4. कानूनी सलाह लें - NALSA (15100) पर कॉल करके मुफ्त कानूनी सहायता प्राप्त करें हमारा संदेश | Our Message आप मजबूत हैं। आप सम्मान की हकदार हैं। आपका जीवन अनमोल है। यह संकट अस्थायी है, आप स्थायी हैं। आगे बढ़ें - बस शुरुआत करें। गोपनीयता | Privacy: आपकी बातचीत पूरी तरह सुरक्षित और गोपनीय है।""" return output except Exception as e: print(f"❌ Pipeline Error: {e}") import traceback traceback.print_exc() return f"""त्रुटि | Error एक तकनीकी समस्या आई है। कृपया पुनः प्रयास करें। यदि समस्या बनी रहे: तुरंत महिला हेल्पलाइन 181 पर कॉल करें आपातकालीन स्थिति में 100/112 पर कॉल करें Technical Error: {str(e)} If the problem persists: Call Women Helpline 181 immediately For emergencies, call 100/112""" # ============================================ # GRADIO INTERFACE - DARK TECH THEME # ============================================ # Custom dark tech theme matching website aesthetic # Using minimal theme config and CSS for styling theme = gr.themes.Base( primary_hue=gr.themes.colors.cyan, secondary_hue=gr.themes.colors.blue, neutral_hue=gr.themes.colors.slate, font=("ui-monospace", "SFMono-Regular", "Menlo", "Monaco", "Consolas", "monospace"), font_mono=("ui-monospace", "SFMono-Regular", "Menlo", "Monaco", "Consolas", "monospace"), ) demo = gr.Interface( fn=process_voice_input, inputs=gr.Audio( sources=["microphone"], type="filepath", label="अपनी आवाज़ रिकॉर्ड करें / Record Your Voice", show_label=True ), outputs=gr.Textbox( label="विश्लेषण & समाधान / Analysis & Solutions", lines=40, show_label=True, max_lines=60, show_copy_button=True ), title="महिला सशक्तिकरण सहायक / Women Empowerment Assistant", description=""" **हिंदी या अंग्रेजी में बोलें | Speak in Hindi or English** यह एक AI-सशक्त समाधान है जो भारतीय महिलाओं को: • उनकी समस्याएं सुनता है • सहानुभूति के साथ समझता है • प्रेरणादायक कहानियां देता है • व्यावहारिक समाधान प्रदान करता है • कानूनी सहायता तक पहुंचने में मदद करता है *An AI solution that listens to Indian women's concerns with empathy and provides actionable solutions.* **आपकी गोपनीयता 100% सुरक्षित है | Your privacy is completely secure** **यह पूरी तरह FREE है | Completely FREE** """, theme=theme, flagging_mode="never", css=""" /* Custom dark tech styling - Batman inspired */ .gradio-container { background: #000000 !important; font-family: 'ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', monospace !important; color: #e0e0e0 !important; } /* Main background */ body, .gradio-container > div { background: #000000 !important; } /* Tech grid overlay effect */ .gradio-container::before { content: ''; position: fixed; inset: 0; background-image: linear-gradient(rgba(0, 212, 255, 0.02) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 212, 255, 0.02) 1px, transparent 1px); background-size: 40px 40px; pointer-events: none; z-index: 0; opacity: 0.6; } /* Block styling - dark tech */ .block, .panel { background: rgba(10, 10, 10, 0.95) !important; border: 1px solid rgba(0, 212, 255, 0.2) !important; border-radius: 4px !important; } /* Label styling */ .block-label, label { color: #00d4ff !important; font-weight: 600 !important; text-transform: uppercase !important; letter-spacing: 0.1em !important; font-family: 'ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', monospace !important; } /* Title styling */ h1, h2, h3, .block-title { color: #ffffff !important; font-family: 'ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', monospace !important; } /* Button styling - tech cyan */ button.primary, button[type="submit"] { background: rgba(0, 212, 255, 0.1) !important; border: 2px solid rgba(0, 212, 255, 0.5) !important; color: #00d4ff !important; box-shadow: 0 0 20px rgba(0, 212, 255, 0.3) !important; transition: all 0.3s ease !important; font-family: 'ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', monospace !important; text-transform: uppercase !important; letter-spacing: 0.1em !important; } button.primary:hover, button[type="submit"]:hover { background: rgba(0, 212, 255, 0.2) !important; border-color: #00d4ff !important; box-shadow: 0 0 30px rgba(0, 212, 255, 0.5) !important; } /* Secondary buttons */ button.secondary, button:not(.primary) { background: rgba(26, 26, 26, 0.8) !important; border: 1px solid rgba(0, 212, 255, 0.2) !important; color: #e0e0e0 !important; } button.secondary:hover, button:not(.primary):hover { background: rgba(26, 26, 26, 1) !important; border-color: rgba(0, 212, 255, 0.4) !important; } /* Input styling */ input, textarea, select { background: #0a0a0a !important; border: 1px solid rgba(0, 212, 255, 0.3) !important; color: #e0e0e0 !important; font-family: 'ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', monospace !important; } input:focus, textarea:focus, select:focus { border-color: rgba(0, 212, 255, 0.6) !important; box-shadow: 0 0 15px rgba(0, 212, 255, 0.2) !important; outline: none !important; } /* Text styling */ p, span, div { color: #e0e0e0 !important; } /* Description text */ .description, .prose { color: #b0b0b0 !important; } /* Scrollbar styling */ ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.8); border-left: 1px solid rgba(0, 212, 255, 0.1); } ::-webkit-scrollbar-thumb { background: linear-gradient(180deg, #00d4ff, #0099cc); border-radius: 4px; box-shadow: 0 0 8px rgba(0, 212, 255, 0.4); } ::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, #0099cc, #0066aa); box-shadow: 0 0 12px rgba(0, 212, 255, 0.6); } """ ) if __name__ == "__main__": demo.launch(share=False)