mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-02 03:40:38 +08:00
Merge pull request #6 from Codium-ai/feature/github_tag_improve
Improve handling of user interaction on the Github App and the polling bot
This commit is contained in:
@ -10,11 +10,16 @@ class PRAgent:
|
||||
self.installation_id = installation_id
|
||||
|
||||
async def handle_request(self, pr_url, request):
|
||||
if 'please review' in request.lower():
|
||||
if 'please review' in request.lower() or 'review' == request.lower().strip() or len(request) == 0:
|
||||
reviewer = PRReviewer(pr_url, self.installation_id)
|
||||
await reviewer.review()
|
||||
|
||||
elif 'please answer' in request.lower():
|
||||
question = re.split(r'(?i)please answer', request)[1].strip()
|
||||
else:
|
||||
if "please answer" in request.lower():
|
||||
question = re.split(r'(?i)please answer', request)[1].strip()
|
||||
elif request.lower().strip().startswith("answer"):
|
||||
question = re.split(r'(?i)answer', request)[1].strip()
|
||||
else:
|
||||
question = request
|
||||
answerer = PRQuestions(pr_url, question, self.installation_id)
|
||||
await answerer.answer()
|
||||
|
@ -24,6 +24,7 @@ class GithubProvider:
|
||||
self.repo = None
|
||||
self.pr_num = None
|
||||
self.pr = None
|
||||
self.github_user_id = None
|
||||
if pr_url:
|
||||
self.set_pr(pr_url)
|
||||
|
||||
@ -42,6 +43,8 @@ class GithubProvider:
|
||||
|
||||
def publish_comment(self, pr_comment: str, is_temporary: bool = False):
|
||||
response = self.pr.create_issue_comment(pr_comment)
|
||||
if hasattr(response, "user") and hasattr(response.user, "login"):
|
||||
self.github_user_id = response.user.login
|
||||
response.is_temporary = is_temporary
|
||||
if not hasattr(self.pr, 'comments_list'):
|
||||
self.pr.comments_list = []
|
||||
@ -109,6 +112,14 @@ class GithubProvider:
|
||||
def get_pr_branch(self):
|
||||
return self.pr.head.ref
|
||||
|
||||
def get_user_id(self):
|
||||
if not self.github_user_id:
|
||||
try:
|
||||
self.github_user_id = self.github_client.get_user().login
|
||||
except Exception as e:
|
||||
logging.exception(f"Failed to get user id, error: {e}")
|
||||
return self.github_user_id
|
||||
|
||||
def get_notifications(self, since: datetime):
|
||||
deployment_type = settings.get("GITHUB.DEPLOYMENT_TYPE", "user")
|
||||
|
||||
|
@ -40,7 +40,7 @@ async def handle_request(body):
|
||||
if "comment" not in body:
|
||||
return {}
|
||||
comment_body = body.get("comment", {}).get("body", None)
|
||||
if "says 'Please" in comment_body:
|
||||
if 'sender' in body and 'login' in body['sender'] and 'bot' in body['sender']['login']:
|
||||
return {}
|
||||
if "issue" not in body and "pull_request" not in body["issue"]:
|
||||
return {}
|
||||
|
@ -7,6 +7,7 @@ import aiohttp
|
||||
|
||||
from pr_agent.agent.pr_agent import PRAgent
|
||||
from pr_agent.config_loader import settings
|
||||
from pr_agent.git_providers import get_git_provider
|
||||
|
||||
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
|
||||
NOTIFICATION_URL = "https://api.github.com/notifications"
|
||||
@ -21,6 +22,8 @@ def now() -> str:
|
||||
async def polling_loop():
|
||||
since = [now()]
|
||||
last_modified = [None]
|
||||
git_provider = get_git_provider()()
|
||||
user_id = git_provider.get_user_id()
|
||||
try:
|
||||
deployment_type = settings.github.deployment_type
|
||||
token = settings.github.user_token
|
||||
@ -58,12 +61,18 @@ async def polling_loop():
|
||||
async with session.get(latest_comment, headers=headers) as comment_response:
|
||||
if comment_response.status == 200:
|
||||
comment = await comment_response.json()
|
||||
if 'user' in comment and 'login' in comment['user']:
|
||||
if comment['user']['login'] == user_id:
|
||||
continue
|
||||
comment_body = comment['body'] if 'body' in comment else ''
|
||||
commenter_github_user = comment['user']['login'] if 'user' in comment else ''
|
||||
logging.info(f"Commenter: {commenter_github_user}\nComment: {comment_body}")
|
||||
if comment_body.strip().startswith("@"):
|
||||
agent = PRAgent()
|
||||
await agent.handle_request(pr_url, comment_body)
|
||||
user_tag = "@" + user_id
|
||||
if user_tag not in comment_body:
|
||||
continue
|
||||
rest_of_comment = comment_body.split(user_tag)[1].strip()
|
||||
agent = PRAgent()
|
||||
await agent.handle_request(pr_url, rest_of_comment)
|
||||
elif response.status != 304:
|
||||
print(f"Failed to fetch notifications. Status code: {response.status}")
|
||||
|
||||
|
@ -90,9 +90,18 @@ class PRReviewer:
|
||||
data['PR Analysis']['Security concerns'] = val
|
||||
|
||||
markdown_text = convert_to_markdown(data)
|
||||
markdown_text += "\n## How to use\n\n"
|
||||
markdown_text += "```\nMention '@pr-agent' in a pr comment to get another review.\n"
|
||||
markdown_text += "Mention '@pr-agent <QUESTION>' in a pr comment to ask a question about this PR.\n```\n"
|
||||
user = self.git_provider.get_user_id()
|
||||
markdown_text += "\n### How to use\n"
|
||||
if user and '[bot]' not in user:
|
||||
markdown_text += f"> Tag me in a comment '@{user}' to ask for a new review after you update the PR.\n"
|
||||
markdown_text += "> You can also tag me and ask any question, " \
|
||||
f"for example '@{user} is the PR ready for merge?'"
|
||||
else:
|
||||
markdown_text += "> Add a comment that says 'review' to ask for a new review " \
|
||||
"after you update the PR.\n"
|
||||
markdown_text += "> You can also add a comment that says 'answer QUESTION', " \
|
||||
"for example 'answer is the PR ready for merge?'"
|
||||
|
||||
if settings.config.verbosity_level >= 2:
|
||||
logging.info(f"Markdown response:\n{markdown_text}")
|
||||
return markdown_text
|
||||
|
Reference in New Issue
Block a user