Add dynamic context handling in git patch processing

- Introduce `allow_dynamic_context` and `max_extra_lines_before_dynamic_context` settings.
- Adjust context limits dynamically based on section headers.
- Add logging for dynamic context adjustments and section header findings.
This commit is contained in:
mrT23
2024-08-18 17:45:18 +03:00
parent 7cbe797108
commit e9535ea164
2 changed files with 44 additions and 10 deletions

View File

@ -17,6 +17,16 @@ def extend_patch(original_file_str, patch_str, patch_extra_lines_before=0, patch
except UnicodeDecodeError: except UnicodeDecodeError:
return "" return ""
allow_dynamic_context = get_settings().config.allow_dynamic_context
max_extra_lines_before_dynamic_context = get_settings().config.max_extra_lines_before_dynamic_context
patch_extra_lines_before_original = patch_extra_lines_before
patch_extra_lines_before_new = patch_extra_lines_before
if allow_dynamic_context:
if max_extra_lines_before_dynamic_context > patch_extra_lines_before:
patch_extra_lines_before_new = max_extra_lines_before_dynamic_context
else:
get_logger().warning(f"'max_extra_lines_before_dynamic_context' should be greater than 'patch_extra_lines_before'")
original_lines = original_file_str.splitlines() original_lines = original_file_str.splitlines()
len_original_lines = len(original_lines) len_original_lines = len(original_lines)
patch_lines = patch_str.splitlines() patch_lines = patch_str.splitlines()
@ -48,18 +58,40 @@ def extend_patch(original_file_str, patch_str, patch_extra_lines_before=0, patch
section_header = res[4] section_header = res[4]
if patch_extra_lines_before > 0 or patch_extra_lines_after > 0: if patch_extra_lines_before > 0 or patch_extra_lines_after > 0:
extended_start1 = max(1, start1 - patch_extra_lines_before) def _calc_context_limits(patch_lines_before):
extended_size1 = size1 + (start1 - extended_start1) + patch_extra_lines_after extended_start1 = max(1, start1 - patch_lines_before)
extended_start2 = max(1, start2 - patch_extra_lines_before) extended_size1 = size1 + (start1 - extended_start1) + patch_extra_lines_after
extended_size2 = size2 + (start2 - extended_start2) + patch_extra_lines_after extended_start2 = max(1, start2 - patch_lines_before)
if extended_start1 - 1 + extended_size1 > len_original_lines: extended_size2 = size2 + (start2 - extended_start2) + patch_extra_lines_after
# we cannot extend beyond the original file if extended_start1 - 1 + extended_size1 > len_original_lines:
delta_cap = extended_start1 - 1 + extended_size1 - len_original_lines # we cannot extend beyond the original file
extended_size1 = max(extended_size1 - delta_cap, size1) delta_cap = extended_start1 - 1 + extended_size1 - len_original_lines
extended_size2 = max(extended_size2 - delta_cap, size2) extended_size1 = max(extended_size1 - delta_cap, size1)
extended_size2 = max(extended_size2 - delta_cap, size2)
return extended_start1, extended_size1, extended_start2, extended_size2
extended_start1, extended_size1, extended_start2, extended_size2 =\
_calc_context_limits(patch_extra_lines_before_new)
if allow_dynamic_context:
lines_before = original_lines[extended_start1 - 1:start1 - 1]
found_header = False
for i,line, in enumerate(lines_before):
if section_header in line:
found_header = True
extended_start1 = extended_start1 + i
get_logger().debug(f"Found section header in line {i} before the hunk")
section_header = ''
break
if not found_header:
get_logger().debug(f"Section header not found in the extra lines before the hunk")
extended_start1, extended_size1, extended_start2, extended_size2 = \
_calc_context_limits(patch_extra_lines_before_original)
delta_lines = original_lines[extended_start1 - 1:start1 - 1] delta_lines = original_lines[extended_start1 - 1:start1 - 1]
delta_lines = [f' {line}' for line in delta_lines] delta_lines = [f' {line}' for line in delta_lines]
if section_header: if section_header and not allow_dynamic_context:
for line in delta_lines: for line in delta_lines:
if section_header in line: if section_header in line:
section_header = '' # remove section header if it is in the extra delta lines section_header = '' # remove section header if it is in the extra delta lines

View File

@ -20,6 +20,8 @@ max_commits_tokens = 500
max_model_tokens = 32000 # Limits the maximum number of tokens that can be used by any model, regardless of the model's default capabilities. max_model_tokens = 32000 # Limits the maximum number of tokens that can be used by any model, regardless of the model's default capabilities.
custom_model_max_tokens=-1 # for models not in the default list custom_model_max_tokens=-1 # for models not in the default list
# #
allow_dynamic_context=true
max_extra_lines_before_dynamic_context = 10 # will try to include up to 10 extra lines before the hunk in the patch, until we reach an enclosing function or class
patch_extra_lines_before = 3 # Number of extra lines (+3 default ones) to include before each hunk in the patch patch_extra_lines_before = 3 # Number of extra lines (+3 default ones) to include before each hunk in the patch
patch_extra_lines_after = 1 # Number of extra lines (+3 default ones) to include after each hunk in the patch patch_extra_lines_after = 1 # Number of extra lines (+3 default ones) to include after each hunk in the patch
secret_provider="" secret_provider=""