Enhancements in YAML Parsing and Error Handling

PR Type:
Refactoring

PR Description:
This PR focuses on improving the handling and parsing of YAML data in the application. The main changes include:

Refactoring the load_yaml and try_fix_yaml functions in pr_agent/algo/utils.py to improve error handling and make the code more robust.
The load_yaml function now takes a response_text parameter instead of review_text.
The try_fix_yaml function now checks for more keys ('relevant line:', 'suggestion content:', 'relevant file:') to fix the YAML.
In pr_agent/tools/pr_reviewer.py, the load_yaml function is now used to parse the prediction data.
The unit tests in tests/unittest/test_load_yaml.py have been updated to reflect these changes.
The prompts in pr_agent/settings/pr_code_suggestions_prompts.toml have been updated for better readability.

PR Main Files Walkthrough:
 files:

pr_agent/algo/utils.py: Refactored the load_yaml and try_fix_yaml functions to improve error handling and robustness. The load_yaml function now takes a response_text parameter instead of review_text. The try_fix_yaml function now checks for more keys to fix the YAML.
pr_agent/tools/pr_reviewer.py: The load_yaml function is now used to parse the prediction data, replacing the previous direct usage of yaml.load.
tests/unittest/test_load_yaml.py: Updated the unit tests to reflect the changes in the load_yaml and try_fix_yaml functions. Added a new test case for invalid YAML.
pr_agent/settings/pr_code_suggestions_prompts.toml: Updated the prompts for better readability. The YAML output must now be after a newline, indented, with block scalar indicator ('|-').

/describe

Preparing review...

Code suggestions:

{'relevant file': 'pr_agent/algo/utils.py', 'suggestion content': 'Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.', 'existing code': 'try:\n    data = yaml.safe_load(response_text)\nexcept Exception as e:\n    get_logger().error(f"Failed to parse AI prediction: {e}")\n    data = try_fix_yaml(response_text)', 'relevant lines start': '291', 'relevant lines end': '295', 'improved code': 'try:\n    data = yaml.safe_load(response_text)\nexcept yaml.YAMLError as e:\n    get_logger().error(f"Failed to parse AI prediction: {e}")\n    data = try_fix_yaml(response_text)'}

{'relevant file': 'pr_agent/algo/utils.py', 'suggestion content': 'Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.', 'existing code': 'get_logger().error(f"Failed to parse AI prediction: {e}")\nget_logger().info(f"Successfully parsed AI prediction after adding |-\n")\nget_logger().debug(f"Failed to parse AI prediction after adding |-\n")', 'relevant lines start': '294', 'relevant lines end': '314', 'improved code': 'get_logger().error("Failed to parse AI prediction:", e)\nget_logger().info("Successfully parsed AI prediction after adding |-")\nget_logger().debug("Failed to parse AI prediction after adding |-")'}

{'relevant file': 'pr_agent/algo/utils.py', 'suggestion content': 'Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.', 'existing code': "response_text_lines_copy = response_text_lines.copy()\nfor i in range(0, len(response_text_lines_copy)):\n    for key in keys:\n        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:\n            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',\n                                                                              f'{key}: |-\n        ')", 'relevant lines start': '303', 'relevant lines end': '308', 'improved code': "with open(response_text, 'r') as file:\n    response_text_lines_copy = file.readlines()\nfor i, line in enumerate(response_text_lines_copy):\n    for key in keys:\n        if key in line and not '|-' in line:\n            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')"}

{'relevant file': 'pr_agent/algo/utils.py', 'suggestion content': 'Refactor the fallback mechanisms into separate functions for better readability and maintainability.', 'existing code': '# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'\nresponse_text_lines_copy = response_text_lines.copy()\nfor i in range(0, len(response_text_lines_copy)):\n    for key in keys:\n        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:\n            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',\n                                                                              f'{key}: |-\n        ')\ntry:\n    data = yaml.safe_load('\n'.join(response_text_lines_copy))\n    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")\n    return data\nexcept:\n    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")\n# second fallback - try to remove last lines\ndata = {}\nfor i in range(1, len(response_text_lines)):\n    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])\n    try:\n        data = yaml.safe_load(response_text_lines_tmp,)\n        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")\n        break\n    except:', 'relevant lines start': '301', 'relevant lines end': '324', 'improved code': 'def first_fallback(response_text_lines):\n    response_text_lines_copy = response_text_lines.copy()\n    for i in range(0, len(response_text_lines_copy)):\n        for key in keys:\n            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:\n                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',\n                                                                                f'{key}: |-\n        ')\n    return '\n'.join(response_text_lines_copy)\n\ndef second_fallback(response_text_lines):\n    for i in range(1, len(response_text_lines)):\n        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])\n        try:\n            data = yaml.safe_load(response_text_lines_tmp)\n            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")\n            return data\n        except yaml.YAMLError:\n            continue\n    return {}\n\n# Attempt first fallback\nmodified_text = first_fallback(response_text_lines)\ntry:\n    data = yaml.safe_load(modified_text)\n    get_logger().info("Successfully parsed AI prediction after adding |-")\n    return data\nexcept yaml.YAMLError:\n    get_logger().debug("Failed to parse AI prediction after adding |-")\n\n# Attempt second fallback\ndata = second_fallback(response_text_lines)\nif data:\n    return data\nelse:\n    get_logger().error("Failed to parse AI prediction after all fallbacks")\n    return {}'}

Suggestion: Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Suggestion: Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

Suggestion: Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

Suggestion: Refactor the fallback mechanisms into separate functions for better readability and maintainability.
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

File: pr_agent/algo/utils.py
Suggestion: Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

File: pr_agent/algo/utils.py
Suggestion: Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

File: pr_agent/algo/utils.py
Suggestion: Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

File: pr_agent/algo/utils.py
Suggestion: Refactor the fallback mechanisms into separate functions for better readability and maintainability.
Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

File: pr_agent/algo/utils.py
Suggestion: Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  Example code:Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

___
**File:** pr_agent/algo/utils.py
**Suggestion:** Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
**  Example code:**Existing code:
```suggestion
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
```
Improved code:
```suggestion
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")
```

___
**File:** pr_agent/algo/utils.py
**Suggestion:** Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
**  Example code:**Existing code:
```suggestion
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
```
Improved code:
```suggestion
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')
```

___
**File:** pr_agent/algo/utils.py
**Suggestion:** Refactor the fallback mechanisms into separate functions for better readability and maintainability.
**  Example code:**Existing code:
```suggestion
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:
```
Improved code:
```suggestion
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)
def second_fallback(response_text_lines):
for i in range(1, len(response_text_lines)):
response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
try:
data = yaml.safe_load(response_text_lines_tmp)
get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
return data
except yaml.YAMLError:
continue
return {}
Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
data = yaml.safe_load(modified_text)
get_logger().info("Successfully parsed AI prediction after adding |-")
return data
except yaml.YAMLError:
get_logger().debug("Failed to parse AI prediction after adding |-")
Attempt second fallback
data = second_fallback(response_text_lines)
if data:
return data
else:
get_logger().error("Failed to parse AI prediction after all fallbacks")
return {}
</details>
___

File: pr_agent/algo/utils.py
Suggestion: Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  Example code:Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

___
File: pr_agent/algo/utils.py
Suggestion: Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
  Example code:Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

___
File: pr_agent/algo/utils.py
Suggestion: Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
  Example code:Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

___
File: pr_agent/algo/utils.py
Suggestion: Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  Example code:Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

___

File: pr_agent/algo/utils.py
Suggestion: Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  Example code:Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

File: pr_agent/algo/utils.py
Suggestion: Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
  Example code:Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

File: pr_agent/algo/utils.py
Suggestion: Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
  Example code:Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

File: pr_agent/algo/utils.py
Suggestion: Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  Example code:Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

Location: pr_agent/algo/utils.py-291-295
Suggestion: Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  Example code:Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Location: pr_agent/algo/utils.py-294-314
Suggestion: Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
  Example code:Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

Location: pr_agent/algo/utils.py-303-308
Suggestion: Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
  Example code:Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

Location: pr_agent/algo/utils.py-301-324
Suggestion: Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  Example code:Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

Location: pr_agent/algo/utils.py-291-295
Suggestion: Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  Example code:Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Location: pr_agent/algo/utils.py-294-314
Suggestion: Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
  Example code:Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

Location: pr_agent/algo/utils.py-303-308
Suggestion: Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
  Example code:Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

Location: pr_agent/algo/utils.py-301-324
Suggestion: Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  Example code:Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

File: pr_agent/algo/utils.py(301-324)
Suggestion: Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  Example code:Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

File: pr_agent/algo/utils.py(291-295)
Suggestion:Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  Example code:Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

File: pr_agent/algo/utils.py(294-314)
Suggestion:Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
  Example code:Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

File: pr_agent/algo/utils.py(303-308)
Suggestion:Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
  Example code:Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

File: pr_agent/algo/utils.py(301-324)
Suggestion:Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  Example code:Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

File:
pr_agent/algo/utils.py(291-295)
Suggestion:
Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  Example code:
Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

File:
pr_agent/algo/utils.py(294-314)
Suggestion:
Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
  Example code:
Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

File:
pr_agent/algo/utils.py(303-308)
Suggestion:
Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
  Example code:
Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

File:
pr_agent/algo/utils.py(301-324)
Suggestion:
Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  Example code:
Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

🎯 File:
pr_agent/algo/utils.py(291-295)
💡 Suggestion:
Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  📝 Example code:
Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

🎯 File:
pr_agent/algo/utils.py(294-314)
💡 Suggestion:
Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
  📝 Example code:
Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

🎯 File:
pr_agent/algo/utils.py(303-308)
💡 Suggestion:
Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
  📝 Example code:
Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

🎯 File:
pr_agent/algo/utils.py(301-324)
💡 Suggestion:
Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  📝 Example code:
Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

File:
pr_agent/algo/utils.py(291-295)
Suggestion:
Ensure that the YAML parsing errors are specific to help with debugging. Catching a general Exception can mask different issues. Use yaml.YAMLError to catch YAML parsing errors specifically.
  Example code:
Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

File:
pr_agent/algo/utils.py(294-314)
Suggestion:
Avoid using string concatenation in logging and use comma-separated arguments instead for better performance and readability.
  Example code:
Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")
get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
get_logger().error("Failed to parse AI prediction:", e)
get_logger().info("Successfully parsed AI prediction after adding |-")
get_logger().debug("Failed to parse AI prediction after adding |-")

File:
pr_agent/algo/utils.py(303-308)
Suggestion:
Use a context manager to handle file operations to ensure that the file is properly closed after its suite finishes executing.
  Example code:
Existing code:
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')

Improved code:
with open(response_text, 'r') as file:
    response_text_lines_copy = file.readlines()
for i, line in enumerate(response_text_lines_copy):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines_copy[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')

File:
pr_agent/algo/utils.py(301-324)
Suggestion:
Refactor the fallback mechanisms into separate functions for better readability and maintainability.
  Example code:
Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
# second fallback - try to remove last lines
data = {}
for i in range(1, len(response_text_lines)):
    response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
    try:
        data = yaml.safe_load(response_text_lines_tmp,)
        get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
        break
    except:

Improved code:
def first_fallback(response_text_lines):
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')
    return '\n'.join(response_text_lines_copy)

def second_fallback(response_text_lines):
    for i in range(1, len(response_text_lines)):
        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
        try:
            data = yaml.safe_load(response_text_lines_tmp)
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except yaml.YAMLError:
            continue
    return {}

# Attempt first fallback
modified_text = first_fallback(response_text_lines)
try:
    data = yaml.safe_load(modified_text)
    get_logger().info("Successfully parsed AI prediction after adding |-")
    return data
except yaml.YAMLError:
    get_logger().debug("Failed to parse AI prediction after adding |-")

# Attempt second fallback
data = second_fallback(response_text_lines)
if data:
    return data
else:
    get_logger().error("Failed to parse AI prediction after all fallbacks")
    return {}

Preparing review...

Code suggestions
File:
pr_agent/algo/utils.py(291-295)
Suggestion:
Use specific exception handling rather than a generic exception to make the error handling more precise.
  Example code:
Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

File:
pr_agent/algo/utils.py(294-294)
Suggestion:
Avoid using string concatenation in logging and use comma-separated arguments instead for better performance.
  Example code:
Existing code:
get_logger().error(f"Failed to parse AI prediction: {e}")

Improved code:
get_logger().error("Failed to parse AI prediction: %s", e)

File:
pr_agent/algo/utils.py(321-321)
Suggestion:
Remove the trailing comma in the yaml.safe_load function call for consistency and readability.
  Example code:
Existing code:
data = yaml.safe_load(response_text_lines_tmp,)

Improved code:
data = yaml.safe_load(response_text_lines_tmp)

File:
pr_agent/algo/utils.py(322-322)
Suggestion:
Add a break statement after logging the successful parsing of AI prediction to avoid unnecessary iterations.
  Example code:
Existing code:
get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")

Improved code:
get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
break

Preparing review...

Code suggestions
File:
pr_agent/algo/utils.py(290-296)
Suggestion:
Ensure that the 'yaml.safe_load' function is called with a stream that is guaranteed to be a string. The 'response_text' parameter should be checked to ensure it is a string before attempting to load it as YAML.
  Example code:
Existing code:
```suggestion
response_text = response_text.removeprefix('```yaml').rstrip('`')
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)
return data
```
Improved code:
```suggestion
response_text = response_text.removeprefix('```yaml').rstrip('`')
if not isinstance(response_text, str):
    get_logger().error("Expected a string for 'response_text' but got a different type")
    return {}
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)
return data
```

File:
pr_agent/algo/utils.py(291-296)
Suggestion:
Replace the generic 'Exception' with more specific exceptions to avoid catching unintended exceptions and to provide more specific error handling.
  Example code:
Existing code:
```suggestion
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)
return data
```
Improved code:
```suggestion
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)
except Exception as e:
    get_logger().error(f"An unexpected error occurred: {e}")
    data = {}
return data
```

File:
pr_agent/algo/utils.py(303-308)
Suggestion:
Avoid modifying the list you are iterating over. Instead, iterate over a copy of the list or iterate using indices.
  Example code:
Existing code:
```suggestion
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
```
Improved code:
```suggestion
for i, line in enumerate(response_text_lines):
    for key in keys:
        if key in line and not '|-' in line:
            response_text_lines[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')
```

File:
pr_agent/algo/utils.py(309-315)
Suggestion:
Use a context manager to ensure that the logger's file handler is properly closed after logging, especially when logging within a loop or multiple try-except blocks.
  Example code:
Existing code:
```suggestion
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
```
Improved code:
```suggestion
with get_logger() as logger:
    try:
        data = yaml.safe_load('\n'.join(response_text_lines_copy))
        logger.info(f"Successfully parsed AI prediction after adding |-\n")
        return data
    except:
        logger.debug(f"Failed to parse AI prediction after adding |-\n")
```

Preparing review...

Code suggestions
📝 File:
pr_agent/algo/utils.py(289-292)
Suggestion:
Ensure that the 'load_yaml' function strips the correct number of backticks. The current implementation might not work correctly if there are more than three backticks at the end of the 'response_text'.
  Example code:

Existing code:
def load_yaml(response_text: str) -> dict:
    response_text = response_text.removeprefix('```yaml').rstrip('`')
    try:
        data = yaml.safe_load(response_text)

Improved code:
def load_yaml(response_text: str) -> dict:
    response_text = response_text.removeprefix('```yaml').removesuffix('```')
    try:
        data = yaml.safe_load(response_text)

📝 File:
pr_agent/algo/utils.py(298-308)
Suggestion:
Refactor the 'try_fix_yaml' function to avoid modifying the original 'response_text_lines' list directly. This can prevent potential bugs and make the code more readable.
  Example code:

Existing code:
def try_fix_yaml(response_text: str) -> dict:
    response_text_lines = response_text.split('\n')
    keys = ['relevant line:', 'suggestion content:', 'relevant file:']
    response_text_lines_copy = response_text_lines.copy()
    for i in range(0, len(response_text_lines_copy)):
        for key in keys:
            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                                f'{key}: |-\n        ')

Improved code:
def try_fix_yaml(response_text: str) -> dict:
    response_text_lines = response_text.split('\n')
    keys = ['relevant line:', 'suggestion content:', 'relevant file:']
    fixed_lines = []
    for line in response_text_lines:
        for key in keys:
            if key in line and not '|-' in line:
                line = line.replace(f'{key}: ', f'{key}: |-\n        ')
        fixed_lines.append(line)

📝 File:
pr_agent/algo/utils.py(291-295)
Suggestion:
Add specific exception handling for YAML parsing errors instead of catching all exceptions. This will make the error handling more precise and avoid catching unrelated exceptions.
  Example code:

Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

📝 File:
tests/unittest/test_load_yaml.py(34-40)
Suggestion:
The test case 'test_load_invalid_yaml2' expects a list as the output, but the 'load_yaml' function should return a dictionary. Update the expected output to match the correct data structure.
  Example code:

Existing code:
def test_load_invalid_yaml2(self):
    yaml_str = '''\
    - relevant file: src/app.py
      suggestion content: The print statement is outside inside the if __name__ == \
    '''
    expected_output =[{'relevant file': 'src/app.py', 'suggestion content': 'The print statement is outside inside the if __name__ =='}]
    assert load_yaml(yaml_str) == expected_output

Improved code:
def test_load_invalid_yaml2(self):
    yaml_str = '''\
    - relevant file: src/app.py
      suggestion content: The print statement is outside inside the if __name__ == \
    '''
    expected_output = {'Code suggestions': [{'relevant file': 'src/app.py', 'suggestion content': 'The print statement is outside inside the if __name__ =='}]}
    assert load_yaml(yaml_str) == expected_output

Preparing suggestions...

Code Suggestions
📝 File:
pr_agent/algo/utils.py(289-292)
Suggestion:
Ensure that the yaml.safe_load function is called with a stream that can be safely parsed. The current implementation strips the YAML block indicators, which could lead to incorrect parsing if the content starts or ends with backticks unrelated to the YAML block.
  Example code:

--- +++ @@ -2 +2,2 @@-    response_text = response_text.removeprefix('```yaml').rstrip('`')+    if response_text.startswith('```yaml') and response_text.endswith('```'):+        response_text = response_text[7:-3]  # Remove the starting and ending YAML block indicators

📝 File:
pr_agent/algo/utils.py(291-295)
Suggestion:
Refactor the error handling in load_yaml to avoid catching a generic Exception. Instead, catch yaml.YAMLError to be more specific about the type of exceptions that are related to YAML parsing.
  Example code:

--- +++ @@ -3 +3 @@-except Exception as e:+except yaml.YAMLError as e:

📝 File:
pr_agent/algo/utils.py(304-308)
Suggestion:
Instead of using string replacement to add the block scalar indicator '|-', consider parsing the YAML and reconstructing it with the correct formatting to avoid potential issues with incorrect replacements.
  Example code:

--- +++ @@ -3,3 +3,5 @@-        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:-            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',-                                                                              f'{key}: |-\n        ')+        if key in response_text_lines_copy[i] and not response_text_lines_copy[i].strip().endswith('|-'):+            key_index = response_text_lines_copy[i].index(f'{key}: ') + len(f'{key}: ')+            response_text_lines_copy[i] = (response_text_lines_copy[i][:key_index] ++                                           '|-\n        ' ++                                           response_text_lines_copy[i][key_index:].lstrip())

📝 File:
pr_agent/algo/utils.py(298-324)
Suggestion:
The try_fix_yaml function currently attempts to fix YAML parsing issues by adding block scalar indicators and removing lines. However, this approach may not be reliable for all cases. It would be better to use a more robust method for fixing YAML, such as a dedicated parser that can handle common errors and provide more accurate fixes.
  Example code:

--- +++ @@ -1,25 +1 @@-def try_fix_yaml(response_text: str) -> dict:-    response_text_lines = response_text.split('\n')-    keys = ['relevant line:', 'suggestion content:', 'relevant file:']-    # first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'-    response_text_lines_copy = response_text_lines.copy()-    for i in range(0, len(response_text_lines_copy)):-        for key in keys:-            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:-                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',-                                                                                f'{key}: |-\n        ')-    try:-        data = yaml.safe_load('\n'.join(response_text_lines_copy))-        get_logger().info(f"Successfully parsed AI prediction after adding |-\n")-        return data-    except:-        get_logger().debug(f"Failed to parse AI prediction after adding |-\n")-    # second fallback - try to remove last lines-    data = {}-    for i in range(1, len(response_text_lines)):-        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])-        try:-            data = yaml.safe_load(response_text_lines_tmp,)-            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")-            break-        except:+# Suggestion to use a dedicated YAML error correction library or implement a more robust solution

Code Suggestions
📝 File:
pr_agent/algo/utils.py(289-292)
Suggestion:
Ensure that the yaml.safe_load function is called with a stream that can be safely parsed. The current implementation strips the YAML block indicators, which could lead to incorrect parsing if the content starts or ends with backticks unrelated to the YAML block.
  Example code:

-    response_text = response_text.removeprefix('```yaml').rstrip('`')
+    if response_text.startswith('```yaml') and response_text.endswith('```'):
+        response_text = response_text[7:-3]  # Remove the starting and ending YAML block indicators

📝 File:
pr_agent/algo/utils.py(291-295)
Suggestion:
Refactor the error handling in load_yaml to avoid catching a generic Exception. Instead, catch yaml.YAMLError to be more specific about the type of exceptions that are related to YAML parsing.
  Example code:

-except Exception as e:
+except yaml.YAMLError as e:

📝 File:
pr_agent/algo/utils.py(304-308)
Suggestion:
Instead of using string replacement to add the block scalar indicator '|-', consider parsing the YAML and reconstructing it with the correct formatting to avoid potential issues with incorrect replacements.
  Example code:

-        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
-            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
-                                                                              f'{key}: |-\n        ')
+        if key in response_text_lines_copy[i] and not response_text_lines_copy[i].strip().endswith('|-'):
+            key_index = response_text_lines_copy[i].index(f'{key}: ') + len(f'{key}: ')
+            response_text_lines_copy[i] = (response_text_lines_copy[i][:key_index] +
+                                           '|-\n        ' +
+                                           response_text_lines_copy[i][key_index:].lstrip())

📝 File:
pr_agent/algo/utils.py(298-324)
Suggestion:
The try_fix_yaml function currently attempts to fix YAML parsing issues by adding block scalar indicators and removing lines. However, this approach may not be reliable for all cases. It would be better to use a more robust method for fixing YAML, such as a dedicated parser that can handle common errors and provide more accurate fixes.
  Example code:

-def try_fix_yaml(response_text: str) -> dict:
-    response_text_lines = response_text.split('\n')
-    keys = ['relevant line:', 'suggestion content:', 'relevant file:']
-    # first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
-    response_text_lines_copy = response_text_lines.copy()
-    for i in range(0, len(response_text_lines_copy)):
-        for key in keys:
-            if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
-                response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
-                                                                                f'{key}: |-\n        ')
-    try:
-        data = yaml.safe_load('\n'.join(response_text_lines_copy))
-        get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
-        return data
-    except:
-        get_logger().debug(f"Failed to parse AI prediction after adding |-\n")
-    # second fallback - try to remove last lines
-    data = {}
-    for i in range(1, len(response_text_lines)):
-        response_text_lines_tmp = '\n'.join(response_text_lines[:-i])
-        try:
-            data = yaml.safe_load(response_text_lines_tmp,)
-            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
-            break
-        except:
+# Suggestion to use a dedicated YAML error correction library or implement a more robust solution

Preparing suggestions...

Code Suggestions
📝 File:
pr_agent/algo/utils.py(293-295)
Suggestion:
Consider using a context manager for logging to ensure that all logging tags are consistent and to reduce redundancy in logging statements.
  Example code:

Existing code:
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)
return data

Improved code:
except Exception as e:
    with get_logger().contextualize(parse_attempt="initial") as log:
        log.error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)
return data

📝 File:
pr_agent/algo/utils.py(291-295)
Suggestion:
Add specific exception handling for known YAML parsing errors to provide more targeted error messages and recovery options.
  Example code:

Existing code:
try:
    data = yaml.safe_load(response_text)
except Exception as e:
    get_logger().error(f"Failed to parse AI prediction: {e}")
    data = try_fix_yaml(response_text)

Improved code:
try:
    data = yaml.safe_load(response_text)
except yaml.YAMLError as e:
    get_logger().error(f"YAML parsing error: {e}")
    data = try_fix_yaml(response_text)
except Exception as e:
    get_logger().error(f"Unexpected error during YAML parsing: {e}")
    data = try_fix_yaml(response_text)

📝 File:
pr_agent/algo/utils.py(302-314)
Suggestion:
Refactor the fallback mechanisms in try_fix_yaml into separate functions for better readability and maintainability.
  Example code:

Existing code:
# first fallback - try to convert 'relevant line: ...' to relevant line: |-\n        ...'
response_text_lines_copy = response_text_lines.copy()
for i in range(0, len(response_text_lines_copy)):
    for key in keys:
        if key in response_text_lines_copy[i] and not '|-' in response_text_lines_copy[i]:
            response_text_lines_copy[i] = response_text_lines_copy[i].replace(f'{key}: ',
                                                                              f'{key}: |-\n        ')
try:
    data = yaml.safe_load('\n'.join(response_text_lines_copy))
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data
except:
    get_logger().debug(f"Failed to parse AI prediction after adding |-\n")

Improved code:
def _fix_missing_block_indicators(text_lines, keys):
    for i, line in enumerate(text_lines):
        for key in keys:
            if key in line and not '|-' in line:
                text_lines[i] = line.replace(f'{key}: ', f'{key}: |-\n        ')
    return text_lines

def _try_remove_last_lines(text_lines):
    for i in range(1, len(text_lines)):
        try:
            data = yaml.safe_load('\n'.join(text_lines[:-i]))
            get_logger().info(f"Successfully parsed AI prediction after removing {i} lines")
            return data
        except Exception:
            continue
    return {}

# first fallback
response_text_lines_copy = _fix_missing_block_indicators(response_text_lines.copy(), keys)
data = yaml.safe_load('\n'.join(response_text_lines_copy))
if data:
    get_logger().info(f"Successfully parsed AI prediction after adding |-\n")
    return data

# second fallback
data = _try_remove_last_lines(response_text_lines)
if data:
    get_logger().info(f"Successfully parsed AI prediction after removing lines")
    return data

get_logger().debug(f"Failed to parse AI prediction after all fallbacks")
return {}

📝 File:
tests/unittest/test_load_yaml.py(15-15)
Suggestion:
Use more descriptive test method names that reflect the specific scenario being tested.
  Example code:

Existing code:
def test_load_invalid_yaml1(self):
    yaml_str = '''\
    PR Analysis:

Improved code:
def test_load_yaml_with_missing_values(self):
    yaml_str = '''\
    PR Analysis:

Preparing review...

Persistent review updated to latest commit https://github.com/Codium-ai/pr-agent/commit/3504a64269549dd4e276c98432d791c107bea3e0


[BugFix] do not support create list partition cloud table

report an error if user tries to create list partition cloud table
What type of PR is this:

[x] BugFix
[ ] Feature
[ ] Enhancement
[ ] Refactor
[ ] UT
[ ] Doc
[ ] Tool

Checklist:

[x] I have added test cases for my bug fix or my new feature
[ ] This pr will affect users' behaviors
[ ] This pr needs user documentation (for new or modified features or behaviors)

[ ] I have added documentation for my new feature or new function

Bugfix cherry-pick branch check:

[x] I have checked the version labels which the pr will be auto-backported to the target branch

[x] 3.1
[x] 3.0
[ ] 2.5
[ ] 2.4

[FE PR Coverage Check]
:disappointed: fail : 7 / 10 (70.00%)
file detail

path
covered_line
new_line
coverage
not_covered_line_detail

:large_blue_circle:
com/starrocks/server/OlapTableFactory.java
6
9
66.67%
[346, 348, 349]

:large_blue_circle:
com/starrocks/server/LocalMetastore.java
1
1
100.00%
[]

[FE PR Coverage Check]
:disappointed: fail : 7 / 10 (70.00%)
file detail

path
covered_line
new_line
coverage
not_covered_line_detail

:large_blue_circle:
com/starrocks/server/OlapTableFactory.java
6
9
66.67%
[346, 348, 349]

:large_blue_circle:
com/starrocks/server/LocalMetastore.java
1
1
100.00%
[]

[FE PR Coverage Check]
:disappointed: fail : 6 / 9 (66.67%)
file detail

path
covered_line
new_line
coverage
not_covered_line_detail

:large_blue_circle:
com/starrocks/server/OlapTableFactory.java
6
9
66.67%
[346, 348, 349]

@Mergifyio backport branch-3.1

@Mergifyio backport branch-3.0


WIP/Draft SignalR Core Hubs

Internal review URL
Fixes #5626
Working with @1kevgriff on this one

@rachelappel  can you remove WIP/Draft from title?

@Rick-Anderson  It's still WIP/Draft though.


Results?

Are results from some run aggregated or published anywhere?

Hi @mitar maybe you missed the results folder -- the output from various runs are there!
If you'd like to pull those together into a single doc, I'd love to have a README.md in that folder if you're willing to contribute some analysis.


Question about Input Preparation

Thanks for your work and sharing code! Now I want to use my now datasets to test the network.
And how can I can get the processed data like provided?
Best wishes!

Thank you for your interest. Please refer to https://github.com/hzykent/JSENet/issues/2


Add TypeSpec Definition for APIView TreeStyle Parser

TypeSpec Definition for APIView TreeStyle Parser

Overall this is a great step forward. Two things I would like to see:

a script of some kind (though preferably not Powershell) that would allow you to evaluate a provided tokenfile against the generated JSON schema. Every inner-loop dev will need to do that, so that should live here.

@chidozieononiwu the JSON registry that Jonathan was mentioning will probably suffice for this, which is great. It will also simplify ask 2.

Approving to work in a more incremental way, but @tjprescott point about incorporating the TypeSpec and schema into automation should be taken into account seriously CC @maririos @weshaggard

I have updated the tracking issue
https://github.com/Azure/azure-sdk-tools/issues/8517


Migrate from Go to Erlang NIF

This work will take place in a separate branch, based off of the latest release branch. If the work is successful and preferred to the Go solution, it will become the next release branch.
High-level tasks that need to be completed first include:

[x] Create new epic branch
[x] Update CI/CD with the latest and ensure that current code still works
[x] ❌ ut-proj/midiserver#40

[ ] Does the rebar3 plugin support rustler-precompiled?

[x] ❌ Explore the process of creating an Erlang API wrapping Rust bindings with Rustler, e.g.:

[x] https://medium.com/@brucifi/writing-your-first-erlang-nif-in-rust-274374094207
[x] https://github.com/haubie/midiex/blob/main/lib/midiex/backend.ex

[x] ut-proj/midiserver#41

Lower-level tasks:

[x] ut-proj/midiserver#43
[x] Update deps, etc.
[x] Remove all old code referencing midiserver, Go, erlexec, etc.
[x] #56
[x] #57
[x] #58
[x] #53
[ ] #59

Enhancements/cleanup:

[x] When using the rebar3 profile + alias rebar3 as undermidi repl, ensure that undermidi is started automatically
[x] When starting undermidi automatically (or with that repl alias), replace the LFE banner with the undermidi one

Final epic tasks:

[x] Update LICENSE with notes about pulled in software (Sonic Pi Erlang, C/C++, etc.)
[ ] ❌ Update copied files with file header comments for attribution/license (code not included; it's downloaded via git)
[ ] Evaluate effort for level of success/future viability
[ ] ❌ Create new repo for old code, e.g., midiserver-go, and push main there for easy reference/use (the old repo was moved out of ut-proj, back to geomyidia)
[ ] ❌ Update logo (Liffybot?!), merge epic to main, cut release, push to hex.pm

I think the goal of this epic has been fully satisfied -- the remaining work that is to be done or is in progress, can be decoupled from this particular effort.


Update awscrt version to 0.20.11

Update to latest release of the awscrt with recent bug fixes.

Just waiting for all tests to pass


Runtime: Implement wrapper function to call metadata access functions

See here: https://forums.swift.org/t/bitcast-pointer-to-swift-function/32324
This is a runtime function that takes an arbitrary metadata access function along with the request and generics and calls said access function. This is useful for those creating their own Swift metadata libraries to be able to call these access functions.
Right now this is using the Swift cc so that I could play around with something in an interpreter test, but it might make more sense to give this the C cc.
cc: @jckarter @rjmccall

Seems like a reasonable helper to me.
I wonder if the dispatch code could be factored in such a way that the basic logic could be phrased in plain C and exposed into the standard library via SwiftShims. It would be nice if it could be inlined into Swift code. (It probably doesn't make that big a difference though.)

@swift-ci Please smoke test

I originally had this in in SwiftShims, but it couldn't find swift/ABI/Metadata.h. This could be moved into there if we reimplemented things like MetadataResponse and MetadataAccessFunction in there as well.

I've gone ahead and moved this to SwiftShims! Let me know if there's anything else that needs changing.

@swift-ci Please test

⛵

We are seeing failure on Swift in the OS bot - https://ci.swift.org/job/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/2127/
Note this bot is using dylib from the OS not just built.
20:26:03 FAIL: Swift(macosx-x86_64) :: Interpreter/metadata_access.swift (11046 of 13138)
20:26:03 ******************** TEST 'Swift(macosx-x86_64) :: Interpreter/metadata_access.swift' FAILED ********************
20:26:03 Script:
20:26:03 --
20:26:03 : 'RUN: at line 1';   rm -rf "/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/test-macosx-x86_64/Interpreter/Output/metadata_access.swift.tmp" && mkdir -p "/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/test-macosx-x86_64/Interpreter/Output/metadata_access.swift.tmp" && xcrun --toolchain default --sdk '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk' /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/bin/swiftc -target x86_64-apple-macosx10.9  -module-cache-path '/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/swift-test-results/x86_64-apple-macosx10.9/clang-module-cache'  -F '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks' -toolchain-stdlib-rpath -Xlinker -rpath -Xlinker '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks'  -swift-version 4  -Xfrontend -ignore-module-source-info  -F '/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/lib' -Xlinker -rpath -Xlinker '/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/lib' -module-cache-path '/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/swift-test-results/x86_64-apple-macosx10.9/clang-module-cache' /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/swift/test/Interpreter/metadata_access.swift -o /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/test-macosx-x86_64/Interpreter/Output/metadata_access.swift.tmp/a.out -module-name main  && codesign -f -s - /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/test-macosx-x86_64/Interpreter/Output/metadata_access.swift.tmp/a.out && /usr/bin/env DYLD_LIBRARY_PATH='/usr/lib/swift:/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/lib/swift/macosx' LD_LIBRARY_PATH='/usr/lib/swift:/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/lib/swift/macosx:' SIMCTL_CHILD_DYLD_LIBRARY_PATH='/usr/lib/swift:/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/lib/swift/macosx'  /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/test-macosx-x86_64/Interpreter/Output/metadata_access.swift.tmp/a.out | '/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python' '/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/swift/utils/PathSanitizingFileCheck' --sanitize BUILD_DIR='/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64' --sanitize SOURCE_DIR='/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/swift' --use-filecheck '/Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/llvm-macosx-x86_64/bin/FileCheck'  /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/swift/test/Interpreter/metadata_access.swift
20:26:03 --
20:26:03 Exit Code: 2
20:26:03
20:26:03 Command Output (stderr):
20:26:03 --
20:26:03 dyld: lazy symbol binding failed: Symbol not found: __swift_metadataAccessorCall
20:26:03   Referenced from: /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/test-macosx-x86_64/Interpreter/Output/metadata_access.swift.tmp/a.out
20:26:03   Expected in: /usr/lib/swift/libswiftCore.dylib
20:26:03
20:26:03 dyld: Symbol not found: __swift_metadataAccessorCall
20:26:03   Referenced from: /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/swift-macosx-x86_64/test-macosx-x86_64/Interpreter/Output/metadata_access.swift.tmp/a.out
20:26:03   Expected in: /usr/lib/swift/libswiftCore.dylib
20:26:03
20:26:03 FileCheck error: '-' is empty.
20:26:03 FileCheck command line:  /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/buildbot-custom/llvm-macosx-x86_64/bin/FileCheck /Users/buildnode/jenkins/workspace/oss-swift_tools-RA_stdlib-RA-test-simulator-swift-in-the-os/swift/test/Interpreter/metadata_access.swift
20:26:03
20:26:03 --
20:26:03
20:26:03 ********************

@shahmishal is this just a matter of forcing the test to use the just built libraries? How would one achieve that?

@Azoy You will want to update your test so that it only runs on a newer Swift runtime that has your added metadata call. For unreleased features, you can do this by requiring version 9999, by putting a guard #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) else { exit(0) } before your test, and decorating the shim header declaration with an API_AVAILABLE(macos(9999), ios(9999), watchos(9999), tvos(9999)) attribute.

I don't think we should've accepted this; it's a pretty limited API that's never going to handle arbitrary generics well.  What exactly are you trying to do at a high level?
I have some ideas about supporting higher-kinded types as a first-class language feature that would allow you to abstractly pass around uninstantiated generics.  That would naturally result in code-generation like what you've got here, while also working correctly with constrained generics.
Alternatively, if you're trying to do something more inherently reflective, I think we should think much more carefully about how we want to satisfy that.  This API does not seem like a good stepping-stone for that; it's actually extremely unsafe.