First_agent_smolagent / Gradio_UI.py
Ludo7127's picture
Create Gradio_UI.py
42887ea verified
import os
import re
import gradio as gr
class GradioUI:
"""
Gradio UI for a smolagents agent:
- unwraps FinalAnswerStep to plain text,
- extracts 'IMAGE:<path>' lines and shows them in a gallery,
- keeps chat and gallery state across messages (Spaces safe).
"""
def __init__(self, agent):
self.agent = agent
self.images_dir = os.path.abspath("generated_images")
os.makedirs(self.images_dir, exist_ok=True)
# --- helpers ------------------------------------------------------------
def _pretty_text(self, out):
# smolagents FinalAnswerTool result object
if hasattr(out, "final_answer"):
v = out.final_answer
return v if isinstance(v, str) else str(v)
# dict with "final_answer"
if isinstance(out, dict) and "final_answer" in out:
v = out["final_answer"]
return v if isinstance(v, str) else str(v)
# plain string or anything else
return out if isinstance(out, str) else str(out)
IMAGE_LINE_RE = re.compile(
r"^\s*(?:IMAGE|IMG_PATH)\s*:\s*(.+\.(?:png|jpg|jpeg|webp|bmp|gif))\s*$",
re.IGNORECASE | re.MULTILINE
)
def _extract_image_paths(self, text):
paths = []
for m in self.IMAGE_LINE_RE.finditer(text or ""):
p = m.group(1).strip().strip('"').strip("'")
p_abs = os.path.abspath(p)
if os.path.isfile(p_abs):
paths.append(p_abs)
return paths
# --- callbacks ----------------------------------------------------------
def _chat(self, history_state, message, gallery_state):
out = self.agent.run(message)
clean = self._pretty_text(out)
img_paths = self._extract_image_paths(clean)
# update conversation history
history = (history_state or []) + [(message, clean)]
# update gallery items
gallery_list = list(gallery_state or [])
for p in img_paths:
if p not in gallery_list:
gallery_list.append(p)
# Return updated states and component values
return history, gallery_list, history, gallery_list
def _clear(self):
# clear both the UI components and the states
return [], [], [], []
# --- layout -------------------------------------------------------------
def launch(self, **kwargs):
with gr.Blocks(fill_height=True) as demo:
gr.Markdown("## 🧠 Tools Agent (text + images) — Hugging Face Space")
with gr.Row():
chatbot = gr.Chatbot(label="Chat", height=420, type="messages")
gallery = gr.Gallery(label="Generated images", height=420, columns=[2], preview=True)
msg = gr.Textbox(placeholder="Ask: 'What's the time in America/New_York?' or 'Generate an image of a cat astronaut'", lines=2)
with gr.Row():
send = gr.Button("Send", variant="primary")
clear = gr.Button("Clear")
# persistent states
chat_state = gr.State([])
gallery_state = gr.State([])
send.click(
self._chat,
inputs=[chat_state, msg, gallery_state],
outputs=[chat_state, gallery_state, chatbot, gallery],
).then(
lambda: "",
inputs=None,
outputs=msg
)
clear.click(
self._clear,
inputs=None,
outputs=[chat_state, gallery_state, chatbot, gallery]
)
# queue() is recommended on Spaces
demo.queue().launch(**kwargs)