Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions pr_agent/algo/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,44 @@ def try_fix_yaml(response_text: str,
except:
pass

# 5.5 fallback - try to normalize diff-style removal markers ('-') within list items
response_text_lines_copy = response_text_lines.copy()
modified = False

for i, line in enumerate(response_text_lines_copy):
if line.startswith('+'):
response_text_lines_copy[i] = ' ' + line[1:]
modified = True

# normalize lines starting with '-'. Distinguish real YAML list items from diff deletions.
for i, line in enumerate(response_text_lines_copy):
if not line.startswith('-'):
continue

remainder = line[1:]
if line.startswith('- '):
second_char = remainder[1] if len(remainder) > 1 else ''
if second_char and second_char not in (' ', '\t', '+', '-'):
continue # real list item → keep as-is

# treat it as a diff "removed" marker inside block content
cleaned = remainder
while cleaned and cleaned[0] in ('+', '-'):
cleaned = cleaned[1:]
if cleaned and cleaned[0] not in (' ', '\t'):
cleaned = ' ' + cleaned
if cleaned != line:
response_text_lines_copy[i] = cleaned
modified = True
if modified:
try:
data = yaml.safe_load('\n'.join(response_text_lines_copy))
get_logger().info("Successfully parsed AI prediction after normalizing diff removal markers")
return data
except:
pass


# sixth fallback - replace tabs with spaces
if '\t' in response_text:
response_text_copy = copy.deepcopy(response_text)
Expand Down
33 changes: 33 additions & 0 deletions tests/unittest/test_try_fix_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,36 @@ def test_wrong_indentation_code_block_scalar(self):
'''
expected_output = {'code_suggestions': [{'relevant_file': 'a.c\n', 'existing_code': ' int sum(int a, int b) {\n return a + b;\n }\n\n int sub(int a, int b) {\n return a - b;\n }\n'}]}
assert try_fix_yaml(review_text, first_key='code_suggestions', last_key='existing_code') == expected_output

def test_diff_markers_removed_within_list_item(self):
"""
Ensures diff-style '-' markers nested inside list items are normalised so the YAML parses
into the expected structure.
"""
review_text = '''\
code_suggestions:
- relevant_file: |
example.rb
existing_code: |
+ puts 'hello'
+ puts 'world'
- relevant_file: |
- example.py
- existing_code: |
-+ print('hello')
-+ print('world')
'''
expected_output = {
'code_suggestions': [
{
'relevant_file': 'example.rb\n',
'existing_code': "puts 'hello'\nputs 'world'\n"
},
{
'relevant_file': 'example.py\n',
'existing_code': "print('hello')\nprint('world')\n"
}
]
}

assert try_fix_yaml(review_text, first_key='code_suggestions', last_key='existing_code') == expected_output