diff --git a/docs/docs/tools/describe.md b/docs/docs/tools/describe.md index d929679c..1ade6c56 100644 --- a/docs/docs/tools/describe.md +++ b/docs/docs/tools/describe.md @@ -124,6 +124,10 @@ This option is enabled by default via the `pr_description.enable_pr_diagram` par enable_semantic_files_types If set to true, "Changes walkthrough" section will be generated. Default is true. + + file_table_collapsible_open_by_default + If set to true, the file list in the "Changes walkthrough" section will be open by default. If set to false, it will be closed by default. Default is false. + collapsible_file_list If set to true, the file list in the "Changes walkthrough" section will be collapsible. If set to "adaptive", the file list will be collapsible only if there are more than 8 files. Default is "adaptive". diff --git a/pr_agent/algo/utils.py b/pr_agent/algo/utils.py index 00d52a14..9b924554 100644 --- a/pr_agent/algo/utils.py +++ b/pr_agent/algo/utils.py @@ -70,7 +70,8 @@ class ReasoningEffort(str, Enum): class PRDescriptionHeader(str, Enum): - CHANGES_WALKTHROUGH = "### **Changes walkthrough** 📝" + DIAGRAM_WALKTHROUGH = "Diagram Walkthrough" + FILE_WALKTHROUGH = "File Walkthrough" def get_setting(key: str) -> Any: @@ -1284,14 +1285,35 @@ def process_description(description_full: str) -> Tuple[str, List]: if not description_full: return "", [] - description_split = description_full.split(PRDescriptionHeader.CHANGES_WALKTHROUGH.value) - base_description_str = description_split[0] - changes_walkthrough_str = "" - files = [] - if len(description_split) > 1: - changes_walkthrough_str = description_split[1] + # description_split = description_full.split(PRDescriptionHeader.FILE_WALKTHROUGH.value) + if PRDescriptionHeader.FILE_WALKTHROUGH.value in description_full: + try: + # FILE_WALKTHROUGH are presented in a collapsible section in the description + regex_pattern = r'\s*\s*

\s*' + re.escape(PRDescriptionHeader.FILE_WALKTHROUGH.value) + r'\s*

\s*
' + description_split = re.split(regex_pattern, description_full, maxsplit=1, flags=re.DOTALL) + + # If the regex pattern is not found, fallback to the previous method + if len(description_split) == 1: + get_logger().debug("Could not find regex pattern for file walkthrough, falling back to simple split") + description_split = description_full.split(PRDescriptionHeader.FILE_WALKTHROUGH.value, 1) + except Exception as e: + get_logger().warning(f"Failed to split description using regex, falling back to simple split: {e}") + description_split = description_full.split(PRDescriptionHeader.FILE_WALKTHROUGH.value, 1) + + if len(description_split) < 2: + get_logger().error("Failed to split description into base and changes walkthrough", artifact={'description': description_full}) + return description_full.strip(), [] + + base_description_str = description_split[0].strip() + changes_walkthrough_str = "" + files = [] + if len(description_split) > 1: + changes_walkthrough_str = description_split[1] + else: + get_logger().debug("No changes walkthrough found") else: - get_logger().debug("No changes walkthrough found") + base_description_str = description_full.strip() + return base_description_str, [] try: if changes_walkthrough_str: @@ -1314,18 +1336,20 @@ def process_description(description_full: str) -> Tuple[str, List]: try: if isinstance(file_data, tuple): file_data = file_data[0] - pattern = r'
\s*(.*?)\s*
(.*?).*?
\s*
\s*(.*?)\s*
  • (.*?)
  • ' + pattern = r'
    \s*(.*?)\s*
    (.*?).*?
    \s*
    \s*(.*?)\s*(?:
  • |•)(.*?)
  • ' res = re.search(pattern, file_data, re.DOTALL) if not res or res.lastindex != 4: pattern_back = r'
    \s*(.*?)
    (.*?).*?
    \s*
    \s*(.*?)\n\n\s*(.*?)
    ' res = re.search(pattern_back, file_data, re.DOTALL) if not res or res.lastindex != 4: - pattern_back = r'
    \s*(.*?)\s*
    (.*?).*?
    \s*
    \s*(.*?)\s*-\s*(.*?)\s*
    ' # looking for hyphen ('- ') + pattern_back = r'
    \s*(.*?)\s*
    (.*?).*?
    \s*
    \s*(.*?)\s*-\s*(.*?)\s*
    ' # looking for hypen ('- ') res = re.search(pattern_back, file_data, re.DOTALL) if res and res.lastindex == 4: short_filename = res.group(1).strip() short_summary = res.group(2).strip() long_filename = res.group(3).strip() + if long_filename.endswith('