LukeMattingly commited on
Commit
9094565
·
1 Parent(s): 0a1f3e9

add additional pull request review capabilities

Browse files
Files changed (1) hide show
  1. app.py +125 -12
app.py CHANGED
@@ -5,6 +5,10 @@ import pytz
5
  import yaml
6
  from tools.final_answer import FinalAnswerTool
7
  from duckduckgo_search import DDGS
 
 
 
 
8
 
9
  from Gradio_UI import GradioUI
10
 
@@ -34,20 +38,132 @@ def search_my_code(github_url:str, code:str)-> str:
34
  return f"Error searching for code in {github_url}: {str(e)}"
35
 
36
  @tool
37
- def get_current_time_in_timezone(timezone: str) -> str:
38
- """A tool that fetches the current local time in a specified timezone.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  Args:
40
- timezone: A string representing a valid timezone (e.g., 'America/New_York').
 
 
 
 
 
41
  """
42
  try:
43
- # Create timezone object
44
- tz = pytz.timezone(timezone)
45
- # Get current time in that timezone
46
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
47
- return f"The current local time in {timezone} is: {local_time}"
 
 
 
 
 
48
  except Exception as e:
49
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  final_answer = FinalAnswerTool()
53
 
@@ -62,9 +178,6 @@ custom_role_conversions=None,
62
  )
63
 
64
 
65
- # Import tool from Hub
66
- image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
67
-
68
  with open("prompts.yaml", 'r') as stream:
69
  prompt_templates = yaml.safe_load(stream)
70
 
 
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
 
 
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:
42
+ """Fetches a list of open pull requests for a given GitHub repository.
43
+
44
+ Args:
45
+ github_url: The URL of the GitHub repository where the pull requests should be retrieved.
46
+ (e.g., 'https://github.com/LukeMattingly/huggingface-agents-course',
47
+ 'https://github.com/upb-lea/reinforcement_learning_course_materials').
48
+
49
+ Returns:
50
+ A string containing the list of open pull requests with their titles and links.
51
+ If no pull requests are open, returns a message indicating no PRs were found.
52
+ """
53
+ try:
54
+ owner_repo = github_url.replace("https://github.com/", "")
55
+ api_url = f"https://api.github.com/repos/{owner_repo}/pulls"
56
+ response = requests.get(api_url)
57
+
58
+ if response.status_code != 200:
59
+ return f"Error fetching PRs: {response.json().get('message', 'Unknown error')}"
60
+
61
+ pull_requests = response.json()
62
+ if not pull_requests:
63
+ return "No open pull requests found."
64
+
65
+ return "\n".join([f"PR #{pr['number']}: {pr['title']} - {pr['html_url']}" for pr in pull_requests])
66
+
67
+ except Exception as e:
68
+ return f"Error retrieving pull requests: {str(e)}"
69
+
70
+ @tool
71
+ def find_todo_comments(code: str) -> str:
72
+ """Finds TODO and FIXME comments in the provided code.
73
+
74
+ Args:
75
+ code: The source code in which to search for TODO and FIXME comments.
76
+
77
+ Returns:
78
+ A string listing all TODO and FIXME comments found in the code.
79
+ If no comments are found, returns a message indicating that no TODO or FIXME comments exist.
80
+ """
81
+ matches = re.findall(r"#\s*(TODO|FIXME):?\s*(.*)", code, re.IGNORECASE)
82
+
83
+ if not matches:
84
+ return "No TODO or FIXME comments found."
85
+
86
+ return "\n".join([f"{match[0]}: {match[1]}" for match in matches])
87
+
88
+ @tool
89
+ def get_pr_diff(github_url: str, pr_number: int) -> str:
90
+ """Fetches the code diff of a specific pull request.
91
+
92
+ Args:
93
+ github_url: The URL of the GitHub repository where the pull request is located.
94
+ pr_number: The pull request number for which the code diff should be retrieved.
95
+
96
+ Returns:
97
+ A string containing the code diff of the specified pull request.
98
+ If the diff cannot be retrieved, returns an error message.
99
+ """
100
+ try:
101
+ owner_repo = github_url.replace("https://github.com/", "")
102
+ api_url = f"https://api.github.com/repos/{owner_repo}/pulls/{pr_number}"
103
+ response = requests.get(api_url, headers={"Accept": "application/vnd.github.v3.diff"})
104
+
105
+ if response.status_code != 200:
106
+ return f"Error fetching PR diff: {response.json().get('message', 'Unknown error')}"
107
+
108
+ return response.text[:1000] # Limit output to avoid overload
109
+
110
+ except Exception as e:
111
+ return f"Error retrieving PR diff: {str(e)}"
112
+
113
+
114
+ @tool
115
+ def get_pr_files_changed(github_url: str, pr_number: int) -> str:
116
+ """Retrieves the list of files changed in a given pull request.
117
+
118
  Args:
119
+ github_url: The URL of the GitHub repository where the pull request is located.
120
+ pr_number: The pull request number for which the changed files should be retrieved.
121
+
122
+ Returns:
123
+ A string listing the files modified in the specified pull request.
124
+ If no files were found or an error occurs, returns an appropriate message.
125
  """
126
  try:
127
+ owner_repo = github_url.replace("https://github.com/", "")
128
+ api_url = f"https://api.github.com/repos/{owner_repo}/pulls/{pr_number}/files"
129
+ response = requests.get(api_url)
130
+
131
+ if response.status_code != 200:
132
+ return f"Error fetching PR files: {response.json().get('message', 'Unknown error')}"
133
+
134
+ files = response.json()
135
+ return "\n".join([file['filename'] for file in files])
136
+
137
  except Exception as e:
138
+ return f"Error retrieving files for PR #{pr_number}: {str(e)}"
139
 
140
+ @tool
141
+ def detect_code_smells(code: str) -> str:
142
+ """Detects common code smells such as long functions and deeply nested loops.
143
+
144
+ Args:
145
+ code: The source code to analyze for potential code smells.
146
+
147
+ Returns:
148
+ A string listing detected code smells, including long functions and deeply nested loops.
149
+ If no code smells are found, returns a message indicating the code is clean.
150
+ """
151
+ try:
152
+ tree = ast.parse(code)
153
+ issues = []
154
+
155
+ for node in ast.walk(tree):
156
+ if isinstance(node, ast.FunctionDef) and len(node.body) > 20:
157
+ issues.append(f"Long function detected: {node.name} ({len(node.body)} lines)")
158
+ if isinstance(node, ast.For) or isinstance(node, ast.While):
159
+ nested_loops = sum(isinstance(n, (ast.For, ast.While)) for n in ast.walk(node))
160
+ if nested_loops > 2:
161
+ issues.append(f"Deeply nested loop detected in function: {node.lineno}")
162
+
163
+ return "\n".join(issues) if issues else "No code smells detected."
164
+
165
+ except Exception as e:
166
+ return f"Error analyzing code: {str(e)}"
167
 
168
  final_answer = FinalAnswerTool()
169
 
 
178
  )
179
 
180
 
 
 
 
181
  with open("prompts.yaml", 'r') as stream:
182
  prompt_templates = yaml.safe_load(stream)
183