mgbam commited on
Commit
5b4c3e2
Β·
verified Β·
1 Parent(s): 81dc1a4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -64
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import streamlit as st
2
  import google.generativeai as genai
3
  import os
@@ -17,7 +18,7 @@ st.markdown(
17
  """
18
  ### Welcome to the AI Clinical Support Demonstrator
19
  This application demonstrates how Generative AI (Google Gemini) can be guided to assist with analyzing clinical information.
20
- - **Agentic Text Analysis:** Simulates a structured reasoning process on clinical text to identify key findings, suggest considerations, and note information gaps.
21
  - **Medical Image Analysis:** Provides descriptive observations of potential anomalies in medical images.
22
 
23
  **Crucially, this tool is for demonstration purposes ONLY. It does NOT provide medical advice or diagnosis.**
@@ -43,11 +44,10 @@ else:
43
  st.error("⚠️ Gemini API Key not found. Please configure `GEMINI_API_KEY` in Streamlit secrets or environment variables.", icon="πŸ”‘")
44
  st.stop()
45
 
46
- # Initialize models
47
  TEXT_MODEL_NAME = 'gemini-1.5-pro-latest' # For agentic text reasoning
48
- VISION_MODEL_NAME = 'gemini-1.5-flash' # For image analysis
49
 
50
- # Use session state to initialize models only once
51
  if 'models_initialized' not in st.session_state:
52
  st.session_state.models_initialized = False
53
  st.session_state.text_model = None
@@ -58,20 +58,17 @@ if genai_client_configured and not st.session_state.models_initialized:
58
  st.session_state.text_model = genai.GenerativeModel(TEXT_MODEL_NAME)
59
  st.session_state.vision_model = genai.GenerativeModel(VISION_MODEL_NAME)
60
  st.session_state.models_initialized = True
61
- # Display success message subtly in sidebar perhaps, or remove if too noisy
62
- # st.sidebar.success("AI Models Ready.", icon="βœ…")
63
  except Exception as e:
64
  st.error(f"Fatal Error: Failed to initialize Gemini models. Text: {TEXT_MODEL_NAME}, Vision: {VISION_MODEL_NAME}. Details: {e}", icon="πŸ’₯")
65
  st.stop()
66
  elif not genai_client_configured:
67
- # Should have stopped already, but defensive check
68
  st.error("AI Models could not be initialized due to configuration issues.", icon="🚫")
69
  st.stop()
70
 
71
 
72
  # --- Core AI Interaction Functions ---
73
 
74
- # Refined AGENTIC prompt for Text Analysis with formatting request
75
  AGENTIC_TEXT_ANALYSIS_PROMPT_TEMPLATE = """
76
  **Simulated Clinical Reasoning Agent Task:**
77
 
@@ -83,26 +80,26 @@ AGENTIC_TEXT_ANALYSIS_PROMPT_TEMPLATE = """
83
 
84
  **Simulated Agentic Steps (Perform sequentially):**
85
 
86
- 1. **Information Extraction & Structuring:**
87
  * Key Demographics (Age, Sex if provided).
88
  * Primary Symptoms/Signs.
89
  * Relevant Medical History.
90
  * Pertinent Negatives (if mentioned).
91
 
92
- 2. **Differential Considerations Generation:**
93
  * Based *only* on Step 1, list **potential differential considerations** (possible conditions).
94
  * **Use cautious language:** "could be consistent with," "warrants consideration," "less likely but possible." **AVOID definitive statements.**
95
  * Briefly justify each consideration based on findings.
96
 
97
- 3. **Information Gap Analysis:**
98
  * Identify critical missing information (e.g., lab results, imaging, exam specifics, duration/onset).
99
 
100
- 4. **Suggested Next Steps for Investigation (for Clinician):**
101
  * Propose logical next steps a **healthcare professional might consider**.
102
  * Categorize (e.g., Further History, Exam Points, Labs, Imaging).
103
  * Frame as *suggestions* (e.g., "Consider ordering...", "Assessment of X may be informative").
104
 
105
- 5. **Mandatory Disclaimer:** Conclude with: "This AI-generated analysis is for informational support only. It is **NOT** a diagnosis and cannot replace the judgment of a qualified healthcare professional."
106
 
107
  **Input Clinical Information:**
108
  ---
@@ -112,21 +109,46 @@ AGENTIC_TEXT_ANALYSIS_PROMPT_TEMPLATE = """
112
  **Agentic Analysis:**
113
  """
114
 
115
- # Refined prompt for Image Analysis with formatting request
116
  IMAGE_ANALYSIS_PROMPT_TEMPLATE = """
117
  **Medical Image Analysis Request:**
118
 
119
- **Context:** Analyze the provided medical image. User may provide additional context or questions.
120
 
121
- **Output Format:** Please structure your response using Markdown headings for each step (e.g., `## 1. Visible Structures`).
122
 
123
  **Task:**
124
 
125
- 1. **Describe Visible Structures:** Briefly describe main anatomical structures.
126
- 2. **Identify Potential Anomalies:** Point out areas that *appear* abnormal or deviate from typical presentation (e.g., "potential opacity," "altered signal intensity," "possible asymmetry"). Use cautious, descriptive language. **This is not a definitive finding.**
127
- 3. **Correlate with User Prompt (if provided):** Address specific user questions based *only* on visual information. State if the image cannot answer the question.
128
- 4. **Limitations:** State that image quality, view, lack of clinical context, and the AI's nature limit analysis.
129
- 5. **Mandatory Disclaimer:** Explicitly state this is AI visual analysis, not radiological interpretation or diagnosis, requiring review by a qualified professional with clinical context.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
  **User's Additional Context/Question (if any):**
132
  ---
@@ -136,68 +158,76 @@ IMAGE_ANALYSIS_PROMPT_TEMPLATE = """
136
  **Image Analysis:**
137
  """
138
 
 
 
139
  def run_agentic_text_analysis(text_input: str) -> Tuple[Optional[str], Optional[str]]:
140
  """Sends clinical text to the configured text model for simulated agentic analysis."""
141
  if not text_input or not text_input.strip():
142
  return None, "Input text cannot be empty."
143
  if not st.session_state.models_initialized or not st.session_state.text_model:
144
- return None, "Text analysis model not initialized."
145
 
146
  try:
147
  prompt = AGENTIC_TEXT_ANALYSIS_PROMPT_TEMPLATE.format(text_input=text_input)
148
- response = st.session_state.text_model.generate_content(prompt)
149
 
 
150
  if response.parts:
151
  return response.text, None
152
  elif response.prompt_feedback.block_reason:
153
- return None, f"Analysis blocked by safety filters: {response.prompt_feedback.block_reason.name}. Review input."
154
  else:
155
  candidate = response.candidates[0] if response.candidates else None
156
  if candidate and candidate.finish_reason != "STOP":
157
- return None, f"Analysis stopped prematurely. Reason: {candidate.finish_reason.name}."
 
158
  else:
159
- return None, "Received an empty or unexpected response from the AI model."
 
160
 
161
  except Exception as e:
162
- print(f"ERROR in run_agentic_text_analysis: {e}") # Basic server-side log
163
- st.error("An error occurred during text analysis.", icon="🚨") # User-facing error
164
- return None, "An internal error occurred during text analysis. Please try again later."
165
 
166
  def analyze_medical_image(image_file: Any, user_prompt: str = "") -> Tuple[Optional[str], Optional[str]]:
167
- """Sends a medical image to the configured vision model for analysis."""
168
  if not image_file:
169
  return None, "Image file cannot be empty."
170
  if not st.session_state.models_initialized or not st.session_state.vision_model:
171
- return None, "Image analysis model not initialized."
172
 
173
  try:
174
  try:
 
175
  image = Image.open(image_file)
176
- # Convert to RGB ensure compatibility, common requirement for vision models
177
  if image.mode != 'RGB':
178
- image = image.convert('RGB')
179
  except Exception as img_e:
180
- return None, f"Error opening or processing the uploaded image file: {img_e}"
181
 
 
182
  prompt_text = IMAGE_ANALYSIS_PROMPT_TEMPLATE.format(user_prompt=user_prompt if user_prompt else "N/A")
183
- model_input = [prompt_text, image]
184
- response = st.session_state.vision_model.generate_content(model_input)
 
185
 
 
186
  if response.parts:
187
  return response.text, None
188
  elif response.prompt_feedback.block_reason:
189
- return None, f"Image analysis blocked by safety filters: {response.prompt_feedback.block_reason.name}. This may relate to sensitive content policies."
190
  else:
191
  candidate = response.candidates[0] if response.candidates else None
192
  if candidate and candidate.finish_reason != "STOP":
193
- return None, f"Image analysis stopped prematurely. Reason: {candidate.finish_reason.name}."
194
  else:
195
  return None, "Received an empty or unexpected response from the AI model for image analysis."
196
 
197
  except Exception as e:
198
- print(f"ERROR in analyze_medical_image: {e}") # Basic server-side log
199
- st.error("An error occurred during image analysis.", icon="πŸ–ΌοΈ") # User-facing error
200
- return None, "An internal error occurred during image analysis. Please try again later."
201
 
202
 
203
  # --- Streamlit User Interface ---
@@ -208,7 +238,6 @@ def main():
208
  st.caption(f"Utilizing: Text Model ({TEXT_MODEL_NAME}), Vision Model ({VISION_MODEL_NAME})")
209
 
210
  # --- CRITICAL DISCLAIMER ---
211
- # Positioned prominently after title/intro
212
  st.warning(
213
  """
214
  **πŸ”΄ IMPORTANT SAFETY & USE DISCLAIMER πŸ”΄**
@@ -236,9 +265,10 @@ def main():
236
  # --- Main Area Layout (Input and Output Columns) ---
237
  col1, col2 = st.columns(2)
238
 
239
- analysis_result = None # Initialize results variables for this run
240
  error_message = None
241
  output_header = "Analysis Results" # Default header
 
242
 
243
  # --- Column 1: Input Area ---
244
  with col1:
@@ -254,12 +284,12 @@ def main():
254
  placeholder="Example: 68yo male, sudden SOB & pleuritic chest pain post-flight. HR 110, SpO2 92% RA. No known cardiac hx...",
255
  key="text_input_area"
256
  )
257
- analyze_button_key = "analyze_text_button"
258
  analyze_button_label = "▢️ Run Agentic Text Analysis"
259
 
260
  if st.button(analyze_button_label, key=analyze_button_key, type="primary"):
261
  if text_input:
262
- with st.spinner("🧠 Simulating agentic reasoning..."):
263
  analysis_result, error_message = run_agentic_text_analysis(text_input)
264
  output_header = "Simulated Agentic Analysis Output"
265
  else:
@@ -278,7 +308,7 @@ def main():
278
  placeholder="Example: 'Describe findings in the lung fields' or 'Any visible fractures?'",
279
  key="image_prompt_input"
280
  )
281
- analyze_button_key = "analyze_image_button"
282
  analyze_button_label = "πŸ–ΌοΈ Analyze Medical Image"
283
 
284
  if image_file:
@@ -287,7 +317,7 @@ def main():
287
 
288
  if st.button(analyze_button_label, key=analyze_button_key, type="primary"):
289
  if image_file:
290
- with st.spinner("πŸ‘οΈ Analyzing image..."):
291
  analysis_result, error_message = analyze_medical_image(image_file, user_image_prompt)
292
  output_header = "Medical Image Analysis Output"
293
  else:
@@ -297,30 +327,33 @@ def main():
297
  with col2:
298
  st.header(output_header)
299
 
300
- # Display results or errors if an analysis was attempted
301
- # Check if button was pressed and corresponding result/error exists
302
- button_pressed = st.session_state.get(analyze_button_key, False) if 'analyze_button_key' in locals() else False
303
 
304
- if button_pressed and (analysis_result or error_message):
305
- if error_message:
 
306
  st.error(f"Analysis Failed: {error_message}", icon="❌")
307
- elif analysis_result:
308
- # Use st.markdown to render potential formatting from AI
309
- st.markdown(analysis_result)
310
- elif not button_pressed :
 
 
311
  st.info("Analysis results will appear here after providing input and clicking the corresponding analysis button.")
312
- # Add a condition for button pressed but no input provided (already handled by st.warning in col1)
313
 
314
 
315
  # --- Sidebar Explanations ---
316
  st.sidebar.markdown("---")
317
  st.sidebar.header("About The Prompts")
318
  with st.sidebar.expander("View Agentic Text Prompt Structure", icon="πŸ“„"):
319
- st.markdown(f"```plaintext\n{AGENTIC_TEXT_ANALYSIS_PROMPT_TEMPLATE.split('---')[0]} ... [Input Text] ...\n```")
 
320
  st.caption("Guides the AI through structured reasoning steps for text.")
321
  with st.sidebar.expander("View Image Analysis Prompt Structure", icon="πŸ–ΌοΈ"):
322
- st.markdown(f"```plaintext\n{IMAGE_ANALYSIS_PROMPT_TEMPLATE.split('---')[0]} ... [User Prompt] ...\n```")
323
- st.caption("Guides the AI to describe visual features and potential anomalies in images.")
 
324
 
325
  st.sidebar.markdown("---")
326
  st.sidebar.error(
@@ -334,7 +367,7 @@ if __name__ == "__main__":
334
  if st.session_state.models_initialized:
335
  main()
336
  else:
337
- # If models failed to initialize, errors would have been shown already.
338
- # We might add a placeholder or further message here if needed.
339
- st.info("Waiting for model initialization...") # Or check specific errors if needed
340
- # The script might stop earlier if initialization fails critically.
 
1
+ # -*- coding: utf-8 -*-
2
  import streamlit as st
3
  import google.generativeai as genai
4
  import os
 
18
  """
19
  ### Welcome to the AI Clinical Support Demonstrator
20
  This application demonstrates how Generative AI (Google Gemini) can be guided to assist with analyzing clinical information.
21
+ - **Agentic Text Analysis:** Simulates a structured reasoning process on clinical text.
22
  - **Medical Image Analysis:** Provides descriptive observations of potential anomalies in medical images.
23
 
24
  **Crucially, this tool is for demonstration purposes ONLY. It does NOT provide medical advice or diagnosis.**
 
44
  st.error("⚠️ Gemini API Key not found. Please configure `GEMINI_API_KEY` in Streamlit secrets or environment variables.", icon="πŸ”‘")
45
  st.stop()
46
 
47
+ # Initialize models using Session State for persistence across reruns
48
  TEXT_MODEL_NAME = 'gemini-1.5-pro-latest' # For agentic text reasoning
49
+ VISION_MODEL_NAME = 'gemini-1.5-flash' # For image analysis (or 'gemini-pro-vision')
50
 
 
51
  if 'models_initialized' not in st.session_state:
52
  st.session_state.models_initialized = False
53
  st.session_state.text_model = None
 
58
  st.session_state.text_model = genai.GenerativeModel(TEXT_MODEL_NAME)
59
  st.session_state.vision_model = genai.GenerativeModel(VISION_MODEL_NAME)
60
  st.session_state.models_initialized = True
 
 
61
  except Exception as e:
62
  st.error(f"Fatal Error: Failed to initialize Gemini models. Text: {TEXT_MODEL_NAME}, Vision: {VISION_MODEL_NAME}. Details: {e}", icon="πŸ’₯")
63
  st.stop()
64
  elif not genai_client_configured:
 
65
  st.error("AI Models could not be initialized due to configuration issues.", icon="🚫")
66
  st.stop()
67
 
68
 
69
  # --- Core AI Interaction Functions ---
70
 
71
+ # AGENTIC prompt for Text Analysis (Remains the same as previous good version)
72
  AGENTIC_TEXT_ANALYSIS_PROMPT_TEMPLATE = """
73
  **Simulated Clinical Reasoning Agent Task:**
74
 
 
80
 
81
  **Simulated Agentic Steps (Perform sequentially):**
82
 
83
+ 1. **## 1. Information Extraction & Structuring:**
84
  * Key Demographics (Age, Sex if provided).
85
  * Primary Symptoms/Signs.
86
  * Relevant Medical History.
87
  * Pertinent Negatives (if mentioned).
88
 
89
+ 2. **## 2. Differential Considerations Generation:**
90
  * Based *only* on Step 1, list **potential differential considerations** (possible conditions).
91
  * **Use cautious language:** "could be consistent with," "warrants consideration," "less likely but possible." **AVOID definitive statements.**
92
  * Briefly justify each consideration based on findings.
93
 
94
+ 3. **## 3. Information Gap Analysis:**
95
  * Identify critical missing information (e.g., lab results, imaging, exam specifics, duration/onset).
96
 
97
+ 4. **## 4. Suggested Next Steps for Investigation (for Clinician):**
98
  * Propose logical next steps a **healthcare professional might consider**.
99
  * Categorize (e.g., Further History, Exam Points, Labs, Imaging).
100
  * Frame as *suggestions* (e.g., "Consider ordering...", "Assessment of X may be informative").
101
 
102
+ 5. **## 5. Mandatory Disclaimer:** Conclude with: "This AI-generated analysis is for informational support only. It is **NOT** a diagnosis and cannot replace the judgment of a qualified healthcare professional."
103
 
104
  **Input Clinical Information:**
105
  ---
 
109
  **Agentic Analysis:**
110
  """
111
 
112
+ # REFINED prompt for Image Analysis - More explicit instructions based on good example
113
  IMAGE_ANALYSIS_PROMPT_TEMPLATE = """
114
  **Medical Image Analysis Request:**
115
 
116
+ **Context:** Analyze the provided medical image objectively based *only* on visual information. User may provide additional context or questions.
117
 
118
+ **Output Format:** Structure your response precisely using the following Markdown headings. Be factual and descriptive.
119
 
120
  **Task:**
121
 
122
+ 1. **## 1. Visible Structures:**
123
+ * Identify the likely imaging modality and view (e.g., PA Chest Radiograph, Axial CT slice of the abdomen).
124
+ * Briefly list the main anatomical structures clearly visible (e.g., ribs, heart silhouette, lung fields, diaphragm).
125
+
126
+ 2. **## 2. Identify Potential Anomalies / Key Findings:**
127
+ * Carefully examine the image for any areas that *appear* abnormal or deviate significantly from typical presentation.
128
+ * **Use extremely cautious, descriptive language.** Describe *what* you see (e.g., "area of increased opacity," "region of lucency," "asymmetry observed in X," "potential contour abnormality," "patchy distribution").
129
+ * **Specify location accurately** using standard anatomical terms (e.g., "right lower lung zone," "left hilum," "hepatic flexure region").
130
+ * **Crucially, AVOID interpretive or diagnostic terms** (DO NOT use words like "pneumonia," "tumor," "fracture," "infection," "inflammation"). Stick strictly to visual observation.
131
+ * If relevant and clearly discernible, mention the **absence** of certain major expected abnormalities (pertinent negatives, e.g., "No obvious large pneumothorax identified," "Bowel gas pattern appears unremarkable in visualized areas").
132
+ * Compare sides if applicable and relevant differences are seen (e.g., "Left lung field demonstrates greater transparency compared to the right").
133
+
134
+ 3. **## 3. Correlate with User Prompt (if provided):**
135
+ * Address specific user questions based *strictly* on the visual information identifiable in the image.
136
+ * If the image cannot visually answer the question (e.g., requires clinical context, different view), state that clearly.
137
+ * If no user prompt was provided, state "N/A".
138
+
139
+ 4. **## 4. Limitations of this AI Analysis:**
140
+ * **Explicitly list the following limitations inherent to this analysis:**
141
+ * Dependency on the **quality, resolution, and potential artifacts** of the provided image.
142
+ * Analysis is restricted to the **single view/slice(s)** provided; other areas are not assessed.
143
+ * **Complete lack of clinical context:** Patient history, symptoms, physical exam findings, and laboratory results are unknown and not considered.
144
+ * **Absence of prior imaging studies:** Comparisons over time are not possible, which is often crucial for interpretation.
145
+ * The AI functions purely on **visual pattern recognition**; it does not perform clinical reasoning or differential diagnosis.
146
+
147
+ 5. **## 5. Mandatory Disclaimer:**
148
+ * State clearly: This is an AI-generated visual analysis intended for informational and demonstration purposes **ONLY**.
149
+ * It is **NOT** a radiological interpretation or medical diagnosis.
150
+ * It **CANNOT** substitute for a comprehensive evaluation and interpretation by a qualified radiologist or physician integrating full clinical information.
151
+ * Any potential observations noted herein **MUST** be correlated with clinical findings and reviewed/confirmed by qualified healthcare professionals.
152
 
153
  **User's Additional Context/Question (if any):**
154
  ---
 
158
  **Image Analysis:**
159
  """
160
 
161
+ # --- Backend Functions ---
162
+
163
  def run_agentic_text_analysis(text_input: str) -> Tuple[Optional[str], Optional[str]]:
164
  """Sends clinical text to the configured text model for simulated agentic analysis."""
165
  if not text_input or not text_input.strip():
166
  return None, "Input text cannot be empty."
167
  if not st.session_state.models_initialized or not st.session_state.text_model:
168
+ return None, "Text analysis model not initialized. Please refresh or check configuration."
169
 
170
  try:
171
  prompt = AGENTIC_TEXT_ANALYSIS_PROMPT_TEMPLATE.format(text_input=text_input)
172
+ response = st.session_state.text_model.generate_content(prompt) # Use model from session state
173
 
174
+ # Handle response variations
175
  if response.parts:
176
  return response.text, None
177
  elif response.prompt_feedback.block_reason:
178
+ return None, f"Analysis blocked by safety filters: {response.prompt_feedback.block_reason.name}. Please review or revise input."
179
  else:
180
  candidate = response.candidates[0] if response.candidates else None
181
  if candidate and candidate.finish_reason != "STOP":
182
+ # If stopped for reasons other than normal completion (e.g., length, safety)
183
+ return None, f"Analysis stopped prematurely. Reason: {candidate.finish_reason.name}. Input might be too long or triggered other limits."
184
  else:
185
+ # General case for empty or unexpected response
186
+ return None, "Received an empty or unexpected response from the AI model for text analysis."
187
 
188
  except Exception as e:
189
+ print(f"ERROR in run_agentic_text_analysis: {e}") # Log for server/dev console
190
+ st.error("An error occurred during text analysis.", icon="🚨") # User-facing generic error
191
+ return None, "An internal error occurred during text analysis. Please try again later or contact support if the issue persists."
192
 
193
  def analyze_medical_image(image_file: Any, user_prompt: str = "") -> Tuple[Optional[str], Optional[str]]:
194
+ """Sends a medical image to the configured vision model for analysis using the refined prompt."""
195
  if not image_file:
196
  return None, "Image file cannot be empty."
197
  if not st.session_state.models_initialized or not st.session_state.vision_model:
198
+ return None, "Image analysis model not initialized. Please refresh or check configuration."
199
 
200
  try:
201
  try:
202
+ # Open and prepare the image
203
  image = Image.open(image_file)
 
204
  if image.mode != 'RGB':
205
+ image = image.convert('RGB') # Ensure RGB format
206
  except Exception as img_e:
207
+ return None, f"Error opening or processing the uploaded image file: {img_e}. Please ensure it's a valid image."
208
 
209
+ # Prepare the prompt using the refined template
210
  prompt_text = IMAGE_ANALYSIS_PROMPT_TEMPLATE.format(user_prompt=user_prompt if user_prompt else "N/A")
211
+ model_input = [prompt_text, image] # Combine text prompt and image data
212
+
213
+ response = st.session_state.vision_model.generate_content(model_input) # Use model from session state
214
 
215
+ # Handle response variations
216
  if response.parts:
217
  return response.text, None
218
  elif response.prompt_feedback.block_reason:
219
+ return None, f"Image analysis blocked by safety filters: {response.prompt_feedback.block_reason.name}. This might relate to sensitive content policies regarding medical images."
220
  else:
221
  candidate = response.candidates[0] if response.candidates else None
222
  if candidate and candidate.finish_reason != "STOP":
223
+ return None, f"Image analysis stopped prematurely. Reason: {candidate.finish_reason.name}. Input might be too complex or triggered other limits."
224
  else:
225
  return None, "Received an empty or unexpected response from the AI model for image analysis."
226
 
227
  except Exception as e:
228
+ print(f"ERROR in analyze_medical_image: {e}") # Log for server/dev console
229
+ st.error("An error occurred during image analysis.", icon="πŸ–ΌοΈ") # User-facing generic error
230
+ return None, "An internal error occurred during image analysis. Please try again later or contact support if the issue persists."
231
 
232
 
233
  # --- Streamlit User Interface ---
 
238
  st.caption(f"Utilizing: Text Model ({TEXT_MODEL_NAME}), Vision Model ({VISION_MODEL_NAME})")
239
 
240
  # --- CRITICAL DISCLAIMER ---
 
241
  st.warning(
242
  """
243
  **πŸ”΄ IMPORTANT SAFETY & USE DISCLAIMER πŸ”΄**
 
265
  # --- Main Area Layout (Input and Output Columns) ---
266
  col1, col2 = st.columns(2)
267
 
268
+ analysis_result = None # Reset results variables for this run
269
  error_message = None
270
  output_header = "Analysis Results" # Default header
271
+ analyze_button_key = None # Initialize key variable
272
 
273
  # --- Column 1: Input Area ---
274
  with col1:
 
284
  placeholder="Example: 68yo male, sudden SOB & pleuritic chest pain post-flight. HR 110, SpO2 92% RA. No known cardiac hx...",
285
  key="text_input_area"
286
  )
287
+ analyze_button_key = "analyze_text_button" # Set key for this branch
288
  analyze_button_label = "▢️ Run Agentic Text Analysis"
289
 
290
  if st.button(analyze_button_label, key=analyze_button_key, type="primary"):
291
  if text_input:
292
+ with st.spinner("🧠 Simulating agentic reasoning... Please wait."):
293
  analysis_result, error_message = run_agentic_text_analysis(text_input)
294
  output_header = "Simulated Agentic Analysis Output"
295
  else:
 
308
  placeholder="Example: 'Describe findings in the lung fields' or 'Any visible fractures?'",
309
  key="image_prompt_input"
310
  )
311
+ analyze_button_key = "analyze_image_button" # Set key for this branch
312
  analyze_button_label = "πŸ–ΌοΈ Analyze Medical Image"
313
 
314
  if image_file:
 
317
 
318
  if st.button(analyze_button_label, key=analyze_button_key, type="primary"):
319
  if image_file:
320
+ with st.spinner("πŸ‘οΈ Analyzing image... Please wait."):
321
  analysis_result, error_message = analyze_medical_image(image_file, user_image_prompt)
322
  output_header = "Medical Image Analysis Output"
323
  else:
 
327
  with col2:
328
  st.header(output_header)
329
 
330
+ # Determine if analysis was attempted in this run using the correct button key
331
+ button_pressed = st.session_state.get(analyze_button_key, False) if analyze_button_key else False
 
332
 
333
+ if button_pressed:
334
+ # Only display results if the corresponding button was pressed AND generated output/error
335
+ if error_message:
336
  st.error(f"Analysis Failed: {error_message}", icon="❌")
337
+ elif analysis_result:
338
+ # Use st.markdown to render potential formatting (like headings) from AI
339
+ st.markdown(analysis_result, unsafe_allow_html=False) # Keep unsafe_allow_html=False for security
340
+ # No explicit 'else' needed here; if button pressed but no result/error, likely handled by input validation warning
341
+ else:
342
+ # Default placeholder message if no analysis attempted yet in this run
343
  st.info("Analysis results will appear here after providing input and clicking the corresponding analysis button.")
 
344
 
345
 
346
  # --- Sidebar Explanations ---
347
  st.sidebar.markdown("---")
348
  st.sidebar.header("About The Prompts")
349
  with st.sidebar.expander("View Agentic Text Prompt Structure", icon="πŸ“„"):
350
+ # Show only the instructive part of the prompt template
351
+ st.code(AGENTIC_TEXT_ANALYSIS_PROMPT_TEMPLATE.split('---')[0] + "...", language='markdown')
352
  st.caption("Guides the AI through structured reasoning steps for text.")
353
  with st.sidebar.expander("View Image Analysis Prompt Structure", icon="πŸ–ΌοΈ"):
354
+ # Show only the instructive part of the prompt template
355
+ st.code(IMAGE_ANALYSIS_PROMPT_TEMPLATE.split('---')[0] + "...", language='markdown')
356
+ st.caption("Guides the AI to provide cautious, descriptive visual observations for images.")
357
 
358
  st.sidebar.markdown("---")
359
  st.sidebar.error(
 
367
  if st.session_state.models_initialized:
368
  main()
369
  else:
370
+ # Errors during initialization should have been shown and stopped execution.
371
+ # This path might be reached if initialization is still pending in an async setup (not the case here)
372
+ # or if there was a non-fatal init issue not caught by st.stop().
373
+ st.info("Waiting for AI model initialization or resolving configuration issues...")