Skip to content

Commit a53f71b

Browse files
authored
chore: pr review commenting tooling (#449)
# Motivation <!-- Why is this change necessary? --> # Content <!-- Please include a summary of the change --> # Testing <!-- How was the change tested? --> # Please check the following before marking your PR as ready for review - [ ] I have added tests for my changes - [ ] I have updated the documentation or added new documentation as needed --------- Co-authored-by: kopekC <[email protected]>
1 parent d48a8e9 commit a53f71b

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

src/codegen/extensions/langchain/tools.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,100 @@ def _run(self, title: str, body: str) -> str:
359359
return pr.html_url
360360

361361

362+
class GetPRContentsInput(BaseModel):
363+
"""Input for getting PR contents."""
364+
365+
pr_id: int = Field(..., description="Number of the PR to get the contents for")
366+
367+
368+
class GetPRcontentsTool(BaseTool):
369+
"""Tool for getting PR data."""
370+
371+
name: ClassVar[str] = "get_pr_contents"
372+
description: ClassVar[str] = "Get the diff and modified symbols of a PR along with the dependencies of the modified symbols"
373+
args_schema: ClassVar[type[BaseModel]] = GetPRContentsInput
374+
codebase: Codebase = Field(exclude=True)
375+
376+
def __init__(self, codebase: Codebase) -> None:
377+
super().__init__(codebase=codebase)
378+
379+
def _run(self, pr_id: int) -> str:
380+
modified_symbols, patch = self.codebase.get_modified_symbols_in_pr(pr_id)
381+
382+
# Convert modified_symbols set to list for JSON serialization
383+
result = {"modified_symbols": list(modified_symbols), "patch": patch}
384+
385+
return json.dumps(result, indent=2)
386+
387+
388+
class CreatePRCommentInput(BaseModel):
389+
"""Input for creating a PR comment"""
390+
391+
pr_number: int = Field(..., description="The PR number to comment on")
392+
body: str = Field(..., description="The comment text")
393+
394+
395+
class CreatePRCommentTool(BaseTool):
396+
"""Tool for creating a general PR comment."""
397+
398+
name: ClassVar[str] = "create_pr_comment"
399+
description: ClassVar[str] = "Create a general comment on a pull request"
400+
args_schema: ClassVar[type[BaseModel]] = CreatePRCommentInput
401+
codebase: Codebase = Field(exclude=True)
402+
403+
def __init__(self, codebase: Codebase) -> None:
404+
super().__init__(codebase=codebase)
405+
406+
def _run(self, pr_number: int, body: str) -> str:
407+
self.codebase.create_pr_comment(pr_number=pr_number, body=body)
408+
return "Comment created successfully"
409+
410+
411+
class CreatePRReviewCommentInput(BaseModel):
412+
"""Input for creating an inline PR review comment"""
413+
414+
pr_number: int = Field(..., description="The PR number to comment on")
415+
body: str = Field(..., description="The comment text")
416+
commit_sha: str = Field(..., description="The commit SHA to attach the comment to")
417+
path: str = Field(..., description="The file path to comment on")
418+
line: int | None = Field(None, description="The line number to comment on")
419+
side: str | None = Field(None, description="Which version of the file to comment on ('LEFT' or 'RIGHT')")
420+
start_line: int | None = Field(None, description="For multi-line comments, the starting line")
421+
422+
423+
class CreatePRReviewCommentTool(BaseTool):
424+
"""Tool for creating inline PR review comments."""
425+
426+
name: ClassVar[str] = "create_pr_review_comment"
427+
description: ClassVar[str] = "Create an inline review comment on a specific line in a pull request"
428+
args_schema: ClassVar[type[BaseModel]] = CreatePRReviewCommentInput
429+
codebase: Codebase = Field(exclude=True)
430+
431+
def __init__(self, codebase: Codebase) -> None:
432+
super().__init__(codebase=codebase)
433+
434+
def _run(
435+
self,
436+
pr_number: int,
437+
body: str,
438+
commit_sha: str,
439+
path: str,
440+
line: int | None = None,
441+
side: str | None = None,
442+
start_line: int | None = None,
443+
) -> str:
444+
self.codebase.create_pr_review_comment(
445+
pr_number=pr_number,
446+
body=body,
447+
commit_sha=commit_sha,
448+
path=path,
449+
line=line,
450+
side=side,
451+
start_line=start_line,
452+
)
453+
return "Review comment created successfully"
454+
455+
362456
def get_workspace_tools(codebase: Codebase) -> list["BaseTool"]:
363457
"""Get all workspace tools initialized with a codebase.
364458
@@ -372,8 +466,11 @@ def get_workspace_tools(codebase: Codebase) -> list["BaseTool"]:
372466
CommitTool(codebase),
373467
CreateFileTool(codebase),
374468
CreatePRTool(codebase),
469+
CreatePRCommentTool(codebase),
470+
CreatePRReviewCommentTool(codebase),
375471
DeleteFileTool(codebase),
376472
EditFileTool(codebase),
473+
GetPRcontentsTool(codebase),
377474
ListDirectoryTool(codebase),
378475
RevealSymbolTool(codebase),
379476
SearchTool(codebase),

src/codegen/git/repo_operator/repo_operator.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,3 +608,49 @@ def stash_pop(self) -> None:
608608
def get_pr_data(self, pr_number: int) -> dict:
609609
"""Returns the data associated with a PR"""
610610
return self.remote_git_repo.get_pr_data(pr_number)
611+
612+
def create_pr_comment(self, pr_number: int, body: str) -> None:
613+
"""Create a general comment on a pull request.
614+
615+
Args:
616+
pr_number (int): The PR number to comment on
617+
body (str): The comment text
618+
"""
619+
pr = self.remote_git_repo.get_pull_safe(pr_number)
620+
if pr:
621+
self.remote_git_repo.create_issue_comment(pr, body)
622+
623+
def create_pr_review_comment(
624+
self,
625+
pr_number: int,
626+
body: str,
627+
commit_sha: str,
628+
path: str,
629+
line: int | None = None,
630+
side: str | None = None,
631+
start_line: int | None = None,
632+
) -> None:
633+
"""Create an inline review comment on a specific line in a pull request.
634+
635+
Args:
636+
pr_number (int): The PR number to comment on
637+
body (str): The comment text
638+
commit_sha (str): The commit SHA to attach the comment to
639+
path (str): The file path to comment on
640+
line (int | None, optional): The line number to comment on. Defaults to None.
641+
side (str | None, optional): Which version of the file to comment on ('LEFT' or 'RIGHT'). Defaults to None.
642+
start_line (int | None, optional): For multi-line comments, the starting line. Defaults to None.
643+
"""
644+
pr = self.remote_git_repo.get_pull_safe(pr_number)
645+
if pr:
646+
commit = self.remote_git_repo.get_commit_safe(commit_sha)
647+
if commit:
648+
self.remote_git_repo.create_review_comment(
649+
pull=pr,
650+
body=body,
651+
commit=commit,
652+
path=path,
653+
line=line,
654+
side=side,
655+
start_line=start_line,
656+
)

0 commit comments

Comments
 (0)