From 5c07afac9eb876cd6b4f8ebbb4f5ac0ce04f1dc3 Mon Sep 17 00:00:00 2001 From: Kye Date: Mon, 1 Apr 2024 22:06:45 -0700 Subject: [PATCH] [README] --- README.md | 109 ++++++++++++++++++++++++++++++++++ devin.py | 48 +++++++++++---- swarms/structs/agent.py | 22 +++++-- swarms/tools/code_executor.py | 22 ++----- swarms/tools/interpreter.py | 41 +++++++++++++ 5 files changed, 206 insertions(+), 36 deletions(-) create mode 100644 swarms/tools/interpreter.py diff --git a/README.md b/README.md index cb382c4c..d84a32ef 100644 --- a/README.md +++ b/README.md @@ -469,7 +469,116 @@ agent = Agent( # Run the workflow on a task agent("Generate a transcript for a youtube video on what swarms are!") +``` + +## Devin +Implementation of Devil in less than 90 lines of code with several tools: +terminal, browser, and edit files! + +```python +from swarms import Agent, Anthropic, tool +import subprocess + +# Model +llm = Anthropic( + temperature=0.1, +) + +# Tools +@tool +def terminal( + code: str, +): + """ + Run code in the terminal. + + Args: + code (str): The code to run in the terminal. + + Returns: + str: The output of the code. + """ + out = subprocess.run( + code, shell=True, capture_output=True, text=True + ).stdout + return str(out) + + +@tool +def browser(query: str): + """ + Search the query in the browser with the `browser` tool. + + Args: + query (str): The query to search in the browser. + + Returns: + str: The search results. + """ + import webbrowser + + url = f"https://www.google.com/search?q={query}" + webbrowser.open(url) + return f"Searching for {query} in the browser." + +@tool +def create_file(file_path: str, content: str): + """ + Create a file using the file editor tool. + + Args: + file_path (str): The path to the file. + content (str): The content to write to the file. + Returns: + str: The result of the file creation operation. + """ + with open(file_path, "w") as file: + file.write(content) + return f"File {file_path} created successfully." + +@tool +def file_editor(file_path: str, mode: str, content: str): + """ + Edit a file using the file editor tool. + + Args: + file_path (str): The path to the file. + mode (str): The mode to open the file in. + content (str): The content to write to the file. + + Returns: + str: The result of the file editing operation. + """ + with open(file_path, mode) as file: + file.write(content) + return f"File {file_path} edited successfully." + + +# Agent +agent = Agent( + agent_name="Devin", + system_prompt=( + "Autonomous agent that can interact with humans and other" + " agents. Be Helpful and Kind. Use the tools provided to" + " assist the user. Return all code in markdown format." + ), + llm=llm, + max_loops="auto", + autosave=True, + dashboard=False, + streaming_on=True, + verbose=True, + stopping_token="", + interactive=True, + tools=[terminal, browser, file_editor, create_file], + code_interpreter=True, + # streaming=True, +) + +# Run the agent +out = agent("Create a new file for a plan to take over the world.") +print(out) ``` diff --git a/devin.py b/devin.py index fb3feb59..45fcf848 100644 --- a/devin.py +++ b/devin.py @@ -1,12 +1,3 @@ -""" -Plan -> act in a loop until observation is met - - -# Tools -- Terminal -- Text Editor -- Browser -""" from swarms import Agent, Anthropic, tool import subprocess @@ -15,7 +6,6 @@ llm = Anthropic( temperature=0.1, ) - # Tools @tool def terminal( @@ -53,6 +43,39 @@ def browser(query: str): webbrowser.open(url) return f"Searching for {query} in the browser." +@tool +def create_file(file_path: str, content: str): + """ + Create a file using the file editor tool. + + Args: + file_path (str): The path to the file. + content (str): The content to write to the file. + + Returns: + str: The result of the file creation operation. + """ + with open(file_path, "w") as file: + file.write(content) + return f"File {file_path} created successfully." + +@tool +def file_editor(file_path: str, mode: str, content: str): + """ + Edit a file using the file editor tool. + + Args: + file_path (str): The path to the file. + mode (str): The mode to open the file in. + content (str): The content to write to the file. + + Returns: + str: The result of the file editing operation. + """ + with open(file_path, mode) as file: + file.write(content) + return f"File {file_path} edited successfully." + # Agent agent = Agent( @@ -70,10 +93,11 @@ agent = Agent( verbose=True, stopping_token="", interactive=True, - tools=[terminal, browser], + tools=[terminal, browser, file_editor, create_file], + code_interpreter=True, # streaming=True, ) # Run the agent -out = agent("What is the weather today in palo alto use the browser tool to search for the weather?") +out = agent("Create a new file for a plan to take over the world.") print(out) diff --git a/swarms/structs/agent.py b/swarms/structs/agent.py index 49361dd6..5544c654 100644 --- a/swarms/structs/agent.py +++ b/swarms/structs/agent.py @@ -26,6 +26,8 @@ from swarms.utils.parse_code import extract_code_from_markdown from swarms.utils.pdf_to_text import pdf_to_text from swarms.tools.exec_tool import execute_tool_by_name from swarms.tools.function_util import process_tool_docs +from swarms.tools.interpreter import execute_command +from swarms.tools.code_executor import CodeExecutor # Utils # Custom stopping condition @@ -631,17 +633,25 @@ class Agent: ) if self.code_interpreter: + # Extract code from markdown extracted_code = ( extract_code_from_markdown(response) ) - task_prompt += extracted_code - response = self.llm( - task_prompt, *args, **kwargs - ) + + # Execute the code + # execution = execute_command(extracted_code) + execution = CodeExecutor().run(extracted_code) + + # Add the execution to the memory self.short_memory.add( - role=self.agent_name, content=response + role=self.agent_name, content=execution ) - + + # Run the llm again + response = self.llm( + self.short_memory.return_history_as_string(), *args, **kwargs + ) + if self.evaluator: evaluated_response = self.evaluator( response diff --git a/swarms/tools/code_executor.py b/swarms/tools/code_executor.py index 5a85f14d..4acf911c 100644 --- a/swarms/tools/code_executor.py +++ b/swarms/tools/code_executor.py @@ -24,21 +24,8 @@ class CodeExecutor: Executes the code and returns the output. """ - def __init__(self, code: str = None): - self.code = code - - def is_python_code(self, code: str = None) -> bool: - """ - Checks if the given code is Python code. - - Args: - code (str, optional): The code to be checked. Defaults to None. - - Returns: - bool: True if the code is Python code, False otherwise. - """ - code = code or self.code - return code.strip().startswith("python") + def __init__(self): + self.code = None def run_python(self, code: str = None) -> str: """ @@ -84,7 +71,6 @@ class CodeExecutor: Returns: str: The output of the code execution. """ - code = code or self.code try: output = subprocess.check_output( code, @@ -96,14 +82,14 @@ class CodeExecutor: except Exception as e: return str(e) - def __call__(self) -> str: + def __call__(self, task: str, *args, **kwargs) -> str: """ Executes the code and returns the output. Returns: str: The output of the code execution. """ - return self.run() + return self.run(task, *args, **kwargs) # model = CodeExecutor() diff --git a/swarms/tools/interpreter.py b/swarms/tools/interpreter.py new file mode 100644 index 00000000..44029a97 --- /dev/null +++ b/swarms/tools/interpreter.py @@ -0,0 +1,41 @@ + +import io +import sys + +from swarms.utils.loguru_logger import logger + + +def execute_command(code): + """ + Executes Python code and returns the output. + + Args: + code (str): The Python code to execute. + + Returns: + str: The output of the code. + """ + # Create a string buffer to capture stdout and stderr + buffer = io.StringIO() + + # Redirect stdout and stderr to the buffer + sys.stdout = buffer + sys.stderr = buffer + + try: + # Execute the code + exec(code) + except Exception as e: + # Log the error + logger.error(f"Error executing code: {code}\n{str(e)}") + return str(e) + finally: + # Restore stdout and stderr + sys.stdout = sys.__stdout__ + sys.stderr = sys.__stderr__ + + # Get the output from the buffer + output = buffer.getvalue() + + # Return the output + return output \ No newline at end of file