Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -137,7 +137,7 @@ class WebhookHandler(BaseHTTPRequestHandler):
|
|
137 |
|
138 |
event = self.headers.get('X-GitHub-Event')
|
139 |
delivery_id = self.headers.get('X-GitHub-Delivery')
|
140 |
-
logger.info(f"Received GitHub webhook event: {{}event}} (Delivery ID: {{delivery_id}})")
|
141 |
|
142 |
if event == 'issues' and WebhookHandler.manager_instance and WebhookHandler.main_loop:
|
143 |
action = payload.get('action')
|
@@ -168,7 +168,7 @@ class WebhookHandler(BaseHTTPRequestHandler):
|
|
168 |
# ========== AI-Powered Issue Manager ==========
|
169 |
class IssueManager:
|
170 |
def __init__(self):
|
171 |
-
self.issues: Dict[int, dict] = {{}
|
172 |
self.repo_url: Optional[str] = None
|
173 |
self.repo_owner: Optional[str] = None
|
174 |
self.repo_name: Optional[str] = None
|
@@ -176,7 +176,7 @@ class IssueManager:
|
|
176 |
self.repo: Optional[Repo] = None
|
177 |
self.github_token: Optional[str] = None
|
178 |
self.hf_token: Optional[str] = None
|
179 |
-
self.collaborators: Dict[str, dict] = {{}
|
180 |
self.points: int = 0
|
181 |
self.severity_rules: Dict[str, List[str]] = {{
|
182 |
"Critical": ["critical", "urgent", "security", "crash", "blocker", "p0", "s0"],
|
@@ -184,21 +184,21 @@ class IssueManager:
|
|
184 |
"Medium": ["medium", "bug", "performance", "minor", "p2", "s2"],
|
185 |
"Low": ["low", "documentation", "enhancement", "trivial", "feature", "p3", "s3", "chore", "refactor", "question", "help wanted"]
|
186 |
}
|
187 |
-
self.issue_clusters: Dict[int, List[int]] = {{}
|
188 |
self.issue_list_for_clustering: List[dict] = []
|
189 |
self.ws_clients: List[WebSocketServerProtocol] = []
|
190 |
-
self.code_editors: Dict[int, OTCodeEditor] = {{}
|
191 |
self.main_loop = asyncio.get_event_loop()
|
192 |
self.broadcast_task: Optional[asyncio.Task] = None
|
193 |
self.idle_task: Optional[asyncio.Task] = None
|
194 |
|
195 |
# --- State for Idle Processing Results ---
|
196 |
-
self.precomputed_context: Dict[int, Dict[str, Any]] = {{}
|
197 |
-
self.precomputed_summaries: Dict[int, Dict[str, Any]] = {{}
|
198 |
-
self.precomputed_missing_info: Dict[int, Dict[str, Any]] = {{}
|
199 |
-
self.precomputed_analysis: Dict[int, Dict[str, Any]] = {{}
|
200 |
-
self.code_embeddings: Dict[str, List[float]] = {{}
|
201 |
-
self.potential_duplicates: Dict[int, List[int]] = {{}
|
202 |
self.stale_issues: List[int] = []
|
203 |
self.high_priority_candidates: List[int] = []
|
204 |
self.last_webhook_time: float = 0.0
|
@@ -368,7 +368,7 @@ class IssueManager:
|
|
368 |
empty_fig = go.Figure()
|
369 |
empty_fig.update_layout(title="Issue Severity Distribution", xaxis={{"visible": False}}, yaxis={{"visible": False}}),
|
370 |
annotations=[{{"text": "Scan needed.", "xref": "paper", "yref": "paper", "showarrow": False}}],
|
371 |
-
plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)'
|
372 |
return [], empty_fig, "Error: Repository URL and Hugging Face Token are required.", empty_fig
|
373 |
|
374 |
logger.info(f"Starting new issue crawl and setup for {{repo_url}}")
|
@@ -376,17 +376,17 @@ class IssueManager:
|
|
376 |
# --- Reset Manager State ---
|
377 |
self.stop_idle_processing()
|
378 |
self.stop_broadcast_loop()
|
379 |
-
self.issues = {{}
|
380 |
-
self.code_editors = {{}
|
381 |
-
self.issue_clusters = {{}
|
382 |
self.issue_list_for_clustering = []
|
383 |
self.cached_suggestion.cache_clear()
|
384 |
-
self.precomputed_context = {{}
|
385 |
-
self.precomputed_summaries = {{}
|
386 |
-
self.precomputed_missing_info = {{}
|
387 |
-
self.precomputed_analysis = {{}
|
388 |
-
self.code_embeddings = {{}
|
389 |
-
self.potential_duplicates = {{}
|
390 |
self.stale_issues = []
|
391 |
self.high_priority_candidates = []
|
392 |
self.needs_recluster = False
|
@@ -526,7 +526,7 @@ class IssueManager:
|
|
526 |
# --- Prepare Dataframe Output & Stats ---
|
527 |
dataframe_data = []
|
528 |
severity_counts = {{"Critical": 0, "High": 0, "Medium": 0, "Low": 0, "Unknown": 0}
|
529 |
-
index_to_cluster_id: Dict[int, int] = {{}
|
530 |
for cluster_id, indices in self.issue_clusters.items():
|
531 |
for index in indices:
|
532 |
if 0 <= index < len(self.issue_list_for_clustering):
|
@@ -620,11 +620,11 @@ class IssueManager:
|
|
620 |
"""Generates embeddings and clusters issues using HDBSCAN. Uses self.issue_list_for_clustering."""
|
621 |
if not self.issue_list_for_clustering:
|
622 |
logger.warning("Cannot cluster issues: No issues loaded or list is empty.")
|
623 |
-
self.issue_clusters = {{}
|
624 |
return
|
625 |
if not self.hf_token:
|
626 |
logger.error("Cannot cluster issues: Hugging Face token missing.")
|
627 |
-
self.issue_clusters = {{}
|
628 |
return
|
629 |
|
630 |
num_issues = len(self.issue_list_for_clustering)
|
@@ -638,14 +638,14 @@ class IssueManager:
|
|
638 |
|
639 |
if embeddings is None or not isinstance(embeddings, list) or len(embeddings) != num_issues:
|
640 |
logger.error(f"Failed to generate valid embeddings for clustering. Expected {{num_issues}, got {{type(embeddings)}} len {{len(embeddings) if embeddings else 'N/A'}.")
|
641 |
-
self.issue_clusters = {{}
|
642 |
return
|
643 |
|
644 |
logger.info(f"Generated {{len(embeddings)}} embeddings. Running HDBSCAN clustering...")
|
645 |
clusterer = HDBSCAN(min_cluster_size=2, metric='cosine', allow_single_cluster=True, gen_min_span_tree=True)
|
646 |
clusters = clusterer.fit_predict(embeddings)
|
647 |
|
648 |
-
new_issue_clusters: Dict[int, List[int]] = {{}
|
649 |
noise_count = 0
|
650 |
for i, cluster_id in enumerate(clusters):
|
651 |
cluster_id_int = int(cluster_id)
|
@@ -666,16 +666,16 @@ class IssueManager:
|
|
666 |
|
667 |
except Exception as e:
|
668 |
logger.exception(f"Error during issue clustering: {{e}}")
|
669 |
-
self.issue_clusters = {{}
|
670 |
|
671 |
def _identify_potential_duplicates(self):
|
672 |
"""Populates self.potential_duplicates based on self.issue_clusters and self.issue_list_for_clustering."""
|
673 |
-
self.potential_duplicates = {{}
|
674 |
if not self.issue_clusters or not self.issue_list_for_clustering:
|
675 |
logger.debug("Skipping duplicate identification: No clusters or issue list.")
|
676 |
return
|
677 |
|
678 |
-
index_to_id = {{}
|
679 |
try:
|
680 |
for i, issue in enumerate(self.issue_list_for_clustering):
|
681 |
issue_id = issue.get('id')
|
@@ -1906,7 +1906,7 @@ def create_ui(manager: IssueManager) -> gr.Blocks:
|
|
1906 |
}
|
1907 |
|
1908 |
issue_data = manager.issues[selected_id]
|
1909 |
-
files_content: Dict[str, str] = {{}
|
1910 |
context_source_msg = "Error determining context source"
|
1911 |
context_load_start = time.time()
|
1912 |
|
@@ -2199,7 +2199,7 @@ def create_ui(manager: IssueManager) -> gr.Blocks:
|
|
2199 |
function updateCollabList(collaborators) {{
|
2200 |
const collabListDiv = document.getElementById('collab-list');
|
2201 |
if (!collabListDiv) return;
|
2202 |
-
const activeCollaborators = Object.entries(collaborators || {{}})
|
2203 |
.filter(([id, info]) => id !== clientId);
|
2204 |
if (activeCollaborators.length > 0) {{
|
2205 |
collabListDiv.innerHTML = activeCollaborators
|
|
|
137 |
|
138 |
event = self.headers.get('X-GitHub-Event')
|
139 |
delivery_id = self.headers.get('X-GitHub-Delivery')
|
140 |
+
logger.info(f"Received GitHub webhook event: {{}}event}} (Delivery ID: {{delivery_id}})")
|
141 |
|
142 |
if event == 'issues' and WebhookHandler.manager_instance and WebhookHandler.main_loop:
|
143 |
action = payload.get('action')
|
|
|
168 |
# ========== AI-Powered Issue Manager ==========
|
169 |
class IssueManager:
|
170 |
def __init__(self):
|
171 |
+
self.issues: Dict[int, dict] = {{}}
|
172 |
self.repo_url: Optional[str] = None
|
173 |
self.repo_owner: Optional[str] = None
|
174 |
self.repo_name: Optional[str] = None
|
|
|
176 |
self.repo: Optional[Repo] = None
|
177 |
self.github_token: Optional[str] = None
|
178 |
self.hf_token: Optional[str] = None
|
179 |
+
self.collaborators: Dict[str, dict] = {{}}
|
180 |
self.points: int = 0
|
181 |
self.severity_rules: Dict[str, List[str]] = {{
|
182 |
"Critical": ["critical", "urgent", "security", "crash", "blocker", "p0", "s0"],
|
|
|
184 |
"Medium": ["medium", "bug", "performance", "minor", "p2", "s2"],
|
185 |
"Low": ["low", "documentation", "enhancement", "trivial", "feature", "p3", "s3", "chore", "refactor", "question", "help wanted"]
|
186 |
}
|
187 |
+
self.issue_clusters: Dict[int, List[int]] = {{}}
|
188 |
self.issue_list_for_clustering: List[dict] = []
|
189 |
self.ws_clients: List[WebSocketServerProtocol] = []
|
190 |
+
self.code_editors: Dict[int, OTCodeEditor] = {{}}
|
191 |
self.main_loop = asyncio.get_event_loop()
|
192 |
self.broadcast_task: Optional[asyncio.Task] = None
|
193 |
self.idle_task: Optional[asyncio.Task] = None
|
194 |
|
195 |
# --- State for Idle Processing Results ---
|
196 |
+
self.precomputed_context: Dict[int, Dict[str, Any]] = {{}}
|
197 |
+
self.precomputed_summaries: Dict[int, Dict[str, Any]] = {{}}
|
198 |
+
self.precomputed_missing_info: Dict[int, Dict[str, Any]] = {{}}
|
199 |
+
self.precomputed_analysis: Dict[int, Dict[str, Any]] = {{}}
|
200 |
+
self.code_embeddings: Dict[str, List[float]] = {{}}
|
201 |
+
self.potential_duplicates: Dict[int, List[int]] = {{}}
|
202 |
self.stale_issues: List[int] = []
|
203 |
self.high_priority_candidates: List[int] = []
|
204 |
self.last_webhook_time: float = 0.0
|
|
|
368 |
empty_fig = go.Figure()
|
369 |
empty_fig.update_layout(title="Issue Severity Distribution", xaxis={{"visible": False}}, yaxis={{"visible": False}}),
|
370 |
annotations=[{{"text": "Scan needed.", "xref": "paper", "yref": "paper", "showarrow": False}}],
|
371 |
+
plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)'
|
372 |
return [], empty_fig, "Error: Repository URL and Hugging Face Token are required.", empty_fig
|
373 |
|
374 |
logger.info(f"Starting new issue crawl and setup for {{repo_url}}")
|
|
|
376 |
# --- Reset Manager State ---
|
377 |
self.stop_idle_processing()
|
378 |
self.stop_broadcast_loop()
|
379 |
+
self.issues = {{}}
|
380 |
+
self.code_editors = {{}}
|
381 |
+
self.issue_clusters = {{}}
|
382 |
self.issue_list_for_clustering = []
|
383 |
self.cached_suggestion.cache_clear()
|
384 |
+
self.precomputed_context = {{}}
|
385 |
+
self.precomputed_summaries = {{}}
|
386 |
+
self.precomputed_missing_info = {{}}
|
387 |
+
self.precomputed_analysis = {{}}
|
388 |
+
self.code_embeddings = {{}}
|
389 |
+
self.potential_duplicates = {{}}
|
390 |
self.stale_issues = []
|
391 |
self.high_priority_candidates = []
|
392 |
self.needs_recluster = False
|
|
|
526 |
# --- Prepare Dataframe Output & Stats ---
|
527 |
dataframe_data = []
|
528 |
severity_counts = {{"Critical": 0, "High": 0, "Medium": 0, "Low": 0, "Unknown": 0}
|
529 |
+
index_to_cluster_id: Dict[int, int] = {{}}
|
530 |
for cluster_id, indices in self.issue_clusters.items():
|
531 |
for index in indices:
|
532 |
if 0 <= index < len(self.issue_list_for_clustering):
|
|
|
620 |
"""Generates embeddings and clusters issues using HDBSCAN. Uses self.issue_list_for_clustering."""
|
621 |
if not self.issue_list_for_clustering:
|
622 |
logger.warning("Cannot cluster issues: No issues loaded or list is empty.")
|
623 |
+
self.issue_clusters = {{}}
|
624 |
return
|
625 |
if not self.hf_token:
|
626 |
logger.error("Cannot cluster issues: Hugging Face token missing.")
|
627 |
+
self.issue_clusters = {{}}
|
628 |
return
|
629 |
|
630 |
num_issues = len(self.issue_list_for_clustering)
|
|
|
638 |
|
639 |
if embeddings is None or not isinstance(embeddings, list) or len(embeddings) != num_issues:
|
640 |
logger.error(f"Failed to generate valid embeddings for clustering. Expected {{num_issues}, got {{type(embeddings)}} len {{len(embeddings) if embeddings else 'N/A'}.")
|
641 |
+
self.issue_clusters = {{}}
|
642 |
return
|
643 |
|
644 |
logger.info(f"Generated {{len(embeddings)}} embeddings. Running HDBSCAN clustering...")
|
645 |
clusterer = HDBSCAN(min_cluster_size=2, metric='cosine', allow_single_cluster=True, gen_min_span_tree=True)
|
646 |
clusters = clusterer.fit_predict(embeddings)
|
647 |
|
648 |
+
new_issue_clusters: Dict[int, List[int]] = {{}}
|
649 |
noise_count = 0
|
650 |
for i, cluster_id in enumerate(clusters):
|
651 |
cluster_id_int = int(cluster_id)
|
|
|
666 |
|
667 |
except Exception as e:
|
668 |
logger.exception(f"Error during issue clustering: {{e}}")
|
669 |
+
self.issue_clusters = {{}}
|
670 |
|
671 |
def _identify_potential_duplicates(self):
|
672 |
"""Populates self.potential_duplicates based on self.issue_clusters and self.issue_list_for_clustering."""
|
673 |
+
self.potential_duplicates = {{}}
|
674 |
if not self.issue_clusters or not self.issue_list_for_clustering:
|
675 |
logger.debug("Skipping duplicate identification: No clusters or issue list.")
|
676 |
return
|
677 |
|
678 |
+
index_to_id = {{}}
|
679 |
try:
|
680 |
for i, issue in enumerate(self.issue_list_for_clustering):
|
681 |
issue_id = issue.get('id')
|
|
|
1906 |
}
|
1907 |
|
1908 |
issue_data = manager.issues[selected_id]
|
1909 |
+
files_content: Dict[str, str] = {{}}
|
1910 |
context_source_msg = "Error determining context source"
|
1911 |
context_load_start = time.time()
|
1912 |
|
|
|
2199 |
function updateCollabList(collaborators) {{
|
2200 |
const collabListDiv = document.getElementById('collab-list');
|
2201 |
if (!collabListDiv) return;
|
2202 |
+
const activeCollaborators = Object.entries(collaborators || {{}}})
|
2203 |
.filter(([id, info]) => id !== clientId);
|
2204 |
if (activeCollaborators.length > 0) {{
|
2205 |
collabListDiv.innerHTML = activeCollaborators
|