-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Problem
DiffScope uses a fixed context window around changed lines. Qodo Merge's approach is smarter: search upward from each hunk for the enclosing function or class boundary, so the context always includes the full function signature and setup code. This dramatically improves the LLM's understanding of what the changed code does.
How Qodo Does It
From pr_agent/algo/git_patch_processing.py, function process_patch_lines():
- Calculate
extended_start = max(1, start - patch_lines_before)(default 5 extra lines) - Within those extra lines, search for section headers (function/class definitions)
- If found, reposition the hunk start to that header
- Asymmetric context: 5 lines before, 1 line after — preceding code matters more
- Validate context lines match between old and new file versions
- Configurable:
max_extra_lines_before_dynamic_context = 10
Example: A change on line 42 inside a function that starts at line 35:
- Fixed context (5 lines): shows lines 37-47 — misses function signature
- Dynamic context: shows lines 35-43 — includes
fn process_payment(order: &Order, amount: f64) -> Result<Receipt>which tells the LLM everything about the types and purpose
Proposed Solution
Enhance context gathering in context.rs / context_helpers.rs:
fn find_enclosing_boundary(
file_content: &str,
hunk_start: usize,
max_search_lines: usize, // default 10
) -> Option<usize> {
// Search upward from hunk_start for function/class/method/impl boundaries
// Use the same language-aware patterns from symbol_index.rs
// Return the line number of the enclosing boundary
}
fn build_dynamic_context(
file_content: &str,
hunk: &DiffHunk,
config: &ContextConfig,
) -> String {
let boundary = find_enclosing_boundary(file_content, hunk.start_line, 10);
let start = boundary.unwrap_or(hunk.start_line.saturating_sub(config.lines_before));
let end = hunk.end_line + config.lines_after; // asymmetric: fewer lines after
extract_lines(file_content, start, end)
}Configuration
context:
dynamic: true # default true
max_search_lines_before: 10
extra_lines_before: 5 # fallback if no boundary found
extra_lines_after: 1 # asymmetric — less afterArchitecture Fit
DiffScope already has:
- Language-aware symbol patterns in
symbol_index.rs(Rust, TypeScript, Python, Go, Java, etc.) ✅ - Context fetcher (
context.rs) ✅ - Function chunker (
function_chunker.rs) ✅
The symbol regex patterns can be reused to detect function/class boundaries during upward search.
Priority
Medium — high impact, low effort. This is a focused improvement to context quality that doesn't require architectural changes.