Spaces:
Sleeping
Sleeping
| """ | |
| Evolva Operator Dashboard | |
| Fetches CURRENT_STATE.md from GitHub and displays: | |
| - Current sprint/phase | |
| - Test pass/fail counts | |
| - Recent session count | |
| - Status indicator (GREEN/YELLOW/RED) | |
| """ | |
| import gradio as gr | |
| import requests | |
| import re | |
| import json | |
| from datetime import datetime, timezone | |
| # βββ GitHub Configuration βββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| GITHUB_RAW_URLS = [ | |
| "https://raw.githubusercontent.com/Gudmundur76/manus-persistent-drive/main/CURRENT_STATE.md", | |
| "https://raw.githubusercontent.com/Gudmundur76/ttruthdesk-platform/main/CURRENT_STATE.md", | |
| "https://raw.githubusercontent.com/Gudmundur76/manus-persistent-drive/main/docs/CURRENT_STATE.md", | |
| ] | |
| # βββ Fetch & Parse CURRENT_STATE.md ββββββββββββββββββββββββββββββββββββββββββ | |
| def fetch_current_state(): | |
| """Fetch CURRENT_STATE.md from GitHub, trying multiple known paths.""" | |
| content = None | |
| source_url = None | |
| for url in GITHUB_RAW_URLS: | |
| try: | |
| resp = requests.get(url, timeout=10) | |
| if resp.status_code == 200: | |
| content = resp.text | |
| source_url = url | |
| break | |
| except Exception: | |
| continue | |
| return content, source_url | |
| def parse_state(content: str) -> dict: | |
| """Parse key metrics from CURRENT_STATE.md markdown.""" | |
| state = { | |
| "sprint": "Unknown", | |
| "phase": "Unknown", | |
| "tests_pass": 0, | |
| "tests_fail": 0, | |
| "tests_total": 0, | |
| "sessions": 0, | |
| "status": "YELLOW", | |
| "last_updated": "Unknown", | |
| "raw_content": content | |
| } | |
| if not content: | |
| return state | |
| # Sprint/phase detection | |
| sprint_match = re.search(r'[Ss]print[\s#:]*(\d+)', content) | |
| if sprint_match: | |
| state["sprint"] = f"Sprint {sprint_match.group(1)}" | |
| phase_match = re.search(r'[Pp]hase[\s#:]*(\d+|[A-Za-z]+)', content) | |
| if phase_match: | |
| state["phase"] = f"Phase {phase_match.group(1)}" | |
| # Test counts | |
| pass_match = re.search(r'[Pp]ass(?:ing|ed)?[\s:]*(\d+)', content) | |
| fail_match = re.search(r'[Ff]ail(?:ing|ed)?[\s:]*(\d+)', content) | |
| total_match = re.search(r'[Tt]otal[\s:]*(\d+)\s*[Tt]ests?', content) | |
| if pass_match: | |
| state["tests_pass"] = int(pass_match.group(1)) | |
| if fail_match: | |
| state["tests_fail"] = int(fail_match.group(1)) | |
| if total_match: | |
| state["tests_total"] = int(total_match.group(1)) | |
| elif state["tests_pass"] or state["tests_fail"]: | |
| state["tests_total"] = state["tests_pass"] + state["tests_fail"] | |
| # Session count | |
| session_match = re.search(r'[Ss]ession(?:s)?[\s:]*(\d+)', content) | |
| if session_match: | |
| state["sessions"] = int(session_match.group(1)) | |
| # Status detection | |
| if re.search(r'\bGREEN\b', content): | |
| state["status"] = "GREEN" | |
| elif re.search(r'\bRED\b', content): | |
| state["status"] = "RED" | |
| elif re.search(r'\bYELLOW\b', content): | |
| state["status"] = "YELLOW" | |
| # Last updated | |
| date_match = re.search(r'(?:[Ll]ast [Uu]pdated|[Dd]ate)[\s:]*([0-9]{4}-[0-9]{2}-[0-9]{2})', content) | |
| if date_match: | |
| state["last_updated"] = date_match.group(1) | |
| return state | |
| def get_status_html(status: str) -> str: | |
| colors = { | |
| "GREEN": ("#28a745", "π’", "All systems operational"), | |
| "YELLOW": ("#ffc107", "π‘", "In progress / attention needed"), | |
| "RED": ("#dc3545", "π΄", "Blocked / critical issues"), | |
| } | |
| color, emoji, label = colors.get(status, ("#6c757d", "βͺ", "Unknown")) | |
| return f""" | |
| <div style=' | |
| padding: 16px 24px; | |
| background: {color}22; | |
| border: 2px solid {color}; | |
| border-radius: 12px; | |
| text-align: center; | |
| font-size: 1.4em; | |
| font-weight: bold; | |
| color: {color}; | |
| '> | |
| {emoji} {status} β {label} | |
| </div> | |
| """ | |
| def get_metrics_html(state: dict) -> str: | |
| pass_pct = (state["tests_pass"] / state["tests_total"] * 100) if state["tests_total"] > 0 else 0 | |
| bar_color = "#28a745" if pass_pct >= 80 else "#ffc107" if pass_pct >= 50 else "#dc3545" | |
| return f""" | |
| <div style='display:grid; grid-template-columns:1fr 1fr 1fr 1fr; gap:12px; margin:12px 0;'> | |
| <div style='background:#f8f9fa; border-radius:10px; padding:14px; text-align:center; border:1px solid #dee2e6;'> | |
| <div style='font-size:0.8em; color:#6c757d; text-transform:uppercase; letter-spacing:1px;'>Sprint</div> | |
| <div style='font-size:1.5em; font-weight:bold; color:#0f3460;'>{state["sprint"]}</div> | |
| </div> | |
| <div style='background:#f8f9fa; border-radius:10px; padding:14px; text-align:center; border:1px solid #dee2e6;'> | |
| <div style='font-size:0.8em; color:#6c757d; text-transform:uppercase; letter-spacing:1px;'>Phase</div> | |
| <div style='font-size:1.5em; font-weight:bold; color:#0f3460;'>{state["phase"]}</div> | |
| </div> | |
| <div style='background:#f8f9fa; border-radius:10px; padding:14px; text-align:center; border:1px solid #dee2e6;'> | |
| <div style='font-size:0.8em; color:#6c757d; text-transform:uppercase; letter-spacing:1px;'>Tests</div> | |
| <div style='font-size:1.1em; font-weight:bold;'> | |
| <span style='color:#28a745;'>β {state["tests_pass"]}</span> | |
| / | |
| <span style='color:#dc3545;'>β {state["tests_fail"]}</span> | |
| </div> | |
| <div style='background:#dee2e6; border-radius:4px; height:6px; margin-top:6px;'> | |
| <div style='background:{bar_color}; width:{pass_pct:.0f}%; height:100%; border-radius:4px;'></div> | |
| </div> | |
| </div> | |
| <div style='background:#f8f9fa; border-radius:10px; padding:14px; text-align:center; border:1px solid #dee2e6;'> | |
| <div style='font-size:0.8em; color:#6c757d; text-transform:uppercase; letter-spacing:1px;'>Sessions</div> | |
| <div style='font-size:1.5em; font-weight:bold; color:#0f3460;'>{state["sessions"]}</div> | |
| </div> | |
| </div> | |
| """ | |
| # βββ Main Dashboard Function ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def load_dashboard(): | |
| """Fetch and render the full operator dashboard.""" | |
| fetch_time = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC") | |
| content, source_url = fetch_current_state() | |
| if content is None: | |
| # Graceful fallback when CURRENT_STATE.md is not found | |
| status_html = get_status_html("YELLOW") | |
| metrics_html = """ | |
| <div style='padding:16px; background:#fff3cd; border:1px solid #ffc107; border-radius:8px; text-align:center;'> | |
| <b>β οΈ CURRENT_STATE.md not found</b><br> | |
| Checked paths:<br> | |
| <small> | |
| β’ github.com/Gudmundur76/manus-persistent-drive/main/CURRENT_STATE.md<br> | |
| β’ github.com/Gudmundur76/ttruthdesk-platform/main/CURRENT_STATE.md | |
| </small><br><br> | |
| The file will be created as part of the Evolva deployment pipeline. | |
| </div> | |
| """ | |
| raw_md = "CURRENT_STATE.md not yet available in the GitHub repository.\n\nThis file will be created automatically by the Evolva CI pipeline." | |
| source_info = "Source: Not found (file pending)" | |
| else: | |
| state = parse_state(content) | |
| status_html = get_status_html(state["status"]) | |
| metrics_html = get_metrics_html(state) | |
| raw_md = content | |
| source_info = f"Source: [{source_url}]({source_url})" | |
| header_html = f""" | |
| <div style=' | |
| background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%); | |
| padding: 20px 24px; border-radius: 12px; margin-bottom: 16px; color: white; | |
| '> | |
| <h2 style='margin:0; color:white;'>𧬠Evolva β Operator Dashboard</h2> | |
| <p style='margin:4px 0 0 0; color:#a0c4ff; font-size:0.9em;'> | |
| Last fetched: {fetch_time} | {source_info} | |
| </p> | |
| </div> | |
| """ | |
| return header_html, status_html, metrics_html, raw_md | |
| # βββ Gradio UI ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with gr.Blocks(title="Evolva Operator Dashboard", theme=gr.themes.Soft()) as demo: | |
| with gr.Row(): | |
| refresh_btn = gr.Button("π Refresh Dashboard", variant="primary", size="lg") | |
| header_out = gr.HTML() | |
| status_out = gr.HTML(label="System Status") | |
| metrics_out = gr.HTML(label="Key Metrics") | |
| with gr.Accordion("π Raw CURRENT_STATE.md", open=False): | |
| raw_out = gr.Markdown() | |
| gr.Markdown(""" | |
| --- | |
| **Links:** | |
| [Model Repo](https://huggingface.co/Pippinlitli/evolva-molecular-slm) | | |
| [Inference API](https://huggingface.co/spaces/Pippinlitli/evolva-inference) | | |
| [Frontend Demo](https://huggingface.co/spaces/Pippinlitli/evolva-frontend) | | |
| [GitHub: manus-persistent-drive](https://github.com/Gudmundur76/manus-persistent-drive) | |
| """) | |
| # Auto-load on startup | |
| demo.load(load_dashboard, outputs=[header_out, status_out, metrics_out, raw_out]) | |
| refresh_btn.click(load_dashboard, outputs=[header_out, status_out, metrics_out, raw_out]) | |
| if __name__ == "__main__": | |
| demo.launch() | |