Skip to content

Commit b3a7d96

Browse files
authored
Merge pull request #45 from commit-0/aider
remove hydra for run_agent
2 parents f6238a8 + 22c0977 commit b3a7d96

File tree

12 files changed

+213
-57
lines changed

12 files changed

+213
-57
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,5 @@ logs/
165165
repos/
166166
config.yml
167167
hydra_outputs/
168-
.commit0*
168+
.commit0*
169+
.agent*
File renamed without changes.

agent/__main__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from agent.cli import agent_app
2+
3+
4+
def main() -> None:
5+
"""Main function to run the CLI"""
6+
agent_app()
7+
8+
9+
if __name__ == "__main__":
10+
main()
File renamed without changes.
File renamed without changes.

agent/cli.py

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
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)

baselines/commit0_utils.py renamed to agent/commit0_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import List
77
import fitz
88

9-
from baselines.class_types import AgentConfig
9+
from agent.class_types import AgentConfig
1010

1111
PROMPT_HEADER = ">>> Here is the Task:\n"
1212
REFERENCE_HEADER = "\n\n>>> Here is the Reference for you to finish the task:\n"
@@ -128,7 +128,7 @@ def get_target_edit_files(target_dir: str) -> list[str]:
128128
if filename.endswith(".py"):
129129
file_path = os.path.join(root, filename)
130130
with open(file_path, "r") as file:
131-
if "NotImplementedError('IMPLEMENT ME HERE')" in file.read():
131+
if " pass" in file.read():
132132
files.append(file_path)
133133

134134
# Remove the base_dir prefix
File renamed without changes.
File renamed without changes.

baselines/run_agent.py renamed to agent/run_agent.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
import os
22
import sys
3-
import hydra
3+
import yaml
44
import multiprocessing
5+
from tqdm import tqdm
56
from datasets import load_dataset
67
from git import Repo
7-
from baselines.commit0_utils import (
8+
from agent.commit0_utils import (
89
args2string,
910
create_branch,
1011
get_message,
1112
get_target_edit_files,
1213
get_lint_cmd,
1314
)
14-
from baselines.agents import AiderAgents
15+
from agent.agents import AiderAgents
1516
from typing import Optional, Type
1617
from types import TracebackType
17-
from hydra.core.config_store import ConfigStore
18-
from baselines.class_types import AgentConfig
18+
from agent.class_types import AgentConfig
1919
from commit0.harness.constants import SPLIT
2020
from commit0.harness.get_pytest_ids import main as get_tests
2121
from commit0.harness.constants import RUN_AIDER_LOG_DIR, RepoInstance
22-
from tqdm import tqdm
2322
from commit0.cli import read_commit0_dot_file
2423

2524

@@ -40,6 +39,14 @@ def __exit__(
4039
os.chdir(self.cwd)
4140

4241

42+
def read_yaml_config(config_file: str) -> dict:
43+
"""Read the yaml config from the file."""
44+
if not os.path.exists(config_file):
45+
raise FileNotFoundError(f"The config file '{config_file}' does not exist.")
46+
with open(config_file, "r") as f:
47+
return yaml.load(f, Loader=yaml.FullLoader)
48+
49+
4350
def run_agent_for_repo(
4451
repo_base_dir: str,
4552
agent_config: AgentConfig,
@@ -111,21 +118,23 @@ def run_agent_for_repo(
111118
for f in target_edit_files:
112119
file_name = f.replace(".py", "").replace("/", "__")
113120
log_dir = RUN_AIDER_LOG_DIR / "no_tests" / file_name
121+
# write agent_config to .agent.yaml
122+
with open(
123+
RUN_AIDER_LOG_DIR / "no_tests" / file_name / ".agent.yaml", "w"
124+
) as agent_config_file:
125+
yaml.dump(agent_config, agent_config_file)
114126
lint_cmd = get_lint_cmd(local_repo, agent_config.use_lint_info)
115-
116127
agent.run(message, "", lint_cmd, [f], log_dir)
117128

118129

119-
def main() -> None:
130+
def run_agent(agent_config_file: str) -> None:
120131
"""Main function to run Aider for a given repository.
121132
122133
Will run in parallel for each repo.
123134
"""
124-
cs = ConfigStore.instance()
125-
cs.store(name="user", node=AgentConfig)
126-
hydra.initialize(version_base=None, config_path="configs")
127-
config = hydra.compose(config_name="agent")
128-
agent_config = AgentConfig(**config.agent_config)
135+
config = read_yaml_config(agent_config_file)
136+
137+
agent_config = AgentConfig(**config)
129138

130139
commit0_config = read_commit0_dot_file(".commit0.yaml")
131140

@@ -168,7 +177,3 @@ def main() -> None:
168177

169178
for result in results:
170179
result.wait()
171-
172-
173-
if __name__ == "__main__":
174-
main()

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ requires-python = ">=3.10"
1010
dependencies = [
1111
"ruff>=0.6.4",
1212
"pre-commit>=3.8.0",
13-
"hydra-core>=1.3.2",
1413
"PyMuPDF>=1.24.5",
1514
"aider-chat>=0.56.0",
1615
"modal>=0.64.95",
@@ -22,7 +21,7 @@ dependencies = [
2221
"gitpython>=3.1.43",
2322
"pytest>=8.3.3",
2423
]
25-
scripts = { commit0 = "commit0.__main__:main" }
24+
scripts = { commit0 = "commit0.__main__:main", agent = "agent.__main__:main" }
2625

2726
[tool.pyright]
2827
include = ["**/commit0"]

uv.lock

Lines changed: 0 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)