Brunwo commited on
Commit
5a0d86a
·
1 Parent(s): 60f49cc
Files changed (1) hide show
  1. app.py +134 -127
app.py CHANGED
@@ -1,34 +1,90 @@
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
- import random
4
- import time
5
- from io import StringIO
6
- import sys
7
- import pprint
8
- import inspect
9
- from HFHub import login_for_publication, litellm_api_keys, load_collection_from_space
10
- from HFHub import createAgent
11
- from typing import Dict
12
  import os
13
  import logging
14
-
15
- def dropdown_update_choices(choices):
16
- return gr.update(choices=choices, value=None)
17
-
18
  # Configure logging
19
- logging.basicConfig(level=logging.INFO) # not working (prints warnings tho)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- # os.environ['HF_TOKEN'] = "..."
22
- # hf_token = os.environ.get("HF_TOKEN")
 
 
 
 
23
 
24
- logging.warning('start')
25
 
 
26
  agent = createAgent()
27
 
28
- def update_agent(collection_slug: str):
29
- load_collection_from_space(agent, collection_slug=collection_slug)
30
- return refresh_ui_elements() # Update the UI elements after loading the collection
31
-
32
 
33
  def process_logs(agent):
34
  logs = ""
@@ -37,8 +93,7 @@ def process_logs(agent):
37
  if hasattr(entry, 'llm_output'):
38
  logs += str(entry.llm_output) + "\n"
39
  return logs
40
- else:
41
- return "The agent object does not have a valid 'logs' attribute or the attribute is not a list."
42
 
43
  def get_tools():
44
  return [{"name": tool.name, "description": tool.description} for tool in agent.tools.values()]
@@ -46,113 +101,94 @@ def get_tools():
46
  def get_functions():
47
  return agent.python_executor.custom_tools
48
 
49
-
50
-
51
  def get_function_code(selected_function_name):
52
  func = get_functions().get(selected_function_name)
53
  if func:
54
  try:
55
  return inspect.getsource(func)
56
-
57
  except OSError:
58
- return "Source code not available for this function."
59
  return "Function not found."
60
 
61
- def get_tool_description(selected_tool_name, tools):
 
 
 
 
62
  for tool in tools:
63
  if tool["name"] == selected_tool_name:
64
  return tool["description"]
65
  return "No description available."
66
 
67
- def get_tools_name():
68
- return [tool["name"] for tool in get_tools()]
69
-
70
-
71
  def refresh_ui_elements():
72
- updated_tools = get_tools() # Get the updated tools after loading the collection
 
73
  updated_functions = get_functions()
74
 
75
  tool_names = [tool["name"] for tool in updated_tools]
 
76
  function_names = list(updated_functions.keys())
77
 
78
- print(f"function_names: {function_names}")
79
-
80
  current_tool = tool_names[0] if tool_names else None
81
  current_function = function_names[0] if function_names else None
82
 
83
- tool_description = get_tool_description(current_tool, updated_tools)
84
  function_code = get_function_code(current_function) if current_function else ""
85
 
86
- # Update dropdown choices
87
  tool_dropdown_update = dropdown_update_choices(tool_names)
88
  function_dropdown_update = dropdown_update_choices(function_names)
89
- return (
90
- tool_dropdown_update,
91
- function_dropdown_update,
92
- tool_description,
93
- function_code
94
- )
95
 
96
- def load_collection_andUploadUI(collection_slug: str ):
97
- # load_collection_from_space(agent,collection_slug)
98
- refresh_ui_elements()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
  with gr.Blocks() as demo:
101
  with gr.Row():
102
  with gr.Column():
103
  with gr.Tab("Chat"):
104
- gr.Markdown("<center><h1>smolAgent chat</h1></center>")
105
  chatbot = gr.Chatbot(type="messages")
106
  msg = gr.Textbox()
107
-
108
- # send_button = gr.Button("Send") # Send button
109
- # send_button.click(respond, [msg, chatbot], [msg, chatbot])
110
-
111
  clear = gr.ClearButton([msg, chatbot])
112
 
113
  with gr.Tab("Console"):
114
- outputbox = gr.Textbox(
115
- lines=25,
116
- scale=1,
117
- interactive=False
118
- )
119
-
120
- with gr.Tab("config"):
121
 
122
- local_storage = gr.BrowserState(["", ""])
123
  gr.Markdown("## Configure litellm API Keys")
124
- api_key_inputs = {}
125
- for provider in litellm_api_keys.keys():
126
- with gr.Row():
127
- api_key_inputs[provider] = gr.Textbox(
128
- label=f'{provider} API Key',
129
- placeholder='Enter key',
130
- type='password',
131
- value=litellm_api_keys[provider]
132
- )
133
-
134
- #TODO : save keys to localstorage
135
-
136
- # api_key_inputs[provider]
137
- # save_keys_button = gr.Button('Save Configuration')
138
-
139
-
140
- # @gr.on(api_key_inputs[provider].change, inputs=[api_key_inputs[provider]], outputs=[local_storage])
141
- # def save_to_local_storage(text):
142
- # return [text]
143
-
144
- # # Load from local storage when page loads
145
- # @demo.load(inputs=[local_storage], outputs=[input_text])
146
- # def load_from_local_storage(saved_values):
147
- # return saved_values[0]
148
-
149
-
150
 
151
  with gr.Column():
152
- gr.Markdown("<center><h1>tool collection</h1></center>")
153
-
154
-
155
  tools = get_tools()
 
156
  tool_dropdown = gr.Dropdown(
157
  show_label=False,
158
  choices=[tool["name"] for tool in tools],
@@ -164,13 +200,12 @@ with gr.Blocks() as demo:
164
 
165
  description_textbox = gr.Textbox(
166
  label="Tool Description",
167
- value=get_tool_description(tool_dropdown.value, tools),
168
  interactive=False,
169
  )
170
 
171
- slug = gr.Textbox(label="collection slug",value="Mightypeacock/agent-tools-6777c9699c231b7a1e87fa31")
172
  greet_btn = gr.Button("Load")
173
-
174
 
175
 
176
  gr.Markdown("<center><h2>Functions</h2></center>")
@@ -186,7 +221,7 @@ with gr.Blocks() as demo:
186
 
187
  tool_dropdown.change(
188
  fn=get_tool_description,
189
- inputs=[tool_dropdown, gr.State(tools)],
190
  outputs=description_textbox,
191
  )
192
 
@@ -195,40 +230,12 @@ with gr.Blocks() as demo:
195
  inputs=function_dropdown,
196
  outputs=code,
197
  )
198
-
199
- greet_btn.click(fn=update_agent, inputs=slug,
200
-
201
- outputs=[tool_dropdown, function_dropdown, description_textbox, code],
202
- # outputs=tool_dropdown,
203
- # outputs=None,
204
- api_name="load_HF_Collection")
205
-
206
- def respond(message, console_output, chat_history):
207
- try:
208
- print(f"Received message: {message}")
209
-
210
- if not isinstance(message, str):
211
- message = str(message)
212
-
213
- bot_message = agent.run(message)
214
- new_console_output = process_logs(agent)
215
-
216
- print(f"Agent response: {bot_message}")
217
- print(f"Console output: {new_console_output}")
218
-
219
- chat_history.extend([
220
- {"role": "user", "content": message},
221
- {"role": "assistant", "content": bot_message}
222
- ])
223
-
224
- updated_console = console_output + f"\nQuery: {message}\nLogs: {new_console_output}"
225
-
226
- tool_dropdown_update, function_dropdown_update, description_update, code_update = refresh_ui_elements()
227
- return "", updated_console, chat_history, tool_dropdown_update, function_dropdown_update, description_update, code_update
228
-
229
- except Exception as e:
230
- print(f"Error in respond function: {e}")
231
- return f"An error occurred: {str(e)}", console_output, chat_history, None, None, None, None
232
 
233
  msg.submit(
234
  respond,
 
1
  import gradio as gr
2
+ from typing import Dict, List, Set
 
 
 
 
 
 
 
 
 
3
  import os
4
  import logging
5
+ import inspect
6
+ from huggingface_hub import login
7
+ from smolagents import ToolCollection, CodeAgent, Tool, HfApiModel
 
8
  # Configure logging
9
+ logging.basicConfig(level=logging.INFO)
10
+ logging.warning('Starting application...')
11
+
12
+ # Global variables
13
+ publishtoken = None
14
+ tool_Collections: dict[str, ToolCollection] = {}
15
+ loaded_tools: Set[Tool] = set()
16
+
17
+ # API keys for litellm providers
18
+ litellm_api_keys = {
19
+ 'xai': '',
20
+ 'HF': '',
21
+ 'grok': '',
22
+ 'anthropic': '',
23
+ 'openAI': '',
24
+ }
25
+
26
+ def all_tools_names() -> List[str]:
27
+ """Return a list of all tool names from loaded collections."""
28
+ all_tools = []
29
+ for collection in tool_Collections.values():
30
+ if isinstance(collection, ToolCollection):
31
+ all_tools.extend(tool.name for tool in collection.tools)
32
+ else:
33
+ all_tools.extend(collection)
34
+ return all_tools
35
+
36
+ def filter_tools(tools):
37
+ """Filter out base tools from a list of tools."""
38
+ if tools is None:
39
+ logging.warning("Received None for tools, defaulting to an empty list.")
40
+ tools = []
41
+
42
+ base_tools_names = ['web search']
43
+ return [tool for tool in tools if tool not in base_tools_names]
44
+
45
+ def load_collection_from_space(agent: CodeAgent, collection_slug: str) -> List[str]:
46
+ """Load a collection of tools from a Hugging Face space."""
47
+ if collection_slug not in tool_Collections:
48
+ tool_collection = ToolCollection(
49
+ collection_slug=collection_slug,
50
+ trust_remote_code=True
51
+ )
52
+
53
+ tool_Collections[collection_slug] = [tool.name for tool in tool_collection.tools]
54
+
55
+ for tool in tool_collection.tools:
56
+ if agent.tools.get(tool.name) is None:
57
+ agent.tools[tool.name] = tool
58
+ loaded_tools.add(tool)
59
+ else:
60
+ agent.tools[tool.name] = tool
61
+
62
+ return all_tools_names()
63
+
64
+ def createAgent() -> CodeAgent:
65
+ """Create and return a CodeAgent instance."""
66
+ agent = CodeAgent(
67
+ tools=filter_tools(list(loaded_tools)),
68
+ model=HfApiModel(),
69
+ additional_authorized_imports=["smolagents", "subprocess", "typing", "os", "inspect", "open", "requests"],
70
+ add_base_tools=True,
71
+ planning_interval=None,
72
+ )
73
 
74
+ # Add base tools to the collection
75
+ for tool in agent.tools:
76
+ if tool not in loaded_tools:
77
+ if "base tools" not in tool_Collections:
78
+ tool_Collections["base tools"] = []
79
+ tool_Collections["base tools"].append(tool)
80
 
81
+ return agent
82
 
83
+ # Initialize the agent
84
  agent = createAgent()
85
 
86
+ def dropdown_update_choices(choices):
87
+ return gr.update(choices=choices, value=None)
 
 
88
 
89
  def process_logs(agent):
90
  logs = ""
 
93
  if hasattr(entry, 'llm_output'):
94
  logs += str(entry.llm_output) + "\n"
95
  return logs
96
+ return "No logs available."
 
97
 
98
  def get_tools():
99
  return [{"name": tool.name, "description": tool.description} for tool in agent.tools.values()]
 
101
  def get_functions():
102
  return agent.python_executor.custom_tools
103
 
 
 
104
  def get_function_code(selected_function_name):
105
  func = get_functions().get(selected_function_name)
106
  if func:
107
  try:
108
  return inspect.getsource(func)
 
109
  except OSError:
110
+ return "Source code not available."
111
  return "Function not found."
112
 
113
+ def get_tool_description(selected_tool_name):
114
+
115
+ tools = get_tools()
116
+ print("Selected tool name:", selected_tool_name)
117
+ print("Tools:",tools )
118
  for tool in tools:
119
  if tool["name"] == selected_tool_name:
120
  return tool["description"]
121
  return "No description available."
122
 
 
 
 
 
123
  def refresh_ui_elements():
124
+ print("Refreshing UI elements...")
125
+ updated_tools = get_tools()
126
  updated_functions = get_functions()
127
 
128
  tool_names = [tool["name"] for tool in updated_tools]
129
+ print("Tool names:", tool_names)
130
  function_names = list(updated_functions.keys())
131
 
 
 
132
  current_tool = tool_names[0] if tool_names else None
133
  current_function = function_names[0] if function_names else None
134
 
135
+ tool_description = get_tool_description(current_tool)
136
  function_code = get_function_code(current_function) if current_function else ""
137
 
 
138
  tool_dropdown_update = dropdown_update_choices(tool_names)
139
  function_dropdown_update = dropdown_update_choices(function_names)
 
 
 
 
 
 
140
 
141
+ return tool_dropdown_update, function_dropdown_update, tool_description, function_code
142
+
143
+ def update_agent(collection_slug: str):
144
+ load_collection_from_space(agent, collection_slug=collection_slug)
145
+ return refresh_ui_elements()
146
+
147
+ def respond(message, console_output, chat_history):
148
+ try:
149
+ bot_message = agent.run(message)
150
+ new_console_output = process_logs(agent)
151
+
152
+ chat_history.extend([
153
+ {"role": "user", "content": message},
154
+ {"role": "assistant", "content": bot_message}
155
+ ])
156
+
157
+ updated_console = console_output + f"\nQuery: {message}\nLogs: {new_console_output}"
158
+ ui_updates = refresh_ui_elements()
159
+
160
+ return "", updated_console, chat_history, *ui_updates
161
+ except Exception as e:
162
+ logging.error(f"Error in respond function: {e}")
163
+ return f"An error occurred: {str(e)}", console_output, chat_history, None, None, None, None
164
 
165
  with gr.Blocks() as demo:
166
  with gr.Row():
167
  with gr.Column():
168
  with gr.Tab("Chat"):
169
+ gr.Markdown("<center><h1>smolAgent Chat</h1></center>")
170
  chatbot = gr.Chatbot(type="messages")
171
  msg = gr.Textbox()
 
 
 
 
172
  clear = gr.ClearButton([msg, chatbot])
173
 
174
  with gr.Tab("Console"):
175
+ outputbox = gr.Textbox(lines=25, scale=1, interactive=False)
 
 
 
 
 
 
176
 
177
+ with gr.Tab("Config"):
178
  gr.Markdown("## Configure litellm API Keys")
179
+ api_key_inputs = {
180
+ provider: gr.Textbox(
181
+ label=f'{provider} API Key',
182
+ placeholder='Enter key',
183
+ type='password',
184
+ value=litellm_api_keys[provider]
185
+ ) for provider in litellm_api_keys
186
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
  with gr.Column():
189
+ gr.Markdown("<center><h1>Tool Collection</h1></center>")
 
 
190
  tools = get_tools()
191
+
192
  tool_dropdown = gr.Dropdown(
193
  show_label=False,
194
  choices=[tool["name"] for tool in tools],
 
200
 
201
  description_textbox = gr.Textbox(
202
  label="Tool Description",
203
+ value=get_tool_description(tool_dropdown.value),
204
  interactive=False,
205
  )
206
 
207
+ slug = gr.Textbox(label="Collection Slug", value="Mightypeacock/agent-tools-6777c9699c231b7a1e87fa31")
208
  greet_btn = gr.Button("Load")
 
209
 
210
 
211
  gr.Markdown("<center><h2>Functions</h2></center>")
 
221
 
222
  tool_dropdown.change(
223
  fn=get_tool_description,
224
+ inputs=[tool_dropdown],
225
  outputs=description_textbox,
226
  )
227
 
 
230
  inputs=function_dropdown,
231
  outputs=code,
232
  )
233
+ greet_btn.click(
234
+ fn=update_agent,
235
+ inputs=slug,
236
+ outputs=[tool_dropdown, function_dropdown, description_textbox, code],
237
+ api_name="load_HF_Collection"
238
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
  msg.submit(
241
  respond,