acecalisto3 commited on
Commit
a7252e1
·
verified ·
1 Parent(s): 5654a45

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +117 -284
app.py CHANGED
@@ -1,9 +1,8 @@
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
- import os
4
- import requests
5
  from transformers import pipeline
6
  from sentence_transformers import SentenceTransformer, util
 
 
7
  import logging
8
 
9
  # Configure logging for detailed insights
@@ -11,8 +10,8 @@ logging.basicConfig(level=logging.INFO)
11
 
12
  # Constants for enhanced organization
13
  GITHUB_API_BASE_URL = "https://api.github.com/repos"
14
- DEFAULT_MODEL = "microsoft/CodeBERT-base" # Robust default model selection
15
- MAX_RELATED_ISSUES = 3
16
 
17
  # Hugging Face Inference Client
18
  client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
@@ -20,126 +19,59 @@ client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
20
  # Load a pre-trained model for sentence similarity
21
  similarity_model = SentenceTransformer('all-mpnet-base-v2')
22
 
23
- ### Function to analyze issues and provide solutions
24
  def analyze_issues(issue_text: str, model_name: str, severity: str = None, programming_language: str = None) -> str:
25
- """
26
- Analyzes issues and provides comprehensive solutions using a specified language model.
27
-
28
- Args:
29
- issue_text (str): The detailed description of the issue.
30
- model_name (str): The name of the language model to use for analysis.
31
- severity (str, optional): The severity level of the issue (e.g., "Critical", "Major"). Defaults to None.
32
- programming_language (str, optional): The programming language relevant to the issue. Defaults to None.
33
-
34
- Returns:
35
- str: A structured analysis of the issue, including problem summary, root cause, solution options,
36
- recommended solution, implementation steps, and verification steps.
37
- """
38
- logging.info(f"Analyzing issue: '{issue_text}' with model: '{model_name}'")
39
-
40
- # Construct a detailed prompt for the language model
41
- prompt = f"""Issue: {issue_text}
42
- Severity: {severity if severity else "Not specified"}
43
- Programming Language: {programming_language if programming_language else "Not specified"}
44
-
45
- Please provide a comprehensive resolution in the following format:
46
-
47
- ## Problem Summary:
48
- (Concise summary of the issue)
49
-
50
- ## Root Cause Analysis:
51
- (Possible reasons for the issue)
52
-
53
- ## Solution Options:
54
- 1. **Option 1:** (Description)
55
- - Pros: (Advantages)
56
- - Cons: (Disadvantages)
57
- 2. **Option 2:** (Description)
58
- - Pros: (Advantages)
59
- - Cons: (Disadvantages)
60
-
61
- ## Recommended Solution:
62
- (The best solution with justification)
63
-
64
- ## Implementation Steps:
65
- 1. (Step 1)
66
- 2. (Step 2)
67
- 3. (Step 3)
68
-
69
- ## Verification Steps:
70
- 1. (Step 1)
71
- 2. (Step 2)
72
- """
73
-
74
- try:
75
- nlp = pipeline("text-generation", model=model_name, max_length=1000)
76
- logging.info(f"Pipeline created with model: '{model_name}'")
77
- result = nlp(prompt)
78
- logging.info(f"Model output: {result}")
79
- return result[0]['generated_text']
80
- except Exception as e:
81
- logging.error(f"Error analyzing issue with model '{model_name}': {e}")
82
- return f"Error analyzing issue. Please try again later." # User-friendly error message
83
-
84
- ### Function to find related issues
85
  def find_related_issues(issue_text: str, issues: list) -> list:
86
- """
87
- Finds semantically related issues from a list of issues based on the input issue text.
88
-
89
- Args:
90
- issue_text (str): The text of the issue for which to find related issues.
91
- issues (list): A list of issues, where each issue is a dictionary with at least a 'title' key.
92
-
93
- Returns:
94
- list: A list of tuples, each containing a related issue (dictionary) and its similarity score to the input issue.
95
- The list is sorted by similarity in descending order, limited to MAX_RELATED_ISSUES.
96
- """
97
- logging.info(f"Finding related issues for: '{issue_text}'")
98
  issue_embedding = similarity_model.encode(issue_text)
99
- related_issues = []
 
 
 
100
 
101
- for issue in issues:
102
- title_embedding = similarity_model.encode(issue['title'])
103
- similarity = util.cos_sim(issue_embedding, title_embedding)[0][0]
104
- related_issues.append((issue, similarity))
105
 
106
- related_issues = sorted(related_issues, key=lambda x: x[1], reverse=True)[:MAX_RELATED_ISSUES]
107
- logging.info(f"Found related issues: {related_issues}")
108
  return related_issues
109
 
110
- ### Function to fetch GitHub issues
111
  def fetch_github_issues(github_api_token: str, github_username: str, github_repository: str) -> list:
112
- """
113
- Fetches issues from a specified GitHub repository using the GitHub API.
114
-
115
- Args:
116
- github_api_token (str): The user's GitHub API token for authentication.
117
- github_username (str): The username of the GitHub account owning the repository.
118
- github_repository (str): The name of the GitHub repository.
119
-
120
- Returns:
121
- list: A list of dictionaries, where each dictionary represents a GitHub issue with its details.
122
-
123
- Raises:
124
- Exception: If there's an error fetching issues from the GitHub API.
125
- """
126
- logging.info(f"Fetching GitHub issues for: '{github_username}/{github_repository}'")
127
  url = f"{GITHUB_API_BASE_URL}/{github_username}/{github_repository}/issues"
128
- headers = {
129
- "Authorization": f"Bearer {github_api_token}",
130
- "Accept": "application/vnd.github.v3+json"
131
- }
132
  response = requests.get(url, headers=headers)
133
 
134
- if response.status_code == 200:
135
- issues = response.json()
136
- logging.info(f"Fetched issues: {issues}")
137
- return issues
138
- else:
139
- logging.error(f"Error fetching issues: Status Code {response.status_code}, Response: {response.text}")
140
- raise Exception(f"Error fetching GitHub issues. Please check your credentials and repository.")
141
 
142
- ### Function to handle chat responses
143
  def respond(
144
  command: str,
145
  history: list[tuple[str, str]],
@@ -154,161 +86,62 @@ def respond(
154
  severity: str,
155
  programming_language: str,
156
  ) -> str:
157
- """
158
- Handles user commands and generates responses using the selected language model.
159
-
160
- Args:
161
- command (str): The user's command or input.
162
- history (list[tuple[str, str]]): The conversation history as a list of (user, assistant) message tuples.
163
- system_message (str): The initial system message defining the chatbot's persona.
164
- max_tokens (int): The maximum number of tokens allowed in the generated response.
165
- temperature (float): The temperature parameter controlling the randomness of the generated text.
166
- top_p (float): The top-p parameter for nucleus sampling, controlling the diversity of the generated text.
167
- github_api_token (str): The user's GitHub API token for authentication.
168
- github_username (str): The username of the GitHub account owning the repository.
169
- github_repository (str): The name of the GitHub repository.
170
- selected_model (str): The name of the language model selected for generating responses.
171
- severity (str): The severity level of the issue (e.g., "Critical", "Major").
172
- programming_language (str): The programming language relevant to the issue.
173
-
174
- Returns:
175
- str: The chatbot's response, generated by the selected language model or based on the command.
176
- """
177
-
178
- global issues
179
- issues = [] # Reset issues for each interaction
180
-
181
- messages = [{"role": "system", "content": system_message}]
182
- logging.info(f"System message: {system_message}")
183
-
184
- for user_msg, assistant_msg in history:
185
- if user_msg:
186
- messages.append({"role": "user", "content": user_msg})
187
- logging.info(f"User message: {user_msg}")
188
- if assistant_msg:
189
- messages.append({"role": "assistant", "content": assistant_msg})
190
- logging.info(f"Assistant message: {assistant_msg}")
191
-
192
- logging.info(f"Command received: {command}")
193
-
194
- if command == "/github":
195
- if not github_api_token:
196
- return "Please enter your GitHub API token first. <https://github.com/settings/tokens>"
197
- else:
198
- try:
199
- issues = fetch_github_issues(github_api_token, github_username, github_repository)
200
- issue_list = "\n".join([f"{i+1}. {issue['title']}" for i, issue in enumerate(issues)])
201
- return f"Available GitHub Issues:\n{issue_list}\n\nEnter the issue number to analyze:"
202
- except Exception as e:
203
- logging.error(f"Error fetching GitHub issues: {e}")
204
- return "Error fetching GitHub issues. Please check your credentials and repository."
205
-
206
- elif command == "/help":
207
- help_message = """Available commands:
208
- - `/github`: Analyze a GitHub issue
209
- - `/help`: Show this help message
210
- - `/generate_code [code description]`: Generate code based on the description
211
- - `/explain_concept [concept]`: Explain a concept
212
- - `/write_documentation [topic]`: Write documentation for a given topic
213
- - `/translate_code [code] to [target language]`: Translate code to another language"""
214
- return help_message
215
-
216
- elif command.isdigit() and issues:
217
- try:
218
- issue_number = int(command) - 1
219
- issue = issues[issue_number]
220
- issue_text = issue['title'] + "\n\n" + issue['body']
221
- resolution = analyze_issues(issue_text, selected_model, severity, programming_language)
222
-
223
- # Find and display related issues
224
- related_issues = find_related_issues(issue_text, issues)
225
- related_issue_text = "\n".join(
226
- [f"- {issue['title']} (Similarity: {similarity:.2f})" for issue, similarity in related_issues]
227
- )
228
-
229
- return f"Resolution for Issue '{issue['title']}':\n{resolution}\n\nRelated Issues:\n{related_issue_text}"
230
- except Exception as e:
231
- logging.error(f"Error analyzing issue: {e}")
232
- return "Error analyzing issue. Please try again later."
233
-
234
- elif command.startswith("/generate_code"):
235
- # Extract the code description from the command
236
- code_description = command.replace("/generate_code", "").strip()
237
- if not code_description:
238
- return "Please provide a description of the code you want to generate."
239
- else:
240
- prompt = f"Generate code for the following: {code_description}\nProgramming Language: {programming_language}"
241
- try:
242
- generated_code = analyze_issues(prompt, selected_model)
243
- code_output = f"<pre>{generated_code}</pre>"
244
- return code_output
245
- except Exception as e:
246
- logging.error(f"Error generating code: {e}")
247
- return "Error generating code. Please try again later."
248
-
249
- elif command.startswith("/explain_concept"):
250
- concept = command.replace("/explain_concept", "").strip()
251
- if not concept:
252
- return "Please provide a concept to explain."
253
- else:
254
- prompt = f"Explain the concept of {concept} in detail."
255
- try:
256
- explanation = analyze_issues(prompt, selected_model)
257
- return f"<pre>{explanation}</pre>"
258
- except Exception as e:
259
- logging.error(f"Error explaining concept: {e}")
260
- return "Error explaining concept. Please try again later."
261
-
262
- elif command.startswith("/write_documentation"):
263
- topic = command.replace("/write_documentation", "").strip()
264
- if not topic:
265
- return "Please provide a topic for the documentation."
266
  else:
267
- prompt = f"Write documentation for the following topic: {topic}\nProgramming Language: {programming_language}"
268
- try:
269
- documentation = analyze_issues(prompt, selected_model)
270
- return f"<pre>{documentation}</pre>"
271
- except Exception as e:
272
- logging.error(f"Error writing documentation: {e}")
273
- return "Error writing documentation. Please try again later."
274
-
275
- elif command.startswith("/translate_code"):
276
- try:
277
- code_and_language = command.replace("/translate_code", "").strip().split(" to ")
278
- code = code_and_language[0]
279
- target_language = code_and_language[1]
280
- prompt = f"Translate the following code to {target_language}:\n\n{code}"
281
- try:
282
- translated_code = analyze_issues(prompt, selected_model)
283
- code_output = f"<pre>{translated_code}</pre>"
284
- return code_output
285
- except Exception as e:
286
- logging.error(f"Error translating code: {e}")
287
- return "Error translating code. Please try again later."
288
- except Exception as e:
289
- logging.error(f"Error parsing translate_code command: {e}")
290
- return "Error parsing translate_code command. Please check the syntax."
291
-
292
- else:
293
- messages.append({"role": "user", "content": command})
294
- logging.info(f"User message: {command}")
295
-
296
- response = ""
297
- try:
298
- for message in client.chat_completion(
299
- messages,
300
- max_tokens=max_tokens,
301
- stream=True,
302
- temperature=temperature,
303
- top_p=top_p,
304
- ):
305
- logging.info(f"Received message from chat completion: {message}")
306
- token = message.choices[0].delta.content
307
- response += token
308
- yield response # Use yield for streaming responses
309
- except Exception as e:
310
- logging.error(f"Error during chat completion: {e}")
311
- return "An error occurred. Please try again later."
312
 
313
  with gr.Blocks() as demo:
314
  with gr.Row():
@@ -316,47 +149,41 @@ with gr.Blocks() as demo:
316
  github_username = gr.Textbox(label="GitHub Username")
317
  github_repository = gr.Textbox(label="GitHub Repository")
318
 
319
- # Define system_message here, after github_username and github_repository are defined
320
  system_message = gr.Textbox(
321
- value="You are GitBot, the Github project guardian angel. You resolve issues and propose implementation of feature requests",
322
  label="System message",
323
  )
324
 
325
- # Model Selection Dropdown
326
  model_dropdown = gr.Dropdown(
327
  choices=[
328
- "acecalisto3/InstructiPhi",
329
  "microsoft/CodeBERT-base",
330
- "HuggingFaceH4/zephyr-7b-beta"
331
  ],
332
  label="Select Model for Issue Resolution",
333
- value=DEFAULT_MODEL # Set a default model
334
  )
335
 
336
- # Severity Dropdown
337
  severity_dropdown = gr.Dropdown(
338
  choices=["Critical", "Major", "Minor", "Trivial"],
339
  label="Severity",
340
- value=None # Default to no severity selected
341
  )
342
 
343
- # Programming Language Textbox
344
  programming_language_textbox = gr.Textbox(label="Programming Language")
345
 
346
- # Command Dropdown
347
  command_dropdown = gr.Dropdown(
348
  choices=[
349
- "/github",
350
- "/help",
351
- "/generate_code",
352
  "/explain_concept",
353
  "/write_documentation",
354
- "/translate_code"
355
  ],
356
  label="Select Command",
357
  )
358
 
359
- chatbot = gr.ChatInterface(
360
  respond,
361
  additional_inputs=[
362
  command_dropdown,
@@ -375,9 +202,15 @@ with gr.Blocks() as demo:
375
  github_repository,
376
  model_dropdown,
377
  severity_dropdown,
378
- programming_language_textbox
379
  ],
380
  )
381
 
382
  if __name__ == "__main__":
383
- demo.queue().launch(share=True, server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
 
1
  import gradio as gr
 
 
 
2
  from transformers import pipeline
3
  from sentence_transformers import SentenceTransformer, util
4
+ import os
5
+ import requests
6
  import logging
7
 
8
  # Configure logging for detailed insights
 
10
 
11
  # Constants for enhanced organization
12
  GITHUB_API_BASE_URL = "https://api.github.com/repos"
13
+ DEFAULT_MODEL = "microsoft/CodeBERT-base"
14
+ MAX_RELATED_ISSUES = 3
15
 
16
  # Hugging Face Inference Client
17
  client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
 
19
  # Load a pre-trained model for sentence similarity
20
  similarity_model = SentenceTransformer('all-mpnet-base-v2')
21
 
 
22
  def analyze_issues(issue_text: str, model_name: str, severity: str = None, programming_language: str = None) -> str:
23
+ # Initialize the model
24
+ model = pipeline("text-generation", model=model_name)
25
+
26
+ # Generate a response
27
+ response = model(
28
+ f"{system_message}\n{issue_text}\nAssistant: ",
29
+ max_length=max_tokens,
30
+ do_sample=True,
31
+ temperature=temperature,
32
+ top_k=top_p,
33
+ )
34
+
35
+ # Extract the assistant's response
36
+ assistant_response = response[0]['generated_text'].strip()
37
+
38
+ # Analyze the response
39
+ if "Severity" in assistant_response:
40
+ severity = assistant_response.split(":")[1].strip()
41
+
42
+ if "Programming Language" in assistant_response:
43
+ programming_language = assistant_response.split(":")[1].strip()
44
+
45
+ return {
46
+ 'assistant_response': assistant_response,
47
+ 'severity': severity,
48
+ 'programming_language': programming_language,
49
+ }
50
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  def find_related_issues(issue_text: str, issues: list) -> list:
52
+ # Calculate the similarity between the issue and other issues
 
 
 
 
 
 
 
 
 
 
 
53
  issue_embedding = similarity_model.encode(issue_text)
54
+ similarities = [util.cos_sim(issue_embedding, similarity_model.encode(issue['title'])) for issue in issues]
55
+
56
+ # Sort the issues by similarity
57
+ sorted_issues = sorted(enumerate(similarities), key=lambda x: x[1], reverse=True)
58
 
59
+ # Select the top related issues
60
+ related_issues = [issues[i] for i, similarity in sorted_issues[:MAX_RELATED_ISSUES]]
 
 
61
 
 
 
62
  return related_issues
63
 
 
64
  def fetch_github_issues(github_api_token: str, github_username: str, github_repository: str) -> list:
65
+ # Fetch the issues from the GitHub API
66
+ headers = {'Authorization': f'token {github_api_token}'}
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  url = f"{GITHUB_API_BASE_URL}/{github_username}/{github_repository}/issues"
 
 
 
 
68
  response = requests.get(url, headers=headers)
69
 
70
+ # Parse the JSON response
71
+ issues = response.json()
72
+
73
+ return issues
 
 
 
74
 
 
75
  def respond(
76
  command: str,
77
  history: list[tuple[str, str]],
 
86
  severity: str,
87
  programming_language: str,
88
  ) -> str:
89
+ # Initialize the model
90
+ model = pipeline("text-generation", model=selected_model)
91
+
92
+ # Generate a response
93
+ response = model(
94
+ f"{system_message}\n{command}\n{history}\n{github_username}/{github_repository}\n{severity}\n{programming_language}\nAssistant: ",
95
+ max_length=max_tokens,
96
+ do_sample=True,
97
+ temperature=temperature,
98
+ top_k=top_p,
99
+ )
100
+
101
+ # Extract the assistant's response
102
+ assistant_response = response[0]['generated_text'].strip()
103
+
104
+ return assistant_response
105
+
106
+ class MyChatbot(gr.ChatInterface):
107
+ def __init__(self, respond, *args, **kwargs):
108
+ super().__init__(*args, **kwargs)
109
+ self.respond = respond
110
+
111
+ def update_chat_history(self, message: str, is_user: bool) -> None:
112
+ if is_user:
113
+ self.history.append((message, None))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  else:
115
+ self.history.append((None, message))
116
+
117
+ def compute(self, *args, **kwargs):
118
+ command = args[0]
119
+ history = self.history
120
+ system_message = self.additional_inputs["system_message"]
121
+ max_tokens = self.additional_inputs["max_new_tokens"]
122
+ temperature = self.additional_inputs["temperature"]
123
+ top_p = self.additional_inputs["top_p"]
124
+ github_api_token = self.additional_inputs["github_api_token"]
125
+ github_username = self.additional_inputs["github_username"]
126
+ github_repository = self.additional_inputs["github_repository"]
127
+ selected_model = self.additional_inputs["model_dropdown"]
128
+ severity = self.additional_inputs["severity_dropdown"]
129
+ programming_language = self.additional_inputs["programming_language_textbox"]
130
+
131
+ return self.respond(
132
+ command,
133
+ history,
134
+ system_message,
135
+ max_tokens,
136
+ temperature,
137
+ top_p,
138
+ github_api_token,
139
+ github_username,
140
+ github_repository,
141
+ selected_model,
142
+ severity,
143
+ programming_language,
144
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
  with gr.Blocks() as demo:
147
  with gr.Row():
 
149
  github_username = gr.Textbox(label="GitHub Username")
150
  github_repository = gr.Textbox(label="GitHub Repository")
151
 
 
152
  system_message = gr.Textbox(
153
+ value="You are GitBot, the Github project guardian angel. You resolve issues and propose implementation of feature requests",
154
  label="System message",
155
  )
156
 
 
157
  model_dropdown = gr.Dropdown(
158
  choices=[
 
159
  "microsoft/CodeBERT-base",
160
+ "Salesforce/codegen-350M-mono",
161
  ],
162
  label="Select Model for Issue Resolution",
163
+ value=DEFAULT_MODEL,
164
  )
165
 
 
166
  severity_dropdown = gr.Dropdown(
167
  choices=["Critical", "Major", "Minor", "Trivial"],
168
  label="Severity",
169
+ value=None,
170
  )
171
 
 
172
  programming_language_textbox = gr.Textbox(label="Programming Language")
173
 
 
174
  command_dropdown = gr.Dropdown(
175
  choices=[
176
+ "/github",
177
+ "/help",
178
+ "/generate_code",
179
  "/explain_concept",
180
  "/write_documentation",
181
+ "/translate_code",
182
  ],
183
  label="Select Command",
184
  )
185
 
186
+ chatbot = MyChatbot(
187
  respond,
188
  additional_inputs=[
189
  command_dropdown,
 
202
  github_repository,
203
  model_dropdown,
204
  severity_dropdown,
205
+ programming_language_textbox,
206
  ],
207
  )
208
 
209
  if __name__ == "__main__":
210
+ demo.queue().launch(
211
+ share=True,
212
+ server_name="0.0.0.0",
213
+ server_port=7860,
214
+ show_header=False,
215
+ debug=True,
216
+ )