mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-04 04:40:38 +08:00
Refactor AI handler classes
This commit is contained in:
@ -7,11 +7,11 @@ from openai.error import APIError, RateLimitError, Timeout, TryAgain
|
|||||||
from retry import retry
|
from retry import retry
|
||||||
from pr_agent.config_loader import get_settings
|
from pr_agent.config_loader import get_settings
|
||||||
from pr_agent.log import get_logger
|
from pr_agent.log import get_logger
|
||||||
|
from pr_agent.algo.base_ai_handler import BaseAiHandler
|
||||||
OPENAI_RETRIES = 5
|
OPENAI_RETRIES = 5
|
||||||
|
|
||||||
|
|
||||||
class AiHandler:
|
class AiHandler(BaseAiHandler):
|
||||||
"""
|
"""
|
||||||
This class handles interactions with the OpenAI API for chat completions.
|
This class handles interactions with the OpenAI API for chat completions.
|
||||||
It initializes the API key and other settings from a configuration file,
|
It initializes the API key and other settings from a configuration file,
|
||||||
|
48
pr_agent/algo/base_ai_handler.py
Normal file
48
pr_agent/algo/base_ai_handler.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
class BaseAiHandler(ABC):
|
||||||
|
"""
|
||||||
|
This class defines the interface for an AI handler.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def deployment_id(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
async def chat_completion(self, model: str, system: str, user: str, temperature: float = 0.2):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AiHandler(BaseAiHandler):
|
||||||
|
"""
|
||||||
|
This class handles interactions with the OpenAI API for chat completions.
|
||||||
|
It initializes the API key and other settings from a configuration file,
|
||||||
|
and provides a method for performing chat completions using the OpenAI ChatCompletion API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ... rest of your code ...
|
||||||
|
|
||||||
|
|
||||||
|
class CustomAiHandler(BaseAiHandler):
|
||||||
|
"""
|
||||||
|
This class is your custom AI handler that uses a different LLM library.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
# Initialize your custom AI handler
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def deployment_id(self):
|
||||||
|
# Return the deployment ID for your custom AI handler
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def chat_completion(self, model: str, system: str, user: str, temperature: float = 0.2):
|
||||||
|
# Implement the chat completion method for your custom AI handler
|
||||||
|
pass
|
@ -4,7 +4,7 @@ from typing import Dict
|
|||||||
|
|
||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import Environment, StrictUndefined
|
||||||
|
|
||||||
from pr_agent.algo.ai_handler import AiHandler
|
from pr_agent.algo.ai_handler import BaseAiHandler, AiHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.algo.utils import load_yaml
|
from pr_agent.algo.utils import load_yaml
|
||||||
@ -15,14 +15,14 @@ from pr_agent.log import get_logger
|
|||||||
|
|
||||||
|
|
||||||
class PRAddDocs:
|
class PRAddDocs:
|
||||||
def __init__(self, pr_url: str, cli_mode=False, args: list = None):
|
def __init__(self, pr_url: str, cli_mode=False, args: list = None, ai_handler: BaseAiHandler = AiHandler()):
|
||||||
|
|
||||||
self.git_provider = get_git_provider()(pr_url)
|
self.git_provider = get_git_provider()(pr_url)
|
||||||
self.main_language = get_main_pr_language(
|
self.main_language = get_main_pr_language(
|
||||||
self.git_provider.get_languages(), self.git_provider.get_files()
|
self.git_provider.get_languages(), self.git_provider.get_files()
|
||||||
)
|
)
|
||||||
|
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = ai_handler
|
||||||
self.patches_diff = None
|
self.patches_diff = None
|
||||||
self.prediction = None
|
self.prediction = None
|
||||||
self.cli_mode = cli_mode
|
self.cli_mode = cli_mode
|
||||||
|
@ -4,7 +4,7 @@ from typing import Dict, List
|
|||||||
|
|
||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import Environment, StrictUndefined
|
||||||
|
|
||||||
from pr_agent.algo.ai_handler import AiHandler
|
from pr_agent.algo.ai_handler import BaseAiHandler, AiHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, get_pr_multi_diffs, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, get_pr_multi_diffs, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.algo.utils import load_yaml
|
from pr_agent.algo.utils import load_yaml
|
||||||
@ -15,7 +15,7 @@ from pr_agent.log import get_logger
|
|||||||
|
|
||||||
|
|
||||||
class PRCodeSuggestions:
|
class PRCodeSuggestions:
|
||||||
def __init__(self, pr_url: str, cli_mode=False, args: list = None):
|
def __init__(self, pr_url: str, cli_mode=False, args: list = None, ai_handler: BaseAiHandler = AiHandler() ):
|
||||||
|
|
||||||
self.git_provider = get_git_provider()(pr_url)
|
self.git_provider = get_git_provider()(pr_url)
|
||||||
self.main_language = get_main_pr_language(
|
self.main_language = get_main_pr_language(
|
||||||
@ -32,7 +32,7 @@ class PRCodeSuggestions:
|
|||||||
else:
|
else:
|
||||||
num_code_suggestions = get_settings().pr_code_suggestions.num_code_suggestions
|
num_code_suggestions = get_settings().pr_code_suggestions.num_code_suggestions
|
||||||
|
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = ai_handler
|
||||||
self.patches_diff = None
|
self.patches_diff = None
|
||||||
self.prediction = None
|
self.prediction = None
|
||||||
self.cli_mode = cli_mode
|
self.cli_mode = cli_mode
|
||||||
|
@ -4,7 +4,7 @@ from typing import List, Tuple
|
|||||||
|
|
||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import Environment, StrictUndefined
|
||||||
|
|
||||||
from pr_agent.algo.ai_handler import AiHandler
|
from pr_agent.algo.ai_handler import BaseAiHandler, AiHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.algo.utils import load_yaml
|
from pr_agent.algo.utils import load_yaml
|
||||||
@ -15,7 +15,7 @@ from pr_agent.log import get_logger
|
|||||||
|
|
||||||
|
|
||||||
class PRDescription:
|
class PRDescription:
|
||||||
def __init__(self, pr_url: str, args: list = None):
|
def __init__(self, pr_url: str, args: list = None, ai_handler: BaseAiHandler = AiHandler()):
|
||||||
"""
|
"""
|
||||||
Initialize the PRDescription object with the necessary attributes and objects for generating a PR description
|
Initialize the PRDescription object with the necessary attributes and objects for generating a PR description
|
||||||
using an AI model.
|
using an AI model.
|
||||||
@ -31,7 +31,7 @@ class PRDescription:
|
|||||||
self.pr_id = self.git_provider.get_pr_id()
|
self.pr_id = self.git_provider.get_pr_id()
|
||||||
|
|
||||||
# Initialize the AI handler
|
# Initialize the AI handler
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = ai_handler
|
||||||
|
|
||||||
# Initialize the variables dictionary
|
# Initialize the variables dictionary
|
||||||
self.vars = {
|
self.vars = {
|
||||||
|
@ -2,7 +2,7 @@ import copy
|
|||||||
|
|
||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import Environment, StrictUndefined
|
||||||
|
|
||||||
from pr_agent.algo.ai_handler import AiHandler
|
from pr_agent.algo.ai_handler import BaseAiHandler, AiHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.config_loader import get_settings
|
from pr_agent.config_loader import get_settings
|
||||||
@ -12,12 +12,12 @@ from pr_agent.log import get_logger
|
|||||||
|
|
||||||
|
|
||||||
class PRInformationFromUser:
|
class PRInformationFromUser:
|
||||||
def __init__(self, pr_url: str, args: list = None):
|
def __init__(self, pr_url: str, args: list = None, ai_handler: BaseAiHandler = AiHandler()):
|
||||||
self.git_provider = get_git_provider()(pr_url)
|
self.git_provider = get_git_provider()(pr_url)
|
||||||
self.main_pr_language = get_main_pr_language(
|
self.main_pr_language = get_main_pr_language(
|
||||||
self.git_provider.get_languages(), self.git_provider.get_files()
|
self.git_provider.get_languages(), self.git_provider.get_files()
|
||||||
)
|
)
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = ai_handler
|
||||||
self.vars = {
|
self.vars = {
|
||||||
"title": self.git_provider.pr.title,
|
"title": self.git_provider.pr.title,
|
||||||
"branch": self.git_provider.get_pr_branch(),
|
"branch": self.git_provider.get_pr_branch(),
|
||||||
|
@ -2,7 +2,7 @@ import copy
|
|||||||
|
|
||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import Environment, StrictUndefined
|
||||||
|
|
||||||
from pr_agent.algo.ai_handler import AiHandler
|
from pr_agent.algo.ai_handler import BaseAiHandler, AiHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.config_loader import get_settings
|
from pr_agent.config_loader import get_settings
|
||||||
@ -12,13 +12,13 @@ from pr_agent.log import get_logger
|
|||||||
|
|
||||||
|
|
||||||
class PRQuestions:
|
class PRQuestions:
|
||||||
def __init__(self, pr_url: str, args=None):
|
def __init__(self, pr_url: str, args=None, ai_handler: BaseAiHandler = AiHandler()):
|
||||||
question_str = self.parse_args(args)
|
question_str = self.parse_args(args)
|
||||||
self.git_provider = get_git_provider()(pr_url)
|
self.git_provider = get_git_provider()(pr_url)
|
||||||
self.main_pr_language = get_main_pr_language(
|
self.main_pr_language = get_main_pr_language(
|
||||||
self.git_provider.get_languages(), self.git_provider.get_files()
|
self.git_provider.get_languages(), self.git_provider.get_files()
|
||||||
)
|
)
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = ai_handler
|
||||||
self.question_str = question_str
|
self.question_str = question_str
|
||||||
self.vars = {
|
self.vars = {
|
||||||
"title": self.git_provider.pr.title,
|
"title": self.git_provider.pr.title,
|
||||||
|
@ -6,7 +6,7 @@ import yaml
|
|||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import Environment, StrictUndefined
|
||||||
from yaml import SafeLoader
|
from yaml import SafeLoader
|
||||||
|
|
||||||
from pr_agent.algo.ai_handler import AiHandler
|
from pr_agent.algo.ai_handler import BaseAiHandler, AiHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.algo.utils import convert_to_markdown, load_yaml, try_fix_yaml
|
from pr_agent.algo.utils import convert_to_markdown, load_yaml, try_fix_yaml
|
||||||
@ -21,7 +21,7 @@ class PRReviewer:
|
|||||||
"""
|
"""
|
||||||
The PRReviewer class is responsible for reviewing a pull request and generating feedback using an AI model.
|
The PRReviewer class is responsible for reviewing a pull request and generating feedback using an AI model.
|
||||||
"""
|
"""
|
||||||
def __init__(self, pr_url: str, is_answer: bool = False, is_auto: bool = False, args: list = None):
|
def __init__(self, pr_url: str, is_answer: bool = False, is_auto: bool = False, args: list = None, ai_handler: BaseAiHandler = AiHandler()):
|
||||||
"""
|
"""
|
||||||
Initialize the PRReviewer object with the necessary attributes and objects to review a pull request.
|
Initialize the PRReviewer object with the necessary attributes and objects to review a pull request.
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class PRReviewer:
|
|||||||
|
|
||||||
if self.is_answer and not self.git_provider.is_supported("get_issue_comments"):
|
if self.is_answer and not self.git_provider.is_supported("get_issue_comments"):
|
||||||
raise Exception(f"Answer mode is not supported for {get_settings().config.git_provider} for now")
|
raise Exception(f"Answer mode is not supported for {get_settings().config.git_provider} for now")
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = ai_handler
|
||||||
self.patches_diff = None
|
self.patches_diff = None
|
||||||
self.prediction = None
|
self.prediction = None
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from typing import Tuple
|
|||||||
|
|
||||||
from jinja2 import Environment, StrictUndefined
|
from jinja2 import Environment, StrictUndefined
|
||||||
|
|
||||||
from pr_agent.algo.ai_handler import AiHandler
|
from pr_agent.algo.ai_handler import BaseAiHandler, AiHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.config_loader import get_settings
|
from pr_agent.config_loader import get_settings
|
||||||
@ -17,7 +17,7 @@ CHANGELOG_LINES = 50
|
|||||||
|
|
||||||
|
|
||||||
class PRUpdateChangelog:
|
class PRUpdateChangelog:
|
||||||
def __init__(self, pr_url: str, cli_mode=False, args=None):
|
def __init__(self, pr_url: str, cli_mode=False, args=None, ai_handler: BaseAiHandler = AiHandler()):
|
||||||
|
|
||||||
self.git_provider = get_git_provider()(pr_url)
|
self.git_provider = get_git_provider()(pr_url)
|
||||||
self.main_language = get_main_pr_language(
|
self.main_language = get_main_pr_language(
|
||||||
@ -25,7 +25,7 @@ class PRUpdateChangelog:
|
|||||||
)
|
)
|
||||||
self.commit_changelog = get_settings().pr_update_changelog.push_changelog_changes
|
self.commit_changelog = get_settings().pr_update_changelog.push_changelog_changes
|
||||||
self._get_changlog_file() # self.changelog_file_str
|
self._get_changlog_file() # self.changelog_file_str
|
||||||
self.ai_handler = AiHandler()
|
self.ai_handler = ai_handler
|
||||||
self.patches_diff = None
|
self.patches_diff = None
|
||||||
self.prediction = None
|
self.prediction = None
|
||||||
self.cli_mode = cli_mode
|
self.cli_mode = cli_mode
|
||||||
|
Reference in New Issue
Block a user