From 4d4c3faa6859d576b7b0a571e1f1e3ae499095f1 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Tue, 21 Oct 2025 03:04:24 +0200 Subject: [PATCH] Use GPT5-Codex for PR Reviews (#566) Signed-off-by: Glenn Jocher Co-authored-by: UltralyticsAssistant --- README.md | 4 ++-- actions/__init__.py | 2 +- actions/first_interaction.py | 2 +- actions/review_pr.py | 2 +- actions/utils/github_utils.py | 4 ++-- actions/utils/openai_utils.py | 5 +++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 512a561..a0ad2ca 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ Ultralytics Actions automatically applies formats, updates, and enhancements usi - **Spell Check:** Common misspellings are caught using [codespell](https://github.com/codespell-project/codespell). - **Broken Links Check:** Broken links in documentation and Markdown files are identified using [Lychee](https://github.com/lycheeverse/lychee). - **PR Summary:** Concise Pull Request summaries are generated using [OpenAI](https://openai.com/) GPT-5, improving clarity and review efficiency. -- **PR Review:** AI-powered inline code reviews identify critical bugs, security issues, and code quality concerns with suggested fixes. -- **Auto-labeling:** Relevant labels are applied to issues and pull requests via [OpenAI](https://openai.com/) GPT-5 for intelligent categorization. +- **PR Review:** AI-powered code reviews identify critical bugs, security issues, and code quality concerns with suggested fixes. +- **Auto-labeling:** Applies relevant labels to issues and PRs via [OpenAI](https://openai.com/) GPT-5 for intelligent categorization. ## 🛠️ How It Works diff --git a/actions/__init__.py b/actions/__init__.py index 0afbefb..4e82be0 100644 --- a/actions/__init__.py +++ b/actions/__init__.py @@ -23,4 +23,4 @@ # ├── test_summarize_pr.py # └── ... -__version__ = "0.1.3" +__version__ = "0.1.4" diff --git a/actions/first_interaction.py b/actions/first_interaction.py index f514e1d..1ac0b48 100644 --- a/actions/first_interaction.py +++ b/actions/first_interaction.py @@ -196,7 +196,7 @@ def main(*args, **kwargs): if summary := response.get("summary"): print("Updating PR description with summary...") - event.update_pr_description(number, SUMMARY_START + summary + "\n\n" + body) + event.update_pr_description(number, SUMMARY_START + summary) else: summary = body diff --git a/actions/review_pr.py b/actions/review_pr.py index 03273c1..2de3e40 100644 --- a/actions/review_pr.py +++ b/actions/review_pr.py @@ -125,7 +125,7 @@ def generate_pr_review(repository: str, diff_text: str, pr_title: str, pr_descri ] try: - response = get_completion(messages, reasoning_effort="medium") + response = get_completion(messages, reasoning_effort="medium", model="gpt-5-codex") print("\n" + "=" * 80 + f"\nFULL AI RESPONSE:\n{response}\n" + "=" * 80 + "\n") json_str = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", response, re.DOTALL) diff --git a/actions/utils/github_utils.py b/actions/utils/github_utils.py index cc36258..275b883 100644 --- a/actions/utils/github_utils.py +++ b/actions/utils/github_utils.py @@ -281,10 +281,10 @@ class Action: start = "## 🛠️ PR Summary" if start in description: print("Existing PR Summary found, replacing.") - updated_description = description.split(start)[0] + new_summary + updated_description = description.split(start)[0].rstrip() + "\n\n" + new_summary else: print("PR Summary not found, appending.") - updated_description = description + "\n\n" + new_summary + updated_description = (description.rstrip() + "\n\n" + new_summary) if description.strip() else new_summary self.patch(url, json={"body": updated_description}) self._pr_summary_cache = new_summary diff --git a/actions/utils/openai_utils.py b/actions/utils/openai_utils.py index fb881a5..4543501 100644 --- a/actions/utils/openai_utils.py +++ b/actions/utils/openai_utils.py @@ -112,6 +112,7 @@ def get_completion( temperature: float = 1.0, reasoning_effort: str = None, response_format: dict = None, + model: str = OPENAI_MODEL, ) -> str | dict: """Generates a completion using OpenAI's Responses API based on input messages.""" assert OPENAI_API_KEY, "OpenAI API key is required." @@ -122,8 +123,8 @@ def get_completion( max_retries = 2 for attempt in range(max_retries + 2): - data = {"model": OPENAI_MODEL, "input": messages, "store": False, "temperature": temperature} - if "gpt-5" in OPENAI_MODEL: + data = {"model": model, "input": messages, "store": False, "temperature": temperature} + if "gpt-5" in model: data["reasoning"] = {"effort": reasoning_effort or "low"} # GPT-5 Responses API handles JSON via prompting, not format parameter