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