Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -766,6 +766,7 @@ class IssueManager:
|
|
766 |
if e.status == 404: error_msg = f"Error: Repository not found at {self.repo_url}."
|
767 |
elif e.status == 401: error_msg = "Error: Invalid GitHub token or insufficient permissions for this repository."
|
768 |
elif e.status == 403:
|
|
|
769 |
rate_limit_reset = e.headers.get('X-RateLimit-Reset')
|
770 |
reset_time_str = "unknown"
|
771 |
if rate_limit_reset:
|
@@ -1572,12 +1573,11 @@ Suggested Resolution Approach:
|
|
1572 |
if self.main_loop.is_running():
|
1573 |
self.main_loop.call_soon_threadsafe(self.remove_ws_client, client)
|
1574 |
else:
|
1575 |
-
logger.
|
1576 |
continue # Skip to next client
|
1577 |
|
1578 |
|
1579 |
# No need to await tasks here if remove_ws_client is scheduled via call_soon_threadsafe
|
1580 |
-
# The exceptions will be handled by the individual send calls.
|
1581 |
|
1582 |
except asyncio.CancelledError:
|
1583 |
logger.info("Broadcast loop cancelled.")
|
@@ -1633,6 +1633,7 @@ Suggested Resolution Approach:
|
|
1633 |
tasks.append(client.send(update_payload))
|
1634 |
except (ConnectionClosed, ConnectionAbortedError, ConnectionResetError, WebSocketException) as e:
|
1635 |
logger.warning(f"Client {getattr(client, 'client_id', client.remote_address)} seems disconnected during broadcast: {type(e).__name__}. Attempting removal.")
|
|
|
1636 |
if self.main_loop.is_running():
|
1637 |
self.main_loop.call_soon_threadsafe(self.remove_ws_client, client)
|
1638 |
else:
|
@@ -1742,7 +1743,7 @@ Suggested Resolution Approach:
|
|
1742 |
tasks = []
|
1743 |
# No need for disconnected_clients list here, remove_ws_client handles it
|
1744 |
|
1745 |
-
|
1746 |
# Check if client is closed using the standard websockets property
|
1747 |
if client.closed:
|
1748 |
continue
|
@@ -1763,9 +1764,9 @@ Suggested Resolution Approach:
|
|
1763 |
logger.warning("Main loop not running, cannot schedule client removal.")
|
1764 |
continue
|
1765 |
|
1766 |
-
|
1767 |
-
|
1768 |
-
|
1769 |
|
1770 |
|
1771 |
def _identify_stale_issues(self):
|
@@ -2593,7 +2594,7 @@ def create_ui(manager: IssueManager) -> gr.Blocks:
|
|
2593 |
files_content[file_path_str] = f"# File path resolved outside repository: {file_path_str}"
|
2594 |
else:
|
2595 |
logger.warning(f"On-demand file path {file_path_str} not found or not a file during load for issue {selected_id}.")
|
2596 |
-
|
2597 |
except Exception as e:
|
2598 |
logger.warning(f"Error reading on-demand file {full_path} for issue {selected_id}: {e}")
|
2599 |
files_content[file_path_str] = f"# Error reading file: {e}"
|
@@ -2669,7 +2670,7 @@ def create_ui(manager: IssueManager) -> gr.Blocks:
|
|
2669 |
# Expanded stop words list (lowercase)
|
2670 |
stop_words = set("a an the is are was were be been being has have had do does did will would shall should can could may might must it its this that these those there their then than and or but if because as at by for with without about against between into through during before after above below to from up down in out on off over under again further then once here there when where why how all any both each few more most other some such no nor not only own same so than too very s t can will just don should now d ll m o re ve yo ain aren couldn didn doesn isn it's mustn ouren shan shouldn wasn weren won wouldn".split())
|
2671 |
# Add common code/issue terms (lowercase)
|
2672 |
-
stop_words.update({'issue', 'bug', 'error', 'fix', 'feat', 'chore', 'refactor', 'docs', 'test', 'file', 'line', 'code', 'when', 'user', 'report', 'problem', 'need', 'want', 'get', 'use', 'try', 'make', 'add', 'remove', 'change', 'update', 'create', 'build', 'run', 'start', 'stop', 'click', 'button', 'page', 'app', 'data', 'system', 'service', 'component', 'module', 'function', 'class', 'method', 'variable', 'value', 'string', 'number', 'list', 'dict', 'object', 'array', 'true', 'false', 'null', 'none', 'type', 'size', 'color', 'style', 'width', 'height', 'margin', 'padding', 'border', 'display', 'position', 'float', 'clear', 'overflow', 'index', 'key', 'value', 'id', 'name', 'text', 'html', 'css', 'js', 'py', 'java', 'c', 'cpp', 'go', 'rs', 'php', 'rb', 'json', 'yaml', 'xml', 'sql', 'log', 'config', 'setup', 'install', 'version', 'release', 'branch', 'commit', 'pull', 'request', 'merge', 'diff', 'patch', 'context', 'suggestion', 'analysis', 'missing', 'information', 'duplicate', 'potential', 'cluster', 'severity', 'label', 'assignee', 'state', 'title', 'body', 'url', 'created', 'updated', 'time', 'day', 'week', 'month', 'year', 'ago', 'now', 'new', 'old', 'different', 'same', 'similar', 'group', 'count', 'distribution', 'analytics', 'overview', 'studio', 'board', 'resolution', 'collaborative', 'editor', 'context', 'aware', 'assistance', 'tools', 'output', 'patch', 'steps', 'approach', 'plan', 'identify', 'propose', 'recommendation', 'workflow', 'standard', 'important', 'critical', 'high', 'medium', 'low', 'unknown', 'none', 'needed', 'analysis', 'hypothesis', 'preliminary', 'relevant', 'area', 'investigation', 'implementation', 'testing', 'next'})
|
2673 |
|
2674 |
|
2675 |
def get_top_keywords(indices):
|
@@ -3044,7 +3045,7 @@ def create_ui(manager: IssueManager) -> gr.Blocks:
|
|
3044 |
}}
|
3045 |
}} else {{
|
3046 |
console.warn("Row for issue ID", issueId, "not found in the dataframe.");
|
3047 |
-
updateStatusBar(`Issue #${issueId} not found in the current list. Try re-scanning.`, true);
|
3048 |
}}
|
3049 |
}};
|
3050 |
|
@@ -3397,7 +3398,8 @@ def create_ui(manager: IssueManager) -> gr.Blocks:
|
|
3397 |
// Get the text content of the AI output Markdown block
|
3398 |
const text = aiOutput.textContent || aiOutput.innerText;
|
3399 |
// Use regex to find the content within the ```diff ``` block
|
3400 |
-
|
|
|
3401 |
if (diffMatch && diffMatch[1]) {{
|
3402 |
navigator.clipboard.writeText(diffMatch[1].trim()).then(() => {{
|
3403 |
console.log("Patch copied to clipboard.");
|
@@ -3422,7 +3424,7 @@ def create_ui(manager: IssueManager) -> gr.Blocks:
|
|
3422 |
|
3423 |
}})(); // End IIFE
|
3424 |
</script>
|
3425 |
-
|
3426 |
# The _js parameter injects the JavaScript code into the Gradio page
|
3427 |
demo_app.load(_js=web_socket_js(WS_PORT, GRADIO_PORT), fn=None, inputs=None, outputs=None)
|
3428 |
|
@@ -3436,7 +3438,7 @@ async def handle_ws_connection(websocket: WebSocketServerProtocol, path: str, ma
|
|
3436 |
setattr(websocket, 'client_id', client_id)
|
3437 |
remote_addr = websocket.remote_address
|
3438 |
logger.info(f"WebSocket client connected: {remote_addr} assigned ID {client_id}")
|
3439 |
-
|
3440 |
# Add the new client to the list of active clients
|
3441 |
manager.ws_clients.append(websocket)
|
3442 |
logger.info(f"Client list size: {len(manager.ws_clients)}")
|
@@ -3483,11 +3485,8 @@ async def handle_ws_connection(websocket: WebSocketServerProtocol, path: str, ma
|
|
3483 |
delta_str = data.get("delta")
|
3484 |
# Ensure data is valid and sender ID matches
|
3485 |
if issue_num is not None and delta_str is not None and sender_id == client_id:
|
3486 |
-
#
|
3487 |
-
|
3488 |
-
manager.main_loop.call_soon_threadsafe(asyncio.create_task, manager.handle_code_editor_update(int(issue_num), delta_str, sender_id))
|
3489 |
-
else:
|
3490 |
-
logger.warning("Main loop not running, cannot process code update.")
|
3491 |
else:
|
3492 |
logger.warning(f"Invalid or unauthorized 'code_update' message from {sender_id}: Missing issue_num/delta or sender mismatch. Data: {str(data)[:200]}")
|
3493 |
|
@@ -3796,4 +3795,4 @@ if __name__ == "__main__":
|
|
3796 |
logger.info("Closing asyncio loop.")
|
3797 |
loop.close()
|
3798 |
|
3799 |
-
logger.info("Application shutdown complete.")
|
|
|
766 |
if e.status == 404: error_msg = f"Error: Repository not found at {self.repo_url}."
|
767 |
elif e.status == 401: error_msg = "Error: Invalid GitHub token or insufficient permissions for this repository."
|
768 |
elif e.status == 403:
|
769 |
+
rate_limit_remaining = e.headers.get('X-RateLimit-Remaining') # FIX: Access rate_limit_remaining from error headers
|
770 |
rate_limit_reset = e.headers.get('X-RateLimit-Reset')
|
771 |
reset_time_str = "unknown"
|
772 |
if rate_limit_reset:
|
|
|
1573 |
if self.main_loop.is_running():
|
1574 |
self.main_loop.call_soon_threadsafe(self.remove_ws_client, client)
|
1575 |
else:
|
1576 |
+
logger.warning("Main loop not running, cannot schedule client removal.")
|
1577 |
continue # Skip to next client
|
1578 |
|
1579 |
|
1580 |
# No need to await tasks here if remove_ws_client is scheduled via call_soon_threadsafe
|
|
|
1581 |
|
1582 |
except asyncio.CancelledError:
|
1583 |
logger.info("Broadcast loop cancelled.")
|
|
|
1633 |
tasks.append(client.send(update_payload))
|
1634 |
except (ConnectionClosed, ConnectionAbortedError, ConnectionResetError, WebSocketException) as e:
|
1635 |
logger.warning(f"Client {getattr(client, 'client_id', client.remote_address)} seems disconnected during broadcast: {type(e).__name__}. Attempting removal.")
|
1636 |
+
# Schedule removal in the main loop if not already in it
|
1637 |
if self.main_loop.is_running():
|
1638 |
self.main_loop.call_soon_threadsafe(self.remove_ws_client, client)
|
1639 |
else:
|
|
|
1743 |
tasks = []
|
1744 |
# No need for disconnected_clients list here, remove_ws_client handles it
|
1745 |
|
1746 |
+
for client in active_clients_snapshot:
|
1747 |
# Check if client is closed using the standard websockets property
|
1748 |
if client.closed:
|
1749 |
continue
|
|
|
1764 |
logger.warning("Main loop not running, cannot schedule client removal.")
|
1765 |
continue
|
1766 |
|
1767 |
+
if tasks:
|
1768 |
+
logger.debug(f"Broadcasting single status update to {len(tasks)} clients.")
|
1769 |
+
# No need to await tasks here if remove_ws_client is scheduled via call_soon_threadsafe
|
1770 |
|
1771 |
|
1772 |
def _identify_stale_issues(self):
|
|
|
2594 |
files_content[file_path_str] = f"# File path resolved outside repository: {file_path_str}"
|
2595 |
else:
|
2596 |
logger.warning(f"On-demand file path {file_path_str} not found or not a file during load for issue {selected_id}.")
|
2597 |
+
files_content[file_path_str] = f"# File not found or not a file: {file_path_str}"
|
2598 |
except Exception as e:
|
2599 |
logger.warning(f"Error reading on-demand file {full_path} for issue {selected_id}: {e}")
|
2600 |
files_content[file_path_str] = f"# Error reading file: {e}"
|
|
|
2670 |
# Expanded stop words list (lowercase)
|
2671 |
stop_words = set("a an the is are was were be been being has have had do does did will would shall should can could may might must it its this that these those there their then than and or but if because as at by for with without about against between into through during before after above below to from up down in out on off over under again further then once here there when where why how all any both each few more most other some such no nor not only own same so than too very s t can will just don should now d ll m o re ve yo ain aren couldn didn doesn isn it's mustn ouren shan shouldn wasn weren won wouldn".split())
|
2672 |
# Add common code/issue terms (lowercase)
|
2673 |
+
stop_words.update({'issue', 'bug', 'error', 'fix', 'feat', 'chore', 'refactor', 'docs', 'test', 'file', 'line', 'code', 'when', 'user', 'report', 'problem', 'need', 'want', 'get', 'use', 'try', 'make', 'add', 'remove', 'change', 'update', 'create', 'build', 'run', 'start', 'stop', 'click', 'button', 'page', 'app', 'data', 'system', 'service', 'component', 'module', 'function', 'class', 'method', 'variable', 'value', 'string', 'number', 'list', 'dict', 'object', 'array', 'true', 'false', 'null', 'none', 'type', 'size', 'color', 'style', 'width', 'height', 'margin', 'padding', 'border', 'display', 'position', 'float', 'clear', 'overflow', 'index', 'key', 'value', 'id', 'name', 'text', 'html', 'css', 'js', 'py', 'java', 'c', 'cpp', 'h', 'hpp', 'go', 'rs', 'php', 'rb', 'json', 'yaml', 'xml', 'sql', 'log', 'config', 'setup', 'install', 'version', 'release', 'branch', 'commit', 'pull', 'request', 'merge', 'diff', 'patch', 'context', 'suggestion', 'analysis', 'missing', 'information', 'duplicate', 'potential', 'cluster', 'severity', 'label', 'assignee', 'state', 'title', 'body', 'url', 'created', 'updated', 'time', 'day', 'week', 'month', 'year', 'ago', 'now', 'new', 'old', 'different', 'same', 'similar', 'group', 'count', 'distribution', 'analytics', 'overview', 'studio', 'board', 'resolution', 'collaborative', 'editor', 'context', 'aware', 'assistance', 'tools', 'output', 'patch', 'steps', 'approach', 'plan', 'identify', 'propose', 'recommendation', 'workflow', 'standard', 'important', 'critical', 'high', 'medium', 'low', 'unknown', 'none', 'needed', 'analysis', 'hypothesis', 'preliminary', 'relevant', 'area', 'investigation', 'implementation', 'testing', 'next'})
|
2674 |
|
2675 |
|
2676 |
def get_top_keywords(indices):
|
|
|
3045 |
}}
|
3046 |
}} else {{
|
3047 |
console.warn("Row for issue ID", issueId, "not found in the dataframe.");
|
3048 |
+
updateStatusBar(`Issue #${{issueId}} not found in the current list. Try re-scanning.`, true);
|
3049 |
}}
|
3050 |
}};
|
3051 |
|
|
|
3398 |
// Get the text content of the AI output Markdown block
|
3399 |
const text = aiOutput.textContent || aiOutput.innerText;
|
3400 |
// Use regex to find the content within the ```diff ``` block
|
3401 |
+
// FIX: Escape the backslash in the regex for newline
|
3402 |
+
const diffMatch = text.match(/```diff\\n(.*?)```/s);
|
3403 |
if (diffMatch && diffMatch[1]) {{
|
3404 |
navigator.clipboard.writeText(diffMatch[1].trim()).then(() => {{
|
3405 |
console.log("Patch copied to clipboard.");
|
|
|
3424 |
|
3425 |
}})(); // End IIFE
|
3426 |
</script>
|
3427 |
+
"""
|
3428 |
# The _js parameter injects the JavaScript code into the Gradio page
|
3429 |
demo_app.load(_js=web_socket_js(WS_PORT, GRADIO_PORT), fn=None, inputs=None, outputs=None)
|
3430 |
|
|
|
3438 |
setattr(websocket, 'client_id', client_id)
|
3439 |
remote_addr = websocket.remote_address
|
3440 |
logger.info(f"WebSocket client connected: {remote_addr} assigned ID {client_id}")
|
3441 |
+
|
3442 |
# Add the new client to the list of active clients
|
3443 |
manager.ws_clients.append(websocket)
|
3444 |
logger.info(f"Client list size: {len(manager.ws_clients)}")
|
|
|
3485 |
delta_str = data.get("delta")
|
3486 |
# Ensure data is valid and sender ID matches
|
3487 |
if issue_num is not None and delta_str is not None and sender_id == client_id:
|
3488 |
+
# FIX: Corrected call - handle_ws_connection is already async, just await the async manager method
|
3489 |
+
await manager.handle_code_editor_update(int(issue_num), delta_str, sender_id)
|
|
|
|
|
|
|
3490 |
else:
|
3491 |
logger.warning(f"Invalid or unauthorized 'code_update' message from {sender_id}: Missing issue_num/delta or sender mismatch. Data: {str(data)[:200]}")
|
3492 |
|
|
|
3795 |
logger.info("Closing asyncio loop.")
|
3796 |
loop.close()
|
3797 |
|
3798 |
+
logger.info("Application shutdown complete.")
|