File size: 8,962 Bytes
b171cab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import os, json, streamlit as st
from backend.rag_engine import get_embedder, get_chroma, retrieve, seed_index
from backend.soap_generator import compose_soap
from backend.pdf_utils import generate_pdf
from backend.chat_textgen import chat
from utils.constants import DOCS_DIR, RETRIEVAL_K_DEFAULT

st.set_page_config(
    page_title="MediAssist β€” Clinical Decision Support",
    page_icon="🩺",
    layout="wide",
    initial_sidebar_state="expanded"
)

@st.cache_resource(show_spinner=False)
def _embedder(): 
    return get_embedder()

@st.cache_resource(show_spinner=False)
def _col(): 
    return get_chroma()[1]

# Sidebar Configuration
with st.sidebar:
    st.markdown("## βš™οΈ Configuration")
    
    with st.expander("RAG Index Management", expanded=False):
        if st.button("πŸ”„ Seed / Refresh RAG Index"):
            with st.spinner("Indexing medical guidelines..."):
                try:
                    n = seed_index(_col(), _embedder(), DOCS_DIR)
                    st.success(f"βœ… Indexed {n} chunks from {DOCS_DIR}")
                except Exception as e:
                    st.error(f"❌ Indexing failed: {str(e)}")
        st.caption("Upload .txt/.md files to `data/guidelines/<specialty>/` then reseed.")
    
    st.divider()
    st.markdown("### About")
    st.info(
        "**MediAssist v15** combines clinical guidelines with AI to provide "
        "evidence-based decision support for healthcare professionals."
    )
    
    with st.expander("Features", expanded=False):
        st.markdown("""

        - πŸ“š RAG-based guideline retrieval

        - πŸ€– SOAP note generation

        - πŸ’¬ Context-aware AI chat

        - πŸ“„ PDF report generation

        """)

# Main Content
st.title("🩺 MediAssist β€” Clinical Decision Support System")
st.markdown(
    "AI-powered clinical guidelines with **RAG** β€’ **SOAP** β€’ **Chat** β€’ **PDF Reports**"
)

# Main Input Section
st.markdown("### πŸ“ Patient Information")
narrative = st.text_area(
    "Patient Narrative",
    height=120,
    placeholder="e.g., 32-year-old female with 10 days of period delay, nausea, mild cramps. No fever. Medical history: PCOS.",
    help="Describe the patient's presenting complaint and relevant history"
)

col1, col2 = st.columns([3, 1])
with col1:
    k = st.slider(
        "Number of guidelines to retrieve",
        min_value=1,
        max_value=10,
        value=RETRIEVAL_K_DEFAULT,
        help="More results = more comprehensive but potentially noisy"
    )
with col2:
    st.metric("Retrieval K", k)

st.divider()

# Create Tabs for Different Functions
tab1, tab2, tab3, tab4 = st.tabs(["πŸ“Š SOAP Note", "πŸ’¬ AI Chat", "πŸ“„ PDF Report", "πŸ“š Guidelines"])

# Tab 1: SOAP Note Generation
with tab1:
    st.markdown("### Generate SOAP Note with Clinical Evidence")
    
    col_soap1, col_soap2 = st.columns(2)
    
    if st.button("🧾 Generate SOAP Note", key="soap_button"):
        if not narrative.strip():
            st.warning("⚠️ Please enter patient narrative first.")
        else:
            with st.spinner("Retrieving relevant guidelines..."):
                try:
                    items = retrieve(_col(), _embedder(), narrative, k=k)
                    soap = compose_soap(narrative, items)
                    
                    with col_soap1:
                        st.subheader("SOAP Note (JSON)")
                        st.code(json.dumps(soap, indent=2), language="json")
                        
                        # Copy button helper
                        st.caption("πŸ’‘ Tip: Use the copy button in the code block to copy the JSON")
                    
                    with col_soap2:
                        st.subheader(f"πŸ“š Citations ({len(items)} sources)")
                        if not items:
                            st.info("No relevant guidelines found.")
                        else:
                            for i, it in enumerate(items, 1):
                                with st.container(border=True):
                                    st.markdown(f"**Source {i}: {it.get('title', 'Unknown')}**")
                                    st.caption(f"πŸ“– {it.get('source', 'N/A')}")
                                    st.markdown(f"> {it.get('text', '')[:350]}...")
                
                except Exception as e:
                    st.error(f"❌ Error generating SOAP note: {str(e)}")

# Tab 2: AI Chat
with tab2:
    st.markdown("### Conversational AI Assistant")
    
    col_chat1, col_chat2 = st.columns([1, 1])
    
    with col_chat1:
        mode = st.radio(
            "Chat Mode",
            ["Patient-facing explanation", "Doctor-facing analysis"],
            help="Choose audience for AI response"
        )
    
    if st.button("πŸ’¬ Start Chat Session", key="chat_button"):
        if not narrative.strip():
            st.warning("⚠️ Please enter patient narrative first.")
        else:
            with st.spinner("AI is thinking..."):
                try:
                    reply = chat(
                        narrative,
                        mode="patient" if "Patient" in mode else "doctor"
                    )
                    st.markdown("### AI Response")
                    st.markdown(reply)
                except Exception as e:
                    st.error(f"❌ Chat error: {str(e)}")

# Tab 3: PDF Report
with tab3:
    st.markdown("### Generate Clinical PDF Report")
    
    col_pdf1, col_pdf2 = st.columns([2, 1])
    
    with col_pdf1:
        ai_summary = st.text_area(
            "Doctor-Reviewed Summary",
            height=100,
            placeholder="Enter clinical summary, assessment, and plan...",
            help="This will be included in the PDF report"
        )
    
    with col_pdf2:
        report_name = st.text_input(
            "Report Filename",
            value="MediAssist_Report",
            help="PDF will be saved as [filename].pdf"
        )
    
    if st.button("πŸ“„ Generate PDF Report", key="pdf_button"):
        if not narrative.strip():
            st.warning("⚠️ Please enter patient narrative first.")
        else:
            with st.spinner("Generating PDF..."):
                try:
                    items = retrieve(_col(), _embedder(), narrative, k=3)
                    soap = compose_soap(narrative, items)
                    pdf_path = f"{report_name}.pdf"
                    
                    generate_pdf(
                        pdf_path,
                        "MediAssist β€” Clinical Report",
                        soap,
                        ai_summary
                    )
                    
                    with open(pdf_path, "rb") as pdf_file:
                        st.download_button(
                            label="⬇️ Download PDF Report",
                            data=pdf_file,
                            file_name=pdf_path,
                            mime="application/pdf",
                            key="pdf_download"
                        )
                    st.success("βœ… PDF generated successfully!")
                    
                except Exception as e:
                    st.error(f"❌ PDF generation error: {str(e)}")

# Tab 4: Guidelines Browse
with tab4:
    st.markdown("### Browse Medical Guidelines")
    
    if st.button("πŸ“š Load Available Guidelines", key="guidelines_button"):
        with st.spinner("Loading guidelines..."):
            try:
                if os.path.exists(DOCS_DIR):
                    guidelines = []
                    for root, dirs, files in os.walk(DOCS_DIR):
                        for file in files:
                            if file.endswith(('.txt', '.md')):
                                guidelines.append(os.path.join(root, file))
                    
                    if guidelines:
                        st.info(f"Found {len(guidelines)} guidelines")
                        for guideline in sorted(guidelines)[:10]:  # Show first 10
                            st.caption(f"πŸ“„ {os.path.basename(guideline)}")
                    else:
                        st.warning("No guidelines found. Upload files to `data/guidelines/`")
                else:
                    st.error(f"Guidelines directory not found: {DOCS_DIR}")
            except Exception as e:
                st.error(f"❌ Error loading guidelines: {str(e)}")

st.divider()

# Footer
st.markdown("""

---

**Disclaimer:** MediAssist is a decision support tool and does not replace professional clinical judgment. 

Always consult with qualified healthcare professionals for medical decisions.



Made with ❀️ by the MediAssist Team | Deployed on πŸ€— Hugging Face Spaces

""")