import gradio as gr from transformers import pipeline from huggingface_hub import login from openai import OpenAI import os import json # --- 1. SETUP --- hf_token = os.getenv("HF_TOKEN") if hf_token: login(token=hf_token) # --- 2. LOAD TOOL --- print("Loading Mental-Longformer...") model_name = "avtak/erisk-longformer-depression-v1" classifier = pipeline("text-classification", model=model_name, truncation=True, max_length=4096, top_k=None) # --- 3. MCP TOOLS --- def get_crisis_resources(location: str = "Global") -> str: """Returns mental health resources based on location.""" resources = { "US": "πΊπΈ **US:** Crisis Text Line: 741741 | Suicide Lifeline: 988", "Malaysia": "π²πΎ **Malaysia:** Befrienders KL: 03-76272929 | Talian Kasih: 15999", "Global": "π **International:** [befrienders.org](https://www.befrienders.org)" } for key in resources: if location and key.lower() in location.lower(): return resources[key] return resources["Global"] def detect_depression_risk(text: str) -> dict: """Analyzes text using Mental-Longformer (eRisk 2025).""" # --- THESIS LOGIC: AGGREGATION --- # 1. We replace single newlines with double newlines for the MODEL processed_text = text.replace("\n", "\n\n") results = classifier(processed_text)[0] prob = next((r['score'] for r in results if r['label'] == 'LABEL_1'), 0) # Thesis Thresholds (Figure 4.15) if prob < 0.40: level = "Low Risk" biomarker = "Healthy External Focus" desc = "Matches 'Isolated Control' group. High lexical diversity, focus on hobbies/events." color = "#10b981" # Green elif 0.40 <= prob < 0.60: level = "Moderate Risk" biomarker = "Echo Chamber Interaction" desc = "Matches 'Interactive Non-Depressed' group. Engaging in support forums but likely not clinically depressed." color = "#f59e0b" # Yellow else: level = "High Risk" biomarker = "Nocturnal & High-Effort" desc = "Matches 'Depressed' cohort. Indicators: Nocturnal posting spikes (00-05 UTC), high-effort/low-frequency posting." color = "#ef4444" # Red return { "probability": prob, "risk_level": level, "biomarker": biomarker, "description": desc, "color": color, "word_count": len(processed_text.split()) } # --- 4. AGENT REASONING (SambaNova + Nebius Kimi) --- def agent_reasoning(text, risk_data, provider="SambaNova"): """ Uses Sponsor APIs to generate the analysis report. """ client = None model_id = None # IMPROVED SYSTEM PROMPT system_prompt = f""" You are 'MindSight', a Clinical Research Agent specialized in linguistic biomarker analysis. CONTEXTUAL DATA: - Detected Risk: {risk_data['risk_level']} ({risk_data['probability']:.1%}) - Key Biomarker: {risk_data['biomarker']} - Dataset Context: Based on eRisk longitudinal analysis (2017-2022). USER TEXT SNIPPET: "{text[:1000]}..." YOUR MISSION: Synthesize the clinical data with the user's personal narrative to provide a supportive, research-backed insight. GUIDELINES: 1. **Validate:** Start by acknowledging the specific struggles or sentiments expressed in the text (e.g., "I hear your exhaustion..."). 2. **Connect:** Explain *why* the risk level was triggered using the Biomarker. - If High Risk: Link sleep/energy complaints to the "Nocturnal Posting" pattern (activity spikes 00:00-05:00 UTC). - If Moderate Risk: Link their focus on others to the "Supportive Responder" effect found in online echo chambers. - If Low Risk: Affirm their "Healthy External Focus" (hobbies, work, events). 3. **Bridge:** Offer a gentle, non-medical bridge to the resources below. CONSTRAINTS: - Be warm but objective. - NO medical diagnosis (use "suggests alignment with..."). - Max 80 words. """ try: # --- SPONSOR 1: NEBIUS (Kimi K2) --- if provider == "Nebius (Kimi K2)": api_key = os.getenv("NEBIUS_API_KEY") if not api_key: return "β οΈ Nebius API Key missing." client = OpenAI( base_url="https://api.tokenfactory.nebius.com/v1/", api_key=api_key ) model_id = "moonshotai/Kimi-K2-Instruct" # --- SPONSOR 2: SAMBANOVA --- else: # Default to SambaNova api_key = os.getenv("SAMBANOVA_API_KEY") if not api_key: return "β οΈ SambaNova API Key missing." client = OpenAI( base_url="https://api.sambanova.ai/v1", api_key=api_key ) model_id = "Meta-Llama-3.3-70B-Instruct" # EXECUTE response = client.chat.completions.create( model=model_id, messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": "Analyze this."} ], temperature=0.6, max_tokens=300 ) return response.choices[0].message.content except Exception as e: return f"Reasoning Error ({provider}): {str(e)}" # --- 5. PIPELINE --- def full_analysis_pipeline(user_text, location, provider): if not user_text.strip(): return "Please enter text." # 1. Run Tool risk_data = detect_depression_risk(user_text) # 2. Get Resources resources = get_crisis_resources(location) # 3. Agent Reasoning explanation = agent_reasoning(user_text, risk_data, provider) # 4. Color Logic (Fixed) color = risk_data['color'] # 5. Build HTML/Markdown Report return f"""