Malofi commited on
Commit
bdeec3b
·
verified ·
1 Parent(s): 5d95245

Update Gradio_UI.py

Browse files
Files changed (1) hide show
  1. Gradio_UI.py +113 -24
Gradio_UI.py CHANGED
@@ -17,8 +17,16 @@ import mimetypes
17
  import os
18
  import re
19
  import shutil
 
20
  from typing import Optional
21
 
 
 
 
 
 
 
 
22
  from smolagents.agent_types import AgentAudio, AgentImage, AgentText, handle_agent_output_types
23
  from smolagents.agents import ActionStep, MultiStepAgent
24
  from smolagents.memory import MemoryStep
@@ -31,6 +39,7 @@ def pull_messages_from_step(
31
  """Extract ChatMessage objects from agent steps with proper nesting"""
32
  import gradio as gr
33
 
 
34
  if isinstance(step_log, ActionStep):
35
  # Output the step number
36
  step_number = f"Step {step_log.step_number}" if step_log.step_number is not None else ""
@@ -156,22 +165,48 @@ def stream_to_gradio(
156
  final_answer = step_log # Last log is the run's final_answer
157
  final_answer = handle_agent_output_types(final_answer)
158
 
 
159
  if isinstance(final_answer, AgentText):
160
  yield gr.ChatMessage(
161
  role="assistant",
162
  content=f"**Final answer:**\n{final_answer.to_string()}\n",
163
  )
164
  elif isinstance(final_answer, AgentImage):
165
- yield gr.ChatMessage(
166
- role="assistant",
167
- content={"path": final_answer.to_string(), "mime_type": "image/png"},
168
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  elif isinstance(final_answer, AgentAudio):
 
170
  yield gr.ChatMessage(
171
  role="assistant",
172
  content={"path": final_answer.to_string(), "mime_type": "audio/wav"},
173
  )
174
  else:
 
175
  yield gr.ChatMessage(role="assistant", content=f"**Final answer:** {str(final_answer)}")
176
 
177
 
@@ -186,19 +221,31 @@ class GradioUI:
186
  self.agent = agent
187
  self.file_upload_folder = file_upload_folder
188
  if self.file_upload_folder is not None:
189
- if not os.path.exists(file_upload_folder):
190
- os.mkdir(file_upload_folder)
 
191
 
192
  def interact_with_agent(self, prompt, messages):
193
  import gradio as gr
194
 
195
  messages.append(gr.ChatMessage(role="user", content=prompt))
196
  yield messages
197
- for msg in stream_to_gradio(self.agent, task=prompt, reset_agent_memory=False):
 
 
 
 
 
 
 
 
 
 
198
  messages.append(msg)
199
  yield messages
200
  yield messages
201
 
 
202
  def upload_file(
203
  self,
204
  file,
@@ -241,11 +288,17 @@ class GradioUI:
241
  sanitized_name.append("" + type_to_ext[mime_type])
242
  sanitized_name = "".join(sanitized_name)
243
 
244
- # Save the uploaded file to the specified folder
245
- file_path = os.path.join(self.file_upload_folder, os.path.basename(sanitized_name))
246
- shutil.copy(file.name, file_path)
 
 
 
 
 
 
 
247
 
248
- return gr.Textbox(f"File uploaded: {file_path}", visible=True), file_uploads_log + [file_path]
249
 
250
  def log_user_message(self, text_input, file_uploads_log):
251
  return (
@@ -266,31 +319,67 @@ class GradioUI:
266
  file_uploads_log = gr.State([])
267
  chatbot = gr.Chatbot(
268
  label="Agent",
269
- type="messages",
 
 
270
  avatar_images=(
271
- None,
272
- "https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/communication/Alfred.png",
 
273
  ),
274
- resizeable=True,
275
- scale=1,
276
  )
277
  # If an upload folder is provided, enable the upload feature
278
  if self.file_upload_folder is not None:
279
- upload_file = gr.File(label="Upload a file")
280
- upload_status = gr.Textbox(label="Upload Status", interactive=False, visible=False)
 
 
281
  upload_file.change(
282
  self.upload_file,
283
  [upload_file, file_uploads_log],
284
  [upload_status, file_uploads_log],
285
  )
286
- text_input = gr.Textbox(lines=1, label="Chat Message")
287
- text_input.submit(
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  self.log_user_message,
289
  [text_input, file_uploads_log],
290
- [stored_messages, text_input],
291
- ).then(self.interact_with_agent, [stored_messages, chatbot], [chatbot])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
- demo.launch(debug=True, share=True, **kwargs)
 
 
 
294
 
295
 
296
- __all__ = ["stream_to_gradio", "GradioUI"]
 
17
  import os
18
  import re
19
  import shutil
20
+ import tempfile # Import für temporäre Dateien
21
  from typing import Optional
22
 
23
+ # Importiere PIL für Bildverarbeitung (füge 'Pillow' zu requirements.txt hinzu, falls nicht vorhanden)
24
+ try:
25
+ from PIL import Image
26
+ except ImportError:
27
+ print("WARNUNG: Pillow nicht installiert. Bildanzeige funktioniert möglicherweise nicht. Führe 'pip install Pillow' aus oder füge 'Pillow' zu requirements.txt hinzu.")
28
+ Image = None
29
+
30
  from smolagents.agent_types import AgentAudio, AgentImage, AgentText, handle_agent_output_types
31
  from smolagents.agents import ActionStep, MultiStepAgent
32
  from smolagents.memory import MemoryStep
 
39
  """Extract ChatMessage objects from agent steps with proper nesting"""
40
  import gradio as gr
41
 
42
+ # --- (Rest dieser Funktion bleibt unverändert) ---
43
  if isinstance(step_log, ActionStep):
44
  # Output the step number
45
  step_number = f"Step {step_log.step_number}" if step_log.step_number is not None else ""
 
165
  final_answer = step_log # Last log is the run's final_answer
166
  final_answer = handle_agent_output_types(final_answer)
167
 
168
+ # --- *** HIER IST DIE ÄNDERUNG FÜR DIE BILDANZEIGE *** ---
169
  if isinstance(final_answer, AgentText):
170
  yield gr.ChatMessage(
171
  role="assistant",
172
  content=f"**Final answer:**\n{final_answer.to_string()}\n",
173
  )
174
  elif isinstance(final_answer, AgentImage):
175
+ # Versuche, das Bild anzuzeigen
176
+ try:
177
+ # Annahme: final_answer.image enthält ein PIL Image Objekt
178
+ if Image is not None and hasattr(final_answer, 'image') and isinstance(final_answer.image, Image.Image):
179
+ # Erstelle eine temporäre Datei zum Speichern des Bildes
180
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmpfile:
181
+ final_answer.image.save(tmpfile.name, format="PNG")
182
+ temp_file_path = tmpfile.name
183
+ print(f"Bild temporär gespeichert unter: {temp_file_path}") # Debugging-Ausgabe
184
+
185
+ # Gib das ChatMessage mit dem Pfad zur temporären Datei zurück
186
+ yield gr.ChatMessage(
187
+ role="assistant",
188
+ content={"path": temp_file_path, "mime_type": "image/png"},
189
+ # Optional: Füge Text hinzu, falls die Bildanzeige fehlschlägt
190
+ # content=f"Generated Image (saved at {temp_file_path}):",
191
+ )
192
+ else:
193
+ # Fallback, wenn .image nicht das erwartete PIL-Objekt ist oder Pillow fehlt
194
+ print("WARNUNG: Konnte Bild nicht als PIL-Objekt interpretieren. Zeige Text-Repräsentation.")
195
+ yield gr.ChatMessage(role="assistant", content=f"**Final answer (Image Object):** {str(final_answer)}")
196
+
197
+ except Exception as e:
198
+ print(f"FEHLER beim Verarbeiten/Anzeigen des Bildes: {e}")
199
+ # Fallback zur Textanzeige bei Fehlern
200
+ yield gr.ChatMessage(role="assistant", content=f"**Final answer (Error displaying Image):** {str(final_answer)}")
201
+
202
  elif isinstance(final_answer, AgentAudio):
203
+ # Annahme: Funktioniert ähnlich wie bei Bildern, falls nötig anpassen
204
  yield gr.ChatMessage(
205
  role="assistant",
206
  content={"path": final_answer.to_string(), "mime_type": "audio/wav"},
207
  )
208
  else:
209
+ # Fallback für andere Typen
210
  yield gr.ChatMessage(role="assistant", content=f"**Final answer:** {str(final_answer)}")
211
 
212
 
 
221
  self.agent = agent
222
  self.file_upload_folder = file_upload_folder
223
  if self.file_upload_folder is not None:
224
+ # Erstelle Ordner, wenn er nicht existiert
225
+ os.makedirs(self.file_upload_folder, exist_ok=True)
226
+
227
 
228
  def interact_with_agent(self, prompt, messages):
229
  import gradio as gr
230
 
231
  messages.append(gr.ChatMessage(role="user", content=prompt))
232
  yield messages
233
+ # Verwende einen temporären Ordner für generierte Bilder, falls keiner angegeben ist
234
+ # Dies ist wichtig, damit Gradio auf die Dateien zugreifen kann
235
+ temp_image_dir = os.path.join(tempfile.gettempdir(), "gradio_agent_images")
236
+ os.makedirs(temp_image_dir, exist_ok=True)
237
+
238
+ # Füge den temporären Ordner zu additional_args hinzu,
239
+ # damit stream_to_gradio ihn verwenden kann (optional, aber sauberer)
240
+ # current_additional_args = {"image_output_dir": temp_image_dir}
241
+
242
+ # Iteriere durch die Nachrichten vom Agenten
243
+ for msg in stream_to_gradio(self.agent, task=prompt, reset_agent_memory=False): #, additional_args=current_additional_args):
244
  messages.append(msg)
245
  yield messages
246
  yield messages
247
 
248
+ # --- (Rest der Klasse GradioUI bleibt unverändert) ---
249
  def upload_file(
250
  self,
251
  file,
 
288
  sanitized_name.append("" + type_to_ext[mime_type])
289
  sanitized_name = "".join(sanitized_name)
290
 
291
+ # Ensure the upload folder exists
292
+ if self.file_upload_folder:
293
+ os.makedirs(self.file_upload_folder, exist_ok=True)
294
+ # Save the uploaded file to the specified folder
295
+ file_path = os.path.join(self.file_upload_folder, os.path.basename(sanitized_name))
296
+ shutil.copy(file.name, file_path)
297
+ return gr.Textbox(f"File uploaded: {file_path}", visible=True), file_uploads_log + [file_path]
298
+ else:
299
+ # Handle case where no upload folder is specified (optional)
300
+ return gr.Textbox("File upload folder not configured.", visible=True), file_uploads_log
301
 
 
302
 
303
  def log_user_message(self, text_input, file_uploads_log):
304
  return (
 
319
  file_uploads_log = gr.State([])
320
  chatbot = gr.Chatbot(
321
  label="Agent",
322
+ # type="messages", # 'type' ist veraltet, wird automatisch gehandhabt
323
+ elem_id="chatbot", # Gib dem Chatbot eine ID für CSS/JS (optional)
324
+ bubble_full_width=False, # Lässt Nachrichten nicht die volle Breite einnehmen (optional)
325
  avatar_images=(
326
+ None, # Kein Avatar für User
327
+ # Standard-Avatar für den Assistenten (URL oder lokaler Pfad)
328
+ "[https://huggingface.co/datasets/huggingface/brand-assets/resolve/main/hf-logo-round-with-padding.png](https://huggingface.co/datasets/huggingface/brand-assets/resolve/main/hf-logo-round-with-padding.png)"
329
  ),
330
+ # height=600, # Setze eine feste Höhe (optional)
331
+ render=False # Wir rendern es manuell unten
332
  )
333
  # If an upload folder is provided, enable the upload feature
334
  if self.file_upload_folder is not None:
335
+ with gr.Row(): # Ordne Upload-Elemente an
336
+ upload_file = gr.File(label="Upload a file", scale=1) # Nimmt weniger Platz
337
+ upload_status = gr.Textbox(label="Upload Status", interactive=False, visible=False, scale=2) # Mehr Platz für Status
338
+
339
  upload_file.change(
340
  self.upload_file,
341
  [upload_file, file_uploads_log],
342
  [upload_status, file_uploads_log],
343
  )
344
+
345
+ with gr.Row(): # Ordne Textfeld und Senden-Button an (optional)
346
+ text_input = gr.Textbox(
347
+ lines=1,
348
+ label="Chat Message",
349
+ placeholder="Type your message here...",
350
+ scale=4 # Gib dem Textfeld mehr Breite
351
+ )
352
+ # submit_button = gr.Button("Send", scale=1) # Optionaler Senden-Button
353
+
354
+ # Rendere den Chatbot hier, damit er über dem Eingabefeld ist
355
+ chatbot.render()
356
+
357
+ # Definiere die Submit-Aktion
358
+ submit_action = text_input.submit(
359
  self.log_user_message,
360
  [text_input, file_uploads_log],
361
+ [stored_messages, text_input], # Leere Textbox nach Senden
362
+ ).then(
363
+ self.interact_with_agent,
364
+ [stored_messages, chatbot],
365
+ [chatbot] # Update Chatbot
366
+ )
367
+
368
+ # Verknüpfe auch den Button mit der Aktion (falls vorhanden)
369
+ # submit_button.click(
370
+ # self.log_user_message,
371
+ # [text_input, file_uploads_log],
372
+ # [stored_messages, text_input],
373
+ # ).then(
374
+ # self.interact_with_agent,
375
+ # [stored_messages, chatbot],
376
+ # [chatbot]
377
+ # )
378
 
379
+ # Starte die Demo
380
+ # Entferne share=True, da es auf Spaces nicht unterstützt wird und Warnungen verursacht
381
+ # Füge inline=False hinzu, um sicherzustellen, dass es nicht versucht, inline in Notebooks zu laufen
382
+ demo.launch(debug=True, share=False, inline=False, **kwargs)
383
 
384
 
385
+ __all__ = ["stream_to_gradio", "GradioUI"]