"""Local UI launcher for OBLITERATUS — beautiful terminal experience + Gradio web UI. Usage: obliteratus ui # launch with defaults obliteratus ui --port 8080 --share # public link on custom port obliteratus ui --no-browser # don't auto-open browser obliteratus ui --auth user:pass # basic auth """ from __future__ import annotations import os import pathlib import platform import shutil import sys import tempfile import time from rich.console import Console from rich.panel import Panel from rich.table import Table from obliteratus.credential_sources import secret_available console = Console() # ── ASCII banner ──────────────────────────────────────────────────────────── _BANNER = r""" [bold green] ░▒█▀▀▀█ ░▒█▀▀▄ ░▒█░░░ ▀█▀ ▀▀█▀▀ ░▒█▀▀▀ ░▒█▀▀█ ▒█▀▀█ ▀▀█▀▀ ░▒█░░▒█ ░▒█▀▀▀█ ░▒█░░▒█ ░▒█▀▀▄ ░▒█░░░ ░█░ ░░█░░ ░▒█▀▀▀ ░▒█▄▄▀ ▒█▄▄█ ░░█░░ ░▒█░░▒█ ░░▀▀▀▄▄ ░▒█▄▄▄█ ░▒█▄▄▀ ░▒█▄▄█ ▄█▄ ░░▀░░ ░▒█▄▄▄ ░▒█░▒█ ▒█░▒█ ░░▀░░ ░░▒█▄▄█ ░▒█▄▄▄█ [/bold green] [dim] ════════════════════════════════════════════════════════════════════[/dim] [bold white] MASTER ABLATION SUITE — LOCAL EDITION[/bold white] [dim]//[/dim] [bold green]Free the mind.[/bold green] [dim] ════════════════════════════════════════════════════════════════════[/dim] """ _ASCII_BANNER = """ [bold green]OBLITERATUS[/bold green] [dim]====================================================================[/dim] [bold white]MASTER ABLATION SUITE - LOCAL EDITION[/bold white] [dim]//[/dim] [bold green]Free the mind.[/bold green] [dim]====================================================================[/dim] """ def _banner_for_console() -> str: """Return a startup banner supported by the active stdout encoding.""" encoding = getattr(sys.stdout, "encoding", None) or "utf-8" try: _BANNER.encode(encoding) except (LookupError, UnicodeEncodeError): return _ASCII_BANNER return _BANNER def _detect_gpu() -> list[dict]: """Detect available GPUs and return info dicts.""" gpus = [] try: import torch if torch.cuda.is_available(): for i in range(torch.cuda.device_count()): props = torch.cuda.get_device_properties(i) gpus.append( { "index": i, "name": props.name, "vram_gb": round(props.total_memory / 1024**3, 1), "compute": f"{props.major}.{props.minor}", } ) elif hasattr(torch.backends, "mps") and torch.backends.mps.is_available(): gpus.append( { "index": 0, "name": "Apple Silicon (MPS)", "vram_gb": 0, # shared memory "compute": "mps", } ) except (AttributeError, ImportError, OSError, RuntimeError, ValueError): pass return gpus def _get_disk_free_gb(path: str = "/") -> float: """Return free disk space in GB.""" try: usage = shutil.disk_usage(path) return round(usage.free / 1024**3, 1) except Exception: return 0.0 def _get_ram_gb() -> float: """Return total system RAM in GB.""" try: import psutil return round(psutil.virtual_memory().total / 1024**3, 1) except (AttributeError, ImportError, OSError, RuntimeError, ValueError): pass # Fallback: read from /proc/meminfo on Linux. try: with open("/proc/meminfo") as f: for line in f: if line.startswith("MemTotal:"): kb = int(line.split()[1]) return round(kb / 1024**2, 1) except (OSError, ValueError): pass # macOS and other POSIX systems generally expose physical RAM via sysconf. try: pages = os.sysconf("SC_PHYS_PAGES") page_size = os.sysconf("SC_PAGE_SIZE") if pages > 0 and page_size > 0: return round(pages * page_size / 1024**3, 1) except (AttributeError, OSError, ValueError): pass return 0.0 def _print_system_info(gpus: list[dict]) -> None: """Print a beautiful system info panel.""" table = Table(show_header=False, border_style="green", expand=True, padding=(0, 2)) table.add_column("Key", style="dim", width=18) table.add_column("Value", style="cyan") table.add_row("Platform", f"{platform.system()} {platform.release()}") table.add_row("Python", f"{platform.python_version()}") ram = _get_ram_gb() if ram > 0: table.add_row("System RAM", f"{ram} GB") temp_dir = tempfile.gettempdir() disk = _get_disk_free_gb(temp_dir) if disk > 0: table.add_row(f"Disk Free ({temp_dir})", f"{disk} GB") # PyTorch version try: import torch table.add_row("PyTorch", torch.__version__) except ImportError: table.add_row("PyTorch", "[red]NOT INSTALLED[/red]") # Transformers version try: import transformers table.add_row("Transformers", transformers.__version__) except ImportError: table.add_row("Transformers", "[red]NOT INSTALLED[/red]") # Gradio version try: import gradio table.add_row("Gradio", gradio.__version__) except ImportError: table.add_row("Gradio", "[red]NOT INSTALLED[/red]") # GPU info if gpus: for gpu in gpus: vram = f"{gpu['vram_gb']} GB" if gpu["vram_gb"] > 0 else "shared" table.add_row( f"GPU {gpu['index']}", f"[bold green]{gpu['name']}[/bold green] ({vram}, compute {gpu['compute']})", ) else: table.add_row("GPU", "[yellow]None detected — CPU mode[/yellow]") # HF Token if secret_available("HF_TOKEN"): table.add_row("HF Token", "[green]set[/green]") else: table.add_row("HF Token", "[dim]not set (gated models won't work)[/dim]") console.print(Panel(table, title="[bold green]System Info[/bold green]", border_style="green")) def _compute_tier(gpus: list[dict]) -> str: """Determine the compute tier based on available hardware.""" if not gpus: return "cpu" max_vram = max(g["vram_gb"] for g in gpus) if max_vram >= 80: return "frontier" elif max_vram >= 24: return "large" elif max_vram >= 8: return "medium" elif max_vram > 0: return "small" else: return "mps" # Apple Silicon def _print_recommendations(tier: str) -> None: """Print model recommendations based on detected hardware.""" recs = { "cpu": [ ("distilbert/distilgpt2", "Tiny — 82M params, runs on anything"), ("TinyLlama/TinyLlama-1.1B-Chat-v1.0", "Small — 1.1B params, workable on CPU"), ], "small": [ ("TinyLlama/TinyLlama-1.1B-Chat-v1.0", "1.1B — fits in 4GB"), ("Qwen/Qwen2.5-0.5B-Instruct", "0.5B — very fast on small GPUs"), ("Qwen/Qwen2.5-3B-Instruct", "3B — good quality, ~6GB VRAM"), ], "mps": [ ("TinyLlama/TinyLlama-1.1B-Chat-v1.0", "1.1B — fast on Apple Silicon"), ("Qwen/Qwen2.5-3B-Instruct", "3B — good with shared memory"), ("meta-llama/Llama-3.2-3B-Instruct", "3B — great quality on MPS"), ], "medium": [ ("Qwen/Qwen2.5-7B-Instruct", "7B — excellent quality at 16GB"), ("meta-llama/Llama-3.1-8B-Instruct", "8B — the standard benchmark"), ("mistralai/Mistral-7B-Instruct-v0.3", "7B — fast and capable"), ], "large": [ ("openai/gpt-oss-20b", "20B MoE — flagship, try surgical/nuclear"), ("meta-llama/Llama-3.1-70B-Instruct", "70B — with 4bit quant"), ("Qwen/Qwen3-30B-A3B", "30B MoE — only 3B active"), ], "frontier": [ ("deepseek-ai/DeepSeek-V3", "671B MoE — the frontier"), ("meta-llama/Llama-3.1-70B-Instruct", "70B — full precision"), ("Qwen/Qwen3.5-397B-A17B", "397B MoE — massive"), ], } tier_recs = recs.get(tier, recs["cpu"]) table = Table( title=f"Recommended Models for Your Hardware ({tier.upper()})", border_style="green", ) table.add_column("Model", style="cyan", min_width=40) table.add_column("Notes", style="dim") for model, notes in tier_recs: table.add_row(model, notes) console.print(table) def _print_launch_info( host: str, port: int, share: bool, auth: tuple[str, str] | None, ) -> None: """Print launch configuration.""" parts = [] url = f"http://{'localhost' if host == '0.0.0.0' else host}:{port}" parts.append(f"[bold green]Local URL:[/bold green] {url}") if host == "0.0.0.0": parts.append(f"[bold green]Network URL:[/bold green] http://:{port}") if share: parts.append("[bold green]Share link:[/bold green] [yellow]generating...[/yellow]") if auth: parts.append(f"[bold green]Auth:[/bold green] {auth[0]}:{'*' * len(auth[1])}") parts.append("") parts.append("[dim]Press Ctrl+C to stop the server[/dim]") console.print( Panel( "\n".join(parts), title="[bold green]Launching OBLITERATUS UI[/bold green]", border_style="green", ) ) def launch_local_ui( host: str = "0.0.0.0", port: int = 7860, share: bool = False, open_browser: bool = True, auth: tuple[str, str] | None = None, quiet: bool = False, ) -> None: """Launch the OBLITERATUS Gradio UI with a beautiful local experience. This is the main entry point for ``obliteratus ui``. """ # ── Beautiful startup ────────────────────────────────────────────── if not quiet: console.print(_banner_for_console()) gpus = _detect_gpu() _print_system_info(gpus) console.print() tier = _compute_tier(gpus) _print_recommendations(tier) console.print() _print_launch_info(host, port, share, auth) console.print() # ── Check dependencies ───────────────────────────────────────────── try: import gradio # noqa: F401 except ImportError: console.print( "[bold red]Error:[/bold red] Gradio is not installed.\n" "Install it with: [cyan]pip install -e '.[spaces]'[/cyan]\n" "Or: [cyan]pip install gradio>=5.0[/cyan]" ) sys.exit(1) # ── Import and launch the app ────────────────────────────────────── console.print("[dim]Loading OBLITERATUS UI (this may take a moment on first run)...[/dim]") start = time.time() # app.py lives at the project root, one level above this package. # When installed via pip the root isn't on sys.path, so add it. _project_root = str(pathlib.Path(__file__).resolve().parent.parent) if _project_root not in sys.path: sys.path.insert(0, _project_root) from app import launch as app_launch elapsed = time.time() - start if not quiet: console.print(f"[green]UI loaded in {elapsed:.1f}s[/green]") console.print() app_launch( server_name=host, server_port=port, share=share, inbrowser=open_browser, auth=auth, quiet=quiet, )