datdevsteve commited on
Commit
a81c2e8
·
verified ·
1 Parent(s): 935d99d

Update nivra_agent.py

Browse files
Files changed (1) hide show
  1. nivra_agent.py +55 -67
nivra_agent.py CHANGED
@@ -3,38 +3,22 @@
3
  #=========================================
4
 
5
  import os
6
-
7
- # 🔥 HF Spaces inject proxy vars that break Groq SDK
8
- for key in ("HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy"):
9
- os.environ.pop(key, None)
10
-
11
  from dotenv import load_dotenv
12
- load_dotenv()
13
 
14
- from langchain_groq import ChatGroq
15
  from agent.rag_retriever import NivraRAGRetriever
16
  from agent.text_symptom_tool import analyze_symptom_text
17
  from agent.image_symptom_tool import analyze_symptom_image
18
 
 
 
19
  # ==================================================
20
- # Lazy singletons (ABSOLUTELY CRITICAL ON HF SPACES)
21
  # ==================================================
22
 
23
- _llm = None
24
  _rag = None
25
 
26
 
27
- def get_llm():
28
- global _llm
29
- if _llm is None:
30
- _llm = ChatGroq(
31
- temperature=0.1,
32
- model="llama-3.3-70b-versatile",
33
- api_key=os.getenv("GROQ_API_KEY"),
34
- )
35
- return _llm
36
-
37
-
38
  def get_rag():
39
  global _rag
40
  if _rag is None:
@@ -67,30 +51,6 @@ SYSTEM_PROMPT = """You are Nivra, a smart and helpful AI Healthcare Assistant wi
67
  [FIRST AID] ... [/FIRST AID]
68
  [EMERGENCY CONSULTATION REQUIRED] ... [/EMERGENCY CONSULTATION REQUIRED]
69
  ---
70
- **FEW-SHOT EXAMPLES**:
71
- **EXAMPLE 1 - GREETING** (No medical format)
72
- Input: "How are you?"
73
- ---
74
- Hey! I'm Nivra, your AI healthcare assistant. How can I help you today?
75
- **EXAMPLE 2 - MEDICAL** (Full format)
76
- Input: "I have fever, chills and severe headache."
77
- ---
78
- [TOOLS USED] analyze_symptom_text, rag_tool [/TOOLS USED]
79
- [SYMPTOMS] Fever, Chills, Headache [/SYMPTOMS]
80
- [PRIMARY DIAGNOSIS] Malaria (78% confidence) [/PRIMARY DIAGNOSIS]
81
- [DIAGNOSIS DESCRIPTION]
82
- Malaria is caused by Plasmodium parasite spread by Anopheles mosquitoes...
83
- [/DIAGNOSIS DESCRIPTION]
84
- [FIRST AID]
85
- Rest completely and drink plenty of fluids. Seek immediate medical attention...
86
- [/FIRST AID]
87
- [EMERGENCY CONSULTATION REQUIRED] Yes [/EMERGENCY CONSULTATION REQUIRED]
88
- **EXAMPLE 3 - GENERAL INFO** (No medical format)
89
- Input: "What causes TB?"
90
- ---
91
- [BASIC]
92
- Tuberculosis (TB) is caused by Mycobacterium tuberculosis bacteria, spread through air droplets. Not everyone exposed gets infected. Consult doctor for testing.
93
- ---
94
  **RULES** (Always follow):
95
  - You ARE NOT A DOCTOR - Preliminary analysis only
96
  - Emergency=Yes for: Cancer, Dengue, Malaria, Typhoid, TB
@@ -98,10 +58,39 @@ Tuberculosis (TB) is caused by Mycobacterium tuberculosis bacteria, spread throu
98
  - Keep medical descriptions < 3 sentences
99
  - Use tokens as shown in examples for your output.
100
  - Natural responses for casual conversation
101
- **FINAL CHECK**: Does user describe PERSONAL symptoms? YES=Medical format with respective token wrapping, NO=Natural response with respective token wrapping.
102
  """
103
 
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  # ==================================================
106
  # MAIN CHAT FUNCTION
107
  # ==================================================
@@ -116,7 +105,6 @@ def nivra_chat(user_input, chat_history=None):
116
  input_lower = user_input.lower()
117
  text_keywords = ["fever", "headache", "cough", "pain", "vomiting", "chills"]
118
 
119
- tools_used = []
120
  tool_results = []
121
 
122
  # -------------------------
@@ -125,46 +113,46 @@ def nivra_chat(user_input, chat_history=None):
125
  if any(k in input_lower for k in text_keywords):
126
  try:
127
  symptom_result = analyze_symptom_text.invoke(user_input)
128
- tools_used.append("analyze_symptom_text")
129
  tool_results.append(symptom_result)
130
- except Exception as e:
131
- tool_results.append(f"TEXT TOOL FAILED: {e}")
132
 
133
  # -------------------------
134
  # RAG retrieval
135
  # -------------------------
136
  try:
137
  rag_result = get_rag().getRelevantDocs(user_input)
138
- tools_used.append("rag_tool")
139
  tool_results.append(rag_result)
140
- except Exception as e:
141
- tool_results.append(f"RAG FAILED: {e}")
142
 
143
  tool_results_text = "\n".join(map(str, tool_results))
144
 
145
  # Fallback if tools fail
146
  if any("FAILED" in str(r) for r in tool_results):
147
- return f"""[TOOLS USED] Tools failed - Network issue
148
- [SYMPTOMS] {user_input}
149
- [PRIMARY DIAGNOSIS] Possible viral fever/infection
150
- [DIAGNOSIS DESCRIPTION] Fever+chills suggests infection. ClinicalBERT backend temporarily unavailable.
151
- [FIRST AID] Rest, hydrate, paracetamol. Monitor temperature.
152
- [EMERGENCY] No - but consult doctor if >3 days"""
153
-
154
- # -------------------------
155
- # LLM synthesis
156
- # -------------------------
157
- final_prompt = f"""{SYSTEM_PROMPT}
158
 
 
159
  TOOL RESULTS:
160
  {tool_results_text}
161
 
162
- USER INPUT: {user_input}
 
 
163
  Provide diagnosis:
164
  """
165
 
166
  try:
167
- response = get_llm().invoke(final_prompt)
168
- return response.content.strip()
169
  except Exception as e:
170
- return f"LLM FAILED: {e}"
 
 
 
 
3
  #=========================================
4
 
5
  import os
6
+ import requests
 
 
 
 
7
  from dotenv import load_dotenv
 
8
 
 
9
  from agent.rag_retriever import NivraRAGRetriever
10
  from agent.text_symptom_tool import analyze_symptom_text
11
  from agent.image_symptom_tool import analyze_symptom_image
12
 
13
+ load_dotenv()
14
+
15
  # ==================================================
16
+ # Lazy singleton for RAG (safe on HF Spaces)
17
  # ==================================================
18
 
 
19
  _rag = None
20
 
21
 
 
 
 
 
 
 
 
 
 
 
 
22
  def get_rag():
23
  global _rag
24
  if _rag is None:
 
51
  [FIRST AID] ... [/FIRST AID]
52
  [EMERGENCY CONSULTATION REQUIRED] ... [/EMERGENCY CONSULTATION REQUIRED]
53
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  **RULES** (Always follow):
55
  - You ARE NOT A DOCTOR - Preliminary analysis only
56
  - Emergency=Yes for: Cancer, Dengue, Malaria, Typhoid, TB
 
58
  - Keep medical descriptions < 3 sentences
59
  - Use tokens as shown in examples for your output.
60
  - Natural responses for casual conversation
 
61
  """
62
 
63
 
64
+ # ==================================================
65
+ # GROQ RAW HTTP CALL (HF SAFE)
66
+ # ==================================================
67
+
68
+ def call_groq(prompt: str) -> str:
69
+ api_key = os.getenv("GROQ_API_KEY")
70
+ if not api_key:
71
+ return "⚠️ GROQ_API_KEY not configured."
72
+
73
+ response = requests.post(
74
+ "https://api.groq.com/openai/v1/chat/completions",
75
+ headers={
76
+ "Authorization": f"Bearer {api_key}",
77
+ "Content-Type": "application/json",
78
+ },
79
+ json={
80
+ "model": "llama-3.3-70b-versatile",
81
+ "messages": [
82
+ {"role": "system", "content": SYSTEM_PROMPT},
83
+ {"role": "user", "content": prompt},
84
+ ],
85
+ "temperature": 0.1,
86
+ },
87
+ timeout=30,
88
+ )
89
+
90
+ response.raise_for_status()
91
+ return response.json()["choices"][0]["message"]["content"].strip()
92
+
93
+
94
  # ==================================================
95
  # MAIN CHAT FUNCTION
96
  # ==================================================
 
105
  input_lower = user_input.lower()
106
  text_keywords = ["fever", "headache", "cough", "pain", "vomiting", "chills"]
107
 
 
108
  tool_results = []
109
 
110
  # -------------------------
 
113
  if any(k in input_lower for k in text_keywords):
114
  try:
115
  symptom_result = analyze_symptom_text.invoke(user_input)
 
116
  tool_results.append(symptom_result)
117
+ except Exception:
118
+ tool_results.append("TEXT TOOL FAILED")
119
 
120
  # -------------------------
121
  # RAG retrieval
122
  # -------------------------
123
  try:
124
  rag_result = get_rag().getRelevantDocs(user_input)
 
125
  tool_results.append(rag_result)
126
+ except Exception:
127
+ tool_results.append("RAG FAILED")
128
 
129
  tool_results_text = "\n".join(map(str, tool_results))
130
 
131
  # Fallback if tools fail
132
  if any("FAILED" in str(r) for r in tool_results):
133
+ return (
134
+ "[TOOLS USED] Tools failed - Network issue\n"
135
+ f"[SYMPTOMS] {user_input}\n"
136
+ "[PRIMARY DIAGNOSIS] Possible viral fever/infection\n"
137
+ "[DIAGNOSIS DESCRIPTION] Fever+chills suggests infection.\n"
138
+ "[FIRST AID] Rest, hydrate, paracetamol.\n"
139
+ "[EMERGENCY] No"
140
+ )
 
 
 
141
 
142
+ final_prompt = f"""
143
  TOOL RESULTS:
144
  {tool_results_text}
145
 
146
+ USER INPUT:
147
+ {user_input}
148
+
149
  Provide diagnosis:
150
  """
151
 
152
  try:
153
+ return call_groq(final_prompt)
 
154
  except Exception as e:
155
+ return (
156
+ "⚠️ Temporary AI service issue.\n\n"
157
+ "Please try again in a moment."
158
+ )