Skip to content
Open
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
6 changes: 2 additions & 4 deletions bugbug/tools/code_review/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@

# Exceptions (backward compatibility)
from bugbug.tools.core.exceptions import (
FileNotInPatchError,
HunkNotInPatchError,
CommentNotLocatedError,
LargeDiffError,
ModelResultError,
)
Expand All @@ -56,8 +55,7 @@
"InlineComment",
"ReviewRequest",
# Exceptions
"FileNotInPatchError",
"HunkNotInPatchError",
"CommentNotLocatedError",
"LargeDiffError",
"ModelResultError",
# Base classes
Expand Down
45 changes: 37 additions & 8 deletions bugbug/tools/code_review/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@
)
from bugbug.tools.code_review.utils import (
convert_generated_comments_to_inline,
find_line_text,
format_patch_set,
)
from bugbug.tools.core.exceptions import (
CommentNotLocatedError,
LargeDiffError,
RecursionLimitError,
)
Expand Down Expand Up @@ -358,12 +360,31 @@ def _get_comment_examples(self, patch, created_before: datetime | None = None):
for example in comment_examples:
example["comment"]["explanation"] = "THE JUSTIFICATION GOES HERE"

def format_comment(comment):
def format_comment(example):
# TODO: change the schema that we expect the model to return so we
# can remove this function.
comment = example["comment"]
filename = comment["filename"]
raw_hunk = example.get("hunk") or example.get("raw_hunk")
existing_code = None
if raw_hunk:
try:
wrapped = TEMPLATE_PATCH_FROM_HUNK.format(
filename=filename, raw_hunk=raw_hunk
)
patched_file = PatchSet.from_string(wrapped)[0]
existing_code = find_line_text(patched_file, comment["start_line"])
except (CommentNotLocatedError, IndexError):
logger.warning(
"Could not recover existing_code for example comment on %s:%s",
filename,
comment["start_line"],
)
if existing_code is None:
return None
return {
"file": comment["filename"],
"code_line": comment["start_line"],
"file": filename,
"existing_code": existing_code,
"comment": comment["content"],
}

Expand All @@ -375,10 +396,14 @@ def generate_formatted_patch_from_raw_hunk(raw_hunk, filename):
return format_patch_set(patch_set)

if not self.show_patch_example:
return json.dumps(
[format_comment(example["comment"]) for example in comment_examples],
indent=2,
)
formatted_comments = [
comment
for comment in (
format_comment(example) for example in comment_examples
)
if comment is not None
]
return json.dumps(formatted_comments, indent=2)

return "\n\n".join(
TEMPLATE_COMMENT_EXAMPLE.format(
Expand All @@ -387,7 +412,11 @@ def generate_formatted_patch_from_raw_hunk(raw_hunk, filename):
example["raw_hunk"], example["comment"]["filename"]
),
comments=json.dumps(
[format_comment(example["comment"])],
[
comment
for comment in [format_comment(example)]
if comment is not None
],
indent=2,
),
)
Expand Down
9 changes: 8 additions & 1 deletion bugbug/tools/code_review/data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ class GeneratedReviewComment(BaseModel):
"""A review comment generated by the code review agent."""

file: str = Field(description="The path to the file the comment applies to.")
code_line: int = Field(description="The line number that the comment refers to.")
existing_code: str = Field(
description=(
"The exact source line(s) the comment is about, copied verbatim "
"from the patch (leading '+'/'-'/' ' markers may be included or "
"omitted). Used to locate the comment in the diff, so do not "
"paraphrase, reformat, or truncate it."
)
)
comment: str = Field(description="The review comment.")
explanation: str = Field(
description="A brief rationale for the comment, including how confident you are and why."
Expand Down
3 changes: 2 additions & 1 deletion bugbug/tools/code_review/prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
- Use directive language: "Fix", "Remove", "Change", "Add"
- NEVER use these banned phrases: "maybe", "might want to", "consider", "possibly", "could be", "you may want to"
- Focus strictly on code-related concerns
- For `existing_code`, copy the exact source line(s) the comment is about verbatim from the patch — do not paraphrase, reformat, or guess a line number instead

## What NOT to Include

Expand Down Expand Up @@ -72,7 +73,7 @@
- A large change that has no natural seam and must land atomically is acceptable — return an empty list rather than suggesting an impractical split.
- If you do comment, name concrete seams: the distinct concerns, or the stages of a large cohesive change (e.g. land the data-model change separately from the call-site updates).
- Briefly tell the author *why*: larger patches get less thorough review and empirically introduce more bugs and regressions, so smaller patches are easier to review and safer to land.
- Anchor the comment to a representative changed line (a line that begins with `+`). Set `file` to that file's path and `code_line` to that line's number.
- Anchor the comment to a representative changed line (a line that begins with `+`). Set `file` to that file's path and `existing_code` to that line's exact text, copied verbatim.
- Use direct, declarative language. NEVER use these banned phrases: "maybe", "might want to", "consider", "possibly", "could be", "you may want to".

Here is a summary of the patch:
Expand Down
Loading