naldo commited on
Commit ·
efbddab
1
Parent(s): 2f53f16
Add service watchdog for continuous Minecraft autonomy
Browse files
app.py
CHANGED
|
@@ -528,6 +528,54 @@ def _stream(payload: dict[str, Any]) -> Iterator[str]:
|
|
| 528 |
|
| 529 |
api = FastAPI(title="Programa Voyager OpenAI Endpoint", version="6.0.0")
|
| 530 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 531 |
@api.on_event("startup")
|
| 532 |
def _startup() -> None:
|
| 533 |
if PRELOAD:
|
|
@@ -537,6 +585,7 @@ def _startup() -> None:
|
|
| 537 |
STACK.start_async()
|
| 538 |
if os.environ.get("VOYAGER_AUTOSTART", "1") == "1":
|
| 539 |
VOYAGER.start_async()
|
|
|
|
| 540 |
|
| 541 |
@api.get("/")
|
| 542 |
def root():
|
|
@@ -560,6 +609,9 @@ def health():
|
|
| 560 |
"embedding_error": _embed_error or None,
|
| 561 |
"backend": "cpu-only",
|
| 562 |
"n_gpu_layers": 0,
|
|
|
|
|
|
|
|
|
|
| 563 |
"error": _model_error or None,
|
| 564 |
}
|
| 565 |
|
|
|
|
| 528 |
|
| 529 |
api = FastAPI(title="Programa Voyager OpenAI Endpoint", version="6.0.0")
|
| 530 |
|
| 531 |
+
_supervisor_lock = threading.Lock()
|
| 532 |
+
_supervisor_recoveries = 0
|
| 533 |
+
_supervisor_last_action = "startup"
|
| 534 |
+
_supervisor_last_check = 0.0
|
| 535 |
+
|
| 536 |
+
|
| 537 |
+
def _service_supervisor() -> None:
|
| 538 |
+
global _supervisor_recoveries, _supervisor_last_action, _supervisor_last_check
|
| 539 |
+
backoff = 10
|
| 540 |
+
while True:
|
| 541 |
+
try:
|
| 542 |
+
time.sleep(30)
|
| 543 |
+
_supervisor_last_check = time.time()
|
| 544 |
+
mc = STACK.status()
|
| 545 |
+
processes = mc.get("processes") or {}
|
| 546 |
+
critical = ("minecraft", "viaproxy", "friends")
|
| 547 |
+
dead = [name for name in critical if name in processes and not processes[name].get("running")]
|
| 548 |
+
missing = [name for name in critical if mc.get("state") == "running" and name not in processes]
|
| 549 |
+
if mc.get("state") == "error" or dead or missing:
|
| 550 |
+
with _supervisor_lock:
|
| 551 |
+
_supervisor_recoveries += 1
|
| 552 |
+
_supervisor_last_action = f"minecraft recovery #{_supervisor_recoveries}: dead={dead} missing={missing} state={mc.get('state')}"
|
| 553 |
+
VOYAGER.stop()
|
| 554 |
+
STACK.stop()
|
| 555 |
+
time.sleep(backoff)
|
| 556 |
+
STACK.start_async()
|
| 557 |
+
VOYAGER.start_async()
|
| 558 |
+
backoff = min(backoff * 2, 120)
|
| 559 |
+
continue
|
| 560 |
+
|
| 561 |
+
vs = VOYAGER.status()
|
| 562 |
+
if mc.get("state") == "running" and vs.get("state") in {"error", "exited", "stopped"} and not vs.get("running"):
|
| 563 |
+
with _supervisor_lock:
|
| 564 |
+
_supervisor_recoveries += 1
|
| 565 |
+
_supervisor_last_action = f"voyager recovery #{_supervisor_recoveries}: state={vs.get('state')}"
|
| 566 |
+
VOYAGER.start_async()
|
| 567 |
+
backoff = min(backoff * 2, 120)
|
| 568 |
+
continue
|
| 569 |
+
|
| 570 |
+
if mc.get("state") == "running" and vs.get("running"):
|
| 571 |
+
backoff = 10
|
| 572 |
+
_supervisor_last_action = "healthy"
|
| 573 |
+
except Exception as exc:
|
| 574 |
+
_supervisor_last_action = f"supervisor exception: {type(exc).__name__}: {str(exc)[:160]}"
|
| 575 |
+
time.sleep(min(backoff, 120))
|
| 576 |
+
backoff = min(backoff * 2, 120)
|
| 577 |
+
|
| 578 |
+
|
| 579 |
@api.on_event("startup")
|
| 580 |
def _startup() -> None:
|
| 581 |
if PRELOAD:
|
|
|
|
| 585 |
STACK.start_async()
|
| 586 |
if os.environ.get("VOYAGER_AUTOSTART", "1") == "1":
|
| 587 |
VOYAGER.start_async()
|
| 588 |
+
threading.Thread(target=_service_supervisor, daemon=True, name="service-supervisor").start()
|
| 589 |
|
| 590 |
@api.get("/")
|
| 591 |
def root():
|
|
|
|
| 609 |
"embedding_error": _embed_error or None,
|
| 610 |
"backend": "cpu-only",
|
| 611 |
"n_gpu_layers": 0,
|
| 612 |
+
"supervisor_recoveries": _supervisor_recoveries,
|
| 613 |
+
"supervisor_last_action": _supervisor_last_action,
|
| 614 |
+
"supervisor_last_check": _supervisor_last_check or None,
|
| 615 |
"error": _model_error or None,
|
| 616 |
}
|
| 617 |
|