Skip to content

Feat/ai reviewer: add AI review#3

Closed
hapo-nghialuu wants to merge 6 commits intomainfrom
feat/ai-reviewer
Closed

Feat/ai reviewer: add AI review#3
hapo-nghialuu wants to merge 6 commits intomainfrom
feat/ai-reviewer

Conversation

@hapo-nghialuu
Copy link
Copy Markdown
Member

No description provided.

Comment thread scripts/ai_reviewer.py

def should_review(filename):
"""Check if file should be reviewed based on extension and path."""
if any(filename.endswith(ext) for ext in IGNORED_EXTENSIONS):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: MODEL_NAME sử dụng model không rõ ràng, nên xác minh tính khả dụng và chi phí trước khi sử dụng.

Comment thread scripts/ai_reviewer.py Outdated
Comment thread scripts/ai_reviewer.py

Dữ liệu input là JSON list các file kèm patch.
Hãy trả về kết quả là một JSON list thuần túy (không markdown block, không giải thích thêm), mỗi item có format sau:
[
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: API key được lấy từ environment variable nhưng không có validation về định dạng hoặc tính hợp lệ.

Comment thread scripts/ai_reviewer.py
if content.startswith("```json"):
content = content[7:]
if content.startswith("```"):
content = content[3:]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp response.choices rỗng hoặc không tồn tại, có thể gây lỗi runtime.

Comment thread scripts/ai_reviewer.py
commit = pr.get_commits().reversed[0] # Get latest commit

if not comments:
logging.info("No issues found. LGTM!")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không có cơ chế retry hoặc fallback khi gọi API thất bại, ảnh hưởng đến độ tin cậy.

Comment thread scripts/ai_reviewer.py
logging.warning(f"Failed to post comment on {filename}:{line}. Error: {e}")
pr.create_issue_comment(f"Could not comment on line {line} of {filename}. \n\n{body}")

def main():
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Sử dụng commit.reversed[0] có thể gây lỗi nếu danh sách commit rỗng, nên kiểm tra trước.

Comment thread scripts/ai_reviewer.py

with open(event_path, 'r') as f:
event_data = json.load(f)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp line_number không phải là số nguyên, có thể gây lỗi khi ép kiểu.

Comment thread scripts/ai_reviewer.py
def should_review(filename):
"""Check if file should be reviewed based on extension and path."""
if any(filename.endswith(ext) for ext in IGNORED_EXTENSIONS):
return False
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: MODEL_NAME sử dụng model không rõ ràng, nên kiểm tra tính khả dụng và chi phí trước khi sử dụng.

Comment thread scripts/ai_reviewer.py

for file in pr.get_files():
if not should_review(file.filename):
continue
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Hàm should_review không xử lý trường hợp filename là None hoặc rỗng, có thể gây lỗi.

Comment thread scripts/ai_reviewer.py
def analyze_code_with_openrouter(files_data):
"""Send code diff to OpenRouter for review."""
api_key = os.getenv("OPENROUTER_API_KEY")
if not api_key:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không có xử lý ngoại lệ khi gọi pr.get_files() hoặc file.patch, có thể gây crash nếu API trả về lỗi.

Comment thread scripts/ai_reviewer.py

Hãy chỉ ra các vấn đề nghiêm trọng:
1. Lỗi Logic (Logic Errors) - Rất quan trọng.
2. Vấn đề Bảo mật (Security Vulnerabilities) - Rất quan trọng.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: API key được lấy từ environment variable nhưng không có validation về định dạng hoặc tính hợp lệ.

Comment thread scripts/ai_reviewer.py

Nếu code tốt hoàn toàn, hãy trả về danh sách rỗng [].

CODE DIFF TO REVIEW:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không có giới hạn về kích thước của files_data khi gửi đến OpenRouter, có thể gây vượt quá giới hạn API.

Comment thread scripts/ai_reviewer.py
except json.JSONDecodeError:
logging.error(f"Failed to parse JSON response: {content}")
return []
except Exception as e:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không có xử lý ngoại lệ khi gọi pr.get_commits().reversed[0], có thể gây lỗi nếu không có commit nào.

Comment thread scripts/ai_reviewer.py
logging.info(f"Posting {len(comments)} comments...")

for note in comments:
filename = note.get('filename')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Line number từ AI có thể không chính xác, nên có cơ chế xác minh hoặc fallback.

Comment thread scripts/ai_reviewer.py Outdated
Comment thread scripts/ai_reviewer.py

# Configure Logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Hằng số MODEL_NAME sử dụng model không tồn tại (mistralai/devstral-2512:free), cần kiểm tra và sửa lại tên model chính xác.

Comment thread scripts/ai_reviewer.py
IGNORED_EXTENSIONS = ['.json', '.md', '.txt', '.yml', '.yaml', '.lock', '.png', '.jpg', '.jpeg', '.gif', '.svg']
IGNORED_DIRS = ['dist', 'build', 'node_modules', '.github']
MODEL_NAME = "mistralai/devstral-2512:free"
GITHUB_GRAPHQL_URL = "https://api.github.com/graphql"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Hàm should_review không xử lý trường hợp filename là None hoặc rỗng, có thể gây lỗi khi truy cập thuộc tính.

Comment thread scripts/ai_reviewer.py
return False
return True

def get_pr_diff(repo, pr_number):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không kiểm tra quyền truy cập repo trước khi gọi repo.get_pull, có thể gây lỗi nếu token không có quyền.

Comment thread scripts/ai_reviewer.py
continue

# Only review added or modified files (not deleted)
if file.status == 'removed':
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp file.patch là None, có thể gây lỗi khi thêm vào files_data.

Comment thread scripts/ai_reviewer.py
"Content-Type": "application/json"
}
payload = {
"query": mutation,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Headers trong resolve_thread không chứa 'Accept: application/vnd.github.v3+json', có thể gây lỗi với một số API version.

Comment thread scripts/ai_reviewer.py
"""
query = """
query($owner: String!, $repo: String!, $prNumber: Int!) {
repository(owner: $owner, name: $repo) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp data['data'] là None trước khi truy cập các trường con, có thể gây KeyError.

Comment thread scripts/ai_reviewer.py
}
}
"""
headers = {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không giới hạn số lượng threads lấy về (last: 50), có thể gây quá tải nếu PR có nhiều threads.

Comment thread scripts/ai_reviewer.py
threads = data['data']['repository']['pullRequest']['reviewThreads']['nodes']
bot_threads = []

for thread in threads:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp author là None trước khi gọi author.get('login'), có thể gây AttributeError.

Comment thread scripts/ai_reviewer.py
except Exception as e:
logging.error(f"Failed to fetch/resolve threads: {e}")

def analyze_code_with_openrouter(files_data):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không kiểm tra OPENROUTER_API_KEY có hợp lệ hay không trước khi sử dụng, có thể gây lỗi kết nối.

Comment thread scripts/ai_reviewer.py
"X-Title": "Antigravity AI Reviewer"
}
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp response.choices là rỗng hoặc response.choices[0].message.content là None, có thể gây lỗi.

Comment thread scripts/ai_reviewer.py
Hãy trả về kết quả là một JSON list thuần túy (không markdown block, không giải thích thêm), mỗi item có format sau:
[
{
"filename": "tên_file",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không validate định dạng JSON trả về từ OpenRouter, có thể gây lỗi nếu response không phải JSON hợp lệ.

Comment thread scripts/ai_reviewer.py
response = client.chat.completions.create(
model=MODEL_NAME,
messages=[
{"role": "system", "content": "You are a helpful code reviewer. Always respond with valid JSON code only. No markdown formatting."},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp commit là None khi gọi pr.get_commits().reversed[0], có thể gây lỗi.

Comment thread scripts/ai_reviewer.py
content = response.choices[0].message.content.strip()

# Strip markdown code blocks if present (common issue with LLMs)
if content.startswith("```json"):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không kiểm tra tính hợp lệ của line_number trước khi ép kiểu int(line), có thể gây ValueError.

Comment thread scripts/ai_reviewer.py Outdated
Comment thread scripts/ai_reviewer.py
def post_comments(pr, comments):
"""Post comments to the PR."""
commit = pr.get_commits().reversed[0] # Get latest commit

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không kiểm tra quyền truy cập repo trước khi gọi g.get_repo, có thể gây lỗi nếu token không có quyền.

Comment thread scripts/ai_reviewer.py
Comment thread scripts/ai_reviewer.py
IGNORED_EXTENSIONS = ['.json', '.md', '.txt', '.yml', '.yaml', '.lock', '.png', '.jpg', '.jpeg', '.gif', '.svg']
IGNORED_DIRS = ['dist', 'build', 'node_modules', '.github']
# Free tier model from OpenRouter - may have rate limits or availability issues
MODEL_NAME = "mistralai/devstral-2512:free"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Hàm should_review không kiểm tra các file không có phần mở rộng, có thể bỏ sót các file cần review.

Comment thread scripts/ai_reviewer.py

def get_pr_diff(repo, pr_number):
"""Fetch PR diff using PyGithub."""
pr = repo.get_pull(pr_number)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp file.patchNone, có thể gây lỗi khi truy cập.

Comment thread scripts/ai_reviewer.py
query = """
query($owner: String!, $repo: String!, $prNumber: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $prNumber) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không có cơ chế retry khi gọi API GraphQL thất bại, có thể gây mất comments cũ không được resolve.

Comment thread scripts/ai_reviewer.py
threads = pr_data.get('reviewThreads', {}).get('nodes', [])
if not threads:
logging.info("No review threads found.")
return
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không validate định dạng của files_data trước khi gửi đến OpenRouter, có thể gây lỗi nếu dữ liệu không hợp lệ.

Comment thread scripts/ai_reviewer.py
logging.error(f"Network error fetching threads: {e}")
except Exception as e:
logging.error(f"Failed to fetch/resolve threads: {e}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không có cơ chế timeout hoặc retry khi gọi API OpenRouter, có thể gây treo nếu API không phản hồi.

Comment thread scripts/ai_reviewer.py
Hãy trả về kết quả là một JSON list thuần túy (không markdown block, không giải thích thêm), mỗi item có format sau:
[
{
"filename": "tên_file",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không kiểm tra độ dài của comment_text trước khi post, có thể vượt quá giới hạn ký tự của GitHub.

Comment thread scripts/ai_reviewer.py
logging.warning("OpenRouter response has empty content.")
return []

content = content.strip()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review: Không xử lý trường hợp event_data không chứa đủ thông tin cần thiết, có thể gây lỗi khi truy cập các key không tồn tại.

hapo-nghialuu added a commit that referenced this pull request Mar 24, 2026
- Add manifest v2 schema with runtime.files array (12 files)
- Copy runtime files with short renamed paths (avoid copyright)
- Implement settings.json merge preserving user config
- Support install (skip existing) and upgrade (refresh) modes
- Fix task ID tracking in parser.cjs (High Priority #3)
- Fix hook deduplication to check all hooks (High Priority #1)
- Add manifest v2 schema validation (High Priority #4)
- Document statusline feature in README

Runtime files:
- status.cjs - Main statusline renderer
- hooks/session.cjs - Session initialization
- hooks/agent.cjs - Subagent context injection
- hooks/usage.cjs - Usage tracking
- hooks/lib/*.cjs - Shared utilities (color, parser, git, config, etc.)

Installer features:
- Idempotent by default (skip existing files)
- Upgrade mode with --upgrade flag (refresh managed files)
- Settings merge without overwriting user config
- Hook deduplication by command identity

Code review: 4,613 LOC reviewed, 0 critical issues, 3 high-priority fixed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants