From edb0be3adfed7638785bbe3985ade71ee346457a Mon Sep 17 00:00:00 2001 From: Aymeric Date: Tue, 24 Dec 2024 10:31:36 +0100 Subject: [PATCH] Change all names to 'smolagent' --- README.md | 6 +- docs/source/conceptual_guides/intro_agents.md | 2 +- docs/source/examples/text_to_sql.md | 2 +- docs/source/guided_tour.md | 22 +- docs/source/index.md | 2 +- docs/source/tutorials/building_good_agents.md | 6 +- .../source/tutorials/secure_code_execution.md | 5 +- docs/source/tutorials/tools.md | 11 +- examples/docker_example.py | 6 +- examples/e2b_example.py | 6 +- examples/tool_calling_agent.py | 4 +- pyproject.toml | 2 +- src/{agents => smolagents}/__init__.py | 0 src/{agents => smolagents}/agents.py | 4 +- src/smolagents/default_tools.py | 224 ++++++++++++++++++ .../docker_alternative.py | 2 +- .../docker_python_executor.py | 0 src/{agents => smolagents}/e2b_executor.py | 2 +- src/{agents => smolagents}/gradio_ui.py | 0 src/{agents => smolagents}/llm_engines.py | 8 +- .../local_python_executor.py | 0 src/{agents => smolagents}/monitoring.py | 0 src/{agents => smolagents}/prompts.py | 0 src/{agents => smolagents}/tool_validation.py | 0 src/{agents => smolagents}/tools.py | 8 +- src/{agents => smolagents}/types.py | 0 src/{agents => smolagents}/utils.py | 0 tests/test_agents.py | 8 +- tests/test_final_answer.py | 4 +- tests/test_monitoring.py | 2 +- tests/test_python_interpreter.py | 8 +- tests/test_search.py | 2 +- tests/test_tools_common.py | 4 +- tests/test_types.py | 2 +- 34 files changed, 289 insertions(+), 63 deletions(-) rename src/{agents => smolagents}/__init__.py (100%) rename src/{agents => smolagents}/agents.py (99%) create mode 100644 src/smolagents/default_tools.py rename src/{agents => smolagents}/docker_alternative.py (98%) rename src/{agents => smolagents}/docker_python_executor.py (100%) rename src/{agents => smolagents}/e2b_executor.py (98%) rename src/{agents => smolagents}/gradio_ui.py (100%) rename src/{agents => smolagents}/llm_engines.py (97%) rename src/{agents => smolagents}/local_python_executor.py (100%) rename src/{agents => smolagents}/monitoring.py (100%) rename src/{agents => smolagents}/prompts.py (100%) rename src/{agents => smolagents}/tool_validation.py (100%) rename src/{agents => smolagents}/tools.py (99%) rename src/{agents => smolagents}/types.py (100%) rename src/{agents => smolagents}/utils.py (100%) diff --git a/README.md b/README.md index b253f82..712debf 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ limitations under the License.

-

Agents - build great agents!

+

Smolagents - build great agents!

-Agents is a library that enables you to run powerful agents in a few lines of code! +Smolagents is a library that enables you to run powerful agents in a few lines of code! This library offers: @@ -48,7 +48,7 @@ pip install agents ``` Then define your agent, give it the tools it needs and run it! ```py -from agents import CodeAgent, WebSearchTool +from smolagents import CodeAgent, WebSearchTool agent = CodeAgent(tools=[WebSearchTool()]) diff --git a/docs/source/conceptual_guides/intro_agents.md b/docs/source/conceptual_guides/intro_agents.md index ac4cf04..cf066de 100644 --- a/docs/source/conceptual_guides/intro_agents.md +++ b/docs/source/conceptual_guides/intro_agents.md @@ -78,7 +78,7 @@ Actually, most real-life tasks do not fit in a pre-determined workflow. This is Agentic systems are a great way to introduce the vast world of real-world tasks to programs! -### Why {Agents}? +### Why Smolagents? For some low-level agentic use cases, like chains or routers, you can write all the code yourself. You'll be much better that way, since it will let you control and understand your system better. diff --git a/docs/source/examples/text_to_sql.md b/docs/source/examples/text_to_sql.md index 44b56ea..ae69df4 100644 --- a/docs/source/examples/text_to_sql.md +++ b/docs/source/examples/text_to_sql.md @@ -15,7 +15,7 @@ rendered properly in your Markdown viewer. --> # Text-to-SQL -In this tutorial, we’ll see how to implement an agent that leverages SQL using `agents`. +In this tutorial, we’ll see how to implement an agent that leverages SQL using `smolagents`. > Let's start with the goldnen question: why not keep it simple and use a standard text-to-SQL pipeline? diff --git a/docs/source/guided_tour.md b/docs/source/guided_tour.md index 4aa60bb..6aa7ceb 100644 --- a/docs/source/guided_tour.md +++ b/docs/source/guided_tour.md @@ -59,7 +59,7 @@ You will also need a `tools` argument which accepts a list of `Tools` - it can b Once you have these two arguments, `tools` and `llm_engine`, you can create an agent and run it. ```python -from agents import CodeAgent, HfApiEngine +from smolagents import CodeAgent, HfApiEngine llm_engine = HfApiEngine(model=model_id) agent = CodeAgent(tools=[], llm_engine=llm_engine, add_base_tools=True) @@ -72,7 +72,7 @@ agent.run( You can even leave the argument `llm_engine` undefined, and an [`HfApiEngine`] will be created by default. ```python -from agents import CodeAgent +from smolagents import CodeAgent agent = CodeAgent(tools=[], add_base_tools=True) @@ -87,7 +87,7 @@ Note that we used an additional `additional_detail` argument: you can additional You can use this to indicate the path to local or remote files for the model to use: ```py -from agents import CodeAgent, Tool, SpeechToTextTool +from smolagents import CodeAgent, Tool, SpeechToTextTool agent = CodeAgent(tools=[SpeechToTextTool()], add_base_tools=True) @@ -107,7 +107,7 @@ The Python interpreter also doesn't allow imports by default outside of a safe l You can authorize additional imports by passing the authorized modules as a list of strings in argument `additional_authorized_imports` upon initialization of your [`CodeAgent`] or [`CodeAgent`]: ```py -from agents import CodeAgent +from smolagents import CodeAgent agent = CodeAgent(tools=[], additional_authorized_imports=['requests', 'bs4']) agent.run("Could you get me the title of the page at url 'https://huggingface.co/blog'?") @@ -178,7 +178,7 @@ You could improve the system prompt, for example, by adding an explanation of th For maximum flexibility, you can overwrite the whole system prompt template by passing your custom prompt as an argument to the `system_prompt` parameter. ```python -from agents import JsonAgent, PythonInterpreterTool, JSON_SYSTEM_PROMPT +from smolagents import JsonAgent, PythonInterpreterTool, JSON_SYSTEM_PROMPT modified_prompt = JSON_SYSTEM_PROMPT @@ -267,7 +267,7 @@ All these will be automatically baked into the agent's system prompt upon initia Then you can directly initialize your agent: ```py -from agents import CodeAgent +from smolagents import CodeAgent agent = CodeAgent(tools=[model_download_tool], llm_engine=llm_engine) agent.run( "Can you give me the name of the model that has the most downloads in the 'text-to-video' task on the Hugging Face Hub?" @@ -290,17 +290,17 @@ And the output: ## Multi-agents Multi-agent has been introduced in Microsoft's framework [Autogen](https://huggingface.co/papers/2308.08155). -It simply means having several agents working together to solve your task instead of only one. -It empirically yields better performance on most benchmarks. The reason for this better performance is conceptually simple: for many tasks, rather than using a do-it-all system, you would prefer to specialize units on sub-tasks. Here, having agents with separate tool sets and memories allows to achieve efficient specialization. +In this type of framework, you have several agents working together to solve your task instead of only one. +It empirically yields better performance on most benchmarks. The reason for this better performance is conceptually simple: for many tasks, rather than using a do-it-all system, you would prefer to specialize units on sub-tasks. Here, having agents with separate tool sets and memories allows to achieve efficient specialization. For instance, why fill the memory of the code generating agent with all the content of webpages visited by the web search agent? It's better to keep them separate. -You can easily build hierarchical multi-agent systems with `agents`. +You can easily build hierarchical multi-agent systems with `smolagents`. To do so, encapsulate the agent in a [`ManagedAgent`] object. This object needs arguments `agent`, `name`, and a `description`, which will then be embedded in the manager agent's system prompt to let it know how to call this managed agent, as we also do for tools. Here's an example of making an agent that managed a specific web search agent using our [`DuckDuckGoSearchTool`]: ```py -from agents import CodeAgent, HfApiEngine, DuckDuckGoSearchTool, ManagedAgent +from smolagents import CodeAgent, HfApiEngine, DuckDuckGoSearchTool, ManagedAgent llm_engine = HfApiEngine() @@ -328,7 +328,7 @@ manager_agent.run("Who is the CEO of Hugging Face?") You can use `GradioUI` to interactively submit tasks to your agent and observe its thought and execution process, here is an example: ```py -from agents import ( +from smolagents import ( load_tool, CodeAgent, HfApiEngine, diff --git a/docs/source/index.md b/docs/source/index.md index 14f4589..f9e7948 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -13,7 +13,7 @@ specific language governing permissions and limitations under the License. rendered properly in your Markdown viewer. --> -# Agents +# Smolagents 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](conceptual_guides/intro_agents), whe're you'll also find tips for when to use them or not (spoilers: you'll often be better off without agents). diff --git a/docs/source/tutorials/building_good_agents.md b/docs/source/tutorials/building_good_agents.md index 061a218..940fa55 100644 --- a/docs/source/tutorials/building_good_agents.md +++ b/docs/source/tutorials/building_good_agents.md @@ -22,7 +22,7 @@ How to build into this latter category? In this guide, we're going to see best practices for building agents. > [!TIP] -> If you're new to `agents`, make sure to first read the [intro to agents](./intro_agents). +> If you're new to building agents, make sure to first read the [intro to agents](./intro_agents) and the [guided tour of smolagents](../guided_tour). ### The best agentic systems are the simplest: simplify the workflow as much as you can @@ -56,7 +56,7 @@ For instance, here's a tool that : First, here's a poor version: ```python import datetime -from agents import tool +from smolagents import tool def get_weather_report_at_coordinates(coordinates, date_time): # Dummy function, returns a list of [temperature in °C, risk of rain on a scale 0-1, wave height in m] @@ -166,7 +166,7 @@ Better ways to guide your LLM engine are: We provide a model for a supplementary planning step, that an agent can run regularly in-between normal action steps. In this step, there is no tool call, the LLM is simply asked to update a list of facts it knows and to reflect on what steps it should take next based on those facts. ```py -from agents import load_tool, CodeAgent, HfApiEngine, DuckDuckGoSearchTool +from smolagents import load_tool, CodeAgent, HfApiEngine, DuckDuckGoSearchTool from dotenv import load_dotenv load_dotenv() diff --git a/docs/source/tutorials/secure_code_execution.md b/docs/source/tutorials/secure_code_execution.md index 463577b..3a16923 100644 --- a/docs/source/tutorials/secure_code_execution.md +++ b/docs/source/tutorials/secure_code_execution.md @@ -17,6 +17,9 @@ rendered properly in your Markdown viewer. [[open-in-colab]] +> [!TIP] +> If you're new to building agents, make sure to first read the [intro to agents](./intro_agents) and the [guided tour of smolagents](../guided_tour). + ### Code agents [Multiple](https://huggingface.co/papers/2402.01030) [research](https://huggingface.co/papers/2411.01747) [papers](https://huggingface.co/papers/2401.00812) have shown that having the LLM write its actions (the tool calls) in code is much better than the current standard format for tool calling, which is across the industry different shades of "writing actions as a JSON of tools names and arguments to use". @@ -65,7 +68,7 @@ To set the code executor to E2B, simply pass the flag `use_e2b_executor=True` wh Note that you should add all the tool's dependencies in `additional_authorized_imports`, so that the executor installs them. ```py -from agents import CodeAgent, VisitWebpageTool +from smolagents import CodeAgent, VisitWebpageTool agent = CodeAgent( tools = [VisitWebpageTool()], additional_authorized_imports=["requests", "markdownify"], diff --git a/docs/source/tutorials/tools.md b/docs/source/tutorials/tools.md index 6ad0093..9f4a612 100644 --- a/docs/source/tutorials/tools.md +++ b/docs/source/tutorials/tools.md @@ -20,8 +20,7 @@ rendered properly in your Markdown viewer. Here, we're going to see advanced tool usage. > [!TIP] -> If you're new to `agents`, make sure to first read the main [agents documentation](./agents). - +> If you're new to building agents, make sure to first read the [intro to agents](./intro_agents) and the [guided tour of smolagents](../guided_tour). ### Directly define a tool by subclassing Tool @@ -41,7 +40,7 @@ The types for both `inputs` and `output_type` should be amongst [Pydantic format Also, all imports should be put within the tool's forward function, else you will get an error. ```python -from agents import Tool +from smolagents import Tool class HFModelDownloadsTool(Tool): name = "model_download_counter" @@ -83,7 +82,7 @@ Once your tool is pushed to Hub, you can load it with the [`~Tool.load_tool`] fu Since running tools means running custom code, you need to make sure you trust the repository, and pass `trust_remote_code=True`. ```python -from agents import load_tool, CodeAgent +from smolagents import load_tool, CodeAgent model_download_tool = load_tool( "{your_username}/hf-model-downloads", @@ -115,7 +114,7 @@ And voilà, here's your image! 🏖️ Then you can use this tool just like any other tool. For example, let's improve the prompt `a rabbit wearing a space suit` and generate an image of it. ```python -from agents import CodeAgent, HfApiEngine +from smolagents import CodeAgent, HfApiEngine llm_engine = HfApiEngine("Qwen/Qwen2.5-Coder-32B-Instruct") agent = CodeAgent(tools=[image_generation_tool], llm_engine=llm_engine) @@ -182,7 +181,7 @@ You can manage an agent's toolbox by adding or replacing a tool. Let's add the `model_download_tool` to an existing agent initialized with only the default toolbox. ```python -from agents import HfApiEngine +from smolagents import HfApiEngine llm_engine = HfApiEngine("Qwen/Qwen2.5-Coder-32B-Instruct") diff --git a/examples/docker_example.py b/examples/docker_example.py index ddfb50e..cd85e78 100644 --- a/examples/docker_example.py +++ b/examples/docker_example.py @@ -1,8 +1,8 @@ -from agents.default_tools.search import DuckDuckGoSearchTool -from agents.docker_alternative import DockerPythonInterpreter +from smolagents.default_tools.search import DuckDuckGoSearchTool +from smolagents.docker_alternative import DockerPythonInterpreter -from agents.tools import Tool +from smolagents.tools import Tool class DummyTool(Tool): name = "echo" diff --git a/examples/e2b_example.py b/examples/e2b_example.py index 49d2be3..a919773 100644 --- a/examples/e2b_example.py +++ b/examples/e2b_example.py @@ -1,5 +1,5 @@ -from agents import Tool, CodeAgent -from agents.default_tools.search import VisitWebpageTool +from smolagents import Tool, CodeAgent +from smolagents.default_tools.search import VisitWebpageTool from dotenv import load_dotenv load_dotenv() @@ -35,7 +35,7 @@ agent = CodeAgent( ) if LAUNCH_GRADIO: - from agents import GradioUI + from smolagents import GradioUI GradioUI(agent).launch() else: diff --git a/examples/tool_calling_agent.py b/examples/tool_calling_agent.py index 85302b3..0832bca 100644 --- a/examples/tool_calling_agent.py +++ b/examples/tool_calling_agent.py @@ -1,5 +1,5 @@ -from agents.agents import ToolCallingAgent -from agents import tool, HfApiEngine, OpenAIEngine, AnthropicEngine +from smolagents.agents import ToolCallingAgent +from smolagents import tool, HfApiEngine, OpenAIEngine, AnthropicEngine # Choose which LLM engine to use! llm_engine = OpenAIEngine("gpt-4o") diff --git a/pyproject.toml b/pyproject.toml index aaeacd9..6d19c75 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools"] build-backend = "setuptools.build_meta" [project] -name = "agents" +name = "smolagents" version = "0.1.0" description = "Add your description here" readme = "README.md" diff --git a/src/agents/__init__.py b/src/smolagents/__init__.py similarity index 100% rename from src/agents/__init__.py rename to src/smolagents/__init__.py diff --git a/src/agents/agents.py b/src/smolagents/agents.py similarity index 99% rename from src/agents/agents.py rename to src/smolagents/agents.py index fbc9608..9b97ce4 100644 --- a/src/agents/agents.py +++ b/src/smolagents/agents.py @@ -501,7 +501,7 @@ class MultiStepAgent(BaseAgent): Example: ```py - from agents import CodeAgent + from smolagents import CodeAgent agent = CodeAgent(tools=[]) agent.run("What is the result of 2 power 3.7384?") ``` @@ -873,7 +873,7 @@ class JsonAgent(MultiStepAgent): class ToolCallingAgent(MultiStepAgent): """ - This agent uses JSON-like tool calls, but to the difference of JsonAgents, it makes use of the underlying librarie's tool calling facilities. + This agent uses JSON-like tool calls, but to the difference of JsonAgents, it leverages the underlying librarie's tool calling facilities. """ def __init__( diff --git a/src/smolagents/default_tools.py b/src/smolagents/default_tools.py new file mode 100644 index 0000000..d820fc0 --- /dev/null +++ b/src/smolagents/default_tools.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python +# coding=utf-8 + +# Copyright 2024 The HuggingFace Inc. team. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import json +import re +from dataclasses import dataclass +from typing import Dict +import torch +from huggingface_hub import hf_hub_download, list_spaces + +from transformers.utils import is_offline_mode +from transformers.models.whisper import WhisperProcessor, WhisperForConditionalGeneration + +from .local_python_executor import ( + BASE_BUILTIN_MODULES, + BASE_PYTHON_TOOLS, + evaluate_python_code, +) +from .tools import TOOL_CONFIG_FILE, Tool, PipelineTool +from .types import AgentAudio + + +@dataclass +class PreTool: + name: str + inputs: Dict[str, str] + output_type: type + task: str + description: str + repo_id: str + + +def get_remote_tools(logger, organization="huggingface-tools"): + if is_offline_mode(): + logger.info("You are in offline mode, so remote tools are not available.") + return {} + + spaces = list_spaces(author=organization) + tools = {} + for space_info in spaces: + repo_id = space_info.id + resolved_config_file = hf_hub_download( + repo_id, TOOL_CONFIG_FILE, repo_type="space" + ) + with open(resolved_config_file, encoding="utf-8") as reader: + config = json.load(reader) + task = repo_id.split("/")[-1] + tools[config["name"]] = PreTool( + task=task, + description=config["description"], + repo_id=repo_id, + name=task, + inputs=config["inputs"], + output_type=config["output_type"], + ) + + return tools + + +class PythonInterpreterTool(Tool): + name = "python_interpreter" + description = "This is a tool that evaluates python code. It can be used to perform calculations." + inputs = { + "code": { + "type": "string", + "description": "The python code to run in interpreter", + } + } + output_type = "string" + + def __init__(self, *args, authorized_imports=None, **kwargs): + if authorized_imports is None: + self.authorized_imports = list(set(BASE_BUILTIN_MODULES)) + else: + self.authorized_imports = list( + set(BASE_BUILTIN_MODULES) | set(authorized_imports) + ) + self.inputs = { + "code": { + "type": "string", + "description": ( + "The code snippet to evaluate. All variables used in this snippet must be defined in this same snippet, " + f"else you will get an error. This code can only import the following python libraries: {authorized_imports}." + ), + } + } + self.base_python_tool = BASE_PYTHON_TOOLS + self.python_evaluator = evaluate_python_code + super().__init__(*args, **kwargs) + + def forward(self, code: str) -> str: + output = str( + self.python_evaluator( + code, + static_tools=self.base_python_tool, + authorized_imports=self.authorized_imports, + ) + ) + return output + + +class FinalAnswerTool(Tool): + name = "final_answer" + description = "Provides a final answer to the given problem." + inputs = { + "answer": {"type": "any", "description": "The final answer to the problem"} + } + output_type = "any" + + def forward(self, answer): + return answer + + +class UserInputTool(Tool): + name = "user_input" + description = "Asks for user's input on a specific question" + inputs = { + "question": {"type": "string", "description": "The question to ask the user"} + } + output_type = "string" + + def forward(self, question): + user_input = input(f"{question} => ") + return user_input + +import re + +from .tools import Tool + + +class DuckDuckGoSearchTool(Tool): + name = "web_search" + description = """Performs a web search based on your query (think a Google search) then returns the top search results as a list of dict elements. + Each result has keys 'title', 'href' and 'body'.""" + inputs = { + "query": {"type": "string", "description": "The search query to perform."} + } + output_type = "any" + + def forward(self, query: str) -> str: + try: + from duckduckgo_search import DDGS + except ImportError: + raise ImportError( + "You must install package `duckduckgo_search` to run this tool: for instance run `pip install duckduckgo-search`." + ) + results = DDGS().text(query, max_results=7) + return results + + +class VisitWebpageTool(Tool): + name = "visit_webpage" + description = "Visits a webpage at the given url and returns its content as a markdown string." + inputs = { + "url": { + "type": "string", + "description": "The url of the webpage to visit.", + } + } + output_type = "string" + + def forward(self, url: str) -> str: + try: + from markdownify import markdownify + import requests + from requests.exceptions import RequestException + except ImportError: + raise ImportError( + "You must install packages `markdownify` and `requests` to run this tool: for instance run `pip install markdownify requests`." + ) + try: + # Send a GET request to the URL + response = requests.get(url) + response.raise_for_status() # Raise an exception for bad status codes + + # Convert the HTML content to Markdown + markdown_content = markdownify(response.text).strip() + + # Remove multiple line breaks + markdown_content = re.sub(r"\n{3,}", "\n\n", markdown_content) + + return markdown_content + + except RequestException as e: + return f"Error fetching the webpage: {str(e)}" + except Exception as e: + return f"An unexpected error occurred: {str(e)}" + + +class SpeechToTextTool(PipelineTool): + default_checkpoint = "openai/whisper-large-v3-turbo" + description = "This is a tool that transcribes an audio into text. It returns the transcribed text." + name = "transcriber" + pre_processor_class = WhisperProcessor + model_class = WhisperForConditionalGeneration + + inputs = {"audio": {"type": "audio", "description": "The audio to transcribe"}} + output_type = "string" + + def encode(self, audio): + audio = AgentAudio(audio).to_raw() + return self.pre_processor(audio, return_tensors="pt") + + def forward(self, inputs): + return self.model.generate(inputs["input_features"]) + + def decode(self, outputs): + return self.pre_processor.batch_decode(outputs, skip_special_tokens=True)[0] + + +__all__ = ["PythonInterpreterTool", "FinalAnswerTool", "UserInputTool", "DuckDuckGoSearchTool", "VisitWebpageTool", "SpeechToTextTool"] diff --git a/src/agents/docker_alternative.py b/src/smolagents/docker_alternative.py similarity index 98% rename from src/agents/docker_alternative.py rename to src/smolagents/docker_alternative.py index bdb33ce..dfe0f30 100644 --- a/src/agents/docker_alternative.py +++ b/src/smolagents/docker_alternative.py @@ -3,7 +3,7 @@ from typing import List, Optional import warnings import socket -from agents.tools import Tool +from smolagents.tools import Tool class DockerPythonInterpreter: diff --git a/src/agents/docker_python_executor.py b/src/smolagents/docker_python_executor.py similarity index 100% rename from src/agents/docker_python_executor.py rename to src/smolagents/docker_python_executor.py diff --git a/src/agents/e2b_executor.py b/src/smolagents/e2b_executor.py similarity index 98% rename from src/agents/e2b_executor.py rename to src/smolagents/e2b_executor.py index a3ab9b6..bd9412d 100644 --- a/src/agents/e2b_executor.py +++ b/src/smolagents/e2b_executor.py @@ -53,7 +53,7 @@ class E2BExecutor: for tool in tools: validate_tool_attributes(tool.__class__, check_imports=False) tool_code = instance_to_source(tool, base_cls=Tool) - tool_code = tool_code.replace("from agents.tools import Tool", "") + tool_code = tool_code.replace("from smolagents.tools import Tool", "") tool_code += f"\n{tool.name} = {tool.__class__.__name__}()\n" tool_codes.append(tool_code) diff --git a/src/agents/gradio_ui.py b/src/smolagents/gradio_ui.py similarity index 100% rename from src/agents/gradio_ui.py rename to src/smolagents/gradio_ui.py diff --git a/src/agents/llm_engines.py b/src/smolagents/llm_engines.py similarity index 97% rename from src/agents/llm_engines.py rename to src/smolagents/llm_engines.py index 02732d3..3f3f0e5 100644 --- a/src/agents/llm_engines.py +++ b/src/smolagents/llm_engines.py @@ -23,7 +23,7 @@ import os from openai import OpenAI from huggingface_hub import InferenceClient -from agents import Tool +from smolagents import Tool logger = logging.getLogger(__name__) @@ -258,7 +258,7 @@ class HfApiEngine(HfEngine): messages: List[Dict[str, str]], available_tools: List[Tool], ): - """Generates a tool call for the given message list""" + """Generates a tool call for the given message list. This method is used only by `ToolCallingAgent`.""" messages = get_clean_message_list( messages, role_conversions=tool_role_conversions ) @@ -379,7 +379,7 @@ class OpenAIEngine: messages: List[Dict[str, str]], available_tools: List[Tool], ): - """Generates a tool call for the given message list""" + """Generates a tool call for the given message list. This method is used only by `ToolCallingAgent`.""" messages = get_clean_message_list( messages, role_conversions=tool_role_conversions ) @@ -473,7 +473,7 @@ class AnthropicEngine: available_tools: List[Tool], max_tokens: int = 1500, ): - """Generates a tool call for the given message list""" + """Generates a tool call for the given message list. This method is used only by `ToolCallingAgent`.""" messages = get_clean_message_list( messages, role_conversions=tool_role_conversions ) diff --git a/src/agents/local_python_executor.py b/src/smolagents/local_python_executor.py similarity index 100% rename from src/agents/local_python_executor.py rename to src/smolagents/local_python_executor.py diff --git a/src/agents/monitoring.py b/src/smolagents/monitoring.py similarity index 100% rename from src/agents/monitoring.py rename to src/smolagents/monitoring.py diff --git a/src/agents/prompts.py b/src/smolagents/prompts.py similarity index 100% rename from src/agents/prompts.py rename to src/smolagents/prompts.py diff --git a/src/agents/tool_validation.py b/src/smolagents/tool_validation.py similarity index 100% rename from src/agents/tool_validation.py rename to src/smolagents/tool_validation.py diff --git a/src/agents/tools.py b/src/smolagents/tools.py similarity index 99% rename from src/agents/tools.py rename to src/smolagents/tools.py index 0bf4331..8472e0b 100644 --- a/src/agents/tools.py +++ b/src/smolagents/tools.py @@ -83,7 +83,7 @@ def get_repo_type(repo_id, repo_type=None, **hub_kwargs): def setup_default_tools(): default_tools = {} - main_module = importlib.import_module("agents") + main_module = importlib.import_module("smolagents") for task_name, tool_class_name in TOOL_MAPPING.items(): tool_class = getattr(main_module, tool_class_name) @@ -239,7 +239,7 @@ class Tool: forward_source_code = inspect.getsource(self.forward) tool_code = textwrap.dedent(f""" - from agents import Tool + from smolagents import Tool class {class_name}(Tool): name = "{self.name}" @@ -288,7 +288,7 @@ class Tool: with open(app_file, "w", encoding="utf-8") as f: f.write( textwrap.dedent(f""" - from agents import launch_gradio_demo + from smolagents import launch_gradio_demo from tool import {class_name} tool = {class_name}() @@ -800,7 +800,7 @@ def load_tool( """ if task_or_repo_id in TOOL_MAPPING: tool_class_name = TOOL_MAPPING[task_or_repo_id] - main_module = importlib.import_module("agents") + main_module = importlib.import_module("smolagents") tools_module = main_module tool_class = getattr(tools_module, tool_class_name) return tool_class(model_repo_id, token=token, **kwargs) diff --git a/src/agents/types.py b/src/smolagents/types.py similarity index 100% rename from src/agents/types.py rename to src/smolagents/types.py diff --git a/src/agents/utils.py b/src/smolagents/utils.py similarity index 100% rename from src/agents/utils.py rename to src/smolagents/utils.py diff --git a/tests/test_agents.py b/tests/test_agents.py index f39bdba..5a0aae2 100644 --- a/tests/test_agents.py +++ b/tests/test_agents.py @@ -20,8 +20,8 @@ import pytest from pathlib import Path -from agents.types import AgentText -from agents.agents import ( +from smolagents.types import AgentText +from smolagents.agents import ( AgentMaxIterationsError, ManagedAgent, CodeAgent, @@ -29,8 +29,8 @@ from agents.agents import ( Toolbox, ToolCall, ) -from agents.tools import tool -from agents.default_tools import PythonInterpreterTool +from smolagents.tools import tool +from smolagents.default_tools import PythonInterpreterTool from transformers.testing_utils import get_tests_dir diff --git a/tests/test_final_answer.py b/tests/test_final_answer.py index 5b6e50f..381e17d 100644 --- a/tests/test_final_answer.py +++ b/tests/test_final_answer.py @@ -21,9 +21,9 @@ from PIL import Image from transformers import is_torch_available from transformers.testing_utils import get_tests_dir, require_torch -from agents.types import AGENT_TYPE_MAPPING +from smolagents.types import AGENT_TYPE_MAPPING -from agents.default_tools import FinalAnswerTool +from smolagents.default_tools import FinalAnswerTool from .test_tools_common import ToolTesterMixin diff --git a/tests/test_monitoring.py b/tests/test_monitoring.py index 3389c39..f6692e2 100644 --- a/tests/test_monitoring.py +++ b/tests/test_monitoring.py @@ -15,7 +15,7 @@ import unittest -from agents import AgentImage, AgentError, CodeAgent, JsonAgent, stream_to_gradio +from smolagents import AgentImage, AgentError, CodeAgent, JsonAgent, stream_to_gradio class MonitoringTester(unittest.TestCase): diff --git a/tests/test_python_interpreter.py b/tests/test_python_interpreter.py index 34ae802..f9c008b 100644 --- a/tests/test_python_interpreter.py +++ b/tests/test_python_interpreter.py @@ -18,10 +18,10 @@ import unittest import numpy as np import pytest -from agents import load_tool -from agents.types import AGENT_TYPE_MAPPING -from agents.default_tools import BASE_PYTHON_TOOLS -from agents.local_python_executor import ( +from smolagents import load_tool +from smolagents.types import AGENT_TYPE_MAPPING +from smolagents.default_tools import BASE_PYTHON_TOOLS +from smolagents.local_python_executor import ( InterpreterError, evaluate_python_code, ) diff --git a/tests/test_search.py b/tests/test_search.py index 31af552..8d972c7 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -15,7 +15,7 @@ import unittest -from agents import load_tool +from smolagents import load_tool from .test_tools_common import ToolTesterMixin diff --git a/tests/test_tools_common.py b/tests/test_tools_common.py index dd30078..96f804f 100644 --- a/tests/test_tools_common.py +++ b/tests/test_tools_common.py @@ -20,13 +20,13 @@ import numpy as np import pytest from transformers import is_torch_available, is_vision_available -from agents.types import ( +from smolagents.types import ( AGENT_TYPE_MAPPING, AgentAudio, AgentImage, AgentText, ) -from agents.tools import Tool, tool, AUTHORIZED_TYPES +from smolagents.tools import Tool, tool, AUTHORIZED_TYPES from transformers.testing_utils import get_tests_dir diff --git a/tests/test_types.py b/tests/test_types.py index 4bd8940..ee2ec66 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -18,7 +18,7 @@ import unittest import uuid from pathlib import Path -from agents.types import AgentAudio, AgentImage, AgentText +from smolagents.types import AgentAudio, AgentImage, AgentText from transformers.testing_utils import ( get_tests_dir, require_soundfile,