Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -6,40 +6,22 @@ from smolagents import CodeAgent, Tool
|
|
6 |
from smolagents.models import HfApiModel
|
7 |
from smolagents.monitoring import LogLevel
|
8 |
from gradio import ChatMessage
|
9 |
-
import logging
|
10 |
from functools import lru_cache
|
11 |
|
12 |
-
# Configure logging
|
13 |
-
logging.basicConfig(level=logging.INFO)
|
14 |
-
logger = logging.getLogger(__name__)
|
15 |
-
|
16 |
DEFAULT_MODEL = "Qwen/Qwen2.5-Coder-32B-Instruct"
|
17 |
HF_API_TOKEN = os.getenv("HF_TOKEN")
|
18 |
|
19 |
-
# Tool descriptions for the UI
|
20 |
-
TOOL_DESCRIPTIONS = {
|
21 |
-
"Hub Collections": "Add tool collections from Hugging Face Hub.",
|
22 |
-
"Spaces": "Add tools from Hugging Face Spaces.",
|
23 |
-
}
|
24 |
-
|
25 |
@lru_cache(maxsize=128)
|
26 |
def search_spaces(query, limit=1):
|
27 |
-
"""
|
28 |
-
Search for Hugging Face Spaces using the API.
|
29 |
-
Returns the first result or None if no results.
|
30 |
-
"""
|
31 |
try:
|
32 |
url = f"https://huggingface.co/api/spaces?search={query}&limit={limit}"
|
33 |
-
response = requests.get(
|
34 |
-
url, headers={"Authorization": f"Bearer {HF_API_TOKEN}"}
|
35 |
-
)
|
36 |
response.raise_for_status()
|
37 |
spaces = response.json()
|
38 |
if not spaces:
|
39 |
return None
|
40 |
return extract_space_info(spaces[0])
|
41 |
-
except requests.RequestException
|
42 |
-
logger.error(f"Error searching spaces: {e}")
|
43 |
return None
|
44 |
|
45 |
def extract_space_info(space):
|
@@ -57,33 +39,27 @@ def extract_space_info(space):
|
|
57 |
return {"id": space_id, "title": title, "description": description}
|
58 |
|
59 |
def get_space_metadata(space_id):
|
60 |
-
"""
|
61 |
-
Get metadata for a specific Hugging Face Space.
|
62 |
-
"""
|
63 |
try:
|
64 |
url = f"https://huggingface.co/api/spaces/{space_id}"
|
65 |
-
response = requests.get(
|
66 |
-
url, headers={"Authorization": f"Bearer {HF_API_TOKEN}"}
|
67 |
-
)
|
68 |
response.raise_for_status()
|
69 |
space = response.json()
|
70 |
return extract_space_info(space)
|
71 |
-
except requests.RequestException
|
72 |
-
logger.error(f"Error getting space metadata: {e}")
|
73 |
return None
|
74 |
|
75 |
def create_agent(model_name, space_tools=None):
|
76 |
-
"""
|
77 |
-
Create a CodeAgent with the specified model and tools.
|
78 |
-
"""
|
79 |
if not space_tools:
|
80 |
space_tools = []
|
81 |
try:
|
82 |
-
tools = [
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
|
|
|
|
|
|
87 |
model = HfApiModel(model_id=model_name, token=HF_API_TOKEN)
|
88 |
agent = CodeAgent(
|
89 |
tools=tools,
|
@@ -91,12 +67,9 @@ def create_agent(model_name, space_tools=None):
|
|
91 |
additional_authorized_imports=["PIL", "requests"],
|
92 |
verbosity_level=LogLevel.DEBUG,
|
93 |
)
|
94 |
-
logger.info(f"Agent created successfully with {len(tools)} tools")
|
95 |
return agent
|
96 |
-
except
|
97 |
-
logger.error(f"Error creating agent: {e}")
|
98 |
try:
|
99 |
-
logger.info("Trying fallback model...")
|
100 |
fallback_model = HfApiModel(
|
101 |
model_id="Qwen/Qwen2.5-Coder-7B-Instruct", token=HF_API_TOKEN
|
102 |
)
|
@@ -106,13 +79,10 @@ def create_agent(model_name, space_tools=None):
|
|
106 |
additional_authorized_imports=["PIL", "requests"],
|
107 |
verbosity_level=LogLevel.DEBUG,
|
108 |
)
|
109 |
-
logger.info("Agent created successfully with fallback model")
|
110 |
return agent
|
111 |
-
except
|
112 |
-
logger.error(f"Error creating agent with fallback model: {e}")
|
113 |
return None
|
114 |
|
115 |
-
# Event handler functions
|
116 |
def on_search_spaces(query):
|
117 |
if not query:
|
118 |
return "Please enter a search term.", "", "", ""
|
@@ -120,10 +90,13 @@ def on_search_spaces(query):
|
|
120 |
space_info = search_spaces(query)
|
121 |
if space_info is None:
|
122 |
return "No spaces found.", "", "", ""
|
123 |
-
results_md =
|
|
|
|
|
|
|
|
|
124 |
return results_md, space_info["id"], space_info["title"], space_info["description"]
|
125 |
except Exception as e:
|
126 |
-
logger.error(f"Error in search: {e}")
|
127 |
return f"Error: {str(e)}", "", "", ""
|
128 |
|
129 |
def on_validate_space(space_id):
|
@@ -135,12 +108,17 @@ def on_validate_space(space_id):
|
|
135 |
space_info = search_spaces(space_id)
|
136 |
if space_info is None:
|
137 |
return f"No spaces found for '{space_id}'.", "", ""
|
138 |
-
result_md =
|
|
|
|
|
|
|
139 |
return result_md, space_info["title"], space_info["description"]
|
140 |
-
result_md =
|
|
|
|
|
|
|
141 |
return result_md, space_info["title"], space_info["description"]
|
142 |
except Exception as e:
|
143 |
-
logger.error(f"Error validating space: {e}")
|
144 |
return f"Error: {str(e)}", "", ""
|
145 |
|
146 |
def on_add_tool(space_id, space_name, space_description, current_tools):
|
@@ -157,7 +135,9 @@ def on_add_tool(space_id, space_name, space_description, current_tools):
|
|
157 |
updated_tools = current_tools + [new_tool]
|
158 |
tools_md = "### Added Tools:\n"
|
159 |
for i, tool in enumerate(updated_tools, 1):
|
160 |
-
tools_md +=
|
|
|
|
|
161 |
return updated_tools, tools_md
|
162 |
|
163 |
def on_create_agent(model, space_tools):
|
@@ -167,11 +147,10 @@ def on_create_agent(model, space_tools):
|
|
167 |
agent = create_agent(model, space_tools)
|
168 |
if agent is None:
|
169 |
return None, [], "", "Failed to create agent. Please try again with different tools or model.", "No agent created yet."
|
170 |
-
tools_str = ", ".join([f"{
|
171 |
agent_status = update_agent_status(agent)
|
172 |
return agent, [], "", f"✅ Agent created successfully with {model}!\nTools: {tools_str}", agent_status
|
173 |
except Exception as e:
|
174 |
-
logger.error(f"Error creating agent: {e}")
|
175 |
return None, [], "", f"Error creating agent: {str(e)}", "No agent created yet."
|
176 |
|
177 |
def add_user_message(message, chat_history):
|
@@ -217,11 +196,8 @@ def update_agent_status(agent):
|
|
217 |
if agent is None:
|
218 |
return "No agent created yet. Add a Space tool to get started."
|
219 |
tools = agent.tools if hasattr(agent, "tools") else []
|
220 |
-
|
221 |
-
status = f"Agent ready with {tool_count} tools"
|
222 |
-
return status
|
223 |
|
224 |
-
# Create the Gradio app
|
225 |
with gr.Blocks(title="AI Agent Builder") as app:
|
226 |
gr.Markdown("# AI Agent Builder with smolagents")
|
227 |
gr.Markdown("Build your own AI agent by selecting tools from Hugging Face Spaces.")
|
@@ -236,9 +212,20 @@ with gr.Blocks(title="AI Agent Builder") as app:
|
|
236 |
model_input = gr.Textbox(value=DEFAULT_MODEL, label="Model", visible=False)
|
237 |
with gr.Group():
|
238 |
gr.Markdown("### Add Space as Tool")
|
239 |
-
space_tool_input = gr.Textbox(
|
240 |
-
|
241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
add_tool_button = gr.Button("Add Tool", variant="primary")
|
243 |
gr.Markdown("### Added Tools")
|
244 |
tools_display = gr.Markdown("No tools added yet. Add at least one tool before creating an agent.")
|
@@ -256,7 +243,9 @@ with gr.Blocks(title="AI Agent Builder") as app:
|
|
256 |
space_tool_input.submit(on_validate_space, inputs=[space_tool_input], outputs=[status_msg, space_name_input, space_description_input])
|
257 |
add_tool_button.click(on_add_tool, inputs=[space_tool_input, space_name_input, space_description_input, space_tools_state], outputs=[space_tools_state, tools_display])
|
258 |
create_button.click(on_create_agent, inputs=[model_input, space_tools_state], outputs=[agent_state, chatbot, msg, status_msg, agent_status])
|
259 |
-
msg.submit(lambda message: (message, message, ""), inputs=[msg], outputs=[msg_store, msg, msg], queue=False)
|
|
|
|
|
260 |
|
261 |
if __name__ == "__main__":
|
262 |
app.queue().launch()
|
|
|
6 |
from smolagents.models import HfApiModel
|
7 |
from smolagents.monitoring import LogLevel
|
8 |
from gradio import ChatMessage
|
|
|
9 |
from functools import lru_cache
|
10 |
|
|
|
|
|
|
|
|
|
11 |
DEFAULT_MODEL = "Qwen/Qwen2.5-Coder-32B-Instruct"
|
12 |
HF_API_TOKEN = os.getenv("HF_TOKEN")
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
@lru_cache(maxsize=128)
|
15 |
def search_spaces(query, limit=1):
|
|
|
|
|
|
|
|
|
16 |
try:
|
17 |
url = f"https://huggingface.co/api/spaces?search={query}&limit={limit}"
|
18 |
+
response = requests.get(url, headers={"Authorization": f"Bearer {HF_API_TOKEN}"})
|
|
|
|
|
19 |
response.raise_for_status()
|
20 |
spaces = response.json()
|
21 |
if not spaces:
|
22 |
return None
|
23 |
return extract_space_info(spaces[0])
|
24 |
+
except requests.RequestException:
|
|
|
25 |
return None
|
26 |
|
27 |
def extract_space_info(space):
|
|
|
39 |
return {"id": space_id, "title": title, "description": description}
|
40 |
|
41 |
def get_space_metadata(space_id):
|
|
|
|
|
|
|
42 |
try:
|
43 |
url = f"https://huggingface.co/api/spaces/{space_id}"
|
44 |
+
response = requests.get(url, headers={"Authorization": f"Bearer {HF_API_TOKEN}"})
|
|
|
|
|
45 |
response.raise_for_status()
|
46 |
space = response.json()
|
47 |
return extract_space_info(space)
|
48 |
+
except requests.RequestException:
|
|
|
49 |
return None
|
50 |
|
51 |
def create_agent(model_name, space_tools=None):
|
|
|
|
|
|
|
52 |
if not space_tools:
|
53 |
space_tools = []
|
54 |
try:
|
55 |
+
tools = [
|
56 |
+
Tool.from_space(
|
57 |
+
t["id"],
|
58 |
+
name=t.get("name", t["id"]),
|
59 |
+
description=t.get("description", ""),
|
60 |
+
)
|
61 |
+
for t in space_tools
|
62 |
+
]
|
63 |
model = HfApiModel(model_id=model_name, token=HF_API_TOKEN)
|
64 |
agent = CodeAgent(
|
65 |
tools=tools,
|
|
|
67 |
additional_authorized_imports=["PIL", "requests"],
|
68 |
verbosity_level=LogLevel.DEBUG,
|
69 |
)
|
|
|
70 |
return agent
|
71 |
+
except:
|
|
|
72 |
try:
|
|
|
73 |
fallback_model = HfApiModel(
|
74 |
model_id="Qwen/Qwen2.5-Coder-7B-Instruct", token=HF_API_TOKEN
|
75 |
)
|
|
|
79 |
additional_authorized_imports=["PIL", "requests"],
|
80 |
verbosity_level=LogLevel.DEBUG,
|
81 |
)
|
|
|
82 |
return agent
|
83 |
+
except:
|
|
|
84 |
return None
|
85 |
|
|
|
86 |
def on_search_spaces(query):
|
87 |
if not query:
|
88 |
return "Please enter a search term.", "", "", ""
|
|
|
90 |
space_info = search_spaces(query)
|
91 |
if space_info is None:
|
92 |
return "No spaces found.", "", "", ""
|
93 |
+
results_md = (
|
94 |
+
f"### Search Results:\n- ID: `{space_info['id']}`\n"
|
95 |
+
f"- Title: {space_info['title']}\n"
|
96 |
+
f"- Description: {space_info['description']}\n"
|
97 |
+
)
|
98 |
return results_md, space_info["id"], space_info["title"], space_info["description"]
|
99 |
except Exception as e:
|
|
|
100 |
return f"Error: {str(e)}", "", "", ""
|
101 |
|
102 |
def on_validate_space(space_id):
|
|
|
108 |
space_info = search_spaces(space_id)
|
109 |
if space_info is None:
|
110 |
return f"No spaces found for '{space_id}'.", "", ""
|
111 |
+
result_md = (
|
112 |
+
f"### Found Space via Search:\n- ID: `{space_info['id']}`\n"
|
113 |
+
f"- Title: {space_info['title']}\n- Description: {space_info['description']}\n"
|
114 |
+
)
|
115 |
return result_md, space_info["title"], space_info["description"]
|
116 |
+
result_md = (
|
117 |
+
f"### Space Validated Successfully:\n- ID: `{space_info['id']}`\n"
|
118 |
+
f"- Title: {space_info['title']}\n- Description: {space_info['description']}\n"
|
119 |
+
)
|
120 |
return result_md, space_info["title"], space_info["description"]
|
121 |
except Exception as e:
|
|
|
122 |
return f"Error: {str(e)}", "", ""
|
123 |
|
124 |
def on_add_tool(space_id, space_name, space_description, current_tools):
|
|
|
135 |
updated_tools = current_tools + [new_tool]
|
136 |
tools_md = "### Added Tools:\n"
|
137 |
for i, tool in enumerate(updated_tools, 1):
|
138 |
+
tools_md += (
|
139 |
+
f"{i}. **{tool['name']}** (`{tool['id']}`)\n {tool['description']}\n\n"
|
140 |
+
)
|
141 |
return updated_tools, tools_md
|
142 |
|
143 |
def on_create_agent(model, space_tools):
|
|
|
147 |
agent = create_agent(model, space_tools)
|
148 |
if agent is None:
|
149 |
return None, [], "", "Failed to create agent. Please try again with different tools or model.", "No agent created yet."
|
150 |
+
tools_str = ", ".join([f"{t['name']} ({t['id']})" for t in space_tools])
|
151 |
agent_status = update_agent_status(agent)
|
152 |
return agent, [], "", f"✅ Agent created successfully with {model}!\nTools: {tools_str}", agent_status
|
153 |
except Exception as e:
|
|
|
154 |
return None, [], "", f"Error creating agent: {str(e)}", "No agent created yet."
|
155 |
|
156 |
def add_user_message(message, chat_history):
|
|
|
196 |
if agent is None:
|
197 |
return "No agent created yet. Add a Space tool to get started."
|
198 |
tools = agent.tools if hasattr(agent, "tools") else []
|
199 |
+
return f"Agent ready with {len(tools)} tools"
|
|
|
|
|
200 |
|
|
|
201 |
with gr.Blocks(title="AI Agent Builder") as app:
|
202 |
gr.Markdown("# AI Agent Builder with smolagents")
|
203 |
gr.Markdown("Build your own AI agent by selecting tools from Hugging Face Spaces.")
|
|
|
212 |
model_input = gr.Textbox(value=DEFAULT_MODEL, label="Model", visible=False)
|
213 |
with gr.Group():
|
214 |
gr.Markdown("### Add Space as Tool")
|
215 |
+
space_tool_input = gr.Textbox(
|
216 |
+
label="Space ID or Search Term",
|
217 |
+
placeholder="Enter a Space ID (username/space-name) or search term",
|
218 |
+
info="Enter a Space ID (username/space-name) or search term"
|
219 |
+
)
|
220 |
+
space_name_input = gr.Textbox(
|
221 |
+
label="Tool Name (optional)",
|
222 |
+
placeholder="Enter a name for this tool"
|
223 |
+
)
|
224 |
+
space_description_input = gr.Textbox(
|
225 |
+
label="Tool Description (optional)",
|
226 |
+
placeholder="Enter a description for this tool",
|
227 |
+
lines=2
|
228 |
+
)
|
229 |
add_tool_button = gr.Button("Add Tool", variant="primary")
|
230 |
gr.Markdown("### Added Tools")
|
231 |
tools_display = gr.Markdown("No tools added yet. Add at least one tool before creating an agent.")
|
|
|
243 |
space_tool_input.submit(on_validate_space, inputs=[space_tool_input], outputs=[status_msg, space_name_input, space_description_input])
|
244 |
add_tool_button.click(on_add_tool, inputs=[space_tool_input, space_name_input, space_description_input, space_tools_state], outputs=[space_tools_state, tools_display])
|
245 |
create_button.click(on_create_agent, inputs=[model_input, space_tools_state], outputs=[agent_state, chatbot, msg, status_msg, agent_status])
|
246 |
+
msg.submit(lambda message: (message, message, ""), inputs=[msg], outputs=[msg_store, msg, msg], queue=False)\
|
247 |
+
.then(add_user_message, inputs=[msg_store, chatbot], outputs=[msg_store, chatbot], queue=False)\
|
248 |
+
.then(stream_agent_response, inputs=[agent_state, msg_store, chatbot], outputs=chatbot, queue=True)
|
249 |
|
250 |
if __name__ == "__main__":
|
251 |
app.queue().launch()
|