feat(ai): Add comprehensive pre-commit AI code review
Introduces a robust system for running automated, staged diff reviews against various large language models. This feature allows users to submit their changes to external AI services and receive structured feedback on potential bugs, security issues, and maintainability risks before committing. The implementation covers the entire stack: * Backend logic was added to handle API communication with OpenAI, Anthropic, and custom endpoints. * A dedicated parser ensures that complex JSON outputs from LLMs are reliably converted into structured findings (severity, title, description). * New components and UI elements provide a clear visualization of the AI's assessment and actionable suggestions. - Supports multiple major LLM providers (OpenAI, Anthropic) - Parses structured JSON output for consistent review results - Adds dedicated UI dialog to display AI findings and risk level
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
mod cloud;
|
||||
|
||||
pub use cloud::{generate_anthropic, generate_custom, generate_openai};
|
||||
pub use cloud::{
|
||||
generate_anthropic, generate_custom, generate_openai, review_anthropic, review_custom,
|
||||
review_openai,
|
||||
};
|
||||
|
||||
use std::{
|
||||
collections::hash_map::DefaultHasher,
|
||||
@@ -443,3 +446,27 @@ instead of a direct string comparison.\n\n\
|
||||
user.push_str(&format!("Staged diff:\n{diff}"));
|
||||
Ok((system, user))
|
||||
}
|
||||
|
||||
pub(crate) fn build_review_messages(diff: &str) -> Result<(String, String), String> {
|
||||
if diff.trim().is_empty() {
|
||||
return Err("No staged changes available for review.".to_string());
|
||||
}
|
||||
|
||||
const MAX_CHARS: usize = 36_000;
|
||||
let diff = truncate_at_char_boundary(diff, MAX_CHARS);
|
||||
let system = r#"You are a senior software engineer performing a focused pre-commit review.
|
||||
Review only the supplied staged Git diff. Look for concrete correctness bugs, security issues,
|
||||
data loss, regressions, broken edge cases, unsafe error handling, and meaningful performance or
|
||||
maintainability risks. Do not report formatting preferences or speculative nitpicks.
|
||||
|
||||
Return ONLY valid JSON with this exact shape:
|
||||
{"summary":"one concise overall assessment","risk":"low|medium|high","findings":[{"severity":"critical|warning|info","title":"short title","description":"clear evidence and impact","file":"path or null","line":123,"suggestion":"specific safe next step"}]}
|
||||
|
||||
Use the new-file line number from the diff when it is known; otherwise use null. Use null for file
|
||||
when the issue is repository-wide. Maximum 12 findings, ordered critical then warning then info.
|
||||
If no actionable issue exists, return an empty findings array and risk low. Never use markdown,
|
||||
code fences, commentary outside the JSON, or claim that tests were executed."#
|
||||
.to_string();
|
||||
let user = format!("Staged diff to review:\n{diff}");
|
||||
Ok((system, user))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user