From 3d7bc69ce407c0234f45eb4acd61070ea9502950 Mon Sep 17 00:00:00 2001 From: Gaurav Pooniwala Date: Thu, 9 Jul 2026 16:25:30 +0100 Subject: [PATCH 1/2] Improve bot finding extraction --- online/etl/llm/prompts.py | 35 +++++++--- online/etl/llm/schemas.py | 6 +- online/etl/pipeline/analyze.py | 52 ++++++++++++--- online/etl/tests/test_analyze_formatting.py | 71 +++++++++++++++++++++ 4 files changed, 143 insertions(+), 21 deletions(-) create mode 100644 online/etl/tests/test_analyze_formatting.py diff --git a/online/etl/llm/prompts.py b/online/etl/llm/prompts.py index a503bc1..c5875b5 100644 --- a/online/etl/llm/prompts.py +++ b/online/etl/llm/prompts.py @@ -1,32 +1,47 @@ """Prompt templates for the LLM analysis pipeline.""" -EXTRACT_BOT_SUGGESTIONS = """You are analyzing a pull request to extract all actionable suggestions made by a code review bot. +EXTRACT_BOT_SUGGESTIONS = """You are analyzing a pull request to extract concrete code-review findings flagged by a code review bot. The bot's username is: {bot_username} Below you will see: -1. The commits that were under review (the code state the bot saw), including full diffs -2. The bot's review comments on those commits +1. The bot's review comments on the commits +2. The commits that were under review (the code state the bot saw), including full diffs -For each actionable suggestion the bot made, extract: +The Bot Review Comments section is a numbered list. Each entry is labeled as REVIEW_BODY, +INLINE_REVIEW_COMMENT, or ISSUE_COMMENT. Process all numbered comments. Top-level inline +review comments generally contain substantive findings; review bodies and issue comments may +contain findings or summaries. + +Your job is to identify every distinct substantive finding the bot flagged. A finding can be a +bug, defect, risk, incorrect behavior, missing validation, security concern, performance concern, +maintainability issue, documentation problem, test gap, or other concrete code-review concern. + +Only extract findings grounded in the bot's comments. Do not invent findings solely from the +commit diff. Use the commit diff only to understand code context for a comment. + +For each finding, extract: - A unique ID (S1, S2, ...) -- A description of what was suggested +- A concise description of the issue or concern the bot flagged - The category (bug, style, performance, security, refactor, documentation, other) - The file path and line number if available - Severity (low, medium, high, critical) -Only include ACTIONABLE suggestions — skip generic praise, summaries, or "looks good" comments. -Skip bot comments that are purely informational without suggesting any change. +Skip generic praise, status/progress messages, quota/limit messages, pure summaries without a +concrete finding, and "looks good" / "no issues found" comments. Also skip follow-up comments +that merely confirm a fix, acknowledge a clarification, say a parent comment was wrong, too +broad, pre-existing, already addressed, or out of scope, unless that same comment introduces a +new distinct code issue. PR Title: {pr_title} PR Author: {pr_author} Repository: {repo_name} -=== Commits Under Review (code the bot reviewed) === -{commits_under_review} - === Bot Review Comments === {bot_comments} + +=== Commits Under Review (code the bot reviewed) === +{commits_under_review} """ EXTRACT_HUMAN_ACTIONS = """You are analyzing post-review commit diffs to extract every concrete code issue that was fixed or improved AFTER the bot reviewed the PR. diff --git a/online/etl/llm/schemas.py b/online/etl/llm/schemas.py index 543307c..dd65c1e 100644 --- a/online/etl/llm/schemas.py +++ b/online/etl/llm/schemas.py @@ -7,8 +7,8 @@ class BotSuggestion(BaseModel): - issue_id: str = Field(description="Unique identifier for this suggestion (e.g. 'S1', 'S2')") - description: str = Field(description="What the bot suggested or flagged") + issue_id: str = Field(description="Unique identifier for this finding (e.g. 'S1', 'S2')") + description: str = Field(description="The issue or concern the bot flagged") category: str = Field( description="Category: 'bug', 'style', 'performance', 'security', 'refactor', 'documentation', 'other'" ) @@ -18,7 +18,7 @@ class BotSuggestion(BaseModel): class BotSuggestionsResponse(BaseModel): - suggestions: list[BotSuggestion] = Field(description="All actionable suggestions made by the bot") + suggestions: list[BotSuggestion] = Field(description="All concrete code-review findings flagged by the bot") class HumanAction(BaseModel): diff --git a/online/etl/pipeline/analyze.py b/online/etl/pipeline/analyze.py index 953a6aa..fe0b72e 100644 --- a/online/etl/pipeline/analyze.py +++ b/online/etl/pipeline/analyze.py @@ -5,6 +5,7 @@ import asyncio import json import logging +import re from openai import BadRequestError @@ -22,6 +23,16 @@ logger = logging.getLogger(__name__) +_HTML_COMMENT_RE = re.compile(r"", re.DOTALL) +_DETAILS_RE = re.compile(r"]*>.*?", re.DOTALL | re.IGNORECASE) +_SUB_RE = re.compile(r"]*>.*?", re.DOTALL | re.IGNORECASE) +_PROMO_FOOTER_HINTS = ( + "if you found this review helpful", + "coderabbit", + "review details", + "configured", +) + def _find_bot_review_commit( reviews: list[dict], @@ -142,6 +153,24 @@ def _format_commits_with_diffs(commits: list[dict], details_by_sha: dict[str, di return "\n".join(lines) +def _clean_bot_comment_body(body: str) -> str: + """Remove hidden/generated Markdown that is not part of the review finding text.""" + cleaned = _HTML_COMMENT_RE.sub("", body) + cleaned = _DETAILS_RE.sub("", cleaned) + cleaned = _SUB_RE.sub("", cleaned) + + lines = cleaned.splitlines() + for idx, line in enumerate(lines): + if line.strip() != "---": + continue + tail = "\n".join(lines[idx + 1 :]).lower() + if any(hint in tail for hint in _PROMO_FOOTER_HINTS): + lines = lines[:idx] + break + + return "\n".join(lines).strip() + + def _format_bot_comments(events: list[dict], chatbot_username: str) -> str: """Format bot's review/review_comment/issue_comment events with full context. @@ -149,6 +178,7 @@ def _format_bot_comments(events: list[dict], chatbot_username: str) -> str: to other commenters' threads, not original review suggestions. """ lines = [] + comment_num = 1 for e in events: if not same_github_actor(e.get("actor"), chatbot_username): continue @@ -164,23 +194,29 @@ def _format_bot_comments(events: list[dict], chatbot_username: str) -> str: if etype == "review": state = data.get("state", "") - body = data.get("body") or "" - lines.append(f"[{ts}] REVIEW ({state}):") + body = _clean_bot_comment_body(data.get("body") or "") + lines.append(f"COMMENT C{comment_num} [REVIEW_BODY state={state} timestamp={ts}]") if body: - lines.append(f" {body}") + lines.append(body) elif etype in ("review_comment", "issue_comment"): - body = data.get("body") or "" + body = _clean_bot_comment_body(data.get("body") or "") path = data.get("path") or "" line = data.get("line") or "" - loc = f" ({path}:{line})" if path else "" diff_hunk = data.get("diff_hunk") or "" resolved = " [RESOLVED]" if data.get("is_resolved") else "" - lines.append(f"[{ts}] {etype.upper()}{loc}{resolved}:") + if etype == "review_comment": + label = "INLINE_REVIEW_COMMENT" + location = f" path={path}:{line}" if path else "" + else: + label = "ISSUE_COMMENT" + location = "" + lines.append(f"COMMENT C{comment_num} [{label}{location}{resolved} timestamp={ts}]") if diff_hunk: - lines.append(f" Code context:\n ```\n{diff_hunk}\n ```") + lines.append(f"Code context:\n```diff\n{diff_hunk}\n```") if body: - lines.append(f" {body}") + lines.append(body) lines.append("") + comment_num += 1 return "\n".join(lines) if lines else "(no bot comments)" diff --git a/online/etl/tests/test_analyze_formatting.py b/online/etl/tests/test_analyze_formatting.py new file mode 100644 index 0000000..fabffe3 --- /dev/null +++ b/online/etl/tests/test_analyze_formatting.py @@ -0,0 +1,71 @@ +"""Tests for bot comment formatting used by LLM extraction.""" + +from __future__ import annotations + +from pipeline.analyze import _clean_bot_comment_body +from pipeline.analyze import _format_bot_comments + + +def test_clean_bot_comment_body_removes_hidden_metadata() -> None: + body = """ +Actual review finding. + +
+Debug trace +Internal prompt text +
+ +generated metadata +""" + + assert _clean_bot_comment_body(body) == "Actual review finding." + + +def test_clean_bot_comment_body_removes_promotional_footer() -> None: + body = """Potential null dereference here. + +--- +If you found this review helpful, react to this comment. +""" + + assert _clean_bot_comment_body(body) == "Potential null dereference here." + + +def test_format_bot_comments_labels_and_numbers_comments() -> None: + events = [ + { + "actor": "reviewer[bot]", + "event_type": "review_comment", + "timestamp": "2026-07-01T12:00:00Z", + "data": { + "path": "src/app.py", + "line": 42, + "diff_hunk": "@@ -1 +1 @@\n-old\n+new", + "body": "This can throw when value is null.", + }, + }, + { + "actor": "reviewer[bot]", + "event_type": "review_comment", + "timestamp": "2026-07-01T12:01:00Z", + "data": { + "in_reply_to_id": 123, + "path": "src/app.py", + "line": 42, + "body": "Fixed now.", + }, + }, + { + "actor": "reviewer[bot]", + "event_type": "review", + "timestamp": "2026-07-01T12:02:00Z", + "data": {"state": "commented", "body": "Summary finding."}, + }, + ] + + formatted = _format_bot_comments(events, "reviewer[bot]") + + assert "COMMENT C1 [INLINE_REVIEW_COMMENT path=src/app.py:42 timestamp=2026-07-01T12:00:00Z]" in formatted + assert "Code context:\n```diff\n@@ -1 +1 @@\n-old\n+new\n```" in formatted + assert "COMMENT C2 [REVIEW_BODY state=commented timestamp=2026-07-01T12:02:00Z]" in formatted + assert "Fixed now." not in formatted From 23801827d65422f5f521b72d7648ca9452ddb9bf Mon Sep 17 00:00:00 2001 From: Gaurav Pooniwala Date: Thu, 9 Jul 2026 18:33:08 +0100 Subject: [PATCH 2/2] Narrow generated footer stripping --- online/etl/pipeline/analyze.py | 2 +- online/etl/tests/test_analyze_formatting.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/online/etl/pipeline/analyze.py b/online/etl/pipeline/analyze.py index fe0b72e..566a23b 100644 --- a/online/etl/pipeline/analyze.py +++ b/online/etl/pipeline/analyze.py @@ -30,7 +30,7 @@ "if you found this review helpful", "coderabbit", "review details", - "configured", + "configuration used", ) diff --git a/online/etl/tests/test_analyze_formatting.py b/online/etl/tests/test_analyze_formatting.py index fabffe3..39d0bfc 100644 --- a/online/etl/tests/test_analyze_formatting.py +++ b/online/etl/tests/test_analyze_formatting.py @@ -31,6 +31,19 @@ def test_clean_bot_comment_body_removes_promotional_footer() -> None: assert _clean_bot_comment_body(body) == "Potential null dereference here." +def test_clean_bot_comment_body_preserves_configured_findings_after_separator() -> None: + body = """Initial context. + +--- +P2: This option is configured incorrectly and can fail at runtime. +""" + + assert ( + _clean_bot_comment_body(body) + == "Initial context.\n\n---\nP2: This option is configured incorrectly and can fail at runtime." + ) + + def test_format_bot_comments_labels_and_numbers_comments() -> None: events = [ {