LukeMattingly
commited on
Commit
·
c7c05dd
1
Parent(s):
cdc3eac
rename, cleanup, more functionality
Browse files
README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
emoji: ⚡
|
4 |
colorFrom: pink
|
5 |
colorTo: yellow
|
@@ -16,3 +16,4 @@ tags:
|
|
16 |
---
|
17 |
|
18 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
1 |
---
|
2 |
+
title: Github PR Assistant
|
3 |
emoji: ⚡
|
4 |
colorFrom: pink
|
5 |
colorTo: yellow
|
|
|
16 |
---
|
17 |
|
18 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
19 |
+
|
app.py
CHANGED
@@ -1,41 +1,14 @@
|
|
1 |
-
from smolagents import CodeAgent,
|
2 |
import datetime
|
3 |
import requests
|
4 |
import pytz
|
5 |
import yaml
|
6 |
from tools.final_answer import FinalAnswerTool
|
7 |
-
from duckduckgo_search import DDGS
|
8 |
import re
|
9 |
import ast
|
10 |
|
11 |
-
|
12 |
-
|
13 |
from Gradio_UI import GradioUI
|
14 |
|
15 |
-
@tool
|
16 |
-
def search_my_code(github_url:str, code:str)-> str:
|
17 |
-
"""Searches for code in the github repo given it's url using DuckDuckGo.
|
18 |
-
|
19 |
-
Args:
|
20 |
-
github_url: The URL of the GitHub repository where the code resides. (e.g., 'https://github.com/LukeMattingly/huggingface-agents-course', 'https://github.com/upb-lea/reinforcement_learning_course_materials').
|
21 |
-
code: The new code content to update in the repository.
|
22 |
-
|
23 |
-
Returns:
|
24 |
-
A string with top search results for code given a github url.
|
25 |
-
"""
|
26 |
-
try:
|
27 |
-
query = f"{code} site:{github_url}"
|
28 |
-
with DDGS() as ddgs:
|
29 |
-
results = list(ddgs.text(query, max_results=5)) # Get top 5 results
|
30 |
-
|
31 |
-
if results:
|
32 |
-
response = "\n".join([f"{res['title']}: {res['href']}" for res in results])
|
33 |
-
return f"Here is some code from the github repo {github_url}:\n\n{response}"
|
34 |
-
else:
|
35 |
-
return f"No results found for {github_url}."
|
36 |
-
|
37 |
-
except Exception as e:
|
38 |
-
return f"Error searching for code in {github_url}: {str(e)}"
|
39 |
|
40 |
@tool
|
41 |
def get_open_pull_requests(github_url: str) -> str:
|
@@ -185,6 +158,93 @@ def get_file_content(github_url: str, file_path: str) -> str:
|
|
185 |
return response.text
|
186 |
except Exception as e:
|
187 |
return f"Error: {str(e)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
|
189 |
final_answer = FinalAnswerTool()
|
190 |
|
@@ -204,7 +264,7 @@ with open("prompts.yaml", 'r') as stream:
|
|
204 |
|
205 |
agent = CodeAgent(
|
206 |
model=model,
|
207 |
-
tools=[final_answer, get_open_pull_requests, find_todo_comments, get_pr_diff, get_pr_files_changed, detect_code_smells, get_file_content ], ## add your tools here (don't remove final answer)
|
208 |
max_steps=6,
|
209 |
verbosity_level=1,
|
210 |
grammar=None,
|
|
|
1 |
+
from smolagents import CodeAgent, HfApiModel,tool
|
2 |
import datetime
|
3 |
import requests
|
4 |
import pytz
|
5 |
import yaml
|
6 |
from tools.final_answer import FinalAnswerTool
|
|
|
7 |
import re
|
8 |
import ast
|
9 |
|
|
|
|
|
10 |
from Gradio_UI import GradioUI
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
@tool
|
14 |
def get_open_pull_requests(github_url: str) -> str:
|
|
|
158 |
return response.text
|
159 |
except Exception as e:
|
160 |
return f"Error: {str(e)}"
|
161 |
+
|
162 |
+
@tool
|
163 |
+
def security_check_code(code: str) -> str:
|
164 |
+
"""Analyzes the provided code snippet for potential security vulnerabilities.
|
165 |
+
|
166 |
+
Args:
|
167 |
+
code: The source code to be analyzed for common security issues (e.g., hardcoded secrets, unsafe functions).
|
168 |
+
|
169 |
+
Returns:
|
170 |
+
A string listing detected potential security vulnerabilities based on common patterns (e.g., hardcoded credentials,
|
171 |
+
risky usage of functions like eval or os.system, and simple SQL injection risks). If no issues are found, returns a message indicating the code is secure.
|
172 |
+
"""
|
173 |
+
import re
|
174 |
+
issues = []
|
175 |
+
|
176 |
+
# Check for hardcoded credentials (case-insensitive search)
|
177 |
+
secret_patterns = [
|
178 |
+
r'(?i)api[-_]?key\s*=\s*[\'"].+[\'"]',
|
179 |
+
r'(?i)secret\s*=\s*[\'"].+[\'"]',
|
180 |
+
r'(?i)password\s*=\s*[\'"].+[\'"]',
|
181 |
+
r'(?i)token\s*=\s*[\'"].+[\'"]'
|
182 |
+
]
|
183 |
+
for pattern in secret_patterns:
|
184 |
+
matches = re.findall(pattern, code)
|
185 |
+
if matches:
|
186 |
+
issues.append("Potential hardcoded credential(s) found: " + ", ".join(matches))
|
187 |
+
|
188 |
+
# Check for usage of eval() which can be dangerous
|
189 |
+
if "eval(" in code:
|
190 |
+
issues.append("Usage of eval() detected, which can lead to security vulnerabilities if misused.")
|
191 |
+
|
192 |
+
# Check for potential command injection risks with os.system
|
193 |
+
if "os.system(" in code:
|
194 |
+
issues.append("Usage of os.system() detected; consider using safer alternatives to avoid command injection risks.")
|
195 |
+
|
196 |
+
# Check for simple SQL injection patterns (heuristic)
|
197 |
+
sql_injection_patterns = [
|
198 |
+
r"execute\(.+\+.+\)",
|
199 |
+
r"format\(.+%\(.+\)s.+\)"
|
200 |
+
]
|
201 |
+
for pattern in sql_injection_patterns:
|
202 |
+
matches = re.findall(pattern, code)
|
203 |
+
if matches:
|
204 |
+
issues.append("Potential SQL injection risk found in statements: " + ", ".join(matches))
|
205 |
+
|
206 |
+
if issues:
|
207 |
+
return "\n".join(issues)
|
208 |
+
else:
|
209 |
+
return "No obvious security vulnerabilities detected based on heuristic analysis."
|
210 |
+
|
211 |
+
@tool
|
212 |
+
def check_documentation_updates(changed_files: str) -> str:
|
213 |
+
"""Checks whether documentation files have been updated alongside code changes.
|
214 |
+
|
215 |
+
Args:
|
216 |
+
changed_files: A newline-separated string listing the file paths changed in a commit or pull request.
|
217 |
+
|
218 |
+
Returns:
|
219 |
+
A string indicating whether documentation appears to have been updated or if it might be missing.
|
220 |
+
"""
|
221 |
+
files = [f.strip() for f in changed_files.splitlines() if f.strip()]
|
222 |
+
doc_files = [f for f in files if "readme" in f.lower() or "docs" in f.lower()]
|
223 |
+
|
224 |
+
if doc_files:
|
225 |
+
return "Documentation files were updated."
|
226 |
+
else:
|
227 |
+
return "No documentation updates detected. Consider reviewing the docs to ensure they reflect the new changes."
|
228 |
+
|
229 |
+
@tool
|
230 |
+
def lint_code(code: str) -> str:
|
231 |
+
"""Analyzes the provided code snippet for style and potential issues using a linter.
|
232 |
+
|
233 |
+
Args:
|
234 |
+
code: The source code to be analyzed.
|
235 |
+
|
236 |
+
Returns:
|
237 |
+
A string with linting warnings and suggestions for improvement, or a message indicating that no issues were found.
|
238 |
+
"""
|
239 |
+
# This is a placeholder; you could integrate pylint or flake8 via subprocess or an API.
|
240 |
+
# For demonstration, we'll simulate a response.
|
241 |
+
issues = []
|
242 |
+
if "print(" in code:
|
243 |
+
issues.append("Consider removing debug print statements.")
|
244 |
+
if not issues:
|
245 |
+
return "No linting issues found."
|
246 |
+
return "\n".join(issues)
|
247 |
+
|
248 |
|
249 |
final_answer = FinalAnswerTool()
|
250 |
|
|
|
264 |
|
265 |
agent = CodeAgent(
|
266 |
model=model,
|
267 |
+
tools=[final_answer, get_open_pull_requests, find_todo_comments, get_pr_diff, get_pr_files_changed, detect_code_smells, get_file_content, security_check_code, check_documentation_updates, lint_code ], ## add your tools here (don't remove final answer)
|
268 |
max_steps=6,
|
269 |
verbosity_level=1,
|
270 |
grammar=None,
|