Akjava commited on
Commit
ca5d696
·
1 Parent(s): 003cac6
Files changed (6) hide show
  1. .gitignore +171 -0
  2. .gradio/certificate.pem +31 -0
  3. app.py +202 -0
  4. extra_search_tools.py +215 -0
  5. history.json +1 -0
  6. requirements.txt +42 -0
.gitignore ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
116
+ .pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121
+ __pypackages__/
122
+
123
+ # Celery stuff
124
+ celerybeat-schedule
125
+ celerybeat.pid
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .venv
133
+ env/
134
+ venv/
135
+ ENV/
136
+ env.bak/
137
+ venv.bak/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # PyCharm
164
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
167
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
+ #.idea/
169
+
170
+ # PyPI configuration file
171
+ .pypirc
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ -----END CERTIFICATE-----
app.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024-2025 Akihito Miyazaki.
2
+ # This code is derived from the DuckDuckGoSearchTool class,
3
+ # originally part of the HuggingFace smolagents library.
4
+ # https://github.com/huggingface/smolagents
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+
18
+ import os
19
+ import threading
20
+ from typing import Optional
21
+
22
+ from dotenv import load_dotenv
23
+ import gradio as gr
24
+ from smolagents import (
25
+ CodeAgent,
26
+ LiteLLMModel,
27
+ DuckDuckGoSearchTool,
28
+ )
29
+ from smolagents.agent_types import AgentText, AgentImage, AgentAudio
30
+ from smolagents.gradio_ui import pull_messages_from_step, handle_agent_output_types
31
+ from huggingface_hub import InferenceClient
32
+
33
+
34
+ from extra_search_tools import (
35
+ PrioritySearchTool,
36
+ BraveSearchTool,
37
+ GoogleCustomSearchTool,
38
+ )
39
+
40
+
41
+ def hf_chat(api_key, model, text):
42
+ client = InferenceClient(api_key=api_key)
43
+ messages = [
44
+ {
45
+ "role": "user",
46
+ "content": text,
47
+ }
48
+ ]
49
+
50
+ stream = client.chat.completions.create(
51
+ model=model, messages=messages, max_tokens=6000, stream=False
52
+ )
53
+
54
+ return stream.choices[0].message.content
55
+
56
+
57
+ load_dotenv(override=True)
58
+ # login(os.getenv("HF_TOKEN"))
59
+
60
+ append_answer_lock = threading.Lock()
61
+
62
+ # without below chat will duplicate
63
+ custom_role_conversions = {"tool-call": "assistant", "tool-response": "user"}
64
+
65
+ model = LiteLLMModel(
66
+ "groq/llama3-8b-8192",
67
+ api_base="https://api.groq.com/openai/v1",
68
+ max_completion_tokens=500,
69
+ api_key=os.getenv("GROQ_API_KEY"), # Groq API
70
+ )
71
+
72
+ search_tool = PrioritySearchTool(
73
+ [
74
+ DuckDuckGoSearchTool(),
75
+ GoogleCustomSearchTool("YOUR_ENGINE_KEY"),
76
+ BraveSearchTool(),
77
+ ],
78
+ "history.json",
79
+ )
80
+ WEB_TOOLS = [search_tool]
81
+
82
+ max_steps = 1
83
+
84
+
85
+ # Agent creation in a factory function
86
+ def create_agent():
87
+ print("create agent")
88
+ """Creates a fresh agent instance for each session"""
89
+ return CodeAgent(
90
+ model=model,
91
+ tools=WEB_TOOLS,
92
+ max_steps=max_steps,
93
+ verbosity_level=1,
94
+ )
95
+
96
+
97
+ def stream_to_gradio(
98
+ agent,
99
+ task: str,
100
+ reset_agent_memory: bool = False,
101
+ additional_args: Optional[dict] = None,
102
+ ):
103
+ """Runs an agent with the given task and streams the messages from the agent as gradio ChatMessages."""
104
+ steps = 0
105
+ for step_log in agent.run(
106
+ task, stream=True, reset=reset_agent_memory, additional_args=additional_args
107
+ ):
108
+ # I dont know the reason but call more steps
109
+ steps += 1
110
+ if steps <= max_steps:
111
+ for message in pull_messages_from_step(
112
+ step_log,
113
+ ):
114
+ yield message
115
+
116
+ final_answer = step_log # Last log is the run's final_answer
117
+ final_answer = handle_agent_output_types(final_answer)
118
+ # print(final_answer)
119
+ if isinstance(final_answer, AgentText):
120
+ yield gr.ChatMessage(
121
+ role="assistant",
122
+ content=f"**Final answer:**\n{final_answer.to_string()}",
123
+ )
124
+ elif isinstance(final_answer, AgentImage):
125
+ yield gr.ChatMessage(
126
+ role="assistant",
127
+ content={"path": final_answer.to_string(), "mime_type": "image/png"},
128
+ )
129
+ elif isinstance(final_answer, AgentAudio):
130
+ yield gr.ChatMessage(
131
+ role="assistant",
132
+ content={"path": final_answer.to_string(), "mime_type": "audio/wav"},
133
+ )
134
+ else:
135
+ yield gr.ChatMessage(
136
+ role="assistant", content=f"**Final answer:** {str(final_answer)}"
137
+ )
138
+
139
+
140
+ class GradioUI:
141
+ """A one-line interface to launch your agent in Gradio"""
142
+
143
+ def __init__(self, file_upload_folder: str | None = None):
144
+ self.file_upload_folder = file_upload_folder
145
+ if self.file_upload_folder is not None:
146
+ if not os.path.exists(file_upload_folder):
147
+ os.mkdir(file_upload_folder)
148
+
149
+ def interact_with_agent(self, prompt, messages, session_state):
150
+ # Get or create session-specific agent
151
+ if "agent" not in session_state:
152
+ session_state["agent"] = create_agent()
153
+
154
+ messages.append(gr.ChatMessage(role="user", content=prompt))
155
+ yield messages
156
+
157
+ # Use session's agent instance
158
+ for msg in stream_to_gradio(
159
+ session_state["agent"], task=prompt, reset_agent_memory=False
160
+ ):
161
+ messages.append(msg)
162
+ pass
163
+ yield messages
164
+ yield messages
165
+
166
+ def launch(self, **kwargs):
167
+ with gr.Blocks(theme="ocean", fill_height=True) as demo:
168
+ gr.Markdown("""# Smolagents - ExtraSearchtools!
169
+ - [Google Custom Search](https://developers.google.com/custom-search/v1/overview) tool
170
+ - [Brave Search](https://brave.com/search/api/) tool
171
+ - PrioritySearchTool - try duckduckgo fist and then use google
172
+ - PrioritySearchTool - json-save function
173
+
174
+ Built with [smolagents](https://github.com/huggingface/smolagents).This Demo only work duckduckgo if it's not rate-limited.Duplicate and set your own secret key
175
+ """)
176
+ # Add session state to store session-specific data
177
+ session_state = gr.State({}) # Initialize empty state for each session
178
+
179
+ chatbot = gr.Chatbot(
180
+ label="ExtraSearchtools",
181
+ type="messages",
182
+ avatar_images=(
183
+ None,
184
+ "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/smolagents/mascot_smol.png",
185
+ ),
186
+ scale=1,
187
+ )
188
+ text_input = gr.Textbox(
189
+ lines=1, label="Your request", value="What is smolagents?"
190
+ )
191
+ text_input.submit(
192
+ self.interact_with_agent,
193
+ # Include session_state in function calls
194
+ [text_input, chatbot, gr.State({})],
195
+ [chatbot],
196
+ )
197
+
198
+ demo.launch(debug=True, share=True, **kwargs)
199
+
200
+
201
+ if __name__ == "__main__":
202
+ GradioUI().launch() # not support auto update restart by yourself :AttributeError: module '__main__' has no attribute 'demo'
extra_search_tools.py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024-2025 Akihito Miyazaki.
2
+ # This code is derived from the DuckDuckGoSearchTool class,
3
+ # originally part of the HuggingFace smolagents library.
4
+ # https://github.com/huggingface/smolagents
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ from smolagents import Tool
18
+ import json
19
+ import os
20
+ from datetime import datetime
21
+
22
+ """This module provides search tools. The tools share a common name
23
+ because they are designed to be mutually exclusive (only one is used per query).
24
+
25
+ This code is derived from the DuckDuckGoSearchTool class in the HuggingFace
26
+ smolagents library.
27
+
28
+ TODO:
29
+ GoogleCustomSearchTool and BraveSearchTool are not using kwarg in init.
30
+
31
+ requires:
32
+ google-api-python-client
33
+ brave-search
34
+ """
35
+
36
+
37
+ class PrioritySearchTool(Tool):
38
+ """A tool that executes searches using multiple search tools in a prioritized order.
39
+
40
+ This tool takes a list of search tools and executes a query using them. It returns
41
+ the first successful result. Results are optionally cached and saved to a JSON file.
42
+
43
+ Attributes:
44
+ name (str): The name of the tool.
45
+ description (str): A description of the tool.
46
+ inputs (dict): The input schema for the tool.
47
+ output_type (str): The output type of the tool.
48
+ search_tools (list[Tool]): A list of search tools to use for searching.
49
+ save_json_path (str, optional): The path to a JSON file where search results
50
+ will be saved. Defaults to None.
51
+ history_results (dict): A dictionary storing past search results.
52
+
53
+ """
54
+
55
+ name = "web_search"
56
+ description = """Performs a google-custom web search based on your query (think a Google search) then returns the top search results."""
57
+ inputs = {
58
+ "query": {"type": "string", "description": "The search query to perform."}
59
+ }
60
+ output_type = "string"
61
+
62
+ def __init__(
63
+ self,
64
+ search_tools: list[Tool],
65
+ save_json_path: str = None,
66
+ **kwargs,
67
+ ):
68
+ super().__init__()
69
+ self.search_tools = search_tools
70
+ self.save_json_path = save_json_path
71
+ self.history_results = {}
72
+
73
+ def forward(self, query: str) -> str:
74
+ if os.path.exists(self.save_json_path):
75
+ with open(self.save_json_path, "r") as file:
76
+ self.history_results = json.load(file)
77
+ if query in self.history_results:
78
+ return self.history_results[query]["data"]
79
+
80
+ for search_tool in self.search_tools:
81
+ try:
82
+ result = search_tool(query=query)
83
+ if self.save_json_path:
84
+ class_name = search_tool.__class__.__name__
85
+ self.history_results[query] = {
86
+ "cdate": str(datetime.now()),
87
+ "name": class_name,
88
+ "data": result,
89
+ }
90
+ with open(self.save_json_path, "w") as file:
91
+ json.dump(self.history_results, file)
92
+ return result
93
+
94
+ except Exception as e:
95
+ print(f"{e}")
96
+ raise Exception("All search tools failed.")
97
+
98
+
99
+ class GoogleCustomSearchTool(Tool):
100
+ """
101
+ use
102
+ https://github.com/googleapis/google-api-python-client/
103
+
104
+ parameter
105
+ https://developers.google.com/custom-search/v1/reference/rest/v1/cse/list
106
+
107
+ Exp:another language
108
+ search = GoogleCustomSearchTool("33ec073e195bc4fcf", cr="countryJP", lr="lang_ja")
109
+ """
110
+
111
+ name = "web_search"
112
+ description = """Performs a google-custom web search based on your query (think a Google search) then returns the top search results."""
113
+ inputs = {
114
+ "query": {"type": "string", "description": "The search query to perform."}
115
+ }
116
+ output_type = "string"
117
+
118
+ def __init__(self, cx, max_results=10, **kwargs):
119
+ super().__init__()
120
+ if cx is None:
121
+ raise ValueError(
122
+ "Need CX(Search Engine ID) need create in custom-search controlpanel"
123
+ )
124
+ self.cx = cx
125
+ self.max_results = max_results
126
+ api_key_env_name = "GOOGLE_CUSTOM_SEARCH_KEY"
127
+ self.kwargs = kwargs
128
+ try:
129
+ from googleapiclient.discovery import build
130
+ except ImportError as e:
131
+ raise ImportError(
132
+ "You must install package `google-api-python-client` to run this tool: for instance run `pip install google-api-python-client`."
133
+ ) from e
134
+ import os
135
+
136
+ self.key = os.getenv(api_key_env_name)
137
+
138
+ self.custom_search = build("customsearch", "v1")
139
+
140
+ def forward(self, query: str) -> str:
141
+ results = (
142
+ self.custom_search.cse()
143
+ .list(
144
+ key=self.key, q=query, cx=self.cx, num=self.max_results, **self.kwargs
145
+ )
146
+ .execute()
147
+ )
148
+
149
+ results = results["items"]
150
+
151
+ if len(results) == 0:
152
+ raise Exception("No results found! Try a less restrictive/shorter query.")
153
+ postprocessed_results = [
154
+ f"[{result['title']}]({result['link']})\n{result['snippet']}"
155
+ for result in results
156
+ ]
157
+ return "## Search Results\n\n" + "\n\n".join(postprocessed_results)
158
+
159
+
160
+ from smolagents import Tool
161
+ import json
162
+
163
+
164
+ class BraveSearchTool(Tool):
165
+ """
166
+ Use
167
+ https://github.com/kayvane1/brave-api
168
+
169
+ query parameter
170
+ https://api-dashboard.search.brave.com/app/documentation/web-search/query
171
+
172
+ Exp:another language
173
+ search = BraveSearchTool(country="JP", search_lang="jp")
174
+ """
175
+
176
+ name = "web_search"
177
+ description = """Performs a google-custom web search based on your query (think a Google search) then returns the top search results."""
178
+ inputs = {
179
+ "query": {"type": "string", "description": "The search query to perform."}
180
+ }
181
+ output_type = "string"
182
+
183
+ def __init__(self, max_results=10, **kwargs):
184
+ super().__init__()
185
+ self.max_results = max_results
186
+ api_key_env_name = "BRAVE_SEARCH_KEY"
187
+ self.kwargs = kwargs
188
+ try:
189
+ from brave import Brave
190
+ except ImportError as e:
191
+ raise ImportError(
192
+ # there are another lib.but this one work one python-3.10
193
+ "You must install package `brave-search` to run this tool: for instance run `pip install pip install brave-search`."
194
+ ) from e
195
+ import os
196
+
197
+ self.brave = Brave(api_key=os.getenv(api_key_env_name))
198
+
199
+ def clean(text):
200
+ return text.replace("<STRING>", "").replace("</STRONG>")
201
+
202
+ def forward(self, query: str) -> str:
203
+ search_results = self.brave.search(
204
+ q=query, count=self.max_results, **self.kwargs
205
+ )
206
+ # pprint.pprint(search_results, indent=4)
207
+ results = search_results.web_results
208
+ # pprint.pprint(search_results.web_results, indent=4)
209
+ if len(results) == 0:
210
+ raise Exception("No results found! Try a less restrictive/shorter query.")
211
+ postprocessed_results = [
212
+ f"[{result['title']}]({result['url']._url})\n{self.clean(result['description'])}"
213
+ for result in results
214
+ ]
215
+ return "## Search Results\n\n" + "\n\n".join(postprocessed_results)
history.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"smolagents": {"cdate": "2025-03-14 16:04:17.000743", "name": "DuckDuckGoSearchTool", "data": "## Search Results\n\n[smolagents: a barebones library for agents. Agents write ... - GitHub](https://github.com/huggingface/smolagents)\nsmolagents is a library that enables you to run powerful agents in a few lines of code. It supports CodeAgents that write actions as Python code snippets, and integrates with various tools and models from Hugging Face Hub and other providers.\n\n[smolagents - Hugging Face](https://huggingface.co/docs/smolagents/index)\nsmolagents is a library that lets you create powerful agents with any LLM, including Code Agents. Learn how to use it with guides, tutorials and examples on the Hugging Face documentation.\n\n[Smolagents : Huggingface AI Agent Framework](https://smolagents.org/)\nSmolagents is a minimalist and efficient framework for creating and running AI agents with large language models. Learn how to use code agents, tools, and the Hugging Face Hub to build powerful and versatile agents for various tasks.\n\n[Agents - Guided tour - Smolagents](https://smolagents.org/docs/agents-guided-tour/)\nSmolagents lets you create agents that can use text-generation models and tools to solve tasks. Learn how to initialize, run, and customize agents with different models, tools, and options.\n\n[Building good Smolagents - Smolagents](https://smolagents.org/docs/building-good-smolagents/)\nSmolagents is a framework for creating agents that can perform tasks using natural language and external tools. Learn best practices for simplifying workflows, improving information flow, and debugging agents with LLMs.\n\n[Introducing smolagents , a simple library to build agents - Hugging Face](https://huggingface.co/blog/smolagents)\nsmolagents is a simple library that unlocks agentic capabilities for language models. It allows LLMs to write actions in code, such as calling external tools or executing loops, to solve real-world tasks.\n\n[Introduction to Agents - Hugging Face](https://huggingface.co/docs/smolagents/conceptual_guides/intro_agents)\nsmolagents documentation Introduction to Agents. smolagents Search documentation. Get started. \ud83e\udd17 Agents Guided tour. Tutorials. Building good agents \ud83d\udcca Inspect your agent runs using telemetry \ud83d\udee0\ufe0f Tools - in-depth guide \ud83d\udee1\ufe0f Secure code execution \ud83d\udcda Manage your agent's memory. Conceptual guides ...\n\n[smolagents/README.md at main \u00b7 huggingface/smolagents - GitHub](https://github.com/huggingface/smolagents/blob/main/README.md)\nsmolagents is a Python library that lets you create agents that can perform tasks using natural language and various tools. It supports code agents, model-agnostic agents, modality-agnostic agents, and tool-agnostic agents.\n\n[smolagents \u00b7 PyPI](https://pypi.org/project/smolagents/)\nsmolagents is a library that enables you to run powerful agents in a few lines of code. It offers: Simplicity: the logic for agents fits in ~1,000 lines of code (see agents.py).We kept abstractions to their minimal shape above raw code! \ud83e\uddd1\u200d\ud83d\udcbb First-class support for Code Agents.Our CodeAgent writes its actions in code (as opposed to \"agents being used to write code\").\n\n[SmolAgents. SmolAgents from HuggingFace | by Cobus Greyling | Feb, 2025 ...](https://cobusgreyling.medium.com/smolagents-7a4bf7712814)\nHugging Face launched SmolAgents with a clear mission: to democratise the creation of sophisticated agentic systems by prioritising simplicity and reducing technical overhead.. Unlike more complex frameworks, which often involve intricate architectures, SmolAgents intentionally strips away unnecessary layers of abstraction. The library emphasises lightweight efficiency without sacrificing ..."}, "What is smolagents?": {"cdate": "2025-03-14 18:08:58.593568", "name": "DuckDuckGoSearchTool", "data": "## Search Results\n\n[smolagents - Hugging Face](https://huggingface.co/docs/smolagents/index)\nsmolagents. This library is the simplest framework out there to build powerful agents! By the way, wtf are \"agents\"? We provide our definition in this page, where you'll also find tips for when to use them or not (spoilers: you'll often be better off without agents).\n\n[Smolagents : Huggingface AI Agent Framework](https://smolagents.org/)\n\ud83e\udd17 Smolagents is a minimalist AI agent framework developed by the Hugging Face team, crafted to enable developers to deploy robust agents with just a few lines of code. Embracing simplicity and efficiency, smolagents empowers large language models (LLMs) to interact seamlessly with the real world.\n\n[Introducing smolagents , a simple library to build agents - Hugging Face](https://huggingface.co/blog/smolagents)\nsmolagents is the successor to transformers.agents, and will be replacing it as transformers.agents gets deprecated in the future. Building an agent To build an agent, you need at least two elements: tools: a list of tools the agent has access to;\n\n[smolagents: a barebones library for agents. Agents write ... - GitHub](https://github.com/huggingface/smolagents)\nsmolagents is a library that enables you to run powerful agents in a few lines of code. It offers: Simplicity: the logic for agents fits in ~1,000 lines of code (see agents.py).We kept abstractions to their minimal shape above raw code! \ud83e\uddd1\u200d\ud83d\udcbb First-class support for Code Agents.Our CodeAgent writes its actions in code (as opposed to \"agents being used to write code\").\n\n[What are SmolAgents?: A Easy Guide With Code Examples](https://analyticsiksha.com/smolagents-by-hugging-face-a-comprehensive-guide/)\nIn the evolving world of artificial intelligence, Hugging Face has once again pushed the boundaries of innovation with its latest release: SmolAgents. SmolAgents - This lightweight, efficient, and versatile framework for building and running AI agents is designed to simplify complex workflows, making AI-powered solutions more accessible than ...\n\n[SmolAgents by Hugging Face: Build AI Agents in Under 30 Lines](https://www.analyticsvidhya.com/blog/2025/01/smolagents/)\nSmolAgents is an innovative library designed to simplify the creation and execution of powerful agents. Developed by Hugging Face, it stands out for its minimalist approach, with the entire agent logic encapsulated in approximately 1,000 lines of code. This streamlined design ensures ease of use while maintaining robust functionality.\n\n[Agents - Guided tour - Smolagents](https://smolagents.org/docs/agents-guided-tour/)\nfrom smolagents import tool @tool def model_download_tool(task: str) -> str: \"\"\" This is a tool that returns the most downloaded model of a given task on the Hugging Face Hub. It returns the name of the checkpoint.\n\n[HuggingFace smolagents: The best Multi-Agent framework so far?](https://medium.com/data-science-in-your-pocket/huggingface-smolagents-the-best-multi-agent-framework-so-far-313178ef3c2e)\nWhat are smolagents? Smolagents is a newly launched agent framework by Hugging Face, designed to simplify the creation of intelligent agents that leverage large language models (LLMs).\n\n[smolagents\u2014Simplifying AI Agent Development](https://smolagents.org/smolagents-simplifying-ai-agent-development/)\nWhat is smolagents? smolagents is an open-source, lightweight AI agent library that allows developers to create powerful agents with minimal code. With a core codebase of approximately 1,000 lines in agents.py, smolagents reduces unnecessary abstractions, making the development process straightforward and accessible.By focusing on simplicity and efficiency, smolagents enables LLMs to interact ...\n\n[Getting Started with Smolagents](https://debuggercafe.com/smolagents/)\nWe have three Python files: app.py, tool.py, tool_config.py. The primary code resides in the tool.py file. This contains a class to generate the image and is a subclass of the Tool class.. The app.py file just imports the class and launches the Gradio demo.. And finally, the tool_config.py file is what tells the load_tool function that this is a tool and how to use it."}}
requirements.txt ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ smolagents==1.9.1
2
+ anthropic>=0.37.1
3
+ beautifulsoup4>=4.12.3
4
+ datasets>=2.21.0
5
+ google_search_results>=2.4.2
6
+ huggingface_hub>=0.23.4
7
+ mammoth>=1.8.0
8
+ markdownify>=0.13.1
9
+ numexpr>=2.10.1
10
+ numpy>=2.1.2
11
+ openai>=1.52.2
12
+ openpyxl
13
+ pandas>=2.2.3
14
+ pathvalidate>=3.2.1
15
+ pdfminer>=20191125
16
+ pdfminer.six>=20240706
17
+ Pillow>=11.0.0
18
+ puremagic>=1.28
19
+ pypdf>=5.1.0
20
+ python-dotenv>=1.0.1
21
+ python_pptx>=1.0.2
22
+ Requests>=2.32.3
23
+ serpapi>=0.1.5
24
+ tqdm>=4.66.4
25
+ torch>=2.2.2
26
+ torchvision>=0.17.2
27
+ transformers>=4.46.0
28
+ youtube_transcript_api>=0.6.2
29
+ chess
30
+ sympy
31
+ pubchempy
32
+ Bio
33
+ scikit-learn
34
+ scipy
35
+ pydub
36
+ PyPDF2
37
+ python-pptx
38
+ torch
39
+ xlrd
40
+ SpeechRecognition
41
+ litellm
42
+ duckduckgo-search