File size: 3,591 Bytes
1786f57
c4bf66f
 
 
 
 
 
 
 
 
 
 
 
1786f57
 
c4bf66f
 
1786f57
 
c4bf66f
 
 
 
 
 
 
 
 
 
 
 
1786f57
c4bf66f
 
 
1786f57
c4bf66f
 
 
 
 
 
 
 
 
 
1786f57
c4bf66f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# app.py
import asyncio, re
from pathlib import Path

import streamlit as st
import pandas as pd
import plotly.express as px
from fpdf import FPDF
from streamlit_agraph import agraph

from mcp.orchestrator    import orchestrate_search, answer_ai_question
from mcp.knowledge_graph import build_agraph
from mcp.graph_metrics   import build_nx, get_top_hubs, get_density

st.set_page_config(layout="wide", page_title="MedGenesis AI")
if "res" not in st.session_state:
    st.session_state.res = None

st.title("🧬 MedGenesis AI")
llm   = st.radio("LLM engine", ["openai","gemini"], horizontal=True)
query= st.text_input("Enter biomedical question")

def _make_pdf(papers):
    pdf = FPDF(); pdf.add_page(); pdf.set_font("Helvetica",size=12)
    pdf.cell(0,10,"MedGenesis AI – Results",ln=True,align="C"); pdf.ln(5)
    for i,p in enumerate(papers,1):
        pdf.set_font("Helvetica","B",11); pdf.multi_cell(0,7,f"{i}. {p.get('title','')}")
        pdf.set_font("Helvetica",size=9)
        body = f"{p.get('authors','')}\n{p.get('summary','')}\n{p.get('link','')}"
        pdf.multi_cell(0,6,body); pdf.ln(3)
    return pdf.output(dest="S").encode("latin-1",errors="replace")

if st.button("Run Search πŸš€") and query:
    with st.spinner("Gathering data…"):
        st.session_state.res = asyncio.run(orchestrate_search(query, llm))
res = st.session_state.res

if not res:
    st.info("Enter a query and press Run Search")
    st.stop()

# ── Results tab
tabs = st.tabs(["Results","Graph","Variants","Trials","Metrics","Visuals"])
with tabs[0]:
    for i,p in enumerate(res["papers"],1):
        st.markdown(f"**{i}. [{p['title']}]({p['link']})**")
        st.write(p["summary"])
    c1,c2 = st.columns(2)
    c1.download_button("CSV", pd.DataFrame(res["papers"]).to_csv(index=False),
                       "papers.csv","text/csv")
    c2.download_button("PDF", _make_pdf(res["papers"]),
                       "papers.pdf","application/pdf")
    st.subheader("AI summary"); st.info(res["ai_summary"])

# ── Graph tab
with tabs[1]:
    nodes,edges,cfg = build_agraph(
        res["papers"], res["umls"], res["drug_safety"], res["umls_relations"]
    )
    hl = st.text_input("Highlight node:", key="hl")
    if hl:
        pat = re.compile(re.escape(hl), re.I)
        for n in nodes:
            n.color = "#f1c40f" if pat.search(n.label) else n.color
    agraph(nodes, edges, cfg)

# ── Variants tab
with tabs[2]:
    if res["variants"]:
        st.json(res["variants"])
    else:
        st.warning("No variants found. Try β€˜TP53’ or β€˜BRCA1’.")

# ── Trials tab
with tabs[3]:
    if res["clinical_trials"]:
        st.json(res["clinical_trials"])
    else:
        st.warning("No trials found. Try a disease or drug.")

# ── Metrics tab
with tabs[4]:
    G = build_nx([n.__dict__ for n in nodes],[e.__dict__ for e in edges])
    st.metric("Density", f"{get_density(G):.3f}")
    st.markdown("**Top hubs**")
    for nid,sc in get_top_hubs(G):
        lbl = next((n.label for n in nodes if n.id==nid), nid)
        st.write(f"- {lbl}: {sc:.3f}")

# ── Visuals tab
with tabs[5]:
    yrs = [p.get("published","")[:4] for p in res["papers"] if p.get("published")]
    if yrs:
        st.plotly_chart(px.histogram(yrs,nbins=10,title="Publication Year"))

# ── Follow-up QA
st.markdown("---")
q = st.text_input("Ask follow-up question:", key="followup_input")
if st.button("Ask AI"):
    with st.spinner("Querying LLM…"):
        ans = asyncio.run(answer_ai_question(
            q, context=res["ai_summary"], llm=llm))
        st.write(ans["answer"])