From d3a367f0c700e4246cfb721f06fe24fd0bfe5e37 Mon Sep 17 00:00:00 2001 From: KopekC Date: Thu, 6 Feb 2025 17:38:52 -0500 Subject: [PATCH 1/6] Adds llm query bot example --- examples/pr_review_bot/README.md | 126 +++++++++++++++++++++++++++++++ examples/pr_review_bot/run.py | 100 ++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 examples/pr_review_bot/README.md create mode 100644 examples/pr_review_bot/run.py diff --git a/examples/pr_review_bot/README.md b/examples/pr_review_bot/README.md new file mode 100644 index 0000000..2f71733 --- /dev/null +++ b/examples/pr_review_bot/README.md @@ -0,0 +1,126 @@ +# AI-Powered Pull Request Review Bot + +This example demonstrates how to use Codegen to create an intelligent PR review bot that analyzes code changes and their dependencies to provide comprehensive code reviews. The bot uses GPT-4 to generate contextual feedback based on modified code and its relationships. + +> [!NOTE] +> This codemod helps development teams by providing automated, context-aware code reviews that consider both direct and indirect code dependencies. + +## How the PR Review Bot Works + +The script analyzes pull requests in several key steps: + +1. **Symbol Analysis** + ```python + modified_symbols = codebase.get_modified_symbols_in_pr(pr_number) + for symbol in modified_symbols: + deps = codebase.get_symbol_dependencies(symbol, max_depth=2) + rev_deps = codebase.get_symbol_dependents(symbol, max_depth=2) + ``` + - Identifies modified symbols in the PR + - Analyzes dependencies up to 2 levels deep + - Tracks reverse dependencies (symbols that depend on changes) + +2. **Context Building** + ```python + context = { + "pr_title": pr.title, + "pr_body": pr.body, + "modified_symbols": [...], + "context_symbols": [...] + } + ``` + - Gathers PR metadata + - Collects modified code content + - Includes relevant dependency context + +3. **AI Review Generation** + ```python + review = codebase.ai_client.llm_query_with_retry( + messages=[...], + model="gpt-4", + max_tokens=2000 + ) + ``` + - Uses GPT-4 for analysis + - Generates comprehensive review feedback + - Considers full context of changes + +## Why This Makes Code Review Better + +1. **Context-Aware Analysis** + - Understands code dependencies + - Considers impact of changes + - Reviews code in proper context + +2. **Comprehensive Review** + - Analyzes direct modifications + - Evaluates dependency impact + - Suggests improvements + +3. **Consistent Feedback** + - Structured review format + - Thorough analysis every time + - Scalable review process + +## Review Output Format + +The bot provides structured feedback including: + +``` +1. Overall Assessment + - High-level review of changes + - Impact analysis + +2. Specific Code Feedback + - Detailed code comments + - Style suggestions + - Best practices + +3. Potential Issues + - Security concerns + - Performance impacts + - Edge cases + +4. Dependency Analysis + - Impact on dependent code + - Breaking changes + - Integration considerations + +``` + +## Key Benefits to Note + +1. **Better Code Quality** + - Thorough code analysis + - Consistent review standards + - Early issue detection + +2. **Time Savings** + - Automated initial review + - Quick feedback loop + - Reduced review burden + +3. **Knowledge Sharing** + - Educational feedback + - Best practice suggestions + - Team learning + + +## Configuration Options + +You can customize the review by: +- Adjusting dependency depth +- Modifying the AI prompt +- Changing the review focus areas +- Tuning the GPT-4 parameters + +## Learn More + +- [Codegen Documentation](https://docs.codegen.com) +- [OpenAI API Documentation](https://platform.openai.com/docs/api-reference) +- [GitHub API Documentation](https://docs.github.com/en/rest) +- [Codegen llm integration](https://docs.codegen.com/building-with-codegen/calling-out-to-llms) + +## Contributing + +Feel free to submit issues and enhancement requests! Contributions to improve the review bot's capabilities are welcome. \ No newline at end of file diff --git a/examples/pr_review_bot/run.py b/examples/pr_review_bot/run.py new file mode 100644 index 0000000..8be617f --- /dev/null +++ b/examples/pr_review_bot/run.py @@ -0,0 +1,100 @@ +import codegen +from codegen import Codebase +from codegen.sdk.enums import ProgrammingLanguage +from codegen.sdk.codebase.config import CodebaseConfig, GSFeatureFlags, Secrets +import json +github_token = "Your github token" +open_ai_key = "your open ai key" +pr_number= 0 # Your PR number must be an integer + +def run(codebase: Codebase): + + context_symbols = set() + + modified_symbols = codebase.get_modified_symbols_in_pr(pr_number) + for symbol in modified_symbols: + # Get direct dependencies + deps = codebase.get_symbol_dependencies(symbol, max_depth=2) + context_symbols.update(deps) + + # Get reverse dependencies (symbols that depend on this one) + rev_deps = codebase.get_symbol_dependents(symbol, max_depth=2) + context_symbols.update(rev_deps) + + # Prepare context for LLM + context = { + "pr_title": pr.title, + "pr_body": pr.body, + "modified_symbols": [ + { + "name": symbol.name, + "type": symbol.symbol_type.value, + "filepath": symbol.filepath, + "content": symbol.content, + } for symbol in modified_symbols + ], + "context_symbols": [ + { + "name": symbol.name, + "type": symbol.symbol_type.value, + "filepath": symbol.filepath, + "content": symbol.content, + } for symbol in context_symbols + ] + } + + system_prompt = """ + You are a helpful assistant that reviews pull requests and provides feedback on the code. + """ + # Generate review using AI + prompt = f"""Please review this pull request based on the following context: + +Title: {context['pr_title']} +Description: {context['pr_body']} + +Modified Symbols: +{json.dumps(context['modified_symbols'], indent=2)} + +Related Context (Dependencies): +{json.dumps(context['context_symbols'], indent=2)} + +Please provide a thorough code review that includes: +1. Overall assessment +2. Specific feedback on modified code +3. Potential issues or improvements +4. Impact on dependencies +5. Suggestions for testing +""" + + review = codebase.ai_client.llm_query_with_retry( + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": prompt} + ], + model="gpt-4", + max_tokens=2000, + temperature=0.7 + ) + return review + + +if __name__ == "__main__": + print("Starting codebase analysis...") + codebase = Codebase.from_repo( + 'getsentry/sentry', + shallow=False, + programming_language=ProgrammingLanguage.PYTHON, + config=CodebaseConfig( + secrets=Secrets( + openai_key=open_ai_key, + github_api_key=github_token + + ), + feature_flags=GSFeatureFlags( + sync_enabled=True, ) + + )) + review = run(codebase) + print(review) + + print("Codebase analysis complete.") \ No newline at end of file From ba195a960d3d703a5bc1651520237a000269401a Mon Sep 17 00:00:00 2001 From: kopekC <28070492+kopekC@users.noreply.github.com> Date: Thu, 6 Feb 2025 22:39:39 +0000 Subject: [PATCH 2/6] Automated pre-commit update --- examples/pr_review_bot/run.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/pr_review_bot/run.py b/examples/pr_review_bot/run.py index 8be617f..2d081c1 100644 --- a/examples/pr_review_bot/run.py +++ b/examples/pr_review_bot/run.py @@ -1,4 +1,3 @@ -import codegen from codegen import Codebase from codegen.sdk.enums import ProgrammingLanguage from codegen.sdk.codebase.config import CodebaseConfig, GSFeatureFlags, Secrets From a3376652f16d2c234c1240eba352c5d1aab9d354 Mon Sep 17 00:00:00 2001 From: KopekC Date: Thu, 6 Feb 2025 17:40:04 -0500 Subject: [PATCH 3/6] . --- examples/pr_review_bot/run.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/pr_review_bot/run.py b/examples/pr_review_bot/run.py index 2d081c1..de94752 100644 --- a/examples/pr_review_bot/run.py +++ b/examples/pr_review_bot/run.py @@ -6,6 +6,7 @@ open_ai_key = "your open ai key" pr_number= 0 # Your PR number must be an integer +codegen.function("pr-review-bot") def run(codebase: Codebase): context_symbols = set() From 3913de9fbdbbb487aef55a754a972844eb2f62e5 Mon Sep 17 00:00:00 2001 From: KopekC Date: Thu, 6 Feb 2025 17:40:34 -0500 Subject: [PATCH 4/6] . --- examples/pr_review_bot/run.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/pr_review_bot/run.py b/examples/pr_review_bot/run.py index de94752..4344498 100644 --- a/examples/pr_review_bot/run.py +++ b/examples/pr_review_bot/run.py @@ -1,3 +1,4 @@ +import codegen from codegen import Codebase from codegen.sdk.enums import ProgrammingLanguage from codegen.sdk.codebase.config import CodebaseConfig, GSFeatureFlags, Secrets From 1315ff2edb2e87ad04f316c083c12760b255249a Mon Sep 17 00:00:00 2001 From: KopekC Date: Thu, 6 Feb 2025 17:42:25 -0500 Subject: [PATCH 5/6] . --- examples/pr_review_bot/run.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/pr_review_bot/run.py b/examples/pr_review_bot/run.py index 4344498..ea8be9d 100644 --- a/examples/pr_review_bot/run.py +++ b/examples/pr_review_bot/run.py @@ -24,8 +24,6 @@ def run(codebase: Codebase): # Prepare context for LLM context = { - "pr_title": pr.title, - "pr_body": pr.body, "modified_symbols": [ { "name": symbol.name, From c539cbfc0bfe66614a1479121e64ef7a6f800bbc Mon Sep 17 00:00:00 2001 From: kopekC <28070492+kopekC@users.noreply.github.com> Date: Thu, 6 Feb 2025 22:42:59 +0000 Subject: [PATCH 6/6] Automated pre-commit update --- examples/pr_review_bot/run.py | 59 +++++++++++++++-------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/examples/pr_review_bot/run.py b/examples/pr_review_bot/run.py index ea8be9d..c3cd320 100644 --- a/examples/pr_review_bot/run.py +++ b/examples/pr_review_bot/run.py @@ -3,13 +3,15 @@ from codegen.sdk.enums import ProgrammingLanguage from codegen.sdk.codebase.config import CodebaseConfig, GSFeatureFlags, Secrets import json + github_token = "Your github token" open_ai_key = "your open ai key" -pr_number= 0 # Your PR number must be an integer +pr_number = 0 # Your PR number must be an integer codegen.function("pr-review-bot") -def run(codebase: Codebase): + +def run(codebase: Codebase): context_symbols = set() modified_symbols = codebase.get_modified_symbols_in_pr(pr_number) @@ -17,11 +19,11 @@ def run(codebase: Codebase): # Get direct dependencies deps = codebase.get_symbol_dependencies(symbol, max_depth=2) context_symbols.update(deps) - + # Get reverse dependencies (symbols that depend on this one) - rev_deps = codebase.get_symbol_dependents(symbol, max_depth=2) + rev_deps = codebase.get_symbol_dependents(symbol, max_depth=2) context_symbols.update(rev_deps) - + # Prepare context for LLM context = { "modified_symbols": [ @@ -30,7 +32,8 @@ def run(codebase: Codebase): "type": symbol.symbol_type.value, "filepath": symbol.filepath, "content": symbol.content, - } for symbol in modified_symbols + } + for symbol in modified_symbols ], "context_symbols": [ { @@ -38,24 +41,25 @@ def run(codebase: Codebase): "type": symbol.symbol_type.value, "filepath": symbol.filepath, "content": symbol.content, - } for symbol in context_symbols - ] + } + for symbol in context_symbols + ], } - + system_prompt = """ You are a helpful assistant that reviews pull requests and provides feedback on the code. """ # Generate review using AI prompt = f"""Please review this pull request based on the following context: -Title: {context['pr_title']} -Description: {context['pr_body']} +Title: {context["pr_title"]} +Description: {context["pr_body"]} Modified Symbols: -{json.dumps(context['modified_symbols'], indent=2)} +{json.dumps(context["modified_symbols"], indent=2)} Related Context (Dependencies): -{json.dumps(context['context_symbols'], indent=2)} +{json.dumps(context["context_symbols"], indent=2)} Please provide a thorough code review that includes: 1. Overall assessment @@ -65,35 +69,24 @@ def run(codebase: Codebase): 5. Suggestions for testing """ - review = codebase.ai_client.llm_query_with_retry( - messages=[ - {"role": "system", "content": system_prompt}, - {"role": "user", "content": prompt} - ], - model="gpt-4", - max_tokens=2000, - temperature=0.7 - ) + review = codebase.ai_client.llm_query_with_retry(messages=[{"role": "system", "content": system_prompt}, {"role": "user", "content": prompt}], model="gpt-4", max_tokens=2000, temperature=0.7) return review if __name__ == "__main__": print("Starting codebase analysis...") codebase = Codebase.from_repo( - 'getsentry/sentry', + "getsentry/sentry", shallow=False, - programming_language=ProgrammingLanguage.PYTHON, + programming_language=ProgrammingLanguage.PYTHON, config=CodebaseConfig( - secrets=Secrets( - openai_key=open_ai_key, - github_api_key=github_token - - ), + secrets=Secrets(openai_key=open_ai_key, github_api_key=github_token), feature_flags=GSFeatureFlags( - sync_enabled=True, ) - - )) + sync_enabled=True, + ), + ), + ) review = run(codebase) print(review) - print("Codebase analysis complete.") \ No newline at end of file + print("Codebase analysis complete.")