Update Athena runtimes and sync live extensions

This commit is contained in:
Mikei386
2026-09-15 08:01:40 +02:00
parent aaa96bbed5
commit 2b727a4d7f
14 changed files with 728 additions and 33 deletions
@@ -54,10 +54,12 @@ class UnixConnection(http.client.HTTPConnection):
self.sock.connect(SOCKET_PATH)
def docker_request(method: str, path: str) -> tuple[int, bytes]:
def docker_request(method: str, path: str, payload: dict | None = None) -> tuple[int, bytes]:
conn = UnixConnection("localhost", timeout=30)
try:
conn.request(method, path, headers={"Content-Type": "application/json"})
body = json.dumps(payload).encode() if payload is not None else None
conn.request(method, path, body=body,
headers={"Content-Type": "application/json"})
response = conn.getresponse()
return response.status, response.read()
finally:
@@ -200,6 +202,69 @@ def video_container() -> dict:
return matches[0]
def docker_exec(item: dict, command: str) -> str:
status, body = docker_request("POST", f"/containers/{item['Id']}/exec", {
"AttachStdout": True, "AttachStderr": True, "Tty": True,
"Cmd": ["/bin/sh", "-c", command],
})
if status != 201:
raise RuntimeError(f"failed to create container exec: HTTP {status}")
exec_id = json.loads(body)["Id"]
status, body = docker_request("POST", f"/exec/{exec_id}/start",
{"Detach": False, "Tty": True})
if status != 200:
raise RuntimeError(f"failed to start container exec: HTTP {status}")
return body.decode(errors="replace").strip()
VIDEO_UI_PROCESSES = r'''for p in /proc/[0-9]*; do
[ -r "$p/cmdline" ] || continue
exe=$(readlink "$p/exe" 2>/dev/null) || continue
c=$(tr '\000' ' ' < "$p/cmdline")
case "${exe##*/}:$c" in
ltx-desktop:*--type=*)
printf '%s\n' "${p##*/}";;
esac
done'''
VIDEO_UI_STATE: str | None = None
def video_ui_state(item: dict | None = None) -> str:
item = item or video_container()
if item.get("State") != "running":
return "unavailable"
output = docker_exec(item, VIDEO_UI_PROCESSES + r''' | while read p; do
state=$(sed -n 's/^State:[[:space:]]*\([A-Z]\).*/\1/p' "/proc/$p/status")
printf '%s\n' "$state"
done''')
states = [line.strip() for line in output.splitlines() if line.strip()]
if not states:
return "unavailable"
return "sleeping" if all(state == "T" for state in states) else "awake"
def cached_video_ui_state(item: dict | None = None) -> str:
global VIDEO_UI_STATE
if VIDEO_UI_STATE is None:
VIDEO_UI_STATE = video_ui_state(item)
return VIDEO_UI_STATE
def set_video_ui(awake: bool) -> dict:
global VIDEO_UI_STATE
with LOCK:
item = video_container()
if item.get("State") != "running":
raise RuntimeError("LTX-2 is not running")
signal = "CONT" if awake else "STOP"
docker_exec(item, VIDEO_UI_PROCESSES +
f''' | while read p; do kill -{signal} "$p"; done''')
time.sleep(0.25)
VIDEO_UI_STATE = video_ui_state(item)
return {"video_ui": VIDEO_UI_STATE}
def stop_video_if_configured() -> None:
if VIDEO_WORKER:
stop_container(video_container(), timeout=30)
@@ -482,6 +547,7 @@ def set_trellis_worker(running: bool) -> dict:
def set_video_worker(running: bool) -> dict:
"""Start LTX-2 exclusively, or stop it before another mode is loaded."""
global VIDEO_UI_STATE
with LOCK:
item = video_container()
if running:
@@ -496,8 +562,10 @@ def set_video_worker(running: bool) -> dict:
stop_voice_tools()
stop_trellis_if_configured()
start_container(item)
VIDEO_UI_STATE = "awake"
else:
stop_container(item, timeout=30)
VIDEO_UI_STATE = "unavailable"
return {"video_worker": VIDEO_WORKER,
"state": "running" if running else "stopped"}
@@ -660,6 +728,7 @@ class Handler(BaseHTTPRequestHandler):
"trellis_health": trellis_health,
"video_worker": video.get("State", "disabled"),
"video_health": video_health,
"video_ui": cached_video_ui_state(video) if video else "unavailable",
"profiles": {name: items.get(name, {}).get(
"State", "missing") for name in ALLOWED}})
except Exception as exc:
@@ -733,6 +802,13 @@ class Handler(BaseHTTPRequestHandler):
log.exception("video worker transition failed")
self.reply(503, {"error": str(exc)})
return
if self.path in {"/workers/video/ui/sleep", "/workers/video/ui/wake"}:
try:
self.reply(200, set_video_ui(self.path.endswith("/wake")))
except Exception as exc:
log.exception("video UI transition failed")
self.reply(503, {"error": str(exc)})
return
worker_paths = {
"/workers/image/start": (IMAGE_WORKER, True),
"/workers/image/stop": (IMAGE_WORKER, False),
+1 -1
View File
@@ -1,6 +1,6 @@
FROM python:3.13.7-slim-bookworm
ARG WHISPER_CPP_VERSION=v1.9.1
ARG WHISPER_CPP_VERSION=v1.9.4
RUN apt-get update \
&& apt-get install -y --no-install-recommends \