|
| 1 | +import typer |
| 2 | +import subprocess |
| 3 | +import yaml |
| 4 | +from agent.run_agent import run_agent |
| 5 | + |
| 6 | +agent_app = typer.Typer( |
| 7 | + no_args_is_help=True, |
| 8 | + add_completion=False, |
| 9 | + context_settings={"help_option_names": ["-h", "--help"]}, |
| 10 | + help=""" |
| 11 | + This is the command for running agent on Commit-0. |
| 12 | +
|
| 13 | + See the website at https://commit-0.github.io/ for documentation and more information about Commit-0. |
| 14 | + """, |
| 15 | +) |
| 16 | + |
| 17 | + |
| 18 | +class Colors: |
| 19 | + RESET = "\033[0m" |
| 20 | + RED = "\033[91m" |
| 21 | + YELLOW = "\033[93m" |
| 22 | + CYAN = "\033[96m" |
| 23 | + ORANGE = "\033[95m" |
| 24 | + |
| 25 | + |
| 26 | +def write_agent_config(agent_config_file: str, agent_config: dict) -> None: |
| 27 | + """Write the agent config to the file.""" |
| 28 | + with open(agent_config_file, "w") as f: |
| 29 | + yaml.dump(agent_config, f) |
| 30 | + |
| 31 | + |
| 32 | +def check_aider_path() -> None: |
| 33 | + """Code adapted from https://github.com/modal-labs/modal-client/blob/a8ddd418f8c65b7e168a9125451eeb70da2b6203/modal/cli/entry_point.py#L55 |
| 34 | +
|
| 35 | + Checks whether the `aider` executable is on the path and usable. |
| 36 | + """ |
| 37 | + url = "https://aider.chat/docs/install.html" |
| 38 | + try: |
| 39 | + subprocess.run(["aider", "--help"], capture_output=True) |
| 40 | + # TODO(erikbern): check returncode? |
| 41 | + return |
| 42 | + except FileNotFoundError: |
| 43 | + typer.echo( |
| 44 | + typer.style( |
| 45 | + "The `aider` command was not found on your path!", fg=typer.colors.RED |
| 46 | + ) |
| 47 | + + "\n" |
| 48 | + + typer.style( |
| 49 | + "You may need to add it to your path or use `python -m run_agent` as a workaround.", |
| 50 | + fg=typer.colors.RED, |
| 51 | + ) |
| 52 | + ) |
| 53 | + except PermissionError: |
| 54 | + typer.echo( |
| 55 | + typer.style("The `aider` command is not executable!", fg=typer.colors.RED) |
| 56 | + + "\n" |
| 57 | + + typer.style( |
| 58 | + "You may need to give it permissions or use `python -m run_agent` as a workaround.", |
| 59 | + fg=typer.colors.RED, |
| 60 | + ) |
| 61 | + ) |
| 62 | + typer.echo(f"See more information here:\n\n{url}") |
| 63 | + typer.echo("─" * 80) # Simple rule to separate content |
| 64 | + |
| 65 | + |
| 66 | +def highlight(text: str, color: str) -> str: |
| 67 | + """Highlight text with a color.""" |
| 68 | + return f"{color}{text}{Colors.RESET}" |
| 69 | + |
| 70 | + |
| 71 | +@agent_app.command() |
| 72 | +def config( |
| 73 | + agent_name: str = typer.Argument( |
| 74 | + ..., |
| 75 | + help=f"Agent to use, we only support {highlight('aider', Colors.ORANGE)} for now", |
| 76 | + ), |
| 77 | + model_name: str = typer.Option( |
| 78 | + "claude-3-5-sonnet-20240620", |
| 79 | + help="Model to use, check https://aider.chat/docs/llms.html for more information", |
| 80 | + ), |
| 81 | + use_user_prompt: bool = typer.Option( |
| 82 | + False, |
| 83 | + help="Use the user prompt instead of the default prompt", |
| 84 | + ), |
| 85 | + user_prompt: str = typer.Option( |
| 86 | + "Here is your task:\nYou need to implement all functions with ' pass' and pass the unit tests.\nDo not change the names of existing functions or classes, as they may be referenced from other code like unit tests, etc.\nWhen you generate code, you must maintain the original formatting of the function stubs (such as whitespaces), otherwise we will not able to search/replace blocks for code modifications, and therefore you will receive a score of 0 for your generated code.", |
| 87 | + help="User prompt to use", |
| 88 | + ), |
| 89 | + run_tests: bool = typer.Option( |
| 90 | + False, |
| 91 | + help="Run the tests after the agent is done", |
| 92 | + ), |
| 93 | + max_iteration: int = typer.Option( |
| 94 | + 3, |
| 95 | + help="Maximum number of iterations to run", |
| 96 | + ), |
| 97 | + use_repo_info: bool = typer.Option( |
| 98 | + False, |
| 99 | + help="Use the repository information", |
| 100 | + ), |
| 101 | + max_repo_info_length: int = typer.Option( |
| 102 | + 10000, |
| 103 | + help="Maximum length of the repository information to use", |
| 104 | + ), |
| 105 | + use_unit_tests_info: bool = typer.Option( |
| 106 | + False, |
| 107 | + help="Use the unit tests information", |
| 108 | + ), |
| 109 | + max_unit_tests_info_length: int = typer.Option( |
| 110 | + 10000, |
| 111 | + help="Maximum length of the unit tests information to use", |
| 112 | + ), |
| 113 | + use_spec_info: bool = typer.Option( |
| 114 | + False, |
| 115 | + help="Use the spec information", |
| 116 | + ), |
| 117 | + max_spec_info_length: int = typer.Option( |
| 118 | + 10000, |
| 119 | + help="Maximum length of the spec information to use", |
| 120 | + ), |
| 121 | + use_lint_info: bool = typer.Option( |
| 122 | + False, |
| 123 | + help="Use the lint information", |
| 124 | + ), |
| 125 | + max_lint_info_length: int = typer.Option( |
| 126 | + 10000, |
| 127 | + help="Maximum length of the lint information to use", |
| 128 | + ), |
| 129 | + pre_commit_config_path: str = typer.Option( |
| 130 | + ".pre-commit-config.yaml", |
| 131 | + help="Path to the pre-commit config file", |
| 132 | + ), |
| 133 | + agent_config_file: str = typer.Option( |
| 134 | + ".agent.yaml", |
| 135 | + help="Path to the agent config file", |
| 136 | + ), |
| 137 | +) -> None: |
| 138 | + """Configure the agent.""" |
| 139 | + if agent_name == "aider": |
| 140 | + check_aider_path() |
| 141 | + else: |
| 142 | + raise typer.BadParameter( |
| 143 | + f"Invalid {highlight('AGENT', Colors.RED)}. We only support aider for now", |
| 144 | + param_hint="AGENT", |
| 145 | + ) |
| 146 | + |
| 147 | + agent_config = { |
| 148 | + "agent_name": agent_name, |
| 149 | + "model_name": model_name, |
| 150 | + "use_user_prompt": use_user_prompt, |
| 151 | + "user_prompt": user_prompt, |
| 152 | + "run_tests": run_tests, |
| 153 | + "max_iteration": max_iteration, |
| 154 | + "use_repo_info": use_repo_info, |
| 155 | + "max_repo_info_length": max_repo_info_length, |
| 156 | + "use_unit_tests_info": use_unit_tests_info, |
| 157 | + "max_unit_tests_info_length": max_unit_tests_info_length, |
| 158 | + "use_spec_info": use_spec_info, |
| 159 | + "max_spec_info_length": max_spec_info_length, |
| 160 | + "use_lint_info": use_lint_info, |
| 161 | + "max_lint_info_length": max_lint_info_length, |
| 162 | + "pre_commit_config_path": pre_commit_config_path, |
| 163 | + } |
| 164 | + |
| 165 | + write_agent_config(agent_config_file, agent_config) |
| 166 | + |
| 167 | + |
| 168 | +@agent_app.command() |
| 169 | +def run( |
| 170 | + agent_config_file: str = typer.Argument( |
| 171 | + ".agent.yaml", |
| 172 | + help="Path to the agent config file", |
| 173 | + ), |
| 174 | +) -> None: |
| 175 | + """Run the agent on the repository.""" |
| 176 | + run_agent(agent_config_file) |
0 commit comments