use synwire_core::{SamplingProvider, SamplingRequest};
const MAX_DIFF_CHARS: usize = 4000;
const SUMMARY_MAX_TOKENS: u32 = 256;
const SUMMARY_TEMPERATURE: f32 = 0.3;
const SYSTEM_PROMPT: &str = "You are a code review assistant. Generate a concise \
one-paragraph summary of the following code change. Focus on what was changed and why.";
pub fn summarize_edit(
diff: &str,
affected_files: &[&str],
sampling: &dyn SamplingProvider,
) -> String {
let fallback = || format!("Files: {}", affected_files.join(", "));
if !sampling.is_available() {
return fallback();
}
let truncated_diff = if diff.len() > MAX_DIFF_CHARS {
let mut end = MAX_DIFF_CHARS;
while !diff.is_char_boundary(end) {
end -= 1;
}
&diff[..end]
} else {
diff
};
let file_list = affected_files.join(", ");
let prompt = format!("Affected files: {file_list}\n\nDiff:\n```\n{truncated_diff}\n```");
let request = SamplingRequest::new(prompt)
.with_system(SYSTEM_PROMPT)
.with_max_tokens(SUMMARY_MAX_TOKENS)
.with_temperature(SUMMARY_TEMPERATURE);
let result = match tokio::runtime::Handle::try_current() {
Ok(handle) => {
if handle.runtime_flavor() == tokio::runtime::RuntimeFlavor::CurrentThread {
return fallback();
}
tokio::task::block_in_place(|| handle.block_on(sampling.sample(request)))
}
Err(_) => return fallback(),
};
match result {
Ok(response) => response.text,
Err(_) => fallback(),
}
}