Giter Site home page Giter Site logo

Sweep: In on_comment.py it's possible that the comment is on a closed PR. If this is the case then we should not fire an event. Add logic to src/api.py to address this. about sweep HOT 1 CLOSED

sweepai avatar sweepai commented on May 21, 2024 2
Sweep: In on_comment.py it's possible that the comment is on a closed PR. If this is the case then we should not fire an event. Add logic to src/api.py to address this.

from sweep.

Comments (1)

sweep-nightly avatar sweep-nightly commented on May 21, 2024

Hey @wwzeng1,

I've started working on the issue you've raised. Here's a quick summary of the plan:

  1. I'll add a check in the on_comment.py handler to see if the PR associated with the comment is closed. If it is, we won't fire an event.
  2. I'll then modify the webhook function in src/api.py to handle this new logic.

This should prevent unnecessary processing for comments on closed PRs.

Give me a minute!

-Sweep bot

Some code snippets I looked at (click to expand). If some file is missing from here, you can mention the path in the ticket description.

return {"success": False, "reason": "Issue is closed"}
item_to_react_to = current_issue.get_comment(comment_id) if comment_id else current_issue
eyes_reaction = item_to_react_to.create_reaction("eyes")
def comment_reply(message: str):
current_issue.create_comment(message + "\n\n---\n" + bot_suffix)
comments = current_issue.get_comments()
replies_text = ""
if comment_id:
replies_text = "\nComments:\n" + "\n".join(
[
issue_comment_prompt.format(
username=comment.user.login,
reply=comment.body,
) for comment in comments
]
)
def fetch_file_contents_with_retry():
retries = 3
error = None
for i in range(retries):
try:
logger.info(f"Fetching relevant files for the {i}th time...")
return search_snippets(
repo,
f"{title}\n{summary}\n{replies_text}",
num_files=num_of_snippets_to_query,
branch=None,
installation_id=installation_id,
)
except Exception as e:
error = e
continue
posthog.capture(
username, "fetching_failed", properties={"error": error, **metadata}
)
raise error
# update_index.call(
# repo_full_name,
# installation_id=installation_id,
# )
logger.info("Fetching relevant files...")

return {"success": False, "reason": "Issue is closed"}
item_to_react_to = current_issue.get_comment(comment_id) if comment_id else current_issue
eyes_reaction = item_to_react_to.create_reaction("eyes")
def comment_reply(message: str):
current_issue.create_comment(message + "\n\n---\n" + bot_suffix)
comments = current_issue.get_comments()
replies_text = ""
if comment_id:
replies_text = "\nComments:\n" + "\n".join(
[
issue_comment_prompt.format(
username=comment.user.login,
reply=comment.body,
) for comment in comments
]
)
def fetch_file_contents_with_retry():
retries = 3
error = None
for i in range(retries):
try:
logger.info(f"Fetching relevant files for the {i}th time...")
return search_snippets(

118: posthog.capture(username, "success", properties={**metadata})
119: logger.info("on_comment success")
120: return {"success": True}
</body>
<modify>
* src/handlers/on_comment.py:
1. Add a new method in on_comment that uses pygithub to send a simple response to the user.
</modify>
Pass in start_line and end_line to the `modify` function.
Make sure `end_line` covers the code you wish to delete and that `new_code` is properly formatted.
Also make sure start_line is in ascending order and that the code_edits do not overlap.
'''
def test_chat_gpt_call():
human_message = HumanMessagePrompt(
repo_name ='',
repo_description='',
issue_url='',
username='',
title='',
tree='',
summary='',
snippets=[],
)
cgpt = ChatGPT.from_system_message_content(human_message=human_message, model="gpt-4"
)
response = cgpt.call_openai(model="gpt-4-32k-0613", functions=[modify_file_function], function_name={"name": "modify_file"})
response = openai.ChatCompletion.create(
model="gpt-4-32k-0613",
messages=[
{
"role": "system",
"content": system_message_prompt
},
{
"role": "user",
"content": first_user_prompt
},
],
functions=modify_file_function,
function_call={"name": "modify_file"}
)
assistant_response = response.choices[0]
arguments = assistant_response["message"]["function_call"]["arguments"]

118: logger.info("on_comment success")
119: return {"success":True}
120:
</old_file>"""

sweep/src/api.py

Lines 1 to 227 in 3fc8817

import time
from loguru import logger
import modal
from pydantic import ValidationError
from src.handlers.create_pr import create_pr # type: ignore
from src.handlers.on_ticket import on_ticket
from src.handlers.on_comment import on_comment
from src.utils.constants import API_NAME, BOT_TOKEN_NAME, LABEL_COLOR, LABEL_DESCRIPTION, LABEL_NAME, SWEEP_LOGIN
from src.events import (
CommentCreatedRequest,
InstallationCreatedRequest,
IssueCommentRequest,
IssueRequest,
PRRequest,
ReposAddedRequest,
)
from src.utils.event_logger import posthog
from src.utils.github_utils import get_github_client, index_full_repository
from fastapi import HTTPException, Request
stub = modal.Stub(API_NAME)
image = (
modal.Image.debian_slim()
.apt_install("git")
.pip_install(
"openai",
"anthropic",
"PyGithub",
"loguru",
"docarray",
"backoff",
"tiktoken",
"highlight-io",
"GitPython",
"posthog",
"tqdm"
)
)
secrets = [
modal.Secret.from_name(BOT_TOKEN_NAME),
modal.Secret.from_name("openai-secret"),
modal.Secret.from_name("anthropic"),
modal.Secret.from_name("posthog"),
modal.Secret.from_name("highlight"),
]
FUNCTION_SETTINGS = {
"image": image,
"secrets": secrets,
"timeout": 15 * 60,
}
handle_ticket = stub.function(**FUNCTION_SETTINGS)(on_ticket)
handle_comment = stub.function(**FUNCTION_SETTINGS)(on_comment)
handle_pr = stub.function(**FUNCTION_SETTINGS)(create_pr)
@stub.function(**FUNCTION_SETTINGS)
@modal.web_endpoint(method="POST")
async def webhook(raw_request: Request):
"""Handle a webhook request from GitHub."""
try:
request_dict = await raw_request.json()
logger.info(f"Received request: {request_dict.keys()}")
event = raw_request.headers.get("X-GitHub-Event")
assert event is not None
match event, request_dict.get("action", None):
case "issues", "opened":
request = IssueRequest(**request_dict)
issue_title_lower = request.issue.title.lower()
if issue_title_lower.startswith("sweep") or "sweep:" in issue_title_lower:
g = get_github_client(request.installation.id)
repo = g.get_repo(request.repository.full_name)
labels = repo.get_labels()
label_names = [label.name for label in labels]
if LABEL_NAME not in label_names:
repo.create_label(
name=LABEL_NAME,
color=LABEL_COLOR,
description=LABEL_DESCRIPTION,
)
# TODO(sweep): figure out why this is breaking
# else:
# label = repo.get_label(LABEL_NAME)
# label.edit(
# name=LABEL_NAME,
# color=LABEL_COLOR,
# description=LABEL_DESCRIPTION
# )
current_issue = repo.get_issue(number=request.issue.number)
current_issue.add_to_labels(LABEL_NAME)
case "issues", "labeled":
request = IssueRequest(**request_dict)
if request.issue is not None and (
"sweep" in [label.name.lower() for label in request.issue.labels]
):
request.issue.body = request.issue.body or ""
request.repository.description = (
request.repository.description or ""
)
# Update before we handle the ticket to make sure index is up to date
# other ways suboptimal
handle_ticket.spawn(
request.issue.title,
request.issue.body,
request.issue.number,
request.issue.html_url,
request.issue.user.login,
request.repository.full_name,
request.repository.description,
request.installation.id,
)
case "issue_comment", "created":
request = IssueCommentRequest(**request_dict)
if request.issue is not None \
and "sweep" in [label.name.lower() for label in request.issue.labels] \
and request.comment.user.type == "User":
request.issue.body = request.issue.body or ""
request.repository.description = (
request.repository.description or ""
)
# Update before we handle the ticket to make sure index is up to date
# other ways suboptimal
handle_ticket.spawn(
request.issue.title,
request.issue.body,
request.issue.number,
request.issue.html_url,
request.issue.user.login,
request.repository.full_name,
request.repository.description,
request.installation.id,
request.comment.id
)
elif request.issue.pull_request and request.issue.user.login == SWEEP_LOGIN and request.comment.user.type == "User": # TODO(sweep): set a limit
logger.info(f"Handling comment on PR: {request.issue.pull_request}")
handle_comment.spawn(
repo_full_name=request.repository.full_name,
repo_description=request.repository.description,
comment=request.comment.body,
pr_path=None,
pr_line_position=None,
username=request.comment.user.login,
installation_id=request.installation.id,
pr_number=request.issue.number,
)
case "pull_request_review_comment", "created":
request = CommentCreatedRequest(**request_dict)
if "sweep/" in request.pull_request.head.ref.lower():
handle_comment.spawn(
repo_full_name=request.repository.full_name,
repo_description=request.repository.description,
comment=request.comment.body,
pr_path=request.comment.path,
pr_line_position=request.comment.original_line,
username=request.comment.user.login,
installation_id=request.installation.id,
pr_number=request.pull_request.number,
)
# Todo: update index on comments
case "pull_request_review", "submitted":
# request = ReviewSubmittedRequest(**request_dict)
pass
case "installation_repositories", "added":
repos_added_request = ReposAddedRequest(**request_dict)
metadata = {
"installation_id": repos_added_request.installation.id,
"repositories": [
repo.full_name
for repo in repos_added_request.repositories_added
],
}
posthog.capture("installation_repositories", "started", properties={
**metadata
})
for repo in repos_added_request.repositories_added:
organization, repo_name = repo.full_name.split("/")
posthog.capture(
organization,
"installed_repository",
properties={
"repo_name": repo_name,
"organization": organization,
"repo_full_name": repo.full_name
}
)
index_full_repository(
repo.full_name,
installation_id=repos_added_request.installation.id,
)
case "installation", "created":
repos_added_request = InstallationCreatedRequest(**request_dict)
for repo in repos_added_request.repositories:
index_full_repository(
repo.full_name,
installation_id=repos_added_request.installation.id,
)
case ("pull_request", "closed"):
pr_request = PRRequest(**request_dict)
organization, repo_name = pr_request.repository.full_name.split("/")
commit_author = pr_request.pull_request.user.login
merged_by = pr_request.pull_request.merged_by.login
if SWEEP_LOGIN == commit_author:
posthog.capture(
merged_by,
"merged_sweep_pr",
properties={
"repo_name": repo_name,
"organization": organization,
"repo_full_name": pr_request.repository.full_name,
"username": merged_by
})
case "ping", None:
return {"message": "pong"}
case _:
logger.info(
f"Unhandled event: {event} {request_dict.get('action', None)}"
)
except ValidationError as e:
logger.warning(f"Failed to parse request: {e}")
raise HTTPException(status_code=422, detail="Failed to parse request")
return {"success": True}


I'm a bot that handles simple bugs and feature requests but I might make mistakes. Please be kind!

from sweep.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.