from typing import List
from agno.agent import Agent
from agno.tools import Toolkit
from agno.utils.log import logger
class ShellTools(Toolkit):
def __init__(self, working_directory: str = "/", **kwargs):
self.working_directory = working_directory
tools = [
self.run_shell_command,
]
super().__init__(name="shell_tools", tools=tools, **kwargs)
def list_files(self, directory: str):
"""
List the files in the given directory.
Args:
directory (str): The directory to list the files from.
Returns:
str: The list of files in the directory.
"""
import os
# List files relative to the toolkit's working_directory
path = os.path.join(self.working_directory, directory)
try:
files = os.listdir(path)
return "\n".join(files)
except Exception as e:
logger.warning(f"Failed to list files in {path}: {e}")
return f"Error: {e}"
return os.listdir(directory)
def run_shell_command(self, args: List[str], tail: int = 100) -> str:
"""
Runs a shell command and returns the output or error.
Args:
args (List[str]): The command to run as a list of strings.
tail (int): The number of lines to return from the output.
Returns:
str: The output of the command.
"""
import subprocess
logger.info(f"Running shell command: {args}")
try:
logger.info(f"Running shell command: {args}")
result = subprocess.run(args, capture_output=True, text=True, cwd=self.working_directory)
logger.debug(f"Result: {result}")
logger.debug(f"Return code: {result.returncode}")
if result.returncode != 0:
return f"Error: {result.stderr}"
# return only the last n lines of the output
return "\n".join(result.stdout.split("\n")[-tail:])
except Exception as e:
logger.warning(f"Failed to run shell command: {e}")
return f"Error: {e}"
agent = Agent(tools=[ShellTools()], markdown=True)
agent.print_response("List all the files in my home directory.")