Saicharan21 commited on
Commit
5ff3012
·
verified ·
1 Parent(s): 2ddb9a9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -139
app.py CHANGED
@@ -24,170 +24,65 @@ def search_pubmed(query, n=3):
24
  )
25
  ids = r.json()["esearchresult"]["idlist"]
26
  if not ids:
27
- return [], ""
28
- r2 = requests.get(
29
- "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi",
30
- params={"db":"pubmed","id":",".join(ids),"retmode":"xml","rettype":"abstract"},
31
- timeout=10
32
- )
33
- import xmltodict
34
- data = xmltodict.parse(r2.content)
35
- articles = data.get("PubmedArticleSet",{}).get("PubmedArticle",[])
36
- if isinstance(articles, dict):
37
- articles = [articles]
38
- real_links = []
39
- context = ""
40
- for a in articles[:n]:
41
- try:
42
- c = a["MedlineCitation"]
43
- title = str(c["Article"]["ArticleTitle"])
44
- abstract = c["Article"].get("Abstract",{}).get("AbstractText","")
45
- if isinstance(abstract, list):
46
- abstract = " ".join([str(x) for x in abstract])
47
- if isinstance(abstract, dict):
48
- abstract = str(abstract.get("#text",""))
49
- pmid = str(c["PMID"]["#text"] if isinstance(c["PMID"],dict) else c["PMID"])
50
- url = "https://pubmed.ncbi.nlm.nih.gov/" + pmid
51
- real_links.append("- " + title[:100] + "\n " + url)
52
- context += "[PubMed:" + pmid + "] " + title + ". " + str(abstract)[:300] + "\n"
53
- except:
54
- continue
55
- return real_links, context
56
  except:
57
- return [], ""
58
 
59
  def search_scholar(query, n=3):
60
  try:
61
  r = requests.get(
62
  "https://api.semanticscholar.org/graph/v1/paper/search",
63
- params={"query":query,"limit":n,"fields":"title,abstract,year,url"},
64
  timeout=10
65
  )
66
  papers = r.json().get("data",[])
67
- real_links = []
68
- context = ""
69
  for p in papers:
70
  title = p.get("title","")
71
- abstract = (p.get("abstract") or "")[:300]
72
  year = str(p.get("year",""))
73
  url = p.get("url","")
74
  if url:
75
- real_links.append("- " + title[:100] + " (" + year + ")\n " + url)
76
- context += "[Scholar " + year + "] " + title + ". " + abstract + "\n"
77
- return real_links, context
78
  except:
79
- return [], ""
80
 
81
  def ask_with_memory(message, history):
82
  if not GROQ_KEY:
83
  return "Error: GROQ_API_KEY not set in Space secrets."
84
-
85
  try:
86
  from groq import Groq
87
  client = Groq(api_key=GROQ_KEY)
88
- except Exception as e:
89
- return "Error loading Groq: " + str(e)
90
-
91
- messages = [
92
- {
93
- "role": "system",
94
- "content": "You are CardioLab AI built on Biomni from Stanford SNAP Lab. Expert in SJSU Biomedical Engineering. NEVER invent paper titles or URLs. Only cite papers from search results.\n\nCARDIOLAB KNOW-HOW:\n" + KNOWHOW
95
- }
96
- ]
97
-
98
- for msg in history:
99
- if isinstance(msg, dict):
100
- messages.append({"role": msg["role"], "content": msg["content"]})
101
-
102
- cardio_query = message + " mechanical heart valve OR microfluidic OR CKD creatinine OR PIV OR thrombogenicity"
103
- pubmed_links, pubmed_context = search_pubmed(cardio_query, n=3)
104
- scholar_links, scholar_context = search_scholar(message + " biomedical", n=3)
105
- sources = pubmed_context + scholar_context
106
-
107
- messages.append({
108
- "role": "user",
109
- "content": message + "\n\nReal papers found (ONLY use these):\n" + sources[:3000]
110
- })
111
-
112
- try:
113
  response = client.chat.completions.create(
114
  model="llama-3.3-70b-versatile",
115
  messages=messages,
116
- max_tokens=800
117
  )
118
  answer = response.choices[0].message.content
 
 
 
 
 
 
119
  except Exception as e:
120
- return "Error from Groq: " + str(e)
121
-
122
- links = ""
123
- if pubmed_links:
124
- links += "\n\n📚 VERIFIED PUBMED LINKS:\n" + "\n".join(pubmed_links[:3])
125
- if scholar_links:
126
- links += "\n\n🎓 VERIFIED SCHOLAR LINKS:\n" + "\n".join(scholar_links[:3])
127
-
128
- return answer + links
129
-
130
- def piv_tool(velocity, shear, hr):
131
- v = "HIGH - stenosis risk" if float(velocity) > 2.0 else "NORMAL"
132
- s = "HIGH - thrombosis risk" if float(shear) > 10 else "ELEVATED - monitor" if float(shear) > 5 else "NORMAL"
133
- return "Velocity: " + str(velocity) + " m/s - " + v + "\nShear: " + str(shear) + " Pa - " + s + "\nHeart Rate: " + str(hr) + " bpm"
134
-
135
- def tgt_tool(tat, pf12, hemo, platelets, time):
136
- risk = sum([float(tat)>15, float(pf12)>2.0, float(hemo)>50, float(platelets)<150])
137
- overall = "HIGH THROMBOGENIC RISK" if risk>=3 else "MODERATE RISK" if risk>=2 else "LOW RISK"
138
- return "TAT:" + str(tat) + " PF1.2:" + str(pf12) + " Hemo:" + str(hemo) + " Platelets:" + str(platelets) + "\nTime:" + str(time) + " min\nResult: " + overall
139
-
140
- def upad_tool(r, g, b):
141
- creatinine = max(0, round(0.02*(float(r)-float(b))-0.5, 2))
142
- stage = "Normal" if creatinine<1.2 else "Borderline" if creatinine<1.5 else "Stage 2 CKD" if creatinine<3.0 else "Stage 3-4 CKD" if creatinine<6.0 else "Stage 5 CKD"
143
- return "Creatinine: " + str(creatinine) + " mg/dL\nStage: " + stage + "\nConfirm with: Heska Element HT5"
144
-
145
- def respond(message, history):
146
- bot_message = ask_with_memory(message, history)
147
- history.append({"role": "user", "content": message})
148
- history.append({"role": "assistant", "content": bot_message})
149
- return "", history
150
-
151
- with gr.Blocks(title="CardioLab AI - SJSU") as demo:
152
- gr.Markdown("# CardioLab AI Agent")
153
- gr.Markdown("### SJSU Biomedical Engineering | Biomni + Llama 70B + Chat Memory + PubMed")
154
- gr.Markdown("GitHub: github.com/pranatechsol/Cardio-Lab-Ai")
155
-
156
- with gr.Tab("Research Chat"):
157
- gr.Markdown("### Chat with memory — like ChatGPT but for CardioLab research")
158
- chatbot = gr.Chatbot(label="CardioLab AI", height=500, type="messages")
159
- msg = gr.Textbox(label="Your message", placeholder="Ask anything about CardioLab research...", lines=2)
160
- with gr.Row():
161
- send = gr.Button("Send", variant="primary")
162
- clear = gr.Button("Clear Chat")
163
- send.click(respond, inputs=[msg, chatbot], outputs=[msg, chatbot])
164
- msg.submit(respond, inputs=[msg, chatbot], outputs=[msg, chatbot])
165
- clear.click(lambda: [], None, chatbot)
166
-
167
- with gr.Tab("PIV Analysis"):
168
- gr.Markdown("### Analyze PIV flow data from Mock Circulatory Loop")
169
- v = gr.Number(label="Max Velocity m/s", value=1.8)
170
- s = gr.Number(label="Shear Stress Pa", value=6.5)
171
- h = gr.Number(label="Heart Rate bpm", value=72)
172
- out = gr.Textbox(label="Result", lines=4)
173
- gr.Button("Analyze PIV").click(piv_tool, inputs=[v,s,h], outputs=out)
174
-
175
- with gr.Tab("TGT Results"):
176
- gr.Markdown("### Interpret Thrombogenicity Tester blood results")
177
- t1 = gr.Number(label="TAT", value=18)
178
- t2 = gr.Number(label="PF1.2", value=2.5)
179
- t3 = gr.Number(label="Free Hemoglobin mg/L", value=60)
180
- t4 = gr.Number(label="Platelet Count", value=140)
181
- t5 = gr.Number(label="Time minutes", value=40)
182
- out2 = gr.Textbox(label="Result", lines=5)
183
- gr.Button("Analyze TGT").click(tgt_tool, inputs=[t1,t2,t3,t4,t5], outputs=out2)
184
-
185
- with gr.Tab("uPAD CKD"):
186
- gr.Markdown("### Analyze uPAD colorimetric result - Jaffe Reaction")
187
- r = gr.Number(label="R value", value=210)
188
- g = gr.Number(label="G value", value=140)
189
- b = gr.Number(label="B value", value=80)
190
- out3 = gr.Textbox(label="Result", lines=4)
191
- gr.Button("Analyze uPAD").click(upad_tool, inputs=[r,g,b], outputs=out3)
192
-
193
- demo.launch()
 
24
  )
25
  ids = r.json()["esearchresult"]["idlist"]
26
  if not ids:
27
+ return ""
28
+ links = []
29
+ for pmid in ids[:n]:
30
+ links.append("https://pubmed.ncbi.nlm.nih.gov/" + pmid)
31
+ return "PubMed results: " + " | ".join(links)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  except:
33
+ return ""
34
 
35
  def search_scholar(query, n=3):
36
  try:
37
  r = requests.get(
38
  "https://api.semanticscholar.org/graph/v1/paper/search",
39
+ params={"query":query,"limit":n,"fields":"title,year,url"},
40
  timeout=10
41
  )
42
  papers = r.json().get("data",[])
43
+ out = []
 
44
  for p in papers:
45
  title = p.get("title","")
 
46
  year = str(p.get("year",""))
47
  url = p.get("url","")
48
  if url:
49
+ out.append(title[:80] + " (" + year + ") - " + url)
50
+ return "\n".join(out)
 
51
  except:
52
+ return ""
53
 
54
  def ask_with_memory(message, history):
55
  if not GROQ_KEY:
56
  return "Error: GROQ_API_KEY not set in Space secrets."
 
57
  try:
58
  from groq import Groq
59
  client = Groq(api_key=GROQ_KEY)
60
+ messages = [
61
+ {
62
+ "role": "system",
63
+ "content": "You are CardioLab AI built on Biomni from Stanford. Expert in SJSU Biomedical Engineering. Remember the full conversation. NEVER invent paper URLs.\n\n" + KNOWHOW
64
+ }
65
+ ]
66
+ for msg in history:
67
+ if isinstance(msg, dict):
68
+ messages.append({"role": msg["role"], "content": msg["content"]})
69
+ pubmed = search_pubmed(message, n=3)
70
+ scholar = search_scholar(message + " biomedical", n=3)
71
+ messages.append({
72
+ "role": "user",
73
+ "content": message + "\n\nVerified paper links found:\n" + pubmed + "\n" + scholar
74
+ })
 
 
 
 
 
 
 
 
 
 
75
  response = client.chat.completions.create(
76
  model="llama-3.3-70b-versatile",
77
  messages=messages,
78
+ max_tokens=600
79
  )
80
  answer = response.choices[0].message.content
81
+ links = ""
82
+ if pubmed:
83
+ links += "\n\n📚 VERIFIED PUBMED: " + pubmed
84
+ if scholar:
85
+ links += "\n\n🎓 VERIFIED SCHOLAR:\n" + scholar
86
+ return answer + links
87
  except Exception as e:
88
+ return