Skip to content

Commit

Permalink
Merge branch 'main' into 10-add-rag-support
Browse files Browse the repository at this point in the history
  • Loading branch information
sauravpanda authored Aug 17, 2024
2 parents 9584fd2 + 77de3aa commit b913aeb
Show file tree
Hide file tree
Showing 39 changed files with 1,696 additions and 258 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[
{
"topic": "Error Handling",
"comment": "Removed parameter 'reeval_response' without handling its previous functionality.",
"confidence": "critical",
"reason": "The removal of 'reeval_response' may lead to unexpected behavior if the function relies on it.",
"solution": "Evaluate the necessity of the 'reeval_response' parameter and ensure that its removal does not affect the logic of the code.",
"actual_code": "desc = self._process_full_diff(prompt, user, reeval_response)",
"fixed_code": "desc = self._process_full_diff(prompt, user)",
"file_name": "kaizen/generator/pr_description.py",
"start_line": 54,
"end_line": 54,
"side": "LEFT",
"sentiment": "negative",
"severity_level": 8
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# 🔍 Code Review Summary

## 📊 Stats
- Total Issues: 4
- Critical: 1
- Important: 2
- Minor: 1
- Files Affected: 1
## 🏆 Code Quality
[█████████████████░░░] 85% (Good)

## 🚨 Critical Issues

<details>
<summary><strong>Error Handling (1 issues)</strong></summary>

### 1. Removed parameter 'reeval_response' without handling its previous functionality.
📁 **File:** `kaizen/generator/pr_description.py:54`
⚖️ **Severity:** 8/10
🔍 **Description:** The removal of 'reeval_response' may lead to unexpected behavior if the function relies on it.
💡 **Solution:** Evaluate the necessity of the 'reeval_response' parameter and ensure that its removal does not affect the logic of the code.

**Current Code:**
```python
desc = self._process_full_diff(prompt, user, reeval_response)
```

**Suggested Code:**
```python
desc = self._process_full_diff(prompt, user)
```

</details>

## 🟠 Important Issues

<details>
<summary><strong>Imports (2 issues)</strong></summary>

### 1. Inconsistent naming of imported prompts.
📁 **File:** `kaizen/generator/pr_description.py:8`
⚖️ **Severity:** 5/10
🔍 **Description:** The change from `code_review_prompts` to `pr_desc_prompts` may lead to confusion if not documented properly.
💡 **Solution:** Ensure that the new prompt names are well-documented and consistent across the codebase.

**Current Code:**
```python
from kaizen.llms.prompts.code_review_prompts import (
PR_DESCRIPTION_PROMPT,
MERGE_PR_DESCRIPTION_PROMPT,
PR_FILE_DESCRIPTION_PROMPT,
PR_DESC_EVALUATION_PROMPT,
CODE_REVIEW_SYSTEM_PROMPT,
)
```

**Suggested Code:**
```python
from kaizen.llms.prompts.pr_desc_prompts import (
PR_DESCRIPTION_PROMPT,
MERGE_PR_DESCRIPTION_PROMPT,
PR_FILE_DESCRIPTION_PROMPT,
PR_DESCRIPTION_SYSTEM_PROMPT,
)
```

### 2. Inconsistent handling of response extraction.
📁 **File:** `kaizen/generator/pr_description.py:110`
⚖️ **Severity:** 7/10
🔍 **Description:** The change from 'chat_completion_with_json' to 'chat_completion' may alter the expected response format.
💡 **Solution:** Ensure that the new method returns the same structure as the previous one or update the handling logic accordingly.

**Current Code:**
```python
resp, usage = self.provider.chat_completion_with_json(prompt, user=user)
```

**Suggested Code:**
```python
resp, usage = self.provider.chat_completion(prompt, user=user)
```

</details>

---

> ✨ Generated with love by [Kaizen](https://cloudcode.ai) ❤️
<details>
<summary>Useful Commands</summary>

- **Feedback:** Reply with `!feedback [your message]`
- **Ask PR:** Reply with `!ask-pr [your question]`
- **Review:** Reply with `!review`
- **Explain:** Reply with `!explain [issue number]` for more details on a specific issue
- **Ignore:** Reply with `!ignore [issue number]` to mark an issue as false positive
- **Update Tests:** Reply with `!unittest` to create a PR with test changes
</details>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[
{
"topic": "Functionality",
"comment": "Changing the method from 'chat_completion_with_json' to 'chat_completion' may alter expected behavior.",
"confidence": "critical",
"reason": "If 'chat_completion_with_json' was designed to handle specific JSON formatting, switching to 'chat_completion' may lead to data handling issues.",
"solution": "Review the implementation of 'chat_completion' to ensure it meets the requirements previously handled by 'chat_completion_with_json'.",
"actual_code": "resp, usage = self.provider.chat_completion_with_json(prompt, user=user)",
"fixed_code": "resp, usage = self.provider.chat_completion(prompt, user=user)",
"file_name": "kaizen/generator/pr_description.py",
"start_line": 83,
"end_line": 83,
"side": "LEFT",
"sentiment": "negative",
"severity_level": 8
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# 🔍 Code Review Summary

## 📊 Stats
- Total Issues: 5
- Critical: 1
- Important: 3
- Minor: 1
- Files Affected: 1
## 🏆 Code Quality
[████████████████░░░░] 80% (Good)

## 🚨 Critical Issues

<details>
<summary><strong>Functionality (1 issues)</strong></summary>

### 1. Changing the method from 'chat_completion_with_json' to 'chat_completion' may alter expected behavior.
📁 **File:** `kaizen/generator/pr_description.py:83`
⚖️ **Severity:** 8/10
🔍 **Description:** If 'chat_completion_with_json' was designed to handle specific JSON formatting, switching to 'chat_completion' may lead to data handling issues.
💡 **Solution:** Review the implementation of 'chat_completion' to ensure it meets the requirements previously handled by 'chat_completion_with_json'.

**Current Code:**
```python
resp, usage = self.provider.chat_completion_with_json(prompt, user=user)
```

**Suggested Code:**
```python
resp, usage = self.provider.chat_completion(prompt, user=user)
```

</details>

## 🟠 Important Issues

<details>
<summary><strong>Imports (3 issues)</strong></summary>

### 1. Updated import statements may lead to confusion regarding the source of prompts.
📁 **File:** `kaizen/generator/pr_description.py:8`
⚖️ **Severity:** 5/10
🔍 **Description:** Changing the import path for prompts can lead to issues if the new module does not contain the expected constants.
💡 **Solution:** Ensure that the new import path is correct and that all necessary constants are defined in the new module.

**Current Code:**
```python
from kaizen.llms.prompts.code_review_prompts import (
PR_DESCRIPTION_PROMPT,
MERGE_PR_DESCRIPTION_PROMPT,
PR_FILE_DESCRIPTION_PROMPT,
PR_DESC_EVALUATION_PROMPT,
CODE_REVIEW_SYSTEM_PROMPT,
)
```

**Suggested Code:**
```python
from kaizen.llms.prompts.pr_desc_prompts import (
PR_DESCRIPTION_PROMPT,
MERGE_PR_DESCRIPTION_PROMPT,
PR_FILE_DESCRIPTION_PROMPT,
PR_DESCRIPTION_SYSTEM_PROMPT,
)
```

### 2. Raising a generic Exception can obscure the cause of errors.
📁 **File:** `kaizen/generator/pr_description.py:51`
⚖️ **Severity:** 7/10
🔍 **Description:** Using a generic Exception does not provide specific information about the error, making debugging difficult.
💡 **Solution:** Use a more specific exception type or create a custom exception class to provide better context.

**Current Code:**
```python
raise Exception("Both diff_text and pull_request_files are empty!")
```

**Suggested Code:**
```python
raise ValueError("Both diff_text and pull_request_files are empty!")
```

### 3. Removing 'reeval_response' from multiple function signatures may lead to loss of intended functionality.
📁 **File:** `kaizen/generator/pr_description.py:40`
⚖️ **Severity:** 6/10
🔍 **Description:** If 'reeval_response' was previously used to control logic, its removal could lead to unintended behavior.
💡 **Solution:** Carefully assess the logic that relies on 'reeval_response' to determine if it should be retained.

**Current Code:**
```python
def _process_full_diff(self, prompt: str, user: Optional[str], reeval_response: bool) -> str:
```

**Suggested Code:**
```python
def _process_full_diff(self, prompt: str, user: Optional[str]) -> str:
```

</details>

---

> ✨ Generated with love by [Kaizen](https://cloudcode.ai) ❤️
<details>
<summary>Useful Commands</summary>

- **Feedback:** Reply with `!feedback [your message]`
- **Ask PR:** Reply with `!ask-pr [your question]`
- **Review:** Reply with `!review`
- **Explain:** Reply with `!explain [issue number]` for more details on a specific issue
- **Ignore:** Reply with `!ignore [issue number]` to mark an issue as false positive
- **Update Tests:** Reply with `!unittest` to create a PR with test changes
</details>
107 changes: 107 additions & 0 deletions .experiments/code_review/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import os
import json
import datetime
import logging
from tqdm import tqdm
from kaizen.reviewer.code_review import CodeReviewer
from kaizen.llms.provider import LLMProvider
from github_app.github_helper.utils import get_diff_text, get_pr_files
from github_app.github_helper.pull_requests import (
create_review_comments,
)
from kaizen.formatters.code_review_formatter import create_pr_review_text

# Get the directory where the script is located
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))

# Set up logging
log_file = os.path.join(SCRIPT_DIR, "pr_review.log")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[logging.FileHandler(log_file), logging.StreamHandler()],
)
logger = logging.getLogger(__name__)


def process_pr(pr_url, reeval_response=False):
logger.info(f"Processing PR: {pr_url}")
pr_diff = f"{pr_url}.patch"
pr_files = f"{pr_url}/files".replace("github.com", "api.github.com/repos").replace(
"/pull", "/pulls"
)
pr_title = pr_url.split("/")[-1] # Use PR number as title for simplicity

diff_text = get_diff_text(pr_diff, "")
pr_files = get_pr_files(pr_files, "")

reviewer = CodeReviewer(llm_provider=LLMProvider())
review_data = reviewer.review_pull_request(
diff_text=diff_text,
pull_request_title=pr_title,
pull_request_desc="",
pull_request_files=pr_files,
user="kaizen/example",
reeval_response=reeval_response,
)

# topics = clean_keys(review_data.topics, "important")
logger.info(review_data.topics)
review_desc = create_pr_review_text(
review_data.issues, code_quality=review_data.code_quality
)
comments, topics = create_review_comments(review_data.topics)
logger.info(f"Model: {review_data.model_name}\nUsage: {review_data.usage}")
logger.info(f"Completed processing PR: {pr_url}")
return review_desc, comments, topics


def save_review(pr_number, review_desc, comments, topics, folder):
logger.info(f"Saving review for PR {pr_number} in {folder}")
review_file = os.path.join(folder, f"pr_{pr_number}_review.md")
comments_file = os.path.join(folder, f"pr_{pr_number}_comments.json")

with open(review_file, "w") as f:
f.write(review_desc)

with open(comments_file, "w") as f:
json.dump(comments, f, indent=2)

logger.info(f"Saved review files for PR {pr_number}")


def main(pr_urls):
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
base_folder = os.path.join(SCRIPT_DIR, f"code_reviews_{timestamp}")
with_eval_folder = os.path.join(base_folder, "with_eval")
no_eval_folder = os.path.join(base_folder, "no_eval")

os.makedirs(with_eval_folder, exist_ok=True)
os.makedirs(no_eval_folder, exist_ok=True)

logger.info(f"Created output folders: {base_folder}")

for pr_url in tqdm(pr_urls, desc="Processing PRs", unit="PR"):
pr_number = pr_url.split("/")[-1]

logger.info(f"Starting to process PR {pr_number}")

# Without re-evaluation
review_desc, comments, topics = process_pr(pr_url, reeval_response=False)
save_review(pr_number, review_desc, comments, topics, no_eval_folder)

# With re-evaluation
review_desc, comments, topics = process_pr(pr_url, reeval_response=True)
save_review(pr_number, review_desc, comments, topics, with_eval_folder)

logger.info(f"Completed processing PR {pr_number}")

logger.info("All PRs processed successfully")


if __name__ == "__main__":
pr_urls = [
"https://github.com/Cloud-Code-AI/kaizen/pull/335",
# Add more PR URLs here
]
main(pr_urls)
15 changes: 15 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: ["https://buy.stripe.com/3cs6pNf2Wg4o4owcMW"]
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<img src="/logo.png" alt="Kaizen Logo" width="200"/>
<img src="/assets/logo.png" alt="Kaizen Logo" width="200"/>
</p>

<h1 align="center">Kaizen: The Ultimate Code Quality Guardian</h1>
Expand Down Expand Up @@ -30,6 +30,7 @@ In the ever-evolving world of software development, delivering high-quality code
### 🔍 Key Features

- **🤖 AI-Powered Code Reviews**: Automated pull request reviews with insightful summaries and improvement suggestions, catching potential issues before they escalate.

- **🧪 Smart Test Generation**:
- End-to-end tests based on your application's code and documentation, ensuring comprehensive coverage.
- Unit test generation for Python (with TypeScript and React support coming soon!), saving you valuable time and effort.
Expand Down
File renamed without changes
Loading

0 comments on commit b913aeb

Please sign in to comment.