avtak commited on
Commit
e9bc8e7
Β·
verified Β·
1 Parent(s): b47e2e7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -71
app.py CHANGED
@@ -4,58 +4,45 @@ from huggingface_hub import login
4
  from openai import OpenAI
5
  import os
6
 
7
- # --- 1. AUTHENTICATION & SETUP ---
8
- # Authenticate Hugging Face (for your private Mental-Longformer)
9
  hf_token = os.getenv("HF_TOKEN")
10
  if hf_token:
11
  login(token=hf_token)
12
 
13
- # --- 2. LOAD THE SPECIALIZED TOOL ---
14
  print("Loading Mental-Longformer...")
15
  model_name = "avtak/erisk-longformer-depression-v1"
16
  classifier = pipeline("text-classification", model=model_name, truncation=True, max_length=4096, top_k=None)
17
 
18
- # --- 3. DEFINE MCP TOOLS ---
19
 
20
  def get_crisis_resources(location: str = "Global") -> str:
21
- """
22
- MCP Tool: Returns mental health resources based on location.
23
- """
24
  resources = {
25
- "US": "πŸ‡ΊπŸ‡Έ **US Resources:**\n- Crisis Text Line: Text HOME to 741741\n- Suicide Lifeline: Call 988",
26
- "Malaysia": "πŸ‡²πŸ‡Ύ **Malaysia Resources:**\n- Befrienders KL: 03-76272929\n- Talian Kasih: 15999",
27
- "Global": "🌍 **International:**\n- Find a helpline: [befrienders.org](https://www.befrienders.org)"
28
  }
 
29
  for key in resources:
30
- if key.lower() in location.lower():
31
  return resources[key]
32
  return resources["Global"]
33
 
34
  def detect_depression_risk(text: str) -> dict:
35
- """
36
- MCP Tool: Analyzes text using Mental-Longformer (eRisk 2025).
37
- Returns probability, risk level, and word count.
38
- """
39
- # Thesis Logic: User-Level Aggregation simulation
40
  processed_text = text.replace("\n", "\n\n")
41
  results = classifier(processed_text)[0]
42
  prob = next((r['score'] for r in results if r['label'] == 'LABEL_1'), 0)
43
 
44
- # Thesis Thresholds (Figure 4.15)
45
- if prob < 0.40:
46
- level = "Low Risk (Isolated Control Pattern)"
47
- elif 0.40 <= prob < 0.60:
48
- level = "Moderate Risk (Interactive Echo Chamber Pattern)"
49
- else:
50
- level = "High Risk (Depressed Cohort Pattern)"
51
 
52
- return {
53
- "probability": prob,
54
- "risk_level": level,
55
- "word_count": len(processed_text.split())
56
- }
57
 
58
- # --- 4. AGENT REASONING (MULTI-SPONSOR) ---
59
  def agent_reasoning(text, risk_data, provider="SambaNova"):
60
  """
61
  Uses Sponsor APIs to interpret the clinical data.
@@ -63,21 +50,21 @@ def agent_reasoning(text, risk_data, provider="SambaNova"):
63
  client = None
64
  model = None
65
 
66
- # SYSTEM PROMPT
67
  system_prompt = f"""
68
- You are an empathetic Clinical AI Assistant.
69
 
70
  CLINICAL DATA (Mental-Longformer):
71
  - Risk Level: {risk_data['risk_level']}
72
  - Probability: {risk_data['probability']:.1%}
73
  - Input Length: {risk_data['word_count']} words
74
 
75
- USER TEXT: "{text[:1000]}..."
76
 
77
  INSTRUCTIONS:
78
- 1. Explain the result using terms like 'Nocturnal Posting', 'High Effort' (if High) or 'Supportive Responder' (if Moderate).
79
- 2. Be compassionate but objective.
80
- 3. Max 100 words.
81
  """
82
 
83
  try:
@@ -87,75 +74,71 @@ def agent_reasoning(text, risk_data, provider="SambaNova"):
87
  if not api_key: return "⚠️ Nebius API Key missing."
88
 
89
  client = OpenAI(base_url="https://api.tokenfactory.nebius.com/v1/", api_key=api_key)
90
- model = "moonshotai/Kimi-K2-Thinking" # As requested
 
91
 
92
- # --- SPONSOR 2: SAMBANOVA (Llama 3.1 / DeepSeek) ---
93
  elif provider == "SambaNova":
94
  api_key = os.getenv("SAMBANOVA_API_KEY")
95
  if not api_key: return "⚠️ SambaNova API Key missing."
96
 
97
  client = OpenAI(base_url="https://api.sambanova.ai/v1", api_key=api_key)
98
- model = "Meta-Llama-3.1-70B-Instruct" # Fastest/Stable for Demo
 
99
 
100
  # EXECUTE
101
  response = client.chat.completions.create(
102
  model=model,
103
  messages=[
104
  {"role": "system", "content": system_prompt},
105
- {"role": "user", "content": "Analyze this user status."}
106
  ],
107
  temperature=0.6,
108
- max_tokens=300
109
  )
110
  return response.choices[0].message.content
111
 
112
  except Exception as e:
113
- return f"Agent Logic Error ({provider}): {str(e)}"
114
 
115
- # --- 5. ORCHESTRATION ---
116
  def full_analysis_pipeline(user_text, location, provider):
117
  if not user_text.strip(): return "Please enter text.", "No data", "No data"
118
 
119
- # 1. Tool Use (Local Model)
120
  risk_data = detect_depression_risk(user_text)
121
-
122
- # 2. Tool Use (Resources)
123
  resources = get_crisis_resources(location)
124
-
125
- # 3. Agent Reasoning (Cloud API)
126
  explanation = agent_reasoning(user_text, risk_data, provider)
127
 
 
 
 
128
  return f"""
129
- # {risk_data['risk_level']}
130
- ## Probability: {risk_data['probability']*100:.1f}%
 
 
131
 
132
  ### 🧠 Agent Analysis ({provider})
133
  {explanation}
134
 
135
- ### πŸ†˜ Resources
136
  {resources}
137
  """
138
 
139
- # --- 6. EXAMPLES (THESIS PATTERNS) ---
140
  example_low = """The new update for the Linux kernel (6.8) finally addressed the driver issues I was seeing with Realtek cards. I read the changelog on kernel.org and noticed they patched the module specific to the rtl8821ce chipset.
141
-
142
  On a different note, the defensive stats for the basketball team have improved significantly. Allowing 15% fewer points per possession is a game changer.
143
-
144
  I also spent some time woodworking. I'm building a walnut coffee table and the grain is tricky to plane. I might switch to a polyurethane finish for durability."""
145
 
146
  example_mod = """Things have been pretty busy at work. We're in the middle of a big project and deadlines are tight. Staying a bit later than usual but that's just how it goes sometimes. Team is handling it well overall.
147
-
148
  Sleep could be better. Been staying up too late scrolling my phone. Need to work on that. Usually feel okay once I get moving in the morning though.
149
-
150
- Went hiking with some friends last weekend which was nice. Good to get outside and move around. We're talking about doing another trip next month. Weather should be better by then."""
151
 
152
  example_high = """I don't know why I even bother getting out of bed anymore. I slept for 12 hours yesterday and I'm still exhausted. It feels like my limbs weigh a thousand pounds.
153
-
154
  I've been avoiding my friends for weeks. They keep texting me, but I can't bring myself to reply. The thought of socializing is terrifying.
155
-
156
  Everything feels like a shade of grey. I can't concentrate on my work. I feel like I'm drowning while everyone else is breathing fine. I was up until 4 AM again last night just staring at the ceiling."""
157
 
158
- # --- 7. UI (GRADIO V6) ---
159
  with gr.Blocks(title="Depression Risk Agent") as demo:
160
  gr.Markdown("# 🧠 Early Depression Detection Agent (MCP)")
161
  gr.Markdown("Agentic system using **Mental-Longformer** (Tool) + **Multi-Provider Reasoning** (Nebius/SambaNova).")
@@ -169,18 +152,17 @@ with gr.Blocks(title="Depression Risk Agent") as demo:
169
  placeholder="[Post 1] ...\n\n[Post 2] ...\n\n(Context >100 words recommended)"
170
  )
171
 
172
- # EXAMPLES
173
- gr.Markdown("### 2. Try Thesis Patterns")
174
  with gr.Row():
175
  btn_low = gr.Button("🟒 Low Risk", size="sm", variant="secondary")
176
  btn_mod = gr.Button("🟑 Moderate", size="sm", variant="secondary")
177
  btn_high = gr.Button("πŸ”΄ High Risk", size="sm", variant="secondary")
178
 
179
- # SETTINGS
180
- gr.Markdown("### 3. Settings")
181
  with gr.Row():
182
- loc_dropdown = gr.Dropdown(["US", "Malaysia", "Global"], value="Global", label="Location")
183
- provider_dropdown = gr.Dropdown(["SambaNova", "Nebius (Kimi K2)"], value="SambaNova", label="Agent Brain")
 
184
 
185
  submit = gr.Button("πŸš€ Run Analysis Agent", variant="primary", size="lg")
186
 
@@ -195,16 +177,11 @@ with gr.Blocks(title="Depression Risk Agent") as demo:
195
  - `get_crisis_resources(location)`: Returns localized help.
196
  """)
197
 
198
- # HANDLERS
199
  submit.click(full_analysis_pipeline, inputs=[input_text, loc_dropdown, provider_dropdown], outputs=output)
200
 
201
  btn_low.click(lambda: example_low, None, input_text)
202
  btn_mod.click(lambda: example_mod, None, input_text)
203
  btn_high.click(lambda: example_high, None, input_text)
204
 
205
- # --- 8. LAUNCH ---
206
  if __name__ == "__main__":
207
- demo.launch(
208
- mcp_server=True,
209
- theme=gr.themes.Soft()
210
- )
 
4
  from openai import OpenAI
5
  import os
6
 
7
+ # --- 1. SETUP ---
 
8
  hf_token = os.getenv("HF_TOKEN")
9
  if hf_token:
10
  login(token=hf_token)
11
 
12
+ # --- 2. TOOL LOADING ---
13
  print("Loading Mental-Longformer...")
14
  model_name = "avtak/erisk-longformer-depression-v1"
15
  classifier = pipeline("text-classification", model=model_name, truncation=True, max_length=4096, top_k=None)
16
 
17
+ # --- 3. MCP TOOLS ---
18
 
19
  def get_crisis_resources(location: str = "Global") -> str:
20
+ """Returns mental health resources based on location."""
 
 
21
  resources = {
22
+ "US": "πŸ‡ΊπŸ‡Έ **US:** Crisis Text Line: 741741 | Suicide Lifeline: 988",
23
+ "Malaysia": "πŸ‡²πŸ‡Ύ **Malaysia:** Befrienders KL: 03-76272929 | Talian Kasih: 15999",
24
+ "Global": "🌍 **International:** [befrienders.org](https://www.befrienders.org)"
25
  }
26
+ # Fallback logic
27
  for key in resources:
28
+ if location and key.lower() in location.lower():
29
  return resources[key]
30
  return resources["Global"]
31
 
32
  def detect_depression_risk(text: str) -> dict:
33
+ """Analyzes text using Mental-Longformer (eRisk 2025)."""
34
+ # Thesis Aggregation Logic
 
 
 
35
  processed_text = text.replace("\n", "\n\n")
36
  results = classifier(processed_text)[0]
37
  prob = next((r['score'] for r in results if r['label'] == 'LABEL_1'), 0)
38
 
39
+ if prob < 0.40: level = "Low Risk (Isolated Pattern)"
40
+ elif 0.40 <= prob < 0.60: level = "Moderate Risk (Echo Chamber Pattern)"
41
+ else: level = "High Risk (Depressed Pattern)"
 
 
 
 
42
 
43
+ return {"probability": prob, "risk_level": level, "word_count": len(processed_text.split())}
 
 
 
 
44
 
45
+ # --- 4. AGENT REASONING (UPDATED MODELS) ---
46
  def agent_reasoning(text, risk_data, provider="SambaNova"):
47
  """
48
  Uses Sponsor APIs to interpret the clinical data.
 
50
  client = None
51
  model = None
52
 
53
+ # SYSTEM PROMPT (Thesis-Informed)
54
  system_prompt = f"""
55
+ You are an empathetic Clinical AI Agent.
56
 
57
  CLINICAL DATA (Mental-Longformer):
58
  - Risk Level: {risk_data['risk_level']}
59
  - Probability: {risk_data['probability']:.1%}
60
  - Input Length: {risk_data['word_count']} words
61
 
62
+ USER TEXT SNIPPET: "{text[:800]}..."
63
 
64
  INSTRUCTIONS:
65
+ 1. Acknowledge the user's situation based on the text.
66
+ 2. Explain the risk level using thesis terms: 'Nocturnal Posting' (High), 'Supportive Responder' (Moderate), or 'Healthy External Focus' (Low).
67
+ 3. Be compassionate. Max 80 words.
68
  """
69
 
70
  try:
 
74
  if not api_key: return "⚠️ Nebius API Key missing."
75
 
76
  client = OpenAI(base_url="https://api.tokenfactory.nebius.com/v1/", api_key=api_key)
77
+ # Using the chat version of Kimi K2
78
+ model = "moonshotai/Kimi-K2-Chat"
79
 
80
+ # --- SPONSOR 2: SAMBANOVA (Llama 3.3) ---
81
  elif provider == "SambaNova":
82
  api_key = os.getenv("SAMBANOVA_API_KEY")
83
  if not api_key: return "⚠️ SambaNova API Key missing."
84
 
85
  client = OpenAI(base_url="https://api.sambanova.ai/v1", api_key=api_key)
86
+ # UPDATED MODEL ID
87
+ model = "Meta-Llama-3.3-70B-Instruct"
88
 
89
  # EXECUTE
90
  response = client.chat.completions.create(
91
  model=model,
92
  messages=[
93
  {"role": "system", "content": system_prompt},
94
+ {"role": "user", "content": "Analyze this."}
95
  ],
96
  temperature=0.6,
97
+ max_tokens=200
98
  )
99
  return response.choices[0].message.content
100
 
101
  except Exception as e:
102
+ return f"Reasoning Error ({provider}): {str(e)}"
103
 
104
+ # --- 5. PIPELINE ---
105
  def full_analysis_pipeline(user_text, location, provider):
106
  if not user_text.strip(): return "Please enter text.", "No data", "No data"
107
 
 
108
  risk_data = detect_depression_risk(user_text)
 
 
109
  resources = get_crisis_resources(location)
 
 
110
  explanation = agent_reasoning(user_text, risk_data, provider)
111
 
112
+ # Color logic
113
+ color = "green" if risk_data['probability'] < 0.4 else "orange" if risk_data['probability'] < 0.6 else "red"
114
+
115
  return f"""
116
+ <div style="border-left: 5px solid {color}; padding-left: 10px;">
117
+ <h2 style="color:{color}; margin:0;">{risk_data['risk_level']}</h2>
118
+ <h3 style="margin-top:0;">Probability: {risk_data['probability']*100:.1f}%</h3>
119
+ </div>
120
 
121
  ### 🧠 Agent Analysis ({provider})
122
  {explanation}
123
 
124
+ ### πŸ†˜ Recommended Resources
125
  {resources}
126
  """
127
 
128
+ # --- 6. EXAMPLES ---
129
  example_low = """The new update for the Linux kernel (6.8) finally addressed the driver issues I was seeing with Realtek cards. I read the changelog on kernel.org and noticed they patched the module specific to the rtl8821ce chipset.
 
130
  On a different note, the defensive stats for the basketball team have improved significantly. Allowing 15% fewer points per possession is a game changer.
 
131
  I also spent some time woodworking. I'm building a walnut coffee table and the grain is tricky to plane. I might switch to a polyurethane finish for durability."""
132
 
133
  example_mod = """Things have been pretty busy at work. We're in the middle of a big project and deadlines are tight. Staying a bit later than usual but that's just how it goes sometimes. Team is handling it well overall.
 
134
  Sleep could be better. Been staying up too late scrolling my phone. Need to work on that. Usually feel okay once I get moving in the morning though.
135
+ Went hiking with some friends last weekend which was nice. Good to get outside and move around."""
 
136
 
137
  example_high = """I don't know why I even bother getting out of bed anymore. I slept for 12 hours yesterday and I'm still exhausted. It feels like my limbs weigh a thousand pounds.
 
138
  I've been avoiding my friends for weeks. They keep texting me, but I can't bring myself to reply. The thought of socializing is terrifying.
 
139
  Everything feels like a shade of grey. I can't concentrate on my work. I feel like I'm drowning while everyone else is breathing fine. I was up until 4 AM again last night just staring at the ceiling."""
140
 
141
+ # --- 7. UI ---
142
  with gr.Blocks(title="Depression Risk Agent") as demo:
143
  gr.Markdown("# 🧠 Early Depression Detection Agent (MCP)")
144
  gr.Markdown("Agentic system using **Mental-Longformer** (Tool) + **Multi-Provider Reasoning** (Nebius/SambaNova).")
 
152
  placeholder="[Post 1] ...\n\n[Post 2] ...\n\n(Context >100 words recommended)"
153
  )
154
 
155
+ gr.Markdown("### 2. Thesis Patterns (Click to Load)")
 
156
  with gr.Row():
157
  btn_low = gr.Button("🟒 Low Risk", size="sm", variant="secondary")
158
  btn_mod = gr.Button("🟑 Moderate", size="sm", variant="secondary")
159
  btn_high = gr.Button("πŸ”΄ High Risk", size="sm", variant="secondary")
160
 
161
+ gr.Markdown("### 3. Agent Settings")
 
162
  with gr.Row():
163
+ # RENAMED to be clearer
164
+ loc_dropdown = gr.Dropdown(["Global", "US", "Malaysia"], value="Global", label="Crisis Resource Region")
165
+ provider_dropdown = gr.Dropdown(["SambaNova", "Nebius (Kimi K2)"], value="SambaNova", label="Reasoning Brain")
166
 
167
  submit = gr.Button("πŸš€ Run Analysis Agent", variant="primary", size="lg")
168
 
 
177
  - `get_crisis_resources(location)`: Returns localized help.
178
  """)
179
 
 
180
  submit.click(full_analysis_pipeline, inputs=[input_text, loc_dropdown, provider_dropdown], outputs=output)
181
 
182
  btn_low.click(lambda: example_low, None, input_text)
183
  btn_mod.click(lambda: example_mod, None, input_text)
184
  btn_high.click(lambda: example_high, None, input_text)
185
 
 
186
  if __name__ == "__main__":
187
+ demo.launch(mcp_server=True, theme=gr.themes.Soft())