Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -6,11 +6,11 @@ import requests
|
|
6 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
7 |
import torch
|
8 |
from huggingface_hub import InferenceClient, HfApi
|
|
|
|
|
9 |
|
10 |
# If you have a GPU, move the model to it
|
11 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
12 |
-
model.to(device)
|
13 |
-
|
14 |
|
15 |
# Constants for enhanced organization
|
16 |
system_message = "You are GitBot, the Github project guardian angel. You resolve issues and propose implementation of feature requests"
|
@@ -43,33 +43,61 @@ class InferenceClient:
|
|
43 |
def get_endpoint_metrics(self, repo_id, handler_path):
|
44 |
pass
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
# Define input prompt
|
54 |
-
input_prompt = "(input value = highest-level-quality code content invocation ; True)"
|
55 |
-
|
56 |
-
# Tokenize the input prompt
|
57 |
-
input_ids = tokenizer(input_prompt, return_tensors="pt", truncation=True)
|
58 |
-
|
59 |
-
# Generate the code
|
60 |
-
generated_code = model.generate(input_ids.to(model.device))
|
61 |
-
|
62 |
-
# Decode the generated code
|
63 |
-
generated_code_str = tokenizer.batch_decode(generated_code, skip_special_tokens=True)[0]
|
64 |
-
|
65 |
-
# Print the generated code
|
66 |
-
print(generated_code_str)
|
67 |
|
68 |
-
|
69 |
-
|
|
|
|
|
70 |
|
71 |
-
#
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
def analyze_issues(issue_text: str, model_name: str, severity: str = None, programming_language: str = None) -> str:
|
75 |
"""Analyzes issues and provides solutions using a specified language model."""
|
@@ -97,20 +125,46 @@ def analyze_issues(issue_text: str, model_name: str, severity: str = None, progr
|
|
97 |
|
98 |
def find_related_issues(issue_text: str, issues: list) -> list:
|
99 |
"""Finds semantically related issues from a list of issues based on the input issue text."""
|
|
|
100 |
issue_embedding = similarity_model.encode(issue_text)
|
101 |
similarities = [util.cos_sim(issue_embedding, similarity_model.encode(issue['title'])) for issue in issues]
|
102 |
sorted_issues = sorted(enumerate(similarities), key=lambda x: x[1], reverse=True)
|
103 |
-
related_issues = [issues[i] for i, similarity in sorted_issues[:
|
104 |
return related_issues
|
105 |
|
106 |
def fetch_github_issues(github_api_token: str, github_username: str, github_repository: str) -> list:
|
107 |
"""Fetches issues from a specified GitHub repository using the GitHub API."""
|
108 |
headers = {'Authorization': f'token {github_api_token}'}
|
109 |
-
url = f"
|
110 |
response = requests.get(url, headers=headers)
|
111 |
issues = response.json()
|
112 |
return issues
|
113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
def respond(
|
115 |
command,
|
116 |
history,
|
@@ -128,7 +182,7 @@ def respond(
|
|
128 |
**kwargs,
|
129 |
) -> dict:
|
130 |
"""Handles user commands and generates responses using the selected language model."""
|
131 |
-
model = pipeline("text-generation", model="
|
132 |
response = model(
|
133 |
f"{system_message}\n{command}\n{history}\n{github_username}/{github_repository}\n{severity}\n{programming_language}\nAssistant: ",
|
134 |
max_length=max_tokens,
|
@@ -143,62 +197,6 @@ def respond(
|
|
143 |
'programming_language': programming_language,
|
144 |
}
|
145 |
|
146 |
-
class MyChatbot(gr.Chatbot):
|
147 |
-
"""Custom Chatbot class for enhanced functionality."""
|
148 |
-
def __init__(self, fn, **kwargs):
|
149 |
-
super().__init__(fn, **kwargs)
|
150 |
-
self.issues = [] # Store fetched issues
|
151 |
-
self.current_issue = None # Store the currently selected issue
|
152 |
-
|
153 |
-
def postprocess(self, y):
|
154 |
-
"""Post-processes the response to handle commands and display results."""
|
155 |
-
# Extract the response from the dictionary
|
156 |
-
assistant_response = y['assistant_response']
|
157 |
-
|
158 |
-
# Handle commands
|
159 |
-
if y['command'] == "/github":
|
160 |
-
if not y['github_api_token']:
|
161 |
-
return "Please enter your GitHub API token first."
|
162 |
-
else:
|
163 |
-
try:
|
164 |
-
self.issues = fetch_github_issues(y['github_api_token'], y['github_username'], y['github_repository'])
|
165 |
-
issue_list = "\n".join([f"{i+1}. {issue['title']}" for i, issue in enumerate(self.issues)])
|
166 |
-
return f"Available GitHub Issues:\n{issue_list}\n\nEnter the issue number to analyze:"
|
167 |
-
except Exception as e:
|
168 |
-
return f"Error fetching GitHub issues: {e}"
|
169 |
-
elif y['command'] == "/help":
|
170 |
-
return """Available commands:
|
171 |
-
- `/github`: Analyze a GitHub issue
|
172 |
-
- `/help`: Show this help message
|
173 |
-
- `/generate_code [code description]`: Generate code based on the description
|
174 |
-
- `/explain_concept [concept]`: Explain a concept
|
175 |
-
- `/write_documentation [topic]`: Write documentation for a given topic
|
176 |
-
- `/translate_code [code] to [target language]`: Translate code to another language"""
|
177 |
-
elif y['command'].isdigit() and self.issues:
|
178 |
-
try:
|
179 |
-
issue_number = int(y['command']) - 1
|
180 |
-
self.current_issue = self.issues[issue_number] # Store the selected issue
|
181 |
-
issue_text = self.current_issue['title'] + "\n\n" + self.current_issue['body']
|
182 |
-
resolution = analyze_issues(issue_text, y['selected_model'], y['severity'], y['programming_language'])
|
183 |
-
related_issues = find_related_issues(issue_text, self.issues)
|
184 |
-
related_issue_text = "\n".join(
|
185 |
-
[f"- {issue['title']} (Similarity: {similarity:.2f})" for issue, similarity in related_issues]
|
186 |
-
)
|
187 |
-
return f"Resolution for Issue '{self.current_issue['title']}':\n{resolution['assistant_response']}\n\nRelated Issues:\n{related_issue_text}"
|
188 |
-
except Exception as e:
|
189 |
-
return f"Error analyzing issue: {e}"
|
190 |
-
elif y['command'].startswith("/"):
|
191 |
-
# Handle commands like `/generate_code`, `/explain_concept`, etc.
|
192 |
-
if self.current_issue:
|
193 |
-
# Use the current issue's context for these commands
|
194 |
-
issue_text = self.current_issue['title'] + "\n\n" + self.current_issue['body']
|
195 |
-
return analyze_issues(issue_text, y['selected_model'], y['severity'], y['programming_language'])['assistant_response']
|
196 |
-
else:
|
197 |
-
return "Please select an issue first using `/github`."
|
198 |
-
else:
|
199 |
-
# For free-form text, simply display the assistant's response
|
200 |
-
return assistant_response
|
201 |
-
|
202 |
with gr.Blocks() as demo:
|
203 |
with gr.Row():
|
204 |
github_api_token = gr.Textbox(label="GitHub API Token", type="password")
|
@@ -217,7 +215,7 @@ with gr.Blocks() as demo:
|
|
217 |
"OpenBMB/multilingual-codeparrot"
|
218 |
],
|
219 |
label="Select Model for Issue Resolution",
|
220 |
-
value=
|
221 |
)
|
222 |
|
223 |
severity_dropdown = gr.Dropdown(
|
@@ -258,6 +256,10 @@ with gr.Blocks() as demo:
|
|
258 |
issue_dropdown = gr.Dropdown(label="Select Issue", choices=[], interactive=True)
|
259 |
issue_dropdown.change(fn=lambda issue_number, chatbot: chatbot.postprocess(issue_number), inputs=[issue_dropdown, chatbot], outputs=[chatbot])
|
260 |
|
|
|
|
|
|
|
|
|
261 |
# Connect the chatbot input to the issue dropdown
|
262 |
chatbot.input.change(fn=lambda chatbot, github_api_token, github_username, github_repository: chatbot.postprocess("/github"), inputs=[chatbot, github_api_token, github_username, github_repository], outputs=[chatbot])
|
263 |
|
@@ -266,4 +268,4 @@ if __name__ == "__main__":
|
|
266 |
share=True,
|
267 |
server_name="0.0.0.0",
|
268 |
server_port=7860
|
269 |
-
)
|
|
|
6 |
from transformers import AutoModelForCausalLM, AutoTokenizer
|
7 |
import torch
|
8 |
from huggingface_hub import InferenceClient, HfApi
|
9 |
+
import git
|
10 |
+
import gitdb
|
11 |
|
12 |
# If you have a GPU, move the model to it
|
13 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
|
|
14 |
|
15 |
# Constants for enhanced organization
|
16 |
system_message = "You are GitBot, the Github project guardian angel. You resolve issues and propose implementation of feature requests"
|
|
|
43 |
def get_endpoint_metrics(self, repo_id, handler_path):
|
44 |
pass
|
45 |
|
46 |
+
class MyChatbot(gr.Chatbot):
|
47 |
+
"""Custom Chatbot class for enhanced functionality."""
|
48 |
+
def __init__(self, fn, **kwargs):
|
49 |
+
super().__init__(fn, **kwargs)
|
50 |
+
self.issues = [] # Store fetched issues
|
51 |
+
self.current_issue = None # Store the currently selected issue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
+
def postprocess(self, y):
|
54 |
+
"""Post-processes the response to handle commands and display results."""
|
55 |
+
# Extract the response from the dictionary
|
56 |
+
assistant_response = y['assistant_response']
|
57 |
|
58 |
+
# Handle commands
|
59 |
+
if y['command'] == "/github":
|
60 |
+
if not y['github_api_token']:
|
61 |
+
return "Please enter your GitHub API token first."
|
62 |
+
else:
|
63 |
+
try:
|
64 |
+
self.issues = fetch_github_issues(y['github_api_token'], y['github_username'], y['github_repository'])
|
65 |
+
issue_list = "\n".join([f"{i+1}. {issue['title']}" for i, issue in enumerate(self.issues)])
|
66 |
+
return f"Available GitHub Issues:\n{issue_list}\n\nEnter the issue number to analyze:"
|
67 |
+
except Exception as e:
|
68 |
+
return f"Error fetching GitHub issues: {e}"
|
69 |
+
elif y['command'] == "/help":
|
70 |
+
return """Available commands:
|
71 |
+
- `/github`: Analyze a GitHub issue
|
72 |
+
- `/help`: Show this help message
|
73 |
+
- `/generate_code [code description]`: Generate code based on the description
|
74 |
+
- `/explain_concept [concept]`: Explain a concept
|
75 |
+
- `/write_documentation [topic]`: Write documentation for a given topic
|
76 |
+
- `/translate_code [code] to [target language]`: Translate code to another language"""
|
77 |
+
elif y['command'].isdigit() and self.issues:
|
78 |
+
try:
|
79 |
+
issue_number = int(y['command']) - 1
|
80 |
+
self.current_issue = self.issues[issue_number] # Store the selected issue
|
81 |
+
issue_text = self.current_issue['title'] + "\n\n" + self.current_issue['body']
|
82 |
+
resolution = analyze_issues(issue_text, y['selected_model'], y['severity'], y['programming_language'])
|
83 |
+
related_issues = find_related_issues(issue_text, self.issues)
|
84 |
+
related_issue_text = "\n".join(
|
85 |
+
[f"- {issue['title']} (Similarity: {similarity:.2f})" for issue, similarity in related_issues]
|
86 |
+
)
|
87 |
+
return f"Resolution for Issue '{self.current_issue['title']}':\n{resolution['assistant_response']}\n\nRelated Issues:\n{related_issue_text}"
|
88 |
+
except Exception as e:
|
89 |
+
return f"Error analyzing issue: {e}"
|
90 |
+
elif y['command'].startswith("/"):
|
91 |
+
# Handle commands like `/generate_code`, `/explain_concept`, etc.
|
92 |
+
if self.current_issue:
|
93 |
+
# Use the current issue's context for these commands
|
94 |
+
issue_text = self.current_issue['title'] + "\n\n" + self.current_issue['body']
|
95 |
+
return analyze_issues(issue_text, y['selected_model'], y['severity'], y['programming_language'])['assistant_response']
|
96 |
+
else:
|
97 |
+
return "Please select an issue first using `/github`."
|
98 |
+
else:
|
99 |
+
# For free-form text, simply display the assistant's response
|
100 |
+
return assistant_response
|
101 |
|
102 |
def analyze_issues(issue_text: str, model_name: str, severity: str = None, programming_language: str = None) -> str:
|
103 |
"""Analyzes issues and provides solutions using a specified language model."""
|
|
|
125 |
|
126 |
def find_related_issues(issue_text: str, issues: list) -> list:
|
127 |
"""Finds semantically related issues from a list of issues based on the input issue text."""
|
128 |
+
similarity_model = SentenceTransformer('all-mpnet-base-v2')
|
129 |
issue_embedding = similarity_model.encode(issue_text)
|
130 |
similarities = [util.cos_sim(issue_embedding, similarity_model.encode(issue['title'])) for issue in issues]
|
131 |
sorted_issues = sorted(enumerate(similarities), key=lambda x: x[1], reverse=True)
|
132 |
+
related_issues = [issues[i] for i, similarity in sorted_issues[:5]]
|
133 |
return related_issues
|
134 |
|
135 |
def fetch_github_issues(github_api_token: str, github_username: str, github_repository: str) -> list:
|
136 |
"""Fetches issues from a specified GitHub repository using the GitHub API."""
|
137 |
headers = {'Authorization': f'token {github_api_token}'}
|
138 |
+
url = f"https://api.github.com/repos/{github_username}/{github_repository}/issues"
|
139 |
response = requests.get(url, headers=headers)
|
140 |
issues = response.json()
|
141 |
return issues
|
142 |
|
143 |
+
def push_to_repo(github_api_token: str, github_username: str, github_repository: str, commit_message: str, commit_file: str):
|
144 |
+
"""Pushes changes to a GitHub repository."""
|
145 |
+
try:
|
146 |
+
repo = git.Repo.clone_from(f"https://github.com/{github_username}/{github_repository}.git", f"{github_repository}")
|
147 |
+
repo.git.add(commit_file)
|
148 |
+
repo.git.commit(m=commit_message)
|
149 |
+
repo.git.push()
|
150 |
+
return f"Changes pushed to {github_repository} successfully."
|
151 |
+
except gitdb.exc.InvalidGitRepositoryError:
|
152 |
+
return f"Invalid repository: {github_repository}"
|
153 |
+
except Exception as e:
|
154 |
+
return f"Error pushing to repository: {e}"
|
155 |
+
|
156 |
+
def resolve_issue(github_api_token: str, github_username: str, github_repository: str, issue_number: int, resolution: str):
|
157 |
+
"""Resolves an issue by pushing a commit with the resolution."""
|
158 |
+
try:
|
159 |
+
issue_text = fetch_github_issues(github_api_token, github_username, github_repository)[issue_number]['body']
|
160 |
+
commit_message = f"Resolved issue {issue_number}: {issue_text}"
|
161 |
+
commit_file = "resolution.txt"
|
162 |
+
with open(commit_file, "w") as f:
|
163 |
+
f.write(resolution)
|
164 |
+
return push_to_repo(github_api_token, github_username, github_repository, commit_message, commit_file)
|
165 |
+
except Exception as e:
|
166 |
+
return f"Error resolving issue: {e}"
|
167 |
+
|
168 |
def respond(
|
169 |
command,
|
170 |
history,
|
|
|
182 |
**kwargs,
|
183 |
) -> dict:
|
184 |
"""Handles user commands and generates responses using the selected language model."""
|
185 |
+
model = pipeline("text-generation", model="OpenBMB/multilingual-codeparrot")
|
186 |
response = model(
|
187 |
f"{system_message}\n{command}\n{history}\n{github_username}/{github_repository}\n{severity}\n{programming_language}\nAssistant: ",
|
188 |
max_length=max_tokens,
|
|
|
197 |
'programming_language': programming_language,
|
198 |
}
|
199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
with gr.Blocks() as demo:
|
201 |
with gr.Row():
|
202 |
github_api_token = gr.Textbox(label="GitHub API Token", type="password")
|
|
|
215 |
"OpenBMB/multilingual-codeparrot"
|
216 |
],
|
217 |
label="Select Model for Issue Resolution",
|
218 |
+
value="OpenBMB/multilingual-codeparrot",
|
219 |
)
|
220 |
|
221 |
severity_dropdown = gr.Dropdown(
|
|
|
256 |
issue_dropdown = gr.Dropdown(label="Select Issue", choices=[], interactive=True)
|
257 |
issue_dropdown.change(fn=lambda issue_number, chatbot: chatbot.postprocess(issue_number), inputs=[issue_dropdown, chatbot], outputs=[chatbot])
|
258 |
|
259 |
+
# Add a button to resolve an issue
|
260 |
+
resolve_issue_button = gr.Button(label="Resolve Issue")
|
261 |
+
resolve_issue_button.click(fn=lambda github_api_token, github_username, github_repository, issue_number, resolution: resolve_issue(github_api_token, github_username, github_repository, issue_number, resolution), inputs=[github_api_token, github_username, github_repository, gr.Number(label="Issue Number"), chatbot], outputs=[chatbot])
|
262 |
+
|
263 |
# Connect the chatbot input to the issue dropdown
|
264 |
chatbot.input.change(fn=lambda chatbot, github_api_token, github_username, github_repository: chatbot.postprocess("/github"), inputs=[chatbot, github_api_token, github_username, github_repository], outputs=[chatbot])
|
265 |
|
|
|
268 |
share=True,
|
269 |
server_name="0.0.0.0",
|
270 |
server_port=7860
|
271 |
+
)
|