IAMTFRMZA commited on
Commit
9ee7546
Β·
verified Β·
1 Parent(s): f06d67c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -59
app.py CHANGED
@@ -34,7 +34,7 @@ class WebSocketClient:
34
  await self.websocket.send(f.read())
35
  await asyncio.gather(self.receive_messages(), self.send_audio_chunks())
36
  except Exception as e:
37
- print(f"πŸ”΄ WebSocket Connection Failed: {e}")
38
 
39
  def run(self):
40
  asyncio.set_event_loop(self.loop)
@@ -94,21 +94,17 @@ def clear_chat_only():
94
  def handle_chat(user_input, history, thread_id, image_url):
95
  if not OPENAI_API_KEY or not ASSISTANT_ID:
96
  return "❌ Missing secrets!", history, thread_id, image_url
97
-
98
  try:
99
  if thread_id is None:
100
  thread = client.beta.threads.create()
101
  thread_id = thread.id
102
-
103
  client.beta.threads.messages.create(thread_id=thread_id, role="user", content=user_input)
104
  run = client.beta.threads.runs.create(thread_id=thread_id, assistant_id=ASSISTANT_ID)
105
-
106
  while True:
107
  status = client.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run.id)
108
  if status.status == "completed":
109
  break
110
  time.sleep(1)
111
-
112
  msgs = client.beta.threads.messages.list(thread_id=thread_id)
113
  for msg in reversed(msgs.data):
114
  if msg.role == "assistant":
@@ -116,14 +112,11 @@ def handle_chat(user_input, history, thread_id, image_url):
116
  history.append((user_input, content))
117
  match = re.search(
118
  r'https://raw\.githubusercontent\.com/AndrewLORTech/surgical-pathology-manual/main/[\w\-/]*\.png',
119
- content
120
- )
121
  if match:
122
  image_url = match.group(0)
123
  break
124
-
125
  return "", history, thread_id, image_url
126
-
127
  except Exception as e:
128
  return f"❌ {e}", history, thread_id, image_url
129
 
@@ -139,8 +132,6 @@ def update_image_display(image_url):
139
  return image_url
140
  return None
141
 
142
- # ============ Gradio UI ============
143
-
144
  with gr.Blocks(theme=gr.themes.Soft()) as app:
145
  gr.Markdown("# πŸ“„ Document AI Assistant")
146
 
@@ -154,11 +145,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
154
  margin-top: 10px;
155
  white-space: nowrap;
156
  }
157
- .voice-area {
158
- padding-top: 12px;
159
- border-top: 1px solid #444;
160
- margin-top: 12px;
161
- }
162
  </style>
163
  """)
164
 
@@ -167,64 +154,50 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
167
  image_state = gr.State()
168
  client_id = gr.State()
169
 
170
- with gr.Row(equal_height=True):
 
 
171
 
172
- with gr.Column(scale=1):
173
- with gr.Accordion("πŸ“„ Document Viewer", open=True):
174
- image_display = gr.Image(
175
- label="πŸ–ΌοΈ Document",
176
- type="filepath",
177
- show_download_button=False,
178
- height=480
179
- )
180
 
181
- with gr.Column(scale=2):
182
  chat = gr.Chatbot(label="πŸ’¬ Chat", height=480)
183
-
184
  with gr.Row():
185
  user_prompt = gr.Textbox(placeholder="Ask your question...", show_label=False, scale=8)
186
  send_btn = gr.Button("Send", variant="primary", scale=2)
187
-
188
  with gr.Row():
189
  clear_chat_btn = gr.Button("πŸ—‘οΈ Clear Chat", elem_classes="big-btn")
190
 
191
- with gr.Column(scale=1):
192
- with gr.Accordion("πŸŽ™οΈ Voice Input", open=True):
193
- gr.Markdown("### πŸŽ™οΈ Voice Input")
194
- voice_input = gr.Audio(label="Tap to Record", streaming=True, type="numpy", show_label=True)
195
- voice_transcript = gr.Textbox(label="Transcript", lines=2, interactive=False)
196
-
197
- with gr.Row(equal_height=True):
198
- with gr.Column(scale=1):
199
- voice_send_btn = gr.Button("🟒 Send Voice to Assistant", elem_classes="big-btn")
200
- with gr.Column(scale=1):
201
- clear_transcript_btn = gr.Button("🧹 Clear Transcript", elem_classes="big-btn")
202
-
203
- # Bindings
204
- send_btn.click(fn=handle_chat,
205
- inputs=[user_prompt, chat_state, thread_state, image_state],
206
- outputs=[user_prompt, chat, thread_state, image_state])
207
 
208
- voice_input.stream(fn=send_audio,
209
- inputs=[voice_input, client_id],
210
- outputs=voice_transcript,
211
- stream_every=0.5)
212
 
213
- voice_send_btn.click(fn=feed_transcript,
214
- inputs=[voice_transcript, chat_state, thread_state, image_state, client_id],
215
- outputs=[user_prompt, chat, thread_state, image_state])
216
 
217
- clear_transcript_btn.click(fn=clear_transcript_only,
218
- inputs=[client_id],
219
- outputs=voice_transcript)
220
 
221
- clear_chat_btn.click(fn=clear_chat_only,
222
- outputs=[chat, thread_state, image_state])
223
 
224
- image_state.change(fn=update_image_display,
225
- inputs=image_state,
226
- outputs=image_display)
227
 
 
 
 
228
  app.load(fn=create_ws, outputs=[client_id])
229
 
230
  app.launch()
 
34
  await self.websocket.send(f.read())
35
  await asyncio.gather(self.receive_messages(), self.send_audio_chunks())
36
  except Exception as e:
37
+ print(f"\U0001F534 WebSocket Connection Failed: {e}")
38
 
39
  def run(self):
40
  asyncio.set_event_loop(self.loop)
 
94
  def handle_chat(user_input, history, thread_id, image_url):
95
  if not OPENAI_API_KEY or not ASSISTANT_ID:
96
  return "❌ Missing secrets!", history, thread_id, image_url
 
97
  try:
98
  if thread_id is None:
99
  thread = client.beta.threads.create()
100
  thread_id = thread.id
 
101
  client.beta.threads.messages.create(thread_id=thread_id, role="user", content=user_input)
102
  run = client.beta.threads.runs.create(thread_id=thread_id, assistant_id=ASSISTANT_ID)
 
103
  while True:
104
  status = client.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run.id)
105
  if status.status == "completed":
106
  break
107
  time.sleep(1)
 
108
  msgs = client.beta.threads.messages.list(thread_id=thread_id)
109
  for msg in reversed(msgs.data):
110
  if msg.role == "assistant":
 
112
  history.append((user_input, content))
113
  match = re.search(
114
  r'https://raw\.githubusercontent\.com/AndrewLORTech/surgical-pathology-manual/main/[\w\-/]*\.png',
115
+ content)
 
116
  if match:
117
  image_url = match.group(0)
118
  break
 
119
  return "", history, thread_id, image_url
 
120
  except Exception as e:
121
  return f"❌ {e}", history, thread_id, image_url
122
 
 
132
  return image_url
133
  return None
134
 
 
 
135
  with gr.Blocks(theme=gr.themes.Soft()) as app:
136
  gr.Markdown("# πŸ“„ Document AI Assistant")
137
 
 
145
  margin-top: 10px;
146
  white-space: nowrap;
147
  }
148
+ .toggle-btn { margin-bottom: 8px; }
 
 
 
 
149
  </style>
150
  """)
151
 
 
154
  image_state = gr.State()
155
  client_id = gr.State()
156
 
157
+ with gr.Row():
158
+ toggle_left = gr.Button("πŸ“„ Toggle Document Panel", elem_classes="toggle-btn")
159
+ toggle_right = gr.Button("πŸŽ™οΈ Toggle Voice Panel", elem_classes="toggle-btn")
160
 
161
+ with gr.Row(equal_height=True) as layout_row:
162
+ with gr.Column(scale=1, visible=True) as left_col:
163
+ image_display = gr.Image(label="πŸ–ΌοΈ Document", type="filepath", show_download_button=False, height=480)
 
 
 
 
 
164
 
165
+ with gr.Column(scale=2, visible=True) as center_col:
166
  chat = gr.Chatbot(label="πŸ’¬ Chat", height=480)
 
167
  with gr.Row():
168
  user_prompt = gr.Textbox(placeholder="Ask your question...", show_label=False, scale=8)
169
  send_btn = gr.Button("Send", variant="primary", scale=2)
 
170
  with gr.Row():
171
  clear_chat_btn = gr.Button("πŸ—‘οΈ Clear Chat", elem_classes="big-btn")
172
 
173
+ with gr.Column(scale=1, visible=True) as right_col:
174
+ gr.Markdown("### πŸŽ™οΈ Voice Input")
175
+ voice_input = gr.Audio(label="Tap to Record", streaming=True, type="numpy", show_label=True)
176
+ voice_transcript = gr.Textbox(label="Transcript", lines=2, interactive=False)
177
+ with gr.Row(equal_height=True):
178
+ with gr.Column(scale=1):
179
+ voice_send_btn = gr.Button("🟒 Send Voice to Assistant", elem_classes="big-btn")
180
+ with gr.Column(scale=1):
181
+ clear_transcript_btn = gr.Button("🧹 Clear Transcript", elem_classes="big-btn")
 
 
 
 
 
 
 
182
 
183
+ def toggle_column_visibility(current_vis):
184
+ return gr.update(visible=not current_vis)
 
 
185
 
186
+ toggle_left.click(lambda v: toggle_column_visibility(v), inputs=[left_col], outputs=[left_col])
187
+ toggle_right.click(lambda v: toggle_column_visibility(v), inputs=[right_col], outputs=[right_col])
 
188
 
189
+ send_btn.click(fn=handle_chat, inputs=[user_prompt, chat_state, thread_state, image_state],
190
+ outputs=[user_prompt, chat, thread_state, image_state])
 
191
 
192
+ voice_input.stream(fn=send_audio, inputs=[voice_input, client_id],
193
+ outputs=voice_transcript, stream_every=0.5)
194
 
195
+ voice_send_btn.click(fn=feed_transcript, inputs=[voice_transcript, chat_state, thread_state, image_state, client_id],
196
+ outputs=[user_prompt, chat, thread_state, image_state])
 
197
 
198
+ clear_transcript_btn.click(fn=clear_transcript_only, inputs=[client_id], outputs=voice_transcript)
199
+ clear_chat_btn.click(fn=clear_chat_only, outputs=[chat, thread_state, image_state])
200
+ image_state.change(fn=update_image_display, inputs=image_state, outputs=image_display)
201
  app.load(fn=create_ws, outputs=[client_id])
202
 
203
  app.launch()