acecalisto3 commited on
Commit
f458b19
·
verified ·
1 Parent(s): ef3dea5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -95
app.py CHANGED
@@ -6,9 +6,14 @@ from transformers import pipeline
6
  from sentence_transformers import SentenceTransformer, util
7
  import logging
8
 
9
- # Enable detailed logging
10
  logging.basicConfig(level=logging.INFO)
11
 
 
 
 
 
 
12
  # Hugging Face Inference Client
13
  client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
14
 
@@ -18,24 +23,33 @@ similarity_model = SentenceTransformer('all-mpnet-base-v2')
18
  ### Function to analyze issues and provide solutions
19
  def analyze_issues(issue_text: str, model_name: str, severity: str = None, programming_language: str = None) -> str:
20
  """
21
- Analyze issues and provide solutions.
 
22
  Args:
23
- issue_text (str): The issue text.
24
- model_name (str): The model name.
25
- severity (str, optional): The severity of the issue. Defaults to None.
26
- programming_language (str, optional): The programming language. Defaults to None.
 
27
  Returns:
28
- str: The analyzed issue and solution.
 
29
  """
30
- logging.info("Analyzing issue: {} with model: {}".format(issue_text, model_name))
31
- prompt = """Issue: {}
32
- Severity: {}
33
- Programming Language: {}
 
 
 
34
  Please provide a comprehensive resolution in the following format:
 
35
  ## Problem Summary:
36
  (Concise summary of the issue)
 
37
  ## Root Cause Analysis:
38
  (Possible reasons for the issue)
 
39
  ## Solution Options:
40
  1. **Option 1:** (Description)
41
  - Pros: (Advantages)
@@ -43,72 +57,87 @@ Please provide a comprehensive resolution in the following format:
43
  2. **Option 2:** (Description)
44
  - Pros: (Advantages)
45
  - Cons: (Disadvantages)
 
46
  ## Recommended Solution:
47
  (The best solution with justification)
 
48
  ## Implementation Steps:
49
  1. (Step 1)
50
  2. (Step 2)
51
  3. (Step 3)
 
52
  ## Verification Steps:
53
  1. (Step 1)
54
  2. (Step 2)
55
- """.format(issue_text, severity, programming_language)
 
56
  try:
57
- nlp = pipeline("text-generation", model=model_name, max_length=1000) # Increase max_length
58
- logging.info("Pipeline created with model: {}".format(model_name))
59
  result = nlp(prompt)
60
- logging.info("Model output: {}".format(result))
61
- return result[0]['generated_text']
62
  except Exception as e:
63
- logging.error("Error analyzing issue with model {}: {}".format(model_name, e))
64
- return "Error analyzing issue with model {}: {}".format(model_name, e)
65
 
66
  ### Function to find related issues
67
  def find_related_issues(issue_text: str, issues: list) -> list:
68
  """
69
- Find related issues.
 
70
  Args:
71
- issue_text (str): The issue text.
72
- issues (list): The list of issues.
 
73
  Returns:
74
- list: The list of related issues.
 
75
  """
76
- logging.info("Finding related issues for: {}".format(issue_text))
77
  issue_embedding = similarity_model.encode(issue_text)
78
  related_issues = []
 
79
  for issue in issues:
80
  title_embedding = similarity_model.encode(issue['title'])
81
  similarity = util.cos_sim(issue_embedding, title_embedding)[0][0]
82
  related_issues.append((issue, similarity))
83
- related_issues = sorted(related_issues, key=lambda x: x[1], reverse=True)
84
- logging.info("Found related issues: {}".format(related_issues))
85
- return related_issues[:3] # Return top 3 most similar issues
 
86
 
87
  ### Function to fetch GitHub issues
88
  def fetch_github_issues(github_api_token: str, github_username: str, github_repository: str) -> list:
89
  """
90
- Fetch GitHub issues.
 
91
  Args:
92
- github_api_token (str): The GitHub API token.
93
- github_username (str): The GitHub username.
94
- github_repository (str): The GitHub repository.
 
95
  Returns:
96
- list: The list of GitHub issues.
 
 
 
97
  """
98
- logging.info("Fetching GitHub issues for: {}/{}".format(github_username, github_repository))
99
- url = "https://api.github.com/repos/{}/{}/issues".format(github_username, github_repository)
100
  headers = {
101
- "Authorization": "Bearer {}".format(github_api_token),
102
  "Accept": "application/vnd.github.v3+json"
103
  }
104
  response = requests.get(url, headers=headers)
 
105
  if response.status_code == 200:
106
  issues = response.json()
107
- logging.info("Fetched issues: {}".format(issues))
108
  return issues
109
  else:
110
- logging.error("Error fetching issues: {}".format(response.status_code))
111
- raise Exception("Error fetching issues: {}".format(response.status_code))
112
 
113
  ### Function to handle chat responses
114
  def respond(
@@ -126,40 +155,41 @@ def respond(
126
  programming_language: str,
127
  ) -> str:
128
  """
129
- Handle chat responses.
 
130
  Args:
131
- command (str): The command.
132
- history (list[tuple[str, str]]): The chat history.
133
- system_message (str): The system message.
134
- max_tokens (int): The maximum number of tokens.
135
- temperature (float): The temperature.
136
- top_p (float): The top-p value.
137
- github_api_token (str): The GitHub API token.
138
- github_username (str): The GitHub username.
139
- github_repository (str): The GitHub repository.
140
- selected_model (str): The selected model.
141
- severity (str): The severity.
142
- programming_language (str): The programming language.
 
143
  Returns:
144
- str: The chat response.
145
  """
146
- global GITHUB_API_TOKEN
147
- GITHUB_API_TOKEN = github_api_token
148
- global issues
149
- issues = []
150
 
151
  messages = [{"role": "system", "content": system_message}]
152
- logging.info("System message: {}".format(system_message))
153
 
154
  for user_msg, assistant_msg in history:
155
  if user_msg:
156
  messages.append({"role": "user", "content": user_msg})
157
- logging.info("User message: {}".format(user_msg))
158
  if assistant_msg:
159
  messages.append({"role": "assistant", "content": assistant_msg})
160
- logging.info("Assistant message: {}".format(assistant_msg))
161
 
162
- logging.info("Command received: {}".format(command))
163
 
164
  if command == "/github":
165
  if not github_api_token:
@@ -167,21 +197,21 @@ def respond(
167
  else:
168
  try:
169
  issues = fetch_github_issues(github_api_token, github_username, github_repository)
170
- issue_list = "\n".join(["{}. {}".format(i+1, issue['title']) for i, issue in enumerate(issues)])
171
- return "Available GitHub Issues:\n{}\n\nEnter the issue number to analyze:".format(issue_list)
172
  except Exception as e:
173
- logging.error("Error fetching GitHub issues: {}".format(e))
174
- return "Error fetching GitHub issues: {}".format(e)
175
 
176
- elif command == "/help":
177
- help_message = """Available commands:
178
  - `/github`: Analyze a GitHub issue
179
  - `/help`: Show this help message
180
  - `/generate_code [code description]`: Generate code based on the description
181
  - `/explain_concept [concept]`: Explain a concept
182
  - `/write_documentation [topic]`: Write documentation for a given topic
183
  - `/translate_code [code] to [target language]`: Translate code to another language"""
184
- return help_message # Yield the pre-formatted help message
185
 
186
  elif command.isdigit() and issues:
187
  try:
@@ -193,13 +223,13 @@ def respond(
193
  # Find and display related issues
194
  related_issues = find_related_issues(issue_text, issues)
195
  related_issue_text = "\n".join(
196
- ["- {} (Similarity: {:.2f})".format(issue['title'], similarity) for issue, similarity in related_issues]
197
  )
198
 
199
- return "Resolution for Issue '{}':\n{}\n\nRelated Issues:\n{}".format(issue['title'], resolution, related_issue_text)
200
  except Exception as e:
201
- logging.error("Error analyzing issue: {}".format(e))
202
- return "Error analyzing issue: {}".format(e)
203
 
204
  elif command.startswith("/generate_code"):
205
  # Extract the code description from the command
@@ -207,57 +237,57 @@ def respond(
207
  if not code_description:
208
  return "Please provide a description of the code you want to generate."
209
  else:
210
- prompt = "Generate code for the following: {}\nProgramming Language: {}".format(code_description, programming_language)
211
  try:
212
  generated_code = analyze_issues(prompt, selected_model)
213
- code_output = "<pre>{}</pre>".format(generated_code)
214
- return code_output # Yield the formatted string
215
  except Exception as e:
216
- logging.error("Error generating code: {}".format(e))
217
- return "Error generating code: {}".format(e)
218
 
219
  elif command.startswith("/explain_concept"):
220
  concept = command.replace("/explain_concept", "").strip()
221
  if not concept:
222
  return "Please provide a concept to explain."
223
  else:
224
- prompt = "Explain the concept of {} in detail.".format(concept)
225
  try:
226
  explanation = analyze_issues(prompt, selected_model)
227
- return "<pre>{}</pre>".format(explanation)
228
  except Exception as e:
229
- logging.error("Error explaining concept: {}".format(e))
230
- return "Error explaining concept: {}".format(e)
231
 
232
  elif command.startswith("/write_documentation"):
233
  topic = command.replace("/write_documentation", "").strip()
234
  if not topic:
235
  return "Please provide a topic for the documentation."
236
  else:
237
- prompt = "Write documentation for the following topic: {}\nProgramming Language: {}".format(topic, programming_language)
238
  try:
239
  documentation = analyze_issues(prompt, selected_model)
240
- return "<pre>{}</pre>".format(documentation)
241
  except Exception as e:
242
- logging.error("Error writing documentation: {}".format(e))
243
- return "Error writing documentation: {}".format(e)
244
 
245
  elif command.startswith("/translate_code"):
246
  try:
247
  code_and_language = command.replace("/translate_code", "").strip().split(" to ")
248
  code = code_and_language[0]
249
  target_language = code_and_language[1]
250
- prompt = "Translate the following code to {}:\n\n{}".format(target_language, code)
251
  try:
252
  translated_code = analyze_issues(prompt, selected_model)
253
- code_output = "<pre>{}</pre>".format(translated_code)
254
- return code_output # Yield the formatted string
255
  except Exception as e:
256
- logging.error("Error translating code: {}".format(e))
257
- return "Error translating code: {}".format(e)
258
  except Exception as e:
259
- logging.error("Error parsing translate_code command: {}".format(e))
260
- return "Error parsing translate_code command: {}".format(e)
261
 
262
  else:
263
  messages.append({"role": "user", "content": command})
@@ -275,10 +305,10 @@ def respond(
275
  logging.info(f"Received message from chat completion: {message}")
276
  token = message.choices[0].delta.content
277
  response += token
278
- return response
279
  except Exception as e:
280
  logging.error(f"Error during chat completion: {e}")
281
- return "An error occurred: {}".format(e)
282
 
283
  with gr.Blocks() as demo:
284
  with gr.Row():
@@ -307,7 +337,7 @@ with gr.Blocks() as demo:
307
  "bigcode/starcoder"
308
  ],
309
  label="Select Model for Issue Resolution",
310
- value="microsoft/CodeBERT-base"
311
  )
312
 
313
  # Severity Dropdown
@@ -336,7 +366,7 @@ with gr.Blocks() as demo:
336
  chatbot = gr.ChatInterface(
337
  respond,
338
  additional_inputs=[
339
- command_dropdown, # Use command_dropdown instead of a regular message input
340
  system_message,
341
  gr.Slider(minimum=1, maximum=8192, value=2048, step=1, label="Max new tokens"),
342
  gr.Slider(minimum=0.1, maximum=4.0, value=0.71, step=0.1, label="Temperature"),
@@ -344,7 +374,7 @@ with gr.Blocks() as demo:
344
  minimum=0.1,
345
  maximum=1.0,
346
  value=0.95,
347
- step=1.1,
348
  label="Top-p (nucleus sampling)",
349
  ),
350
  github_api_token,
 
6
  from sentence_transformers import SentenceTransformer, util
7
  import logging
8
 
9
+ # Configure logging for detailed insights
10
  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")
19
 
 
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)
 
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(
 
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:
 
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:
 
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
 
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})
 
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():
 
337
  "bigcode/starcoder"
338
  ],
339
  label="Select Model for Issue Resolution",
340
+ value=DEFAULT_MODEL # Set a default model
341
  )
342
 
343
  # Severity Dropdown
 
366
  chatbot = gr.ChatInterface(
367
  respond,
368
  additional_inputs=[
369
+ command_dropdown,
370
  system_message,
371
  gr.Slider(minimum=1, maximum=8192, value=2048, step=1, label="Max new tokens"),
372
  gr.Slider(minimum=0.1, maximum=4.0, value=0.71, step=0.1, label="Temperature"),
 
374
  minimum=0.1,
375
  maximum=1.0,
376
  value=0.95,
377
+ step=0.01,
378
  label="Top-p (nucleus sampling)",
379
  ),
380
  github_api_token,