Saicharan21 commited on
Commit
cc2da46
·
verified ·
1 Parent(s): 2a92bf6

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +80 -41
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import gradio as gr
2
- import os, requests
3
  from groq import Groq
 
4
 
5
  GROQ_KEY = os.environ.get("GROQ_API_KEY","")
6
  client = Groq(api_key=GROQ_KEY)
@@ -14,9 +15,10 @@ FSI: COMSOL ALE mesh, blood 1060 kg/m3, 0.0035 Pa.s, St Jude geometry
14
  MHV: 27mm SJM Regent, bileaflet trileaflet monoleaflet pediatric
15
  CKD Stages: 1 below 1.5, 2 1.5-3.0, 3-4 3.0-6.0, 5 above 6.0 mg/dL
16
  Equipment: Heska HT5, time-resolved PIV, Tygon tubing, Arduino
 
17
  """
18
 
19
- def search_pubmed(query, n=5):
20
  try:
21
  r = requests.get("https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi",
22
  params={"db":"pubmed","term":query,"retmax":n,"retmode":"json","sort":"date"}, timeout=10)
@@ -39,13 +41,13 @@ def search_pubmed(query, n=5):
39
  if isinstance(abstract, dict): abstract = str(abstract.get("#text",""))
40
  pmid = str(c["PMID"]["#text"] if isinstance(c["PMID"],dict) else c["PMID"])
41
  real_url = "https://pubmed.ncbi.nlm.nih.gov/" + pmid
42
- real_links.append("- " + title[:100] + "\n URL: " + real_url)
43
- context += "[PubMed PMID:" + pmid + "] " + title + ". " + str(abstract)[:300] + "\n\n"
44
  except: continue
45
  return real_links, context
46
  except: return [], ""
47
 
48
- def search_scholar(query, n=5):
49
  try:
50
  r = requests.get("https://api.semanticscholar.org/graph/v1/paper/search",
51
  params={"query":query,"limit":n,"fields":"title,abstract,year,url"}, timeout=10)
@@ -58,50 +60,64 @@ def search_scholar(query, n=5):
58
  year = str(p.get("year",""))
59
  url = p.get("url","")
60
  if url:
61
- real_links.append("- " + title[:100] + " (" + year + ")\n URL: " + url)
62
- context += "[Scholar " + year + "] " + title + ". " + abstract + "\n\n"
63
  return real_links, context
64
  except: return [], ""
65
 
66
- def ask_agent(question):
67
  if not GROQ_KEY:
68
- return "Error: GROQ_API_KEY not set in Space secrets."
69
 
70
- cardio_query = question + " mechanical heart valve OR microfluidic creatinine OR PIV hemodynamics OR thrombogenicity"
71
-
72
- pubmed_links, pubmed_context = search_pubmed(cardio_query, n=5)
73
- scholar_links, scholar_context = search_scholar(question + " biomedical", n=5)
 
 
 
 
 
 
74
 
75
- all_context = pubmed_context + scholar_context
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
  response = client.chat.completions.create(
78
  model="llama-3.3-70b-versatile",
79
- messages=[
80
- {"role":"system","content":"""You are CardioLab AI built on Biomni from Stanford SNAP Lab.
81
- Expert in SJSU Biomedical Engineering research.
82
- IMPORTANT RULES:
83
- 1. NEVER invent or generate paper titles or URLs
84
- 2. ONLY refer to papers provided in the context below
85
- 3. Always say which source you are using
86
- 4. If you do not know something say so clearly
87
-
88
- CARDIOLAB KNOW-HOW:
89
- """ + KNOWHOW},
90
- {"role":"user","content":"Research question: " + question + "\n\nReal papers found (use ONLY these):\n" + all_context[:4000] + "\n\nAnswer the question using only the above sources."}
91
- ],
92
- max_tokens=600
93
  )
94
 
95
  answer = response.choices[0].message.content
96
 
97
- # Add REAL links section — only verified URLs
98
- real_links_section = ""
99
  if pubmed_links:
100
- real_links_section += "\n\n📚 VERIFIED PUBMED LINKS:\n" + "\n".join(pubmed_links[:5])
101
  if scholar_links:
102
- real_links_section += "\n\n🎓 VERIFIED SCHOLAR LINKS:\n" + "\n".join(scholar_links[:5])
103
 
104
- return answer + real_links_section
105
 
106
  def piv_tool(velocity, shear, hr):
107
  v = "HIGH - stenosis risk" if float(velocity)>2.0 else "NORMAL"
@@ -111,7 +127,7 @@ def piv_tool(velocity, shear, hr):
111
  def tgt_tool(tat, pf12, hemo, platelets, time):
112
  risk = sum([float(tat)>15, float(pf12)>2.0, float(hemo)>50, float(platelets)<150])
113
  overall = "HIGH THROMBOGENIC RISK" if risk>=3 else "MODERATE RISK" if risk>=2 else "LOW RISK"
114
- return "TAT:"+str(tat)+" PF1.2:"+str(pf12)+" Hemo:"+str(hemo)+" Platelets:"+str(platelets)+"\nTime: "+str(time)+" min\nResult: "+overall
115
 
116
  def upad_tool(r, g, b):
117
  creatinine = max(0, round(0.02*(float(r)-float(b))-0.5, 2))
@@ -120,13 +136,34 @@ def upad_tool(r, g, b):
120
 
121
  with gr.Blocks(title="CardioLab AI - SJSU") as demo:
122
  gr.Markdown("# CardioLab AI Agent")
123
- gr.Markdown("### SJSU Biomedical Engineering | Biomni + Llama 70B + PubMed + Semantic Scholar")
124
- gr.Markdown("**All paper links are verified real URLs only** | GitHub: github.com/pranatechsol/Cardio-Lab-Ai")
125
- with gr.Tab("Research Assistant"):
126
- gr.Markdown("### Searches PubMed + Semantic Scholar — only real verified links")
127
- q = gr.Textbox(label="Research question", placeholder="e.g. Methods for MHV thrombogenicity detection")
128
- a = gr.Textbox(label="Answer with verified citations", lines=14)
129
- gr.Button("Search & Answer").click(ask_agent, inputs=q, outputs=a)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  with gr.Tab("PIV Analysis"):
131
  gr.Markdown("### Analyze PIV flow data from Mock Circulatory Loop")
132
  v = gr.Number(label="Max Velocity m/s", value=1.8)
@@ -134,6 +171,7 @@ with gr.Blocks(title="CardioLab AI - SJSU") as demo:
134
  h = gr.Number(label="Heart Rate bpm", value=72)
135
  out = gr.Textbox(label="Result", lines=4)
136
  gr.Button("Analyze PIV").click(piv_tool, inputs=[v,s,h], outputs=out)
 
137
  with gr.Tab("TGT Results"):
138
  gr.Markdown("### Interpret Thrombogenicity Tester blood results")
139
  t1 = gr.Number(label="TAT", value=18)
@@ -143,6 +181,7 @@ with gr.Blocks(title="CardioLab AI - SJSU") as demo:
143
  t5 = gr.Number(label="Time minutes", value=40)
144
  out2 = gr.Textbox(label="Result", lines=5)
145
  gr.Button("Analyze TGT").click(tgt_tool, inputs=[t1,t2,t3,t4,t5], outputs=out2)
 
146
  with gr.Tab("uPAD CKD"):
147
  gr.Markdown("### Analyze uPAD colorimetric result - Jaffe Reaction")
148
  r = gr.Number(label="R value", value=210)
 
1
  import gradio as gr
2
+ import os, requests, json
3
  from groq import Groq
4
+ from datetime import datetime
5
 
6
  GROQ_KEY = os.environ.get("GROQ_API_KEY","")
7
  client = Groq(api_key=GROQ_KEY)
 
15
  MHV: 27mm SJM Regent, bileaflet trileaflet monoleaflet pediatric
16
  CKD Stages: 1 below 1.5, 2 1.5-3.0, 3-4 3.0-6.0, 5 above 6.0 mg/dL
17
  Equipment: Heska HT5, time-resolved PIV, Tygon tubing, Arduino
18
+ 13 Projects: MCL/PIV, TGT, FSI simulation, uPAD CKD diagnostics
19
  """
20
 
21
+ def search_pubmed(query, n=3):
22
  try:
23
  r = requests.get("https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi",
24
  params={"db":"pubmed","term":query,"retmax":n,"retmode":"json","sort":"date"}, timeout=10)
 
41
  if isinstance(abstract, dict): abstract = str(abstract.get("#text",""))
42
  pmid = str(c["PMID"]["#text"] if isinstance(c["PMID"],dict) else c["PMID"])
43
  real_url = "https://pubmed.ncbi.nlm.nih.gov/" + pmid
44
+ real_links.append("- " + title[:100] + "\n " + real_url)
45
+ context += "[PubMed:" + pmid + "] " + title + ". " + str(abstract)[:300] + "\n"
46
  except: continue
47
  return real_links, context
48
  except: return [], ""
49
 
50
+ def search_scholar(query, n=3):
51
  try:
52
  r = requests.get("https://api.semanticscholar.org/graph/v1/paper/search",
53
  params={"query":query,"limit":n,"fields":"title,abstract,year,url"}, timeout=10)
 
60
  year = str(p.get("year",""))
61
  url = p.get("url","")
62
  if url:
63
+ real_links.append("- " + title[:100] + " (" + year + ")\n " + url)
64
+ context += "[Scholar " + year + "] " + title + ". " + abstract + "\n"
65
  return real_links, context
66
  except: return [], ""
67
 
68
+ def ask_with_memory(message, history):
69
  if not GROQ_KEY:
70
+ return "Error: GROQ_API_KEY not set."
71
 
72
+ # Build full conversation history for memory
73
+ messages = [
74
+ {
75
+ "role": "system",
76
+ "content": """You are CardioLab AI built on Biomni from Stanford SNAP Lab.
77
+ Expert in SJSU Biomedical Engineering research.
78
+ You remember everything said in this conversation.
79
+ NEVER invent paper titles or URLs.
80
+ ONLY cite papers from the search results provided.
81
+ Always be helpful, detailed and accurate.
82
 
83
+ CARDIOLAB KNOW-HOW:
84
+ """ + KNOWHOW
85
+ }
86
+ ]
87
+
88
+ # Add full chat history so it remembers previous messages
89
+ for human_msg, ai_msg in history:
90
+ messages.append({"role": "user", "content": human_msg})
91
+ messages.append({"role": "assistant", "content": ai_msg})
92
+
93
+ # Search for relevant papers
94
+ cardio_query = message + " mechanical heart valve OR microfluidic OR CKD creatinine OR PIV OR thrombogenicity"
95
+ pubmed_links, pubmed_context = search_pubmed(cardio_query, n=3)
96
+ scholar_links, scholar_context = search_scholar(message + " biomedical", n=3)
97
+ sources = pubmed_context + scholar_context
98
+
99
+ # Add current question with search results
100
+ messages.append({
101
+ "role": "user",
102
+ "content": message + "\n\nReal papers found (ONLY use these, do not invent):\n" + sources[:3000]
103
+ })
104
 
105
  response = client.chat.completions.create(
106
  model="llama-3.3-70b-versatile",
107
+ messages=messages,
108
+ max_tokens=800
 
 
 
 
 
 
 
 
 
 
 
 
109
  )
110
 
111
  answer = response.choices[0].message.content
112
 
113
+ # Add verified links
114
+ links = ""
115
  if pubmed_links:
116
+ links += "\n\n📚 VERIFIED PUBMED LINKS:\n" + "\n".join(pubmed_links[:3])
117
  if scholar_links:
118
+ links += "\n\n🎓 VERIFIED SCHOLAR LINKS:\n" + "\n".join(scholar_links[:3])
119
 
120
+ return answer + links
121
 
122
  def piv_tool(velocity, shear, hr):
123
  v = "HIGH - stenosis risk" if float(velocity)>2.0 else "NORMAL"
 
127
  def tgt_tool(tat, pf12, hemo, platelets, time):
128
  risk = sum([float(tat)>15, float(pf12)>2.0, float(hemo)>50, float(platelets)<150])
129
  overall = "HIGH THROMBOGENIC RISK" if risk>=3 else "MODERATE RISK" if risk>=2 else "LOW RISK"
130
+ return "TAT:"+str(tat)+" PF1.2:"+str(pf12)+" Hemo:"+str(hemo)+" Platelets:"+str(platelets)+"\nTime:"+str(time)+"min\nResult: "+overall
131
 
132
  def upad_tool(r, g, b):
133
  creatinine = max(0, round(0.02*(float(r)-float(b))-0.5, 2))
 
136
 
137
  with gr.Blocks(title="CardioLab AI - SJSU") as demo:
138
  gr.Markdown("# CardioLab AI Agent")
139
+ gr.Markdown("### SJSU Biomedical Engineering | Biomni + Llama 70B + Chat Memory + PubMed")
140
+ gr.Markdown("GitHub: github.com/pranatechsol/Cardio-Lab-Ai")
141
+
142
+ with gr.Tab("Research Chat"):
143
+ gr.Markdown("### Chat with memory remembers your full conversation like ChatGPT")
144
+ chatbot = gr.Chatbot(
145
+ label="CardioLab AI",
146
+ height=500,
147
+ show_label=True
148
+ )
149
+ msg = gr.Textbox(
150
+ label="Your message",
151
+ placeholder="Ask anything about CardioLab research... I remember our full conversation!",
152
+ lines=2
153
+ )
154
+ with gr.Row():
155
+ send = gr.Button("Send", variant="primary")
156
+ clear = gr.Button("Clear Chat")
157
+
158
+ def respond(message, chat_history):
159
+ bot_message = ask_with_memory(message, chat_history)
160
+ chat_history.append((message, bot_message))
161
+ return "", chat_history
162
+
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)
 
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)
 
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)