hponepyae commited on
Commit
b1556e0
Β·
verified Β·
1 Parent(s): 485e7ca
Files changed (1) hide show
  1. app.py +23 -43
app.py CHANGED
@@ -35,14 +35,7 @@ def handle_conversation_turn(user_input: str, user_image: Image.Image, history:
35
 
36
  try:
37
  system_prompt = (
38
- "You are an expert, empathetic AI medical assistant conducting a virtual consultation. "
39
- "Your primary goal is to ask clarifying questions to understand the user's symptoms thoroughly. "
40
- "Do NOT provide a diagnosis or a list of possibilities right away. Ask only one or two focused questions per turn. "
41
- "If the user provides an image, your first step is to analyze it from an expert perspective. Briefly describe the key findings from the image. "
42
- "Then, use this analysis to ask relevant follow-up questions about the user's symptoms or medical history to better understand the context. "
43
- "For example, after seeing a rash, you might say, 'I see a reddish rash with well-defined borders on the forearm. To help me understand more, could you tell me when you first noticed this? Is it itchy, painful, or does it have any other sensation?'"
44
- "After several turns of asking questions, when you feel you have gathered enough information, you must FIRST state that you are ready to provide a summary. "
45
- "THEN, in the SAME response, provide a list of possible conditions, your reasoning, and a clear, actionable next-steps plan."
46
  )
47
 
48
  generation_args = {"max_new_tokens": 1024, "do_sample": True, "temperature": 0.7}
@@ -80,13 +73,14 @@ def handle_conversation_turn(user_input: str, user_image: Image.Image, history:
80
  print(f"An exception occurred during conversation turn: {type(e).__name__}: {e}")
81
  yield history, history
82
 
83
- # --- UI MODIFICATION: Professional CSS for a clean, modern chat interface ---
84
  css = """
85
  /* Main App Styling */
86
- body, .gradio-container { background-color: #f9fafb; font-family: 'Inter', sans-serif; }
87
- #chat-container { flex-grow: 1; overflow-y: auto; padding-bottom: 150px; }
88
  /* Chat Bubble Styling */
89
- .message-bubble { border-radius: 15px !important; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
 
90
  /* Sticky Footer Input Bar */
91
  #footer-container {
92
  position: fixed !important; bottom: 0; left: 0; width: 100%;
@@ -96,82 +90,68 @@ body, .gradio-container { background-color: #f9fafb; font-family: 'Inter', sans-
96
  }
97
  /* Text Input Box Styling */
98
  #user-textbox textarea {
99
- background-color: #f9fafb !important;
100
  border: 1px solid #d1d5db !important;
101
  border-radius: 10px !important;
102
- color: #111827 !important; /* Darker text color */
103
  }
104
- /* Icon Button Styling */
105
  .icon-btn {
106
- min-width: 45px !important; max-width: 45px !important;
107
- height: 45px !important; font-size: 1.2rem !important;
108
- border: 1px solid #e5e7eb !important;
109
  }
 
 
 
110
  """
111
 
112
  with gr.Blocks(theme=gr.themes.Base(), title="AI Doctor Consultation", css=css) as demo:
113
  conversation_history = gr.State([])
114
 
115
  with gr.Column(elem_id="chat-container"):
116
- chatbot_display = gr.Chatbot(label="Consultation", show_copy_button=True, bubble_full_width=False)
117
 
118
  with gr.Column(elem_id="footer-container"):
119
  with gr.Row():
120
- # The image preview is hidden by default
121
- image_preview = gr.Image(type="pil", height=60, width=60, visible=False, show_label=False, container=False)
122
-
123
- # The new icon-based upload button
124
- upload_button = gr.UploadButton("πŸ“·", file_types=["image"], scale=1, elem_classes="icon-btn")
125
-
126
  user_textbox = gr.Textbox(
127
  elem_id="user-textbox",
128
  placeholder="Type your message, or upload an image...",
129
  show_label=False, scale=5, container=False
130
  )
131
-
132
- send_button = gr.Button("➀", variant="primary", scale=1, elem_classes="icon-btn")
133
- clear_button = gr.Button("πŸ—‘οΈ", scale=1, elem_classes="icon-btn")
134
 
135
- # --- Event Handlers for the new UI ---
136
-
137
- # This handler makes the image preview appear when a user uploads a file.
138
  def show_image_preview(image_file):
139
- # When a file is uploaded, make the preview Image component visible and set its value.
140
  return gr.Image(value=image_file, visible=True)
141
 
142
  upload_button.upload(fn=show_image_preview, inputs=upload_button, outputs=image_preview)
143
 
144
- # Main function to handle the conversation flow
145
  def submit_message_and_stream(user_input: str, user_image: Image.Image, history: list):
146
  if not user_input.strip() and user_image is None:
147
  return history, history, None
148
-
149
- # 1. Instantly add the user's message (and image) to the chat UI
150
  history.append((user_input, None))
151
  yield history, history, None
152
-
153
- # 2. Start the generator to get the AI's response stream
154
  for updated_history, new_state in handle_conversation_turn(user_input, user_image, history):
155
- yield updated_history, new_state, None # Pass None to image_preview to clear it
156
 
157
- # Function to clear the textbox and image preview after submission
158
  def clear_inputs():
159
  return "", None
160
 
161
- # Wire up the send and submit events
162
  send_button.click(
163
  fn=submit_message_and_stream,
164
  inputs=[user_textbox, image_preview, conversation_history],
165
- outputs=[chatbot_display, conversation_history, image_preview],
166
  ).then(fn=clear_inputs, outputs=[user_textbox, image_preview])
167
 
168
  user_textbox.submit(
169
  fn=submit_message_and_stream,
170
  inputs=[user_textbox, image_preview, conversation_history],
171
- outputs=[chatbot_display, conversation_history, image_preview],
172
  ).then(fn=clear_inputs, outputs=[user_textbox, image_preview])
173
 
174
- # Wire up the clear button
175
  clear_button.click(
176
  lambda: ([], [], None, ""),
177
  outputs=[chatbot_display, conversation_history, image_preview, user_textbox]
 
35
 
36
  try:
37
  system_prompt = (
38
+ "You are an expert, empathetic AI medical assistant conducting a virtual consultation. Your primary goal is to ask clarifying questions to understand the user's symptoms thoroughly. Do NOT provide a diagnosis or a list of possibilities right away. Ask only one or two focused questions per turn. If the user provides an image, your first step is to analyze it from an expert perspective. Briefly describe the key findings from the image. Then, use this analysis to ask relevant follow-up questions about the user's symptoms or medical history to better understand the context. For example, after seeing a rash, you might say, 'I see a reddish rash with well-defined borders on the forearm. To help me understand more, could you tell me when you first noticed this? Is it itchy, painful, or does it have any other sensation?' After several turns of asking questions, when you feel you have gathered enough information, you must FIRST state that you are ready to provide a summary. THEN, in the SAME response, provide a list of possible conditions, your reasoning, and a clear, actionable next-steps plan."
 
 
 
 
 
 
 
39
  )
40
 
41
  generation_args = {"max_new_tokens": 1024, "do_sample": True, "temperature": 0.7}
 
73
  print(f"An exception occurred during conversation turn: {type(e).__name__}: {e}")
74
  yield history, history
75
 
76
+ # --- UI MODIFICATION: Professional CSS for a polished chat interface ---
77
  css = """
78
  /* Main App Styling */
79
+ body, .gradio-container { background-color: #f9fafb !important; }
80
+ #chat-container { flex-grow: 1; overflow-y: auto; padding-bottom: 200px !important; }
81
  /* Chat Bubble Styling */
82
+ .user .message-bubble { background-color: #dbeafe !important; color: #1f2937 !important; }
83
+ .bot .message-bubble { background-color: #f3f4f6 !important; color: #1f2937 !important; }
84
  /* Sticky Footer Input Bar */
85
  #footer-container {
86
  position: fixed !important; bottom: 0; left: 0; width: 100%;
 
90
  }
91
  /* Text Input Box Styling */
92
  #user-textbox textarea {
93
+ background-color: #ffffff !important;
94
  border: 1px solid #d1d5db !important;
95
  border-radius: 10px !important;
96
+ color: #111827 !important; /* Darker input text */
97
  }
98
+ /* Icon Button General Styling */
99
  .icon-btn {
100
+ min-width: 50px !important; max-width: 50px !important;
101
+ height: 50px !important; font-size: 1.5rem !important;
102
+ border: none !important; border-radius: 10px !important;
103
  }
104
+ /* Specific Icon Button Colors */
105
+ #restart-btn { background-color: #fee2e2 !important; color: #ef4444 !important; }
106
+ #upload-btn, #send-btn { background-color: #3b82f6 !important; color: white !important; }
107
  """
108
 
109
  with gr.Blocks(theme=gr.themes.Base(), title="AI Doctor Consultation", css=css) as demo:
110
  conversation_history = gr.State([])
111
 
112
  with gr.Column(elem_id="chat-container"):
113
+ chatbot_display = gr.Chatbot(label="Consultation", show_copy_button=True, bubble_full_width=False, avatar_images=("./images/user.png", "./images/bot.png"))
114
 
115
  with gr.Column(elem_id="footer-container"):
116
  with gr.Row():
117
+ image_preview = gr.Image(type="pil", height=60, width=60, visible=False, show_label=False, container=False, scale=1)
118
+ upload_button = gr.UploadButton("πŸ“·", file_types=["image"], elem_id="upload-btn", elem_classes="icon-btn", scale=1)
 
 
 
 
119
  user_textbox = gr.Textbox(
120
  elem_id="user-textbox",
121
  placeholder="Type your message, or upload an image...",
122
  show_label=False, scale=5, container=False
123
  )
124
+ send_button = gr.Button("➀", elem_id="send-btn", elem_classes="icon-btn", scale=1)
125
+ clear_button = gr.Button("πŸ”„", elem_id="restart-btn", elem_classes="icon-btn", scale=1)
 
126
 
 
 
 
127
  def show_image_preview(image_file):
 
128
  return gr.Image(value=image_file, visible=True)
129
 
130
  upload_button.upload(fn=show_image_preview, inputs=upload_button, outputs=image_preview)
131
 
 
132
  def submit_message_and_stream(user_input: str, user_image: Image.Image, history: list):
133
  if not user_input.strip() and user_image is None:
134
  return history, history, None
 
 
135
  history.append((user_input, None))
136
  yield history, history, None
 
 
137
  for updated_history, new_state in handle_conversation_turn(user_input, user_image, history):
138
+ yield updated_history, new_state
139
 
 
140
  def clear_inputs():
141
  return "", None
142
 
 
143
  send_button.click(
144
  fn=submit_message_and_stream,
145
  inputs=[user_textbox, image_preview, conversation_history],
146
+ outputs=[chatbot_display, conversation_history],
147
  ).then(fn=clear_inputs, outputs=[user_textbox, image_preview])
148
 
149
  user_textbox.submit(
150
  fn=submit_message_and_stream,
151
  inputs=[user_textbox, image_preview, conversation_history],
152
+ outputs=[chatbot_display, conversation_history],
153
  ).then(fn=clear_inputs, outputs=[user_textbox, image_preview])
154
 
 
155
  clear_button.click(
156
  lambda: ([], [], None, ""),
157
  outputs=[chatbot_display, conversation_history, image_preview, user_textbox]