Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 5 additions & 19 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,16 @@ repos:
# rev: v1.7.3
# hooks:
# - id: actionlint
- repo: https://github.com/pycqa/isort
# rev must match what's in dev-requirements.txt
rev: 5.13.2
# ruff handles linting and import sorting (config in pyproject.toml).
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.20
hooks:
- id: isort
- id: ruff
args: [--fix]
# - repo: https://github.com/PyCQA/bandit
# rev: 1.7.10
# hooks:
# - id: bandit
# args: [
# "-c", "pyproject.toml",
# ]
# - repo: https://github.com/astral-sh/ruff-pre-commit
# rev: v0.7.1
# hooks:
# - id: ruff
# args:
# - --fix
# - id: ruff-format
# - repo: https://github.com/PyCQA/autoflake
# rev: v2.3.1
# hooks:
# - id: autoflake
# args:
# - --in-place
# - --remove-all-unused-imports
# - --remove-unused-variables
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ PR-Agent automates AI-assisted reviews for pull requests across multiple git pro
## Coding Style and Naming Conventions

- Python sources follow the Ruff configuration in `pyproject.toml` (`line-length = 120`, Pyflakes plus `flake8-bugbear` checks, and isort ordering). Keep imports grouped as isort would produce and prefer double quotes for strings.
- Pre-commit (`.pre-commit-config.yaml`) enforces trailing whitespace cleanup, final newlines, TOML/YAML validity, and optional `isort`; run `pre-commit run --all-files` before submitting patches if installed.
- Before committing, run `flake8` and fix every issue it reports. Keep fixes mechanical (rename, reformat, remove unused imports, add missing newlines); do not alter program logic while cleaning up—if a lint fix would change behavior, surface it instead of applying it silently.
- Pre-commit (`.pre-commit-config.yaml`) enforces trailing whitespace cleanup, final newlines, TOML/YAML validity, and `ruff` (lint + import sorting); run `pre-commit run --all-files` before submitting patches if installed.
- Before committing, run `uv run ruff check --fix` and fix every issue it reports. Keep fixes mechanical (rename, reformat, remove unused imports, add missing newlines); do not alter program logic while cleaning up—if a lint fix would change behavior, surface it instead of applying it silently.
- Match existing docstring and comment style—concise English comments using imperative phrasing only where necessary.
- Configuration files in `pr_agent/settings/` are TOML; preserve formatting, section order, and comments when editing prompts or defaults.
- Markdown in `docs/` uses MkDocs conventions (YAML front matter absent; rely on heading hierarchy already in place).
Expand Down
3 changes: 1 addition & 2 deletions pr_agent/algo/ai_handlers/langchain_ai_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
except: # we don't enforce langchain as a dependency, so if it's not installed, just move on
pass

import functools

import openai
from tenacity import retry, retry_if_exception_type, retry_if_not_exception_type, stop_after_attempt
from langchain_core.runnables import Runnable
from tenacity import retry, retry_if_exception_type, retry_if_not_exception_type, stop_after_attempt

from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
from pr_agent.config_loader import get_settings
Expand Down
26 changes: 15 additions & 11 deletions pr_agent/algo/ai_handlers/litellm_ai_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@
import openai
import requests
from litellm import acompletion
from tenacity import (retry, retry_if_exception_type,
retry_if_not_exception_type, stop_after_attempt)

from pr_agent.algo import (CLAUDE_EXTENDED_THINKING_MODELS,
NO_SUPPORT_TEMPERATURE_MODELS,
STREAMING_REQUIRED_MODELS,
SUPPORT_REASONING_EFFORT_MODELS,
USER_MESSAGE_ONLY_MODELS)
from tenacity import retry, retry_if_exception_type, retry_if_not_exception_type, stop_after_attempt

from pr_agent.algo import (
CLAUDE_EXTENDED_THINKING_MODELS,
NO_SUPPORT_TEMPERATURE_MODELS,
STREAMING_REQUIRED_MODELS,
SUPPORT_REASONING_EFFORT_MODELS,
USER_MESSAGE_ONLY_MODELS,
)
from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
from pr_agent.algo.ai_handlers.litellm_helpers import (
MockResponse, _get_azure_ad_token, _handle_streaming_response,
_process_litellm_extra_body)
MockResponse,
_get_azure_ad_token,
_handle_streaming_response,
_process_litellm_extra_body,
)
from pr_agent.algo.utils import ReasoningEffort, get_version
from pr_agent.config_loader import get_settings
from pr_agent.log import get_logger
Expand Down Expand Up @@ -456,7 +460,7 @@ async def chat_completion(self, model: str, system: str, user: str, temperature:
# check if the image link is alive
r = requests.head(img_path, allow_redirects=True)
if r.status_code == 404:
error_msg = f"The image link is not [alive](img_path).\nPlease repost the original image as a comment, and send the question again with 'quote reply' (see [instructions](https://pr-agent-docs.codium.ai/tools/ask/#ask-on-images-using-the-pr-code-as-context))."
error_msg = "The image link is not [alive](img_path).\nPlease repost the original image as a comment, and send the question again with 'quote reply' (see [instructions](https://pr-agent-docs.codium.ai/tools/ask/#ask-on-images-using-the-pr-code-as-context))."
get_logger().error(error_msg)
return f"{error_msg}", "error"
except Exception as e:
Expand Down
2 changes: 1 addition & 1 deletion pr_agent/algo/ai_handlers/openai_ai_handler.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from os import environ
from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler

import openai
from openai import AsyncOpenAI
from tenacity import retry, retry_if_exception_type, retry_if_not_exception_type, stop_after_attempt
Expand Down
4 changes: 2 additions & 2 deletions pr_agent/algo/cli_args.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from base64 import b64decode, encode, b64encode
import hashlib
from base64 import b64decode


class CliArgs:
@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion pr_agent/algo/git_patch_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import re
import traceback

from pr_agent.algo.types import EDIT_TYPE, FilePatchInfo
from pr_agent.algo.types import EDIT_TYPE
from pr_agent.config_loader import get_settings
from pr_agent.log import get_logger

Expand Down
13 changes: 7 additions & 6 deletions pr_agent/algo/pr_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

from github import RateLimitExceededException

from pr_agent.algo.file_filter import filter_ignored
from pr_agent.algo.git_patch_processing import (
extend_patch, handle_patch_deletions,
decouple_and_convert_to_hunks_with_lines_numbers)
decouple_and_convert_to_hunks_with_lines_numbers,
extend_patch,
handle_patch_deletions,
)
from pr_agent.algo.language_handler import sort_files_by_main_languages
from pr_agent.algo.token_handler import TokenHandler
from pr_agent.algo.types import EDIT_TYPE, FilePatchInfo
from pr_agent.algo.types import EDIT_TYPE
from pr_agent.algo.utils import ModelType, clip_tokens, get_max_tokens, get_model
from pr_agent.config_loader import get_settings
from pr_agent.git_providers.git_provider import GitProvider
Expand Down Expand Up @@ -506,7 +507,7 @@ def add_ai_metadata_to_diff_files(git_provider, pr_description_files):
"""
try:
if not pr_description_files:
get_logger().warning(f"PR description files are empty.")
get_logger().warning("PR description files are empty.")
return
available_files = {pr_file['full_file_name'].strip(): pr_file for pr_file in pr_description_files}
diff_files = git_provider.get_diff_files()
Expand All @@ -517,7 +518,7 @@ def add_ai_metadata_to_diff_files(git_provider, pr_description_files):
file.ai_file_summary = available_files[filename]
found_any_match = True
if not found_any_match:
get_logger().error(f"Failed to find any matching files between PR description and diff files.",
get_logger().error("Failed to find any matching files between PR description and diff files.",
artifact={"pr_description_files": pr_description_files})
except Exception as e:
get_logger().error(f"Failed to add AI metadata to diff files: {e}",
Expand Down
5 changes: 3 additions & 2 deletions pr_agent/algo/token_handler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from threading import Lock
from math import ceil
import re
from math import ceil
from threading import Lock

from jinja2 import Environment, StrictUndefined
from tiktoken import encoding_for_model, get_encoding
Expand Down Expand Up @@ -99,6 +99,7 @@ def _get_system_user_tokens(self, pr, encoder, vars: dict, system, user):
def _calc_claude_tokens(self, patch: str) -> int:
try:
import anthropic

from pr_agent.algo import MAX_TOKENS

client = anthropic.Anthropic(api_key=get_settings(use_context=False).get('anthropic.key'))
Expand Down
Loading