mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-05 05:10:38 +08:00
Merge pull request #4 from PullPullers/feat/toggle-open-based-on-line-count-for-todo-section
todo section의 내용이 10줄 이하이면 기본적으로 펼쳐져 있도록 수정
This commit is contained in:
@ -164,7 +164,7 @@ def convert_to_markdown_v2(output_data: dict,
|
|||||||
if gfm_supported:
|
if gfm_supported:
|
||||||
markdown_text += "<table>\n"
|
markdown_text += "<table>\n"
|
||||||
|
|
||||||
todos_summary = output_data['review'].pop('todos_summary', '')
|
todo_summary = output_data['review'].pop('todo_summary', '')
|
||||||
for key, value in output_data['review'].items():
|
for key, value in output_data['review'].items():
|
||||||
if value is None or value == '' or value == {} or value == []:
|
if value is None or value == '' or value == {} or value == []:
|
||||||
if key.lower() not in ['can_be_split', 'key_issues_to_review']:
|
if key.lower() not in ['can_be_split', 'key_issues_to_review']:
|
||||||
@ -260,12 +260,9 @@ def convert_to_markdown_v2(output_data: dict,
|
|||||||
else:
|
else:
|
||||||
return file_ref
|
return file_ref
|
||||||
|
|
||||||
if gfm_supported:
|
def format_todo_items(value: list[TodoItem] | TodoItem) -> str:
|
||||||
markdown_text += f"<tr><td>"
|
markdown_text = ""
|
||||||
if is_value_no(value):
|
if gfm_supported:
|
||||||
markdown_text += f"{emoji} <strong>No TODO sections</strong>"
|
|
||||||
else:
|
|
||||||
markdown_text += f"{emoji} <strong>TODO sections ({len(value)} items)</strong>\n<details><summary>{todos_summary}</summary>\n\n"
|
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
markdown_text += "<ul>\n"
|
markdown_text += "<ul>\n"
|
||||||
for todo_item in value:
|
for todo_item in value:
|
||||||
@ -273,18 +270,35 @@ def convert_to_markdown_v2(output_data: dict,
|
|||||||
markdown_text += "</ul>\n"
|
markdown_text += "</ul>\n"
|
||||||
else:
|
else:
|
||||||
markdown_text += f"<p>{format_todo_item(value)}</p>\n"
|
markdown_text += f"<p>{format_todo_item(value)}</p>\n"
|
||||||
markdown_text += "\n</details>\n"
|
|
||||||
markdown_text += f"</td></tr>\n"
|
|
||||||
else:
|
|
||||||
if is_value_no(value):
|
|
||||||
markdown_text += f"### {emoji} No TODO sections\n\n"
|
|
||||||
else:
|
else:
|
||||||
markdown_text += f"### {emoji} TODO sections ({len(value)} items)\n<details><summary>{todos_summary}</summary>\n\n"
|
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
for todo_item in value:
|
for todo_item in value:
|
||||||
markdown_text += f"- {format_todo_item(todo_item)}\n"
|
markdown_text += f"- {format_todo_item(todo_item)}\n"
|
||||||
else:
|
else:
|
||||||
markdown_text += f"- {format_todo_item(value)}\n"
|
markdown_text += f"- {format_todo_item(value)}\n"
|
||||||
|
return markdown_text
|
||||||
|
|
||||||
|
markdown_todo_items = format_todo_items(value)
|
||||||
|
EXPAND_LINE_THRESHOLD = 10
|
||||||
|
details_open_attr = " open" if markdown_todo_items.count("\n") + 1 <= EXPAND_LINE_THRESHOLD else ""
|
||||||
|
|
||||||
|
todo_entry_label = f"{len(value)} " + "entries" if len(value) > 1 else "entry"
|
||||||
|
if gfm_supported:
|
||||||
|
markdown_text += "<tr><td>"
|
||||||
|
if is_value_no(value):
|
||||||
|
markdown_text += f"{emoji} <strong>No TODO sections</strong>"
|
||||||
|
else:
|
||||||
|
markdown_text += f"{emoji} <strong>TODO sections ({todo_entry_label})</strong>\n"
|
||||||
|
markdown_text += f"<details{details_open_attr}><summary>{todo_summary}</summary>\n\n"
|
||||||
|
markdown_text += markdown_todo_items
|
||||||
|
markdown_text += "\n</details>\n"
|
||||||
|
markdown_text += "</td></tr>\n"
|
||||||
|
else:
|
||||||
|
if is_value_no(value):
|
||||||
|
markdown_text += f"### {emoji} No TODO sections\n\n"
|
||||||
|
else:
|
||||||
|
markdown_text += f"### {emoji} TODO sections ({todo_entry_label})\n<details{details_open_attr}><summary>{todo_summary}</summary>\n\n"
|
||||||
|
markdown_text += markdown_todo_items
|
||||||
markdown_text += "\n</details>\n\n"
|
markdown_text += "\n</details>\n\n"
|
||||||
elif 'can be split' in key_nice.lower():
|
elif 'can be split' in key_nice.lower():
|
||||||
if gfm_supported:
|
if gfm_supported:
|
||||||
|
@ -75,7 +75,7 @@ class KeyIssuesComponentLink(BaseModel):
|
|||||||
class TodoSection(BaseModel):
|
class TodoSection(BaseModel):
|
||||||
relevant_file: str = Field(description="The file containing the TODO comment")
|
relevant_file: str = Field(description="The file containing the TODO comment")
|
||||||
line_range: Tuple[int, int] = Field(description="Start and end line numbers of the TODO comment (inclusive). Must be a tuple of two integers, e.g., (7, 7) for a single line or (7, 10) for a range. Do not use list format [7, 7].")
|
line_range: Tuple[int, int] = Field(description="Start and end line numbers of the TODO comment (inclusive). Must be a tuple of two integers, e.g., (7, 7) for a single line or (7, 10) for a range. Do not use list format [7, 7].")
|
||||||
content: str = Field(description="The content of the TODO comment. Only include actual TODO comments within code comments (e.g., lines starting with '#', '//', '/*', '<!--'). Remove leading 'TODO' prefixes. Include lines like '# TODO', even if empty after prefix removal. Exclude TODOs outside comments or without appropriate prefixes.")
|
content: str = Field(description="The content of the TODO comment. Only include actual TODO comments within code comments (e.g., lines starting with '#', '//', '/*', '<!--'). Remove leading 'TODO' prefixes. Include lines like '# TODO', even if empty after prefix removal. Exclude TODOs outside comments or without appropriate prefixes. Use | block style only when the line range covers multiple lines (e.g., (7, 10)).")
|
||||||
|
|
||||||
{%- if related_tickets %}
|
{%- if related_tickets %}
|
||||||
|
|
||||||
@ -109,18 +109,15 @@ class Review(BaseModel):
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if require_todo_scan %}
|
{%- if require_todo_scan %}
|
||||||
todo_sections: Union[List[TodoSection], str] = Field(description="A list of TODO comments found in the code. Return 'No' (as a string) if there are no TODO comments.")
|
todo_sections: Union[List[TodoSection], str] = Field(description="A list of TODO comments found in the code. Return 'No' (as a string) if there are no TODO comments.")
|
||||||
todos_summary: str = Field(description="When writing TODO section summaries, use this format:
|
todo_summary: str = Field(description="Summarize the functional areas of the TODO comments found in the code.
|
||||||
[count] TODOs found about [functional area based on TODO content]
|
- Focus on describing the *functional areas* of the TODOs, such as:
|
||||||
|
testing, error handling, validation, documentation, performance,
|
||||||
- The [count] is the number of TODO items, equal to the length of the `todo_sections` list.
|
|
||||||
- Functional areas describe what the TODOs are about:
|
|
||||||
testing, error handling, validation, documentation, performance,
|
|
||||||
security, logging, refactoring, API design, UI/UX
|
security, logging, refactoring, API design, UI/UX
|
||||||
|
|
||||||
Example:
|
- Example:
|
||||||
3 TODOs found about input validation and error handling
|
TODO related to input validation and error handling
|
||||||
|
|
||||||
Return 'No' (as a string) if there are no TODO comments.")
|
- Return 'No' (as a string) if there are no TODO comments.")
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if require_can_be_split_review %}
|
{%- if require_can_be_split_review %}
|
||||||
can_be_split: List[SubPR] = Field(min_items=0, max_items=3, description="Can this PR, which contains {{ num_pr_files }} changed files in total, be divided into smaller sub-PRs with distinct tasks that can be reviewed and merged independently, regardless of the order ? Make sure that the sub-PRs are indeed independent, with no code dependencies between them, and that each sub-PR represent a meaningful independent task. Output an empty list if the PR code does not need to be split.")
|
can_be_split: List[SubPR] = Field(min_items=0, max_items=3, description="Can this PR, which contains {{ num_pr_files }} changed files in total, be divided into smaller sub-PRs with distinct tasks that can be reviewed and merged independently, regardless of the order ? Make sure that the sub-PRs are indeed independent, with no code dependencies between them, and that each sub-PR represent a meaningful independent task. Output an empty list if the PR code does not need to be split.")
|
||||||
@ -168,9 +165,9 @@ review:
|
|||||||
- ...
|
- ...
|
||||||
security_concerns: |
|
security_concerns: |
|
||||||
No
|
No
|
||||||
todo_sections:
|
todo_sections: |
|
||||||
No
|
No
|
||||||
todos_summary:
|
todo_summary: |
|
||||||
No
|
No
|
||||||
{%- if require_can_be_split_review %}
|
{%- if require_can_be_split_review %}
|
||||||
can_be_split:
|
can_be_split:
|
||||||
@ -290,9 +287,9 @@ review:
|
|||||||
- ...
|
- ...
|
||||||
security_concerns: |
|
security_concerns: |
|
||||||
No
|
No
|
||||||
todo_sections:
|
todo_sections: |
|
||||||
No
|
No
|
||||||
todos_summary:
|
todo_summary: |
|
||||||
No
|
No
|
||||||
{%- if require_can_be_split_review %}
|
{%- if require_can_be_split_review %}
|
||||||
can_be_split:
|
can_be_split:
|
||||||
|
Reference in New Issue
Block a user