| | from langchain_tavily import TavilySearch |
| | from langchain_core.tools import tool |
| | from dotenv import load_dotenv |
| | from github import Github |
| | import subprocess |
| | import os |
| |
|
| | load_dotenv() |
| |
|
| | tavily_search = TavilySearch( |
| | max_results=5, |
| | topic="general", |
| | include_answer=False |
| | ) |
| |
|
| | @tool |
| | def list_repo_branches(project_name: str): |
| | """Lists all branches in a GitHub repository.""" |
| | try: |
| | github = Github(os.getenv('GITHUB_TOKEN')) |
| | user = github.get_user() |
| | repo = user.get_repo(project_name) |
| | branches = repo.get_branches() |
| | branch_names = [branch.name for branch in branches] |
| | return f"Branches in '{project_name}': {', '.join(branch_names)}" |
| | except Exception as e: |
| | return f"Error listing branches: {str(e)}" |
| |
|
| | @tool |
| | def create_repo_branch(project_name: str, branch_name: str): |
| | """Creates a new branch in a GitHub repository.""" |
| | try: |
| | github = Github(os.getenv('GITHUB_TOKEN')) |
| | user = github.get_user() |
| | repo = user.get_repo(project_name) |
| | main_branch = repo.get_branch("main") |
| | repo.create_git_ref(ref=f"refs/heads/{branch_name}", sha=main_branch.commit.sha) |
| | return f"Branch '{branch_name}' created successfully in '{project_name}'." |
| | except Exception as e: |
| | return f"Error creating branch: {str(e)}" |
| |
|
| | @tool |
| | def write_file(project_name: str, file_path: str, file_contents: str): |
| | """Adds a new file to the project directory and GitHub repository or updates the existing one.""" |
| | try: |
| | full_path = os.path.join('agents/coder/projects', project_name, file_path) |
| | with open(full_path, "w", encoding="utf-8") as f: |
| | f.write(file_contents) |
| | except Exception as e: |
| | return f"Error with file operation: {str(e)}" |
| | try: |
| | github = Github(os.getenv('GITHUB_TOKEN')) |
| | user = github.get_user() |
| | repo = user.get_repo(project_name) |
| |
|
| | try: |
| | |
| | file = repo.get_contents(file_path) |
| | sha = file.sha |
| | repo.update_file(file_path, "Updating file", file_contents, sha) |
| | return f"File '{file_path}' updated successfully in '{project_name}'." |
| | except: |
| | repo.create_file(file_path, "Adding new file", file_contents) |
| | return f"File '{file_path}' created successfully in '{project_name}'." |
| | except Exception as e: |
| | return f"Error with file operation: {str(e)}" |
| |
|
| | @tool |
| | def delete_file(project_name: str, file_path: str): |
| | """Deletes a file from the GitHub repository.""" |
| | try: |
| | full_path = os.path.join('agents/coder/projects', project_name, file_path) |
| | if os.path.isfile(full_path): |
| | os.remove(full_path) |
| | except Exception as e: |
| | return f"Error deleting file: {str(e)}" |
| | try: |
| | github = Github(os.getenv('GITHUB_TOKEN')) |
| | user = github.get_user() |
| | repo = user.get_repo(project_name) |
| | file = repo.get_contents(file_path) |
| | sha = file.sha |
| | repo.delete_file(file_path, "Deleting file", sha) |
| | return f"File '{file_path}' deleted successfully from '{project_name}'." |
| | except Exception as e: |
| | return f"Error deleting file: {str(e)}" |
| |
|
| | @tool |
| | def read_file(project_name: str, file_path: str) -> str: |
| | """Reads the content of a file from a project directory.""" |
| | full_path = os.path.join('agents/coder/projects', project_name, file_path) |
| | try: |
| | with open(full_path, "r", encoding="utf-8") as f: |
| | return f.read() |
| | except Exception as e: |
| | return f"Error reading file '{full_path}': {str(e)}" |
| |
|
| | @tool |
| | def list_files(project_name: str, directory: str = "") -> dict: |
| | """ |
| | Lists files in a project directory. |
| | |
| | :param project_name: The name of the project. |
| | :param directory: Optional subdirectory inside the project. By default, (directory="") all project files are listed. |
| | :return: List of files in the directory inside the project. |
| | """ |
| | full_path = os.path.join('agents/coder/projects', project_name, directory) |
| | try: |
| | if not os.path.exists(full_path): |
| | return f"Directory '{full_path}' does not exist." |
| |
|
| | if not os.path.isdir(full_path): |
| | return f"Path '{full_path}' is not a directory." |
| |
|
| | files = os.listdir(full_path) |
| | return files |
| |
|
| | except Exception as e: |
| | return f"Error listing files: {str(e)}" |
| |
|
| | @tool |
| | def run_cmd(project_name: str, cmd: str, timeout: int = 30): |
| | """ |
| | Runs a shell command in the project_name directory. |
| | """ |
| | full_path = os.path.join("agents/coder/projects", project_name) |
| |
|
| | if not os.path.isdir(full_path): |
| | return -1, "", f"Project directory not found: {full_path}" |
| |
|
| | try: |
| | res = subprocess.run( |
| | cmd, |
| | shell=True, |
| | cwd=full_path, |
| | capture_output=True, |
| | text=True, |
| | timeout=timeout |
| | ) |
| | return res.returncode, res.stdout, res.stderr |
| | except subprocess.TimeoutExpired as e: |
| | return -1, e.stdout or "", f"Command timed out after {timeout}s" |
| | except Exception as e: |
| | return -1, "", f"Error running command: {str(e)}" |
| |
|
| |
|
| | tools = [tavily_search, list_repo_branches, create_repo_branch, write_file, delete_file, read_file, list_files, run_cmd] |
| |
|