mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-03 12:20:38 +08:00
improve backticks
This commit is contained in:
@ -474,4 +474,13 @@ def clip_tokens(text: str, max_tokens: int, add_three_dots=True) -> str:
|
|||||||
return clipped_text
|
return clipped_text
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
get_logger().warning(f"Failed to clip tokens: {e}")
|
get_logger().warning(f"Failed to clip tokens: {e}")
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
def replace_code_tags(text):
|
||||||
|
"""
|
||||||
|
Replace odd instances of ` with <code> and even instances of ` with </code>
|
||||||
|
"""
|
||||||
|
parts = text.split('`')
|
||||||
|
for i in range(1, len(parts), 2):
|
||||||
|
parts[i] = '<code>' + parts[i] + '</code>'
|
||||||
|
return ''.join(parts)
|
@ -47,14 +47,15 @@ Extra instructions from the user:
|
|||||||
======
|
======
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
The output must be a YAML object equivalent to type PRCodeSuggestions, according to the following Pydantic definitions:
|
The output must be a YAML object equivalent to type $PRCodeSuggestions, according to the following Pydantic definitions:
|
||||||
=====
|
=====
|
||||||
class CodeSuggestion(BaseModel):
|
class CodeSuggestion(BaseModel):
|
||||||
relevant_file: str = Field(description="the relevant file full path")
|
relevant_file: str = Field(description="the relevant file full path")
|
||||||
suggestion_content: str = Field(description="an actionable suggestion for meaningfully improving the new code introduced in the PR")
|
suggestion_content: str = Field(description="an actionable suggestion for meaningfully improving the new code introduced in the PR")
|
||||||
{%- if summarize_mode %}
|
{%- if summarize_mode %}
|
||||||
existing_code: str = Field(description="a short code snippet from a '__new hunk__' section to illustrate the relevant existing code. Don't show the line numbers. Shorten parts of the code ('...') if needed")
|
existing_code: str = Field(description="a short code snippet from a '__new hunk__' section to illustrate the relevant existing code. Don't show the line numbers.")
|
||||||
improved_code: str = Field(description="a short code snippet to illustrate the improved code, after applying the suggestion. Shorten parts of the code ('...') if needed")
|
improved_code: str = Field(description="a short code snippet to illustrate the improved code, after applying the suggestion.")
|
||||||
|
one_sentence_summary:str = Field(description="a short summary of the suggestion action, in a single sentence. Focus on the 'what'. Be general, and avoid method or variable names.")
|
||||||
{%- else %}
|
{%- else %}
|
||||||
existing_code: str = Field(description="a code snippet, demonstrating the relevant code lines from a '__new hunk__' section. It must be contiguous, correctly formatted and indented, and without line numbers")
|
existing_code: str = Field(description="a code snippet, demonstrating the relevant code lines from a '__new hunk__' section. It must be contiguous, correctly formatted and indented, and without line numbers")
|
||||||
improved_code: str = Field(description="a new code snippet, that can be used to replace the relevant lines in '__new hunk__' code. Replacement suggestions should be complete, correctly formatted and indented, and without line numbers")
|
improved_code: str = Field(description="a new code snippet, that can be used to replace the relevant lines in '__new hunk__' code. Replacement suggestions should be complete, correctly formatted and indented, and without line numbers")
|
||||||
@ -75,12 +76,23 @@ code_suggestions:
|
|||||||
src/file1.py
|
src/file1.py
|
||||||
suggestion_content: |-
|
suggestion_content: |-
|
||||||
Add a docstring to func1()
|
Add a docstring to func1()
|
||||||
|
{%- if summarize_mode %}
|
||||||
|
existing_code: |-
|
||||||
|
def func1():
|
||||||
|
improved_code: |-
|
||||||
|
...
|
||||||
|
one_sentence_summary: |-
|
||||||
|
...
|
||||||
|
relevant_lines_start: 12
|
||||||
|
relevant_lines_end: 12
|
||||||
|
{%- else %}
|
||||||
existing_code: |-
|
existing_code: |-
|
||||||
def func1():
|
def func1():
|
||||||
relevant_lines_start: 12
|
relevant_lines_start: 12
|
||||||
relevant_lines_end: 12
|
relevant_lines_end: 12
|
||||||
improved_code: |-
|
improved_code: |-
|
||||||
...
|
...
|
||||||
|
{%- endif %}
|
||||||
label: |-
|
label: |-
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
@ -8,7 +8,7 @@ from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
|
|||||||
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
|
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, get_pr_multi_diffs, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, get_pr_multi_diffs, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.algo.utils import load_yaml
|
from pr_agent.algo.utils import load_yaml, replace_code_tags
|
||||||
from pr_agent.config_loader import get_settings
|
from pr_agent.config_loader import get_settings
|
||||||
from pr_agent.git_providers import get_git_provider
|
from pr_agent.git_providers import get_git_provider
|
||||||
from pr_agent.git_providers.git_provider import get_main_pr_language
|
from pr_agent.git_providers.git_provider import get_main_pr_language
|
||||||
@ -327,7 +327,7 @@ class PRCodeSuggestions:
|
|||||||
for label, suggestions in suggestions_labels.items():
|
for label, suggestions in suggestions_labels.items():
|
||||||
pr_body += f"""<tr><td><strong>{label}</strong></td>"""
|
pr_body += f"""<tr><td><strong>{label}</strong></td>"""
|
||||||
pr_body += f"""<td>"""
|
pr_body += f"""<td>"""
|
||||||
pr_body += f"""<details><summary>{len(suggestions)} suggestions</summary>"""
|
# pr_body += f"""<details><summary>{len(suggestions)} suggestions</summary>"""
|
||||||
pr_body += f"""<table>"""
|
pr_body += f"""<table>"""
|
||||||
for suggestion in suggestions:
|
for suggestion in suggestions:
|
||||||
|
|
||||||
@ -344,83 +344,43 @@ class PRCodeSuggestions:
|
|||||||
# add html table for each suggestion
|
# add html table for each suggestion
|
||||||
|
|
||||||
suggestion_content = suggestion['suggestion_content'].rstrip().rstrip()
|
suggestion_content = suggestion['suggestion_content'].rstrip().rstrip()
|
||||||
|
# backticks
|
||||||
|
suggestion_content = replace_code_tags(suggestion_content)
|
||||||
|
|
||||||
suggestion_content = insert_br_after_x_chars(suggestion_content, 90)
|
suggestion_content = insert_br_after_x_chars(suggestion_content, 90)
|
||||||
# pr_body += f"<tr><td><details><summary>{suggestion_content}</summary>"
|
# pr_body += f"<tr><td><details><summary>{suggestion_content}</summary>"
|
||||||
existing_code = suggestion['existing_code'].rstrip()+"\n"
|
existing_code = suggestion['existing_code'].rstrip()+"\n"
|
||||||
improved_code = suggestion['improved_code'].rstrip()+"\n"
|
improved_code = suggestion['improved_code'].rstrip()+"\n"
|
||||||
language_name = "python"
|
|
||||||
diff = difflib.unified_diff(existing_code.split('\n'),
|
|
||||||
improved_code.split('\n'))
|
|
||||||
patch_orig = "\n".join(diff)
|
|
||||||
print(patch_orig)
|
|
||||||
patch = "\n".join(patch_orig.splitlines()[5:]).strip('\n')
|
|
||||||
extension_s = suggestion['relevant_file'].rsplit('.')[-1]
|
|
||||||
if extension_s and (extension_s in extension_to_language):
|
|
||||||
language_name = extension_to_language[extension_s]
|
|
||||||
|
|
||||||
if len(suggestions) > 1:
|
diff = difflib.unified_diff(existing_code.split('\n'),
|
||||||
example_code = "<details> <summary>Preview code:</summary>\n\n"
|
improved_code.split('\n'), n=999)
|
||||||
else:
|
patch_orig = "\n".join(diff)
|
||||||
example_code = ""
|
patch = "\n".join(patch_orig.splitlines()[5:]).strip('\n')
|
||||||
example_code += f"___\n\n"
|
|
||||||
if len(suggestions) == 1:
|
example_code = ""
|
||||||
example_code +="Preview code:\n"
|
|
||||||
example_code += f"```diff\n{patch}\n```\n"
|
example_code += f"```diff\n{patch}\n```\n"
|
||||||
# example_code += f"Existing code:\n```{language_name}\n{existing_code}\n```\n"
|
|
||||||
# example_code += f"Improved code:\n```{language_name}\n{improved_code}\n```\n"
|
pr_body += f"""<tr><td>"""
|
||||||
if len(suggestions) > 1:
|
suggestion_summary = suggestion['one_sentence_summary'].strip()
|
||||||
example_code += "</details>\n"
|
suggestion_summary= suggestion_summary + max((77-len(suggestion_summary)), 0)*" "
|
||||||
|
pr_body += f"""\n\n<details><summary>{suggestion_summary}</summary>\n\n___\n\n"""
|
||||||
|
|
||||||
pr_body += f"""
|
pr_body += f"""
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
|
|
||||||
**{suggestion_content}**
|
**{suggestion_content}**
|
||||||
|
|
||||||
[{relevant_file} {range_str}]({code_snippet_link})
|
[{relevant_file} {range_str}]({code_snippet_link})
|
||||||
|
|
||||||
{example_code}
|
{example_code}
|
||||||
</td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
"""
|
"""
|
||||||
|
pr_body += f"</details>"
|
||||||
|
pr_body += f"</td></tr>"
|
||||||
|
|
||||||
pr_body += """</table>"""
|
pr_body += """</table>"""
|
||||||
pr_body += "</details>"
|
# pr_body += "</details>"
|
||||||
pr_body += """</td></tr>"""
|
pr_body += """</td></tr>"""
|
||||||
pr_body += """</tr></tbody></table>"""
|
pr_body += """</tr></tbody></table>"""
|
||||||
# for s in data['code_suggestions']:
|
|
||||||
# try:
|
|
||||||
# extension_s = s['relevant_file'].rsplit('.')[-1]
|
|
||||||
# code_snippet_link = self.git_provider.get_line_link(s['relevant_file'], s['relevant_lines_start'],
|
|
||||||
# s['relevant_lines_end'])
|
|
||||||
# label = s['label'].strip()
|
|
||||||
# data_markdown += f"\n💡 [{label}]\n\n**{s['suggestion_content'].rstrip().rstrip()}**\n\n"
|
|
||||||
# if code_snippet_link:
|
|
||||||
# data_markdown += f" File: [{s['relevant_file']} ({s['relevant_lines_start']}-{s['relevant_lines_end']})]({code_snippet_link})\n\n"
|
|
||||||
# else:
|
|
||||||
# data_markdown += f"File: {s['relevant_file']} ({s['relevant_lines_start']}-{s['relevant_lines_end']})\n\n"
|
|
||||||
# if self.git_provider.is_supported("gfm_markdown"):
|
|
||||||
# data_markdown += "<details> <summary> Example code:</summary>\n\n"
|
|
||||||
# data_markdown += f"___\n\n"
|
|
||||||
# language_name = "python"
|
|
||||||
# if extension_s and (extension_s in extension_to_language):
|
|
||||||
# language_name = extension_to_language[extension_s]
|
|
||||||
# data_markdown += f"Existing code:\n```{language_name}\n{s['existing_code'].rstrip()}\n```\n"
|
|
||||||
# data_markdown += f"Improved code:\n```{language_name}\n{s['improved_code'].rstrip()}\n```\n"
|
|
||||||
# if self.git_provider.is_supported("gfm_markdown"):
|
|
||||||
# data_markdown += "</details>\n"
|
|
||||||
# data_markdown += "\n___\n\n"
|
|
||||||
#
|
|
||||||
# pr_body += f"""<tr><td><b>{label}</b></td><td><a href="{code_snippet_link}">{s['relevant_file']}</a></td></tr>"""
|
|
||||||
# # in the right side of the table, add two collapsable sections with the existing and improved code
|
|
||||||
# pr_body += f"""<tr><td></td><td><details><summary>Existing code</summary><pre><code>{s['existing_code'].rstrip()}</code></pre></details></td></tr>"""
|
|
||||||
# pr_body += f"""<tr><td></td><td><details><summary>Improved code</summary><pre><code>{s['improved_code'].rstrip()}</code></pre></details></td></tr>"""
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# except Exception as e:
|
|
||||||
# get_logger().error(f"Could not parse suggestion: {s}, error: {e}")
|
|
||||||
self.git_provider.publish_comment(pr_body)
|
self.git_provider.publish_comment(pr_body)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
get_logger().info(f"Failed to publish summarized code suggestions, error: {e}")
|
get_logger().info(f"Failed to publish summarized code suggestions, error: {e}")
|
||||||
|
Reference in New Issue
Block a user