Test: Verify AI Reviewer on Clean Branch#4
Conversation
| @@ -0,0 +1,388 @@ | |||
| """ | |||
There was a problem hiding this comment.
🤖 AI Review: Không có xử lý lỗi khi OPENROUTER_API_KEY không được cung cấp, dẫn đến lỗi runtime.
|
|
||
| # Configure Logging | ||
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | ||
|
|
There was a problem hiding this comment.
🤖 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.
|
|
||
|
|
||
| def should_review(filename): | ||
| """Check if file should be reviewed based on extension and path.""" |
There was a problem hiding this comment.
🤖 AI Review: Không có xử lý lỗi khi pr.get_files() trả về lỗi, có thể gây crash ứng dụng.
| # Only review added or modified files (not deleted) | ||
| if file.status == 'removed': | ||
| continue | ||
|
|
There was a problem hiding this comment.
🤖 AI Review: Không có kiểm tra tính hợp lệ của thread_id trước khi gọi resolve_thread, có thể gây lỗi nếu thread_id không hợp lệ.
|
|
||
| try: | ||
| response = requests.post(GITHUB_GRAPHQL_URL, json=payload, headers=headers, timeout=30) | ||
| response.raise_for_status() |
There was a problem hiding this comment.
🤖 AI Review: Không có xử lý lỗi khi response từ GraphQL không chứa dữ liệu mong đợi, có thể gây crash ứng dụng.
| } | ||
| """ | ||
| headers = { | ||
| "Authorization": f"Bearer {token}", |
There was a problem hiding this comment.
🤖 AI Review: Không có kiểm tra tính hợp lệ của api_key trước khi khởi tạo OpenAI client, có thể gây lỗi nếu api_key không hợp lệ.
| threads = pr_data.get('reviewThreads', {}).get('nodes', []) | ||
| if not threads: | ||
| logging.info("No review threads found.") | ||
| return |
There was a problem hiding this comment.
🤖 AI Review: Không có xử lý lỗi khi response từ OpenRouter không chứa choices, có thể gây crash ứng dụng.
| logging.error(f"Network error fetching threads: {e}") | ||
| except Exception as e: | ||
| logging.error(f"Failed to fetch/resolve threads: {e}") | ||
|
|
There was a problem hiding this comment.
🤖 AI Review: Không có kiểm tra tính hợp lệ của line_number trước khi gọi pr.create_review_comment, có thể gây lỗi nếu line_number không hợp lệ.
| ) | ||
| except Exception as e: | ||
| logging.error(f"Failed to initialize OpenAI client: {e}") | ||
| return [] |
There was a problem hiding this comment.
🤖 AI Review: Không có xử lý lỗi khi event_data không chứa pull_request, có thể gây crash ứng dụng.
| 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", |
There was a problem hiding this comment.
🤖 AI Review: Không có kiểm tra tính hợp lệ của repo_name trước khi split, có thể gây lỗi nếu repo_name không hợp lệ.
| @@ -0,0 +1,392 @@ | |||
| """ | |||
There was a problem hiding this comment.
🤖 AI Review: Không nên hardcode model name trực tiếp trong code. Nên sử dụng biến môi trường để dễ dàng thay đổi khi cần.
| query = """ | ||
| query($owner: String!, $repo: String!, $prNumber: Int!) { | ||
| repository(owner: $owner, name: $repo) { | ||
| pullRequest(number: $prNumber) { |
There was a problem hiding this comment.
🤖 AI Review: Hàm should_review không kiểm tra trường hợp filename là None hoặc rỗng, có thể gây lỗi khi xử lý.
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
🤖 AI Review: Không có xử lý lỗi khi pr.get_files() trả về None hoặc gặp lỗi mạng, có thể gây crash chương trình.
| threads = pr_data.get('reviewThreads', {}).get('nodes', []) | ||
| if not threads: | ||
| logging.info("No review threads found.") | ||
| return |
There was a problem hiding this comment.
🤖 AI Review: Hàm resolve_thread không kiểm tra response từ GraphQL API, có thể bỏ qua lỗi nếu API trả về dữ liệu không hợp lệ.
| ) | ||
| except Exception as e: | ||
| logging.error(f"Failed to initialize OpenAI client: {e}") | ||
| return [] |
There was a problem hiding this comment.
🤖 AI Review: Hàm analyze_code_with_openrouter không có cơ chế retry khi gọi API thất bại, có thể gây mất dữ liệu nếu lỗi tạm thời.
| logging.warning("OpenRouter response has empty content.") | ||
| return [] | ||
|
|
||
| content = content.strip() |
There was a problem hiding this comment.
🤖 AI Review: Hàm post_comments không kiểm tra giới hạn rate limit của GitHub API, có thể gây lỗi nếu gọi quá nhiều lần trong thời gian ngắn.
|
|
||
| body = f"🤖 **AI Review**: {comment_text}" | ||
|
|
||
| try: |
There was a problem hiding this comment.
🤖 AI Review: Hàm main không có xử lý lỗi cho trường hợp event_data không chứa đủ thông tin cần thiết, có thể gây crash.
| @@ -0,0 +1,397 @@ | |||
| """ | |||
There was a problem hiding this comment.
🤖 AI Review: Không nên sử dụng model free-tier cho production do có thể gặp vấn đề về rate limits và độ ổn định.
| 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" |
There was a problem hiding this comment.
🤖 AI Review: Hàm should_review nên kiểm tra cả trường hợp file bị xóa hoặc không tồn tại.
|
|
||
| def get_pr_diff(repo, pr_number): | ||
| """Fetch PR diff using PyGithub.""" | ||
| pr = repo.get_pull(pr_number) |
There was a problem hiding this comment.
🤖 AI Review: Nên thêm xử lý ngoại lệ cho trường hợp pr.get_files() trả về lỗi hoặc không có dữ liệu.
| query = """ | ||
| query($owner: String!, $repo: String!, $prNumber: Int!) { | ||
| repository(owner: $owner, name: $repo) { | ||
| pullRequest(number: $prNumber) { |
There was a problem hiding this comment.
🤖 AI Review: Hàm resolve_thread nên có cơ chế retry khi gặp lỗi mạng hoặc lỗi tạm thời.
| if 'errors' in data: | ||
| logging.error(f"GraphQL Error fetching threads: {data['errors']}") | ||
| return | ||
|
|
There was a problem hiding this comment.
🤖 AI Review: Nên giới hạn số lượng threads được fetch để tránh quá tải hoặc vượt quá giới hạn API.
| logging.error(f"Network error fetching threads: {e}") | ||
| except Exception as e: | ||
| logging.error(f"Failed to fetch/resolve threads: {e}") | ||
|
|
There was a problem hiding this comment.
🤖 AI Review: Không nên hardcode MODEL_NAME trong code, nên đưa vào biến môi trường để dễ dàng thay đổi.
| 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", |
There was a problem hiding this comment.
🤖 AI Review: Nên validate đầu vào files_data trước khi gửi đến OpenRouter để tránh lỗi không mong muốn.
| if content.endswith("```"): | ||
| content = content[:-3] | ||
|
|
||
| content = content.strip() |
There was a problem hiding this comment.
🤖 AI Review: Nên thêm cơ chế timeout cho request đến OpenRouter để tránh treo ứng dụng.
|
|
||
| body = f"🤖 **AI Review**: {comment_text}" | ||
|
|
||
| try: |
There was a problem hiding this comment.
🤖 AI Review: Hàm post_comments nên kiểm tra quyền truy cập trước khi tạo comment để tránh lỗi không cần thiết.
| event_data = json.load(f) | ||
| except (IOError, json.JSONDecodeError) as e: | ||
| logging.error(f"Failed to read event file: {e}") | ||
| return |
There was a problem hiding this comment.
🤖 AI Review: Nên thêm logging chi tiết hơn cho các bước xử lý trong hàm main để dễ dàng debug.
- 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
No description provided.