-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat(improve): load repo best_practices.md in OSS (#2377) #2382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| from starlette_context import context | ||
|
|
||
| from pr_agent.config_loader import get_settings | ||
| from pr_agent.log import get_logger | ||
|
|
||
|
|
||
| def load_repo_best_practices_md(git_provider, tool_name: str = "improve") -> str: | ||
| """Fetch best_practices.md from the repo default branch. | ||
|
|
||
| Returns text (possibly truncated to ``[best_practices].max_lines_allowed``) | ||
| or an empty string when disabled, missing, or unreadable. Result is cached | ||
| in starlette_context for the duration of the request so multiple tools | ||
| share a single fetch. | ||
| """ | ||
| settings = get_settings() | ||
| if not settings.get("best_practices.enable_repo_best_practices_md", True): | ||
| return "" | ||
| try: | ||
| cached = context.get("best_practices_md", None) | ||
| except Exception: | ||
| cached = None | ||
| if cached is not None: | ||
| return cached | ||
| file_path = settings.get("best_practices.repo_best_practices_md_path", "best_practices.md") or "best_practices.md" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1. load_repo_best_practices_md line too long The new file_path = ... assignment exceeds the repository’s 120-character Python line-length limit, which will fail Ruff (E501) and violates the repo style requirements. Agent Prompt
|
||
| raw = b"" | ||
| try: | ||
| raw = git_provider.get_pr_agent_repo_custom_file(file_path) or b"" | ||
| except Exception as e: | ||
| get_logger().warning(f"Failed to fetch {file_path} from repo: {e}") | ||
| if isinstance(raw, (bytes, bytearray)): | ||
| text = raw.decode("utf-8", errors="replace") | ||
| else: | ||
| text = str(raw or "") | ||
| if not text.strip(): | ||
| try: | ||
| context["best_practices_md"] = "" | ||
| except Exception: | ||
| pass | ||
| return "" | ||
| line_count = text.count("\n") + 1 | ||
| get_logger().info( | ||
| f"Loaded {file_path} from repo ({len(text)} bytes, {line_count} lines) for '{tool_name}' tool" | ||
| ) | ||
| raw_max_lines = settings.get("best_practices.max_lines_allowed", 800) | ||
| try: | ||
| max_lines = int(raw_max_lines) if raw_max_lines else 800 | ||
| except (TypeError, ValueError): | ||
| get_logger().warning( | ||
| f"Invalid best_practices.max_lines_allowed={raw_max_lines!r}; falling back to 800" | ||
| ) | ||
| max_lines = 800 | ||
| lines = text.splitlines() | ||
| if len(lines) > max_lines: | ||
| get_logger().warning( | ||
| f"Truncating {file_path} from {len(lines)} to {max_lines} lines " | ||
| f"(see [best_practices].max_lines_allowed)" | ||
| ) | ||
| text = "\n".join(lines[:max_lines]) | ||
| try: | ||
| context["best_practices_md"] = text | ||
| except Exception: | ||
| pass | ||
| return text | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -174,6 +174,21 @@ def get_repo_settings(self): | |
| get_logger().error(f"Failed to get repo settings, error: {e}") | ||
| return "" | ||
|
|
||
| def get_pr_agent_repo_custom_file(self, file_path: str) -> bytes: | ||
| try: | ||
| contents = self.azure_devops_client.get_item_content( | ||
| repository_id=self.repo_slug, | ||
| project=self.workspace_slug, | ||
| download=False, | ||
| include_content_metadata=False, | ||
| include_content=True, | ||
| path=file_path, | ||
| ) | ||
| chunks = [c if isinstance(c, (bytes, bytearray)) else str(c).encode("utf-8") for c in contents] | ||
| return b"".join(chunks) | ||
|
Comment on lines
+187
to
+188
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2. Azure chunks comprehension too long The added list comprehension for chunks is on a single line that exceeds the repository’s 120-character limit, risking Ruff (E501) failures and reducing readability. Agent Prompt
|
||
| except Exception: | ||
| return b"" | ||
|
|
||
| def get_files(self): | ||
| files = [] | ||
| for i in self.azure_devops_client.get_pull_request_commits( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.