From cd9e32e4b0433349d8e08cebf6ed3e20caceec7d Mon Sep 17 00:00:00 2001 From: "Jon Michael Aanes (aider)" Date: Wed, 23 Apr 2025 20:33:57 +0200 Subject: [PATCH 1/9] fix: handle existing pull request error in create_pull_request to prevent crash --- aider_gitea/gitea_client.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/aider_gitea/gitea_client.py b/aider_gitea/gitea_client.py index e239af1..788f0c9 100644 --- a/aider_gitea/gitea_client.py +++ b/aider_gitea/gitea_client.py @@ -166,6 +166,20 @@ class GiteaClient: } response = self.session.post(url, json=json_data) + # If a pull request for this head/base already exists, return it instead of crashing + if response.status_code == 422: + logger.warning( + "Pull request already exists for head %s and base %s", head, base + ) + prs = self.get_pull_requests(owner, repo) + for pr in prs: + if ( + pr.get("head", {}).get("ref") == head + and pr.get("base", {}).get("ref") == base + ): + return pr + # fallback to raise if we can’t find it + response.raise_for_status() response.raise_for_status() return response.json() @@ -182,3 +196,15 @@ class GiteaClient: response = self.session.get(url) response.raise_for_status() return response.json() + + def get_pull_requests( + self, + owner: str, + repo: str, + state: str = "open", + ) -> list[dict]: + """Fetch pull requests for a repository.""" + url = f"{self.gitea_url}/repos/{owner}/{repo}/pulls?state={state}" + response = self.session.get(url) + response.raise_for_status() + return response.json() From 04b3baaba266d332ddf86a4423853cf129510f8a Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Wed, 23 Apr 2025 20:34:01 +0200 Subject: [PATCH 2/9] Ruff after aider --- aider_gitea/gitea_client.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/aider_gitea/gitea_client.py b/aider_gitea/gitea_client.py index 788f0c9..751b2ea 100644 --- a/aider_gitea/gitea_client.py +++ b/aider_gitea/gitea_client.py @@ -169,13 +169,13 @@ class GiteaClient: # If a pull request for this head/base already exists, return it instead of crashing if response.status_code == 422: logger.warning( - "Pull request already exists for head %s and base %s", head, base + 'Pull request already exists for head %s and base %s', head, base, ) prs = self.get_pull_requests(owner, repo) for pr in prs: if ( - pr.get("head", {}).get("ref") == head - and pr.get("base", {}).get("ref") == base + pr.get('head', {}).get('ref') == head + and pr.get('base', {}).get('ref') == base ): return pr # fallback to raise if we can’t find it @@ -201,10 +201,10 @@ class GiteaClient: self, owner: str, repo: str, - state: str = "open", + state: str = 'open', ) -> list[dict]: """Fetch pull requests for a repository.""" - url = f"{self.gitea_url}/repos/{owner}/{repo}/pulls?state={state}" + url = f'{self.gitea_url}/repos/{owner}/{repo}/pulls?state={state}' response = self.session.get(url) response.raise_for_status() return response.json() From 6db1cccaf8dd734aff5e09bd44a47b8202a8c17a Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Wed, 23 Apr 2025 22:20:02 +0200 Subject: [PATCH 3/9] Fix the status_code --- aider_gitea/gitea_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider_gitea/gitea_client.py b/aider_gitea/gitea_client.py index 751b2ea..4133096 100644 --- a/aider_gitea/gitea_client.py +++ b/aider_gitea/gitea_client.py @@ -167,7 +167,7 @@ class GiteaClient: response = self.session.post(url, json=json_data) # If a pull request for this head/base already exists, return it instead of crashing - if response.status_code == 422: + if response.status_code == 409: logger.warning( 'Pull request already exists for head %s and base %s', head, base, ) From b9013b7b2a878dd09816caefdb956a7f8630cdb7 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Wed, 23 Apr 2025 22:24:41 +0200 Subject: [PATCH 4/9] Fixing types --- aider_gitea/__init__.py | 10 +++++++--- aider_gitea/gitea_client.py | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/aider_gitea/__init__.py b/aider_gitea/__init__.py index 4f356a5..2df0e46 100644 --- a/aider_gitea/__init__.py +++ b/aider_gitea/__init__.py @@ -103,7 +103,11 @@ class RepositoryConfig: class IssueResolution: success: bool pull_request_url: str | None = None - pull_request_id: str | None = None + pull_request_id: int | None = None + + def __post_init__(self): + assert self.pull_request_id is None or isinstance(self.pull_request_id, int) + assert self.pull_request_url is None or isinstance(self.pull_request_url, str) def generate_branch_name(issue_number: str, issue_title: str) -> str: @@ -283,8 +287,8 @@ def push_changes( # Extract PR number and URL if available return IssueResolution( True, - str(pr_response.get('number')), pr_response.get('html_url'), + int(pr_response.get('number')), ) @@ -542,7 +546,7 @@ def solve_issues_in_repository( def handle_pr_comments( repository_config, - pr_number, + pr_number: int, branch_name, repository_path, client, diff --git a/aider_gitea/gitea_client.py b/aider_gitea/gitea_client.py index 4133096..89e9498 100644 --- a/aider_gitea/gitea_client.py +++ b/aider_gitea/gitea_client.py @@ -187,11 +187,12 @@ class GiteaClient: self, owner: str, repo: str, - pr_number: str, + pr_number: int, ) -> list[dict]: """ Fetch comments for a pull request. """ + assert isinstance(pr_number, int) url = f'{self.gitea_url}/repos/{owner}/{repo}/pulls/{pr_number}/comments' response = self.session.get(url) response.raise_for_status() From 54cddfde0ba5181dc063434d80ff04b2eb845dbe Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Wed, 23 Apr 2025 23:11:05 +0200 Subject: [PATCH 5/9] Removed useless functionality --- aider_gitea/__init__.py | 28 ++++++++++++++-------------- aider_gitea/gitea_client.py | 15 --------------- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/aider_gitea/__init__.py b/aider_gitea/__init__.py index 2df0e46..d50abdd 100644 --- a/aider_gitea/__init__.py +++ b/aider_gitea/__init__.py @@ -506,21 +506,21 @@ def solve_issues_in_repository( title = issue.get('title', f'Issue {issue_number}') if seen_issues_db.has_seen(issue_url): logger.info('Skipping already processed issue #%s: %s', issue_number, title) - continue + else: + branch_name = generate_branch_name(issue_number, title) + with tempfile.TemporaryDirectory() as repository_path: + issue_resolution = solve_issue_in_repository( + repository_config, + Path(repository_path), + branch_name, + title, + issue_description, + issue_number, + client, + ) - branch_name = generate_branch_name(issue_number, title) - with tempfile.TemporaryDirectory() as repository_path: - issue_resolution = solve_issue_in_repository( - repository_config, - Path(repository_path), - branch_name, - title, - issue_description, - issue_number, - client, - ) - - if issue_resolution.success: + # TODO: PR comment handling disabled for now due to missing functionality + if False: # Handle unresolved pull request comments handle_pr_comments( repository_config, diff --git a/aider_gitea/gitea_client.py b/aider_gitea/gitea_client.py index 89e9498..0c2f8e6 100644 --- a/aider_gitea/gitea_client.py +++ b/aider_gitea/gitea_client.py @@ -183,21 +183,6 @@ class GiteaClient: response.raise_for_status() return response.json() - def get_pull_request_comments( - self, - owner: str, - repo: str, - pr_number: int, - ) -> list[dict]: - """ - Fetch comments for a pull request. - """ - assert isinstance(pr_number, int) - url = f'{self.gitea_url}/repos/{owner}/{repo}/pulls/{pr_number}/comments' - response = self.session.get(url) - response.raise_for_status() - return response.json() - def get_pull_requests( self, owner: str, From 7a73a1e3fc477779711419b2d3af56c6cc5f467d Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Thu, 24 Apr 2025 11:54:41 +0200 Subject: [PATCH 6/9] Initial ruff pass --- aider_gitea/gitea_client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aider_gitea/gitea_client.py b/aider_gitea/gitea_client.py index 0c2f8e6..7360e05 100644 --- a/aider_gitea/gitea_client.py +++ b/aider_gitea/gitea_client.py @@ -169,7 +169,9 @@ class GiteaClient: # If a pull request for this head/base already exists, return it instead of crashing if response.status_code == 409: logger.warning( - 'Pull request already exists for head %s and base %s', head, base, + 'Pull request already exists for head %s and base %s', + head, + base, ) prs = self.get_pull_requests(owner, repo) for pr in prs: From 7a35029a18986c0a8e7cca214a884ec4bb6c3212 Mon Sep 17 00:00:00 2001 From: "Jon Michael Aanes (aider)" Date: Thu, 24 Apr 2025 11:55:21 +0200 Subject: [PATCH 7/9] feat: add CLI options to override aider and evaluator models --- aider_gitea/__main__.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/aider_gitea/__main__.py b/aider_gitea/__main__.py index d2e1185..8c5b35f 100644 --- a/aider_gitea/__main__.py +++ b/aider_gitea/__main__.py @@ -45,6 +45,16 @@ def parse_args(): default=300, help='Interval in seconds between checks in daemon mode (default: 300)', ) + parser.add_argument( + '--aider-model', + help='Model to use for generating code (overrides default)', + default=None, + ) + parser.add_argument( + '--evaluator-model', + help='Model to use for evaluating code (overrides default)', + default=None, + ) return parser.parse_args() @@ -52,6 +62,13 @@ def main(): logging.basicConfig(level='INFO') args = parse_args() + # Override default models if provided + import aider_gitea as core + if args.aider_model: + core.CODE_MODEL = args.aider_model + if args.evaluator_model: + core.EVALUATOR_MODEL = args.evaluator_model + seen_issues_db = SeenIssuesDB() client = GiteaClient(args.gitea_url, secrets.gitea_token()) From 236d1c0a10d2958d79ad543a10b8615815fbfa10 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Thu, 24 Apr 2025 11:55:25 +0200 Subject: [PATCH 8/9] Ruff after aider --- aider_gitea/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider_gitea/__main__.py b/aider_gitea/__main__.py index 8c5b35f..a6f3d49 100644 --- a/aider_gitea/__main__.py +++ b/aider_gitea/__main__.py @@ -64,6 +64,7 @@ def main(): # Override default models if provided import aider_gitea as core + if args.aider_model: core.CODE_MODEL = args.aider_model if args.evaluator_model: From a8ce6102d28fbca27e4d08072ac458ba96def937 Mon Sep 17 00:00:00 2001 From: "Jon Michael Aanes (aider)" Date: Thu, 24 Apr 2025 12:07:08 +0200 Subject: [PATCH 9/9] fix: return true early in verify_solution if no evaluator model is set --- aider_gitea/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aider_gitea/__init__.py b/aider_gitea/__init__.py index d50abdd..2f33267 100644 --- a/aider_gitea/__init__.py +++ b/aider_gitea/__init__.py @@ -387,6 +387,9 @@ def run_ollama_and_get_yes_or_no(cwd, initial_texts: list[str]) -> bool: def verify_solution(repository_path: Path, issue_content: str) -> bool: + if not EVALUATOR_MODEL: + return True + summary = run_ollama( repository_path, [