CoolFace
Apppublic

shaibu01/Titan-Engine

sourceHugging Faceupdated 2d agoView on Hugging Face
0likes
space_supervisor.py423 linesDownload Raw Back to root
1#!/usr/bin/env python32"""Run Titan's autonomous cloud core independently of the Streamlit session.3 4Hugging Face can keep a Space container alive without an attached browser5session.  The execution/provider core therefore must be owned by the container6process, not by Streamlit's per-session script lifecycle.7"""8 9from __future__ import annotations10 11import os12import json13import signal14import shutil15import subprocess16import sys17import time18from pathlib import Path19from typing import IO, Dict, List, Optional20 21 22ROOT = Path(__file__).resolve().parent23RESTART_FLOOR_SEC = 3.024RESTART_CEILING_SEC = 30.025 26 27def _writable_dir(*candidates: Path) -> Path:28    for candidate in candidates:29        try:30            candidate.mkdir(parents=True, exist_ok=True)31            probe = candidate / ".write_probe"32            probe.write_text("ok", encoding="utf-8")33            probe.unlink(missing_ok=True)34            return candidate35        except Exception:36            continue37    fallback = ROOT / ".titan_runtime"38    fallback.mkdir(parents=True, exist_ok=True)39    return fallback40 41 42def durable_root() -> Path:43    configured = os.getenv("TITAN_SPACE_DURABLE_ROOT", "").strip()44    candidates: List[Path] = []45    if configured:46        candidates.append(Path(configured))47    candidates.extend([Path("/data/titan_engine"), ROOT / ".titan_engine_storage", Path("/tmp/titan_engine")])48    return _writable_dir(*candidates)49 50 51def _truthy_env(name: str, default: bool = False) -> bool:52    text = str(os.getenv(name, "1" if default else "0")).strip().lower()53    if text in {"1", "true", "yes", "on", "enabled"}:54        return True55    if text in {"0", "false", "no", "off", "disabled"}:56        return False57    return bool(default)58 59 60def _fresh_start_scrub_default(root: Path) -> bool:61    root_text = str(root)62    hf_runtime = bool(os.getenv("SPACE_ID") or os.getenv("SPACE_HOST") or os.getenv("HF_SPACE_ID"))63    return hf_runtime or root_text == "/data" or root_text.startswith("/data/")64 65 66def fresh_start_scrub_once(root: Path) -> Dict[str, object]:67    scrub_id = os.getenv("TITAN_CLOUD_FRESH_START_SCRUB_ID", "ops_stability_20260826").strip() or "ops_stability_20260826"68    enabled = _truthy_env("TITAN_CLOUD_FRESH_START_SCRUB_ONCE", _fresh_start_scrub_default(root))69    marker = root / f".fresh_start_scrub_{scrub_id}.done"70    report_path = root / "fresh_start_scrub_report.json"71    report: Dict[str, object] = {72        "enabled": bool(enabled),73        "scrub_id": scrub_id,74        "root": str(root),75        "marker": str(marker),76        "deleted": [],77        "errors": [],78        "ts": time.time(),79    }80    if not enabled:81        report["skipped"] = "disabled"82        return report83    if marker.exists():84        report["skipped"] = "already_scrubbed"85        return report86 87    targets = [88        root / "runtime",89        root / "brain_models",90        root / "brain_models_staging",91        root / "storage",92        root / "mlflow",93        root / "logs",94        root / "cache",95        root / "tmp",96        root / "paper_trade_unlock.json",97        ROOT / "runtime",98        ROOT / "brain_models",99        ROOT / "brain_models_staging",100        ROOT / ".titan_engine_storage",101        ROOT / ".pytest_cache",102        ROOT / "__pycache__",103        ROOT / "neural_forge_status.json",104        ROOT / "neural_trainer_boot.log",105        ROOT / "titan_core.log",106    ]107    for pattern in ("*.log", "*.jsonl", "*.tmp", "*.bak", "*.bak_*", "*.sqlite", "*.db"):108        targets.extend(ROOT.glob(pattern))109 110    seen = set()111    root_resolved = str(root.resolve())112    for target in targets:113        try:114            resolved = str(target.resolve()) if target.exists() else str(target)115            if resolved in seen or resolved == str(marker) or resolved == root_resolved:116                continue117            seen.add(resolved)118            if target.is_dir():119                shutil.rmtree(target)120                report["deleted"].append(resolved)121            elif target.exists():122                target.unlink()123                report["deleted"].append(resolved)124        except Exception as exc:125            report["errors"].append({"path": str(target), "error": str(exc)})126 127    for required in (root / "runtime", root / "brain_models", root / "storage", root / "mlflow", root / "cache", root / "logs"):128        try:129            required.mkdir(parents=True, exist_ok=True)130        except Exception as exc:131            report["errors"].append({"path": str(required), "error": str(exc)})132    try:133        report_path.write_text(json.dumps(report, indent=2, sort_keys=True), encoding="utf-8")134        marker.write_text(json.dumps({"scrub_id": scrub_id, "ts": time.time()}, indent=2), encoding="utf-8")135    except Exception as exc:136        report["errors"].append({"path": str(report_path), "error": str(exc)})137    return report138 139 140DURABLE_ROOT = durable_root()141FRESH_START_SCRUB_REPORT = fresh_start_scrub_once(DURABLE_ROOT)142LOG_DIR = _writable_dir(DURABLE_ROOT / "logs", ROOT)143 144 145def child_environment() -> Dict[str, str]:146    env = os.environ.copy()147    runtime_dir = DURABLE_ROOT / "runtime"148    models_dir = DURABLE_ROOT / "brain_models"149    storage_root = DURABLE_ROOT / "storage"150    cache_dir = DURABLE_ROOT / "cache"151    mlflow_dir = DURABLE_ROOT / "mlflow"152    env.update(153        {154            "PYTHONUNBUFFERED": "1",155            "TITAN_CORE_SUPERVISED": "1",156            # The dashboard must never create a second execution core.157            "TITAN_ENABLE_BACKGROUND_CORE": "0",158            "TITAN_SPACE_DURABLE_ROOT": str(DURABLE_ROOT),159            "TITAN_RUNTIME_DIR": str(runtime_dir),160            "TITAN_MODELS_DIR": str(models_dir),161            "TITAN_STORAGE_LOCAL_ROOT": str(storage_root),162            "TITAN_MLFLOW_DIR": str(mlflow_dir),163            "TITAN_TRAINER_STATUS_FILE": str(mlflow_dir / "neural_forge_status.json"),164            "TITAN_OPTUNA_EVENTS_FILE": str(mlflow_dir / "optuna_trials.jsonl"),165            "TITAN_TRAINER_LOG_FILE": str(LOG_DIR / "neural_trainer_boot.log"),166            "TITAN_CORE_LOG_FILE": str(LOG_DIR / "titan_core.log"),167            "TITAN_ALT_DATA_LOG_FILE": str(LOG_DIR / "titan_alt_data.log"),168            "TITAN_ALPACA_LOG_FILE": str(LOG_DIR / "alpaca_direct_feed.log"),169            "TITAN_STREAMLIT_LOG_FILE": str(LOG_DIR / "streamlit.log"),170            "TITAN_PAPER_PROBATION_FILE": env.get("TITAN_PAPER_PROBATION_FILE", str(runtime_dir / "paper_trade_unlock.json")),171            "HF_HOME": str(cache_dir / "hf_home"),172            "TRANSFORMERS_CACHE": str(cache_dir / "transformers"),173            "MPLCONFIGDIR": str(cache_dir / "matplotlib"),174            "TITAN_PROVIDER_ISOLATED_ACCOUNTING": env.get("TITAN_PROVIDER_ISOLATED_ACCOUNTING", "1"),175            "TITAN_ALPACA_INDEPENDENT_MODE": env.get("TITAN_ALPACA_INDEPENDENT_MODE", "1"),176            # PU Prime remains connected for telemetry and close-only risk177            # management, but cannot receive new exposure until its sizing and178            # duplicate-entry behavior has completed postmortem validation.179            # PU Prime is quarantined for this release. Keep telemetry, exits,180            # and the isolated $100 shadow audit active without live entries.181            "TITAN_CLOUD_PUPRIME_ENTRY_ENABLED": "0",182            "TITAN_CLOUD_ALPACA_ENTRY_ENABLED": env.get("TITAN_CLOUD_ALPACA_ENTRY_ENABLED", "1"),183            "TITAN_NEURAL_RETRAIN_REQUIRE_FLAT": env.get("TITAN_NEURAL_RETRAIN_REQUIRE_FLAT", "1"),184            "TITAN_REQUIRE_NEURAL_FOR_ENTRIES": env.get("TITAN_REQUIRE_NEURAL_FOR_ENTRIES", "1"),185            "TITAN_REQUIRE_PAPER_PROBATION": env.get("TITAN_REQUIRE_PAPER_PROBATION", "1"),186            "TITAN_PAPER_PROBATION_REQUIRED_WINS": env.get("TITAN_PAPER_PROBATION_REQUIRED_WINS", "3"),187            "TITAN_PAPER_PROBATION_MIN_NET_PNL_PCT": env.get("TITAN_PAPER_PROBATION_MIN_NET_PNL_PCT", "0.01"),188            "TITAN_PAPER_PROBATION_SLIPPAGE_BPS": env.get("TITAN_PAPER_PROBATION_SLIPPAGE_BPS", "8"),189            "TITAN_PAPER_PROBATION_FEE_BPS": env.get("TITAN_PAPER_PROBATION_FEE_BPS", "2"),190            "TITAN_CLOUD_FRESH_START_SCRUB_REPORT": str(DURABLE_ROOT / "fresh_start_scrub_report.json"),191        }192    )193    for path in (194        runtime_dir,195        models_dir,196        storage_root,197        mlflow_dir,198        cache_dir,199        cache_dir / "hf_home",200        cache_dir / "transformers",201        cache_dir / "matplotlib",202    ):203        path.mkdir(parents=True, exist_ok=True)204    return env205 206 207class Child:208    def __init__(self, name: str, command: List[str], log_name: str) -> None:209        self.name = name210        self.command = command211        self.log_path = LOG_DIR / log_name212        self.process: Optional[subprocess.Popen] = None213        self.log_handle: Optional[IO[bytes]] = None214        self.restart_delay = RESTART_FLOOR_SEC215        self.last_start = 0.0216 217    def start(self, env: Dict[str, str]) -> None:218        self.close_log()219        self.log_handle = self.log_path.open("ab", buffering=0)220        self.process = subprocess.Popen(221            self.command,222            cwd=str(ROOT),223            env=env,224            stdout=self.log_handle,225            stderr=subprocess.STDOUT,226            start_new_session=True,227        )228        self.last_start = time.monotonic()229        print(f"[SUPERVISOR] started {self.name} pid={self.process.pid}", flush=True)230 231    def restart_if_needed(self, env: Dict[str, str]) -> None:232        if self.process is not None and self.process.poll() is None:233            return234        return_code = None if self.process is None else self.process.returncode235        alive_for = max(0.0, time.monotonic() - self.last_start)236        if alive_for >= 60.0:237            self.restart_delay = RESTART_FLOOR_SEC238        print(239            f"[SUPERVISOR] {self.name} exited rc={return_code}; "240            f"restart in {self.restart_delay:.1f}s",241            flush=True,242        )243        time.sleep(self.restart_delay)244        self.restart_delay = min(RESTART_CEILING_SEC, self.restart_delay * 2.0)245        self.start(env)246 247    def stop(self) -> None:248        process = self.process249        if process is not None and process.poll() is None:250            try:251                os.killpg(process.pid, signal.SIGTERM)252                process.wait(timeout=10.0)253            except Exception:254                try:255                    os.killpg(process.pid, signal.SIGKILL)256                except Exception:257                    pass258        self.close_log()259 260    def close_log(self) -> None:261        if self.log_handle is not None:262            try:263                self.log_handle.close()264            except Exception:265                pass266            self.log_handle = None267 268 269def brain_artifacts_status(models_dir: Path) -> Dict[str, object]:270    try:271        models_dir.mkdir(parents=True, exist_ok=True)272    except Exception:273        pass274    experts = 0275    for idx in range(1, 51):276        if (models_dir / f"expert_{idx}_gru.pth").exists():277            experts += 1278    params_ready = (models_dir / "optimal_params.json").exists()279    return {280        "experts": int(experts),281        "params_ready": bool(params_ready),282        "ready": bool(params_ready and experts >= 50),283        "models_dir": str(models_dir),284    }285 286 287def _tail_log(path: Path, lines: int = 24) -> str:288    try:289        if not path.exists():290            return ""291        return "".join(path.read_text(encoding="utf-8", errors="ignore").splitlines(True)[-int(lines):])[-4000:]292    except Exception as exc:293        return f"unable to read trainer log: {exc}"294 295 296def _write_training_supervisor_status(env: Dict[str, str], stage: str, **payload: object) -> None:297    path = Path(env.get("TITAN_TRAINER_STATUS_FILE", str(DURABLE_ROOT / "mlflow" / "neural_forge_status.json")))298    try:299        path.parent.mkdir(parents=True, exist_ok=True)300        status = {301            "stage": str(stage),302            "updated_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),303            "supervisor_pid": os.getpid(),304            **payload,305        }306        tmp = path.with_suffix(path.suffix + ".tmp")307        tmp.write_text(json.dumps(status, indent=2, sort_keys=True), encoding="utf-8")308        tmp.replace(path)309    except Exception as exc:310        print(f"[SUPERVISOR] trainer status write failed: {exc}", flush=True)311 312 313class TrainerChild(Child):314    def __init__(self, name: str, command: List[str], log_name: str) -> None:315        super().__init__(name, command, log_name)316        self.last_idle_status = 0.0317 318    def _write_idle_status(self, env: Dict[str, str], models: Dict[str, object], *, reason: str) -> None:319        now = time.time()320        interval = max(30.0, float(env.get("TITAN_TRAINER_IDLE_STATUS_SEC", os.getenv("TITAN_TRAINER_IDLE_STATUS_SEC", "300")) or 300))321        if now - self.last_idle_status < interval:322            return323        self.last_idle_status = now324        _write_training_supervisor_status(325            env,326            "COMPLETE_IDLE",327            forged_experts=models["experts"],328            params_ready=models["params_ready"],329            models_dir=models["models_dir"],330            trainer_running=False,331            idle=True,332            next_training_check_sec=interval,333            reason=reason,334        )335 336    def start(self, env: Dict[str, str]) -> None:337        models = brain_artifacts_status(Path(env["TITAN_MODELS_DIR"]))338        force = _truthy_env("TITAN_FORCE_RETRAIN", False)339        if models["ready"] and not force:340            self._write_idle_status(env, models, reason="complete 50-expert brain already exists; trainer is intentionally stopped")341            print("[SUPERVISOR] neural-trainer skipped; 50-expert brain already exists", flush=True)342            return343        _write_training_supervisor_status(344            env,345            "SUPERVISOR_STARTING_TRAINER",346            forged_experts=models["experts"],347            params_ready=models["params_ready"],348            models_dir=models["models_dir"],349            reason="brain incomplete; trainer child is required",350        )351        super().start(env)352 353    def restart_if_needed(self, env: Dict[str, str]) -> None:354        if self.process is not None and self.process.poll() is None:355            return356        models = brain_artifacts_status(Path(env["TITAN_MODELS_DIR"]))357        if models["ready"]:358            self._write_idle_status(env, models, reason="trainer exited after complete brain artifacts were created; idle until retrain is requested")359            return360        return_code = None if self.process is None else self.process.returncode361        _write_training_supervisor_status(362            env,363            "TRAINER_EXITED_WITHOUT_COMPLETE_SWARM",364            forged_experts=models["experts"],365            params_ready=models["params_ready"],366            models_dir=models["models_dir"],367            return_code=return_code,368            reason=f"neural trainer exited before 50 experts were ready; restart in {self.restart_delay:.1f}s",369            recent_log=_tail_log(self.log_path),370        )371        super().restart_if_needed(env)372 373 374def main() -> int:375    env = child_environment()376    children = [377        TrainerChild("neural-trainer", [sys.executable, "-u", "neural_trainer.py"], "neural_trainer_boot.log"),378        Child("titan-core", [sys.executable, "-u", "titan_core.py"], "titan_core.log"),379        Child("alt-data", [sys.executable, "-u", "titan_alt_data.py"], "titan_alt_data.log"),380    ]381    streamlit = Child(382        "streamlit",383        [384            sys.executable,385            "-m",386            "streamlit",387            "run",388            "app.py",389            "--server.address=0.0.0.0",390            "--server.port=7860",391            "--server.headless=true",392        ],393        "streamlit.log",394    )395    stopping = False396 397    def request_stop(signum, _frame) -> None:398        nonlocal stopping399        print(f"[SUPERVISOR] received signal {signum}; shutting down", flush=True)400        stopping = True401 402    signal.signal(signal.SIGTERM, request_stop)403    signal.signal(signal.SIGINT, request_stop)404 405    try:406        for child in children:407            child.start(env)408        streamlit.start(env)409        while not stopping:410            streamlit.restart_if_needed(env)411            for child in children:412                child.restart_if_needed(env)413            time.sleep(2.0)414    finally:415        streamlit.stop()416        for child in reversed(children):417            child.stop()418    return 0419 420 421if __name__ == "__main__":422    raise SystemExit(main())423