Spaces:
Sleeping
Sleeping
File size: 9,413 Bytes
0d7df8b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
import io
from contextlib import redirect_stdout
import gradio as gr
from smolagents import (
load_tool,
CodeAgent,
ToolCallingAgent,
VLLMModel,
DuckDuckGoSearchTool,
VisitWebpageTool,
HfApiModel,
GradioUI,
AgentLogger,
LogLevel
)
from smolagents.models import MLXModel
import re
import html
import datetime
# Set up your model and logger
model = HfApiModel()
logger = AgentLogger(level=LogLevel.INFO)
# Import tool from Hub
image_generation_tool = load_tool("m-ric/text-to-image", trust_remote_code=True)
# Create your agents
search_agent = ToolCallingAgent(
tools=[DuckDuckGoSearchTool(), VisitWebpageTool()],
model=model,
name="search_agent",
description="This is an agent that can do web search.",
max_steps=12,
verbosity_level=1
)
mentor_agent = ToolCallingAgent(
tools=[DuckDuckGoSearchTool(), VisitWebpageTool()],
model=model,
name="mentor_agent",
description="This is an agent that creates a persona of a mentor based on the hackathon idea and gives feedback.",
max_steps=12,
planning_interval=2,
verbosity_level=1
)
design_research_agent = ToolCallingAgent(
tools=[DuckDuckGoSearchTool(), VisitWebpageTool()],
model=model,
name="design_research_agent",
description="Searches online for 3-star reviews and conversations on sites like Reddit as a form of 'user research",
max_steps=12,
planning_interval=2,
verbosity_level=1
)
visual_design_agent = ToolCallingAgent(
tools=[image_generation_tool],
model=MLXModel(model_id="HuggingFaceTB/SmolLM-135M-Instruct"),
name="visual_design_agent",
description="Creates, reviews, and iterates on front-end mockups of product ideas",
max_steps=12,
planning_interval=2,
verbosity_level=1
)
# Create a manager agent that can create more agents
manager_agent = CodeAgent(
tools=[],
model=model,
managed_agents=[search_agent, mentor_agent, design_research_agent, visual_design_agent],
name="manager_agent",
description="This agent can solve problems using code and delegate to other agents when needed.",
max_steps=12,
verbosity_level=1,
planning_interval=4
)
# Capture agent visualization
def get_agent_visualization():
buffer = io.StringIO()
with redirect_stdout(buffer):
logger.visualize_agent_tree(manager_agent)
return buffer.getvalue()
def clean_ansi_codes(text):
"""Remove ANSI color codes for clean display"""
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
return ansi_escape.sub('', text)
# Create a custom Gradio UI that extends the GradioUI class
class MonitoringGradioUI(GradioUI):
def __init__(self, agent, file_upload_folder=None):
super().__init__(agent, file_upload_folder)
self.name = "Agent Interface with Monitoring"
def launch(self, share=True, **kwargs):
with gr.Blocks(theme="ocean", fill_height=True) as demo:
# Add session state to store session-specific data
session_state = gr.State({})
stored_messages = gr.State([])
file_uploads_log = gr.State([])
with gr.Tab("Chat"):
with gr.Sidebar():
gr.Markdown(
f"# {self.name.replace('_', ' ').capitalize()}"
"\n> This web UI allows you to interact with a `smolagents` agent that can use tools and execute steps to complete tasks."
+ (f"\n\n**Agent description:**\n{self.description}" if self.description else "")
)
with gr.Group():
gr.Markdown("**Your request**", container=True)
text_input = gr.Textbox(
lines=3,
label="Chat Message",
container=False,
placeholder="Enter your prompt here and press Shift+Enter or press the button",
)
submit_btn = gr.Button("Submit", variant="primary")
# If an upload folder is provided, enable the upload feature
if self.file_upload_folder is not None:
upload_file = gr.File(label="Upload a file")
upload_status = gr.Textbox(label="Upload Status", interactive=False, visible=False)
upload_file.change(
self.upload_file,
[upload_file, file_uploads_log],
[upload_status, file_uploads_log],
)
gr.HTML("<br><br><h4><center>Powered by:</center></h4>")
with gr.Row():
gr.HTML("""<div style="display: flex; align-items: center; gap: 8px; font-family: system-ui, -apple-system, sans-serif;">
<img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smolagents/mascot_smol.png" style="width: 32px; height: 32px; object-fit: contain;" alt="logo">
<a target="_blank" href="https://github.com/huggingface/smolagents"><b>huggingface/smolagents</b></a>
</div>""")
# Main chat interface
chatbot = gr.Chatbot(
label="Agent",
type="messages",
avatar_images=(
None,
"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smolagents/mascot_smol.png",
),
resizeable=True,
scale=1,
)
# Set up event handlers
text_input.submit(
self.log_user_message,
[text_input, file_uploads_log],
[stored_messages, text_input, submit_btn],
).then(self.interact_with_agent, [stored_messages, chatbot, session_state], [chatbot]).then(
lambda: (
gr.Textbox(
interactive=True, placeholder="Enter your prompt here and press Shift+Enter or the button"
),
gr.Button(interactive=True),
),
None,
[text_input, submit_btn],
)
submit_btn.click(
self.log_user_message,
[text_input, file_uploads_log],
[stored_messages, text_input, submit_btn],
).then(self.interact_with_agent, [stored_messages, chatbot, session_state], [chatbot]).then(
lambda: (
gr.Textbox(
interactive=True, placeholder="Enter your prompt here and press Shift+Enter or the button"
),
gr.Button(interactive=True),
),
None,
[text_input, submit_btn],
)
# Add the Monitoring tab
with gr.Tab("Agent Monitoring"):
# Get the visualization text
agent_viz = get_agent_visualization()
agent_viz_clean = clean_ansi_codes(agent_viz)
# Convert the tree characters to HTML with proper formatting
html_viz = agent_viz_clean.replace("βββ", "ββ ").replace("βββ", "ββ ").replace("β", "β ")
html_viz = html.escape(html_viz)
html_viz = f"<pre style='font-family: monospace; white-space: pre; font-size: 14px;'>{html_viz}</pre>"
viz_html = gr.HTML(value=html_viz)
# Add a refresh button
refresh_btn = gr.Button("Refresh Agent Tree")
def refresh_viz():
new_viz = get_agent_visualization()
new_viz_clean = clean_ansi_codes(new_viz)
html_viz = new_viz_clean.replace("βββ", "ββ ").replace("βββ", "ββ ").replace("β", "β ")
html_viz = html.escape(html_viz)
html_viz = f"<pre style='font-family: monospace; white-space: pre; font-size: 14px;'>{html_viz}</pre>"
return html_viz
refresh_btn.click(refresh_viz, None, viz_html)
# Add some explanatory text
gr.Markdown("""
### Monitoring Information
This tab shows the structure of your agent, including:
- Hierarchical organization of agents
- Available tools for each agent
- Agent configurations
Use the refresh button to update the visualization if you modify your agent structure.
""")
demo.launch(debug=True, share=share, **kwargs)
# Create and launch your UI
# Make sure uploads directory exists
import os
os.makedirs("./uploads", exist_ok=True)
ui = MonitoringGradioUI(manager_agent, file_upload_folder="./uploads")
ui.launch(share=True) # Set share=False if you don't want to create a public link |