Spaces:
Runtime error
Runtime error
import gradio as gr | |
import os | |
import requests | |
from git import Repo, GitCommandError | |
from pathlib import Path | |
from datetime import datetime | |
import shutil | |
import time | |
# ========== Configuration ========== | |
REPO_OWNER = "enricoros" | |
REPO_NAME = "big-agi" | |
MIAGI_FORK = "https://github.com/Ig0tU/miagi.git" | |
WORKSPACE = Path("/tmp/issue_workspace") | |
WORKSPACE.mkdir(exist_ok=True) | |
# ========== Theme & Styling ========== | |
theme = gr.themes.Default( | |
primary_hue="emerald", | |
secondary_hue="zinc", | |
).set( | |
button_primary_background_fill="*primary_500", | |
button_primary_background_fill_hover="*primary_400", | |
button_primary_text_color="white", | |
block_label_background_fill="*primary_500", | |
block_label_text_color="white", | |
) | |
# ========== State Management ========== | |
class IssueManager: | |
def __init__(self): | |
self.issues = {} | |
self.last_fetched = None | |
self.current_issue = None | |
self.repo = None | |
def fetch_issues(self): | |
if self.last_fetched and (datetime.now() - self.last_fetched).seconds < 300: | |
return True | |
try: | |
response = requests.get( | |
f"https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/issues", | |
headers={"Authorization": f"Bearer {os.environ.get('GITHUB_TOKEN', '')}"} | |
) | |
response.raise_for_status() | |
self.issues = {issue['number']: issue for issue in response.json()} | |
self.last_fetched = datetime.now() | |
return True | |
except Exception as e: | |
print(f"Error fetching issues: {e}") | |
return False | |
issue_manager = IssueManager() | |
# ========== Core Functions ========== | |
def replicate_issue(issue_number): | |
try: | |
issue_number = int(issue_number) | |
if not issue_manager.fetch_issues(): | |
return {"error": "β οΈ Failed to fetch issues from GitHub"}, None, None | |
if issue_number not in issue_manager.issues: | |
return {"error": f"β Issue #{issue_number} not found"}, None, None | |
issue = issue_manager.issues[issue_number] | |
repo_path = WORKSPACE / f"miagi-{issue_number}" | |
# Clone repository | |
try: | |
repo = Repo.clone_from(MIAGI_FORK, repo_path, branch="main") | |
except GitCommandError: | |
repo = Repo(repo_path) | |
# Create working branch | |
branch_name = f"issue-{issue_number}" | |
repo.git.checkout('-b', branch_name) | |
# Simulate issue replication | |
issues_dir = repo_path / "issues" / str(issue_number) | |
issues_dir.mkdir(parents=True, exist_ok=True) | |
(issues_dir / "replication.log").write_text(f"Replicated at {datetime.utcnow()} UTC") | |
issue_manager.repo = repo | |
issue_manager.current_issue = issue_number | |
return { | |
"success": f"π Replicated issue #{issue_number} in branch '{branch_name}'" | |
}, issue["body"], gr.update(visible=True) | |
except Exception as e: | |
return {"error": f"β Critical error: {str(e)}"}, None, None | |
def resolve_issue(resolution_notes): | |
if not issue_manager.current_issue: | |
return {"error": "β οΈ No active issue selected"}, None | |
try: | |
repo = issue_manager.repo | |
issue_number = issue_manager.current_issue | |
resolution_dir = repo.working_dir / "issues" / str(issue_number) | |
# Create resolution files | |
timestamp = datetime.utcnow().strftime("%Y%m%d-%H%M%S") | |
(resolution_dir / f"resolution_{timestamp}.md").write_text(resolution_notes) | |
(resolution_dir / "RESOLVED").touch() | |
return {"success": "π§ Resolution draft saved locally"}, gr.update(visible=True) | |
except Exception as e: | |
return {"error": f"β Resolution failed: {str(e)}"}, None | |
def submit_resolution(): | |
if not issue_manager.current_issue: | |
return {"error": "β οΈ No active issue selected"} | |
try: | |
repo = issue_manager.repo | |
issue_number = issue_manager.current_issue | |
# Stage changes | |
repo.git.add(all=True) | |
# Commit | |
commit_message = f"Resolve #{issue_number}: {issue_manager.issues[issue_number]['title']}" | |
repo.index.commit(commit_message) | |
# Push | |
origin = repo.remote(name='origin') | |
origin.push(refspec=f"issue-{issue_number}:issue-{issue_number}") | |
# Create PR | |
pr_url = f"https://github.com/Ig0tU/miagi/compare/issue-{issue_number}?expand=1" | |
return { | |
"success": f"π Resolution submitted!\n\n[Review PR]({pr_url})", | |
"pr_url": pr_url | |
} | |
except GitCommandError as e: | |
return {"error": f"β Git operation failed: {str(e)}"} | |
except Exception as e: | |
return {"error": f"β Submission failed: {str(e)}"} | |
# ========== UI Components ========== | |
def create_header(): | |
with gr.Row(): | |
gr.Markdown(""" | |
# π Issue Resolution Workshop | |
### β‘ Power Tools for GitHub Issue Management | |
""") | |
gr.Image(value="https://img.icons8.com/3d-fluency/94/github.png", width=94, height=94) | |
def create_workflow_tabs(): | |
with gr.Tabs() as tabs: | |
with gr.TabItem("π Investigate", id=1): | |
with gr.Row(): | |
with gr.Column(scale=1): | |
issue_input = gr.Number(label="ISSUE NUMBER", precision=0) | |
gr.Button("π‘ Sync GitHub Issues", variant="secondary").click( | |
fn=lambda: issue_manager.fetch_issues(), | |
outputs=None | |
) | |
with gr.Column(scale=2): | |
status_output = gr.JSON(label="STATUS") | |
replicate_btn = gr.Button("β‘ Replicate Issue", variant="primary") | |
with gr.TabItem("π§ Resolve", id=2): | |
with gr.Row(): | |
with gr.Column(): | |
issue_desc = gr.Markdown("### Issue details will appear here") | |
resolution_input = gr.Textbox(label="Resolution Notes", lines=8, | |
placeholder="Describe your solution...") | |
resolve_btn = gr.Button("πΎ Save Resolution", variant="primary") | |
with gr.Column(): | |
resolution_proof = gr.FileExplorer(label="Resolution Artifacts") | |
with gr.TabItem("π Deploy", id=3): | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown("### Deployment Checklist") | |
gr.CheckboxGroup(["β Tests passing", "β Code reviewed", "β Documentation updated"]) | |
deploy_btn = gr.Button("π₯ Submit Resolution", variant="primary") | |
with gr.Column(): | |
pr_output = gr.Markdown() | |
return (issue_input, replicate_btn, status_output, issue_desc, | |
resolution_input, resolve_btn, deploy_btn, pr_output) | |
# ========== App Assembly ========== | |
with gr.Blocks(theme=theme, css="footer {visibility: hidden}") as app: | |
create_header() | |
components = create_workflow_tabs() | |
(issue_input, replicate_btn, status_output, issue_desc, | |
resolution_input, resolve_btn, deploy_btn, pr_output) = components | |
# Event handlers | |
replicate_event = replicate_btn.click( | |
fn=replicate_issue, | |
inputs=issue_input, | |
outputs=[status_output, issue_desc, gr.Tabs(selected=1)] | |
) | |
resolve_event = resolve_btn.click( | |
fn=resolve_issue, | |
inputs=resolution_input, | |
outputs=[status_output, deploy_btn] | |
) | |
deploy_event = deploy_btn.click( | |
fn=submit_resolution, | |
outputs=[status_output, pr_output] | |
) | |
# Progress animations | |
replicate_event.then( | |
fn=lambda: gr.update(visible=True), | |
outputs=resolve_btn | |
) | |
# ========== Execution ========== | |
if __name__ == "__main__": | |
app.launch(server_port=7860, share=True) |