Files
aigc-home/scripts/hel840/restart_config.py
T

121 lines
3.5 KiB
Python

"""Actual server stop/restart and role-routing persistence, isolated from user data."""
import argparse
import json
import subprocess
import time
import urllib.request
from pathlib import Path
parser = argparse.ArgumentParser()
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
root = Path(__file__).resolve().parents[2]
out = args.output.resolve()
out.mkdir(parents=True, exist_ok=True)
base = "http://127.0.0.1:18740"
log = (out / "restart-server.log").open("w")
owned = []
def request(method, path, body=None):
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(
base + path,
data=data,
headers={"Content-Type": "application/json"},
method=method,
)
with urllib.request.urlopen(req, timeout=5) as response:
return json.load(response)
def start(resume=False):
proc = subprocess.Popen(
[
str(root / "calliope-backend/.venv/bin/python"),
str(root / "scripts/hel840/serve_fixture.py"),
"--data",
str(out / "fixture"),
*(["--resume"] if resume else []),
],
cwd=root,
stdout=log,
stderr=subprocess.STDOUT,
)
owned.append(proc)
for _ in range(100):
if proc.poll() is not None:
raise RuntimeError("fixture backend exited")
try:
request("GET", "/api/health")
return proc
except OSError:
time.sleep(0.1)
raise RuntimeError("fixture readiness timeout")
def stop(proc):
if proc.poll() is not None:
return
status = json.loads(
subprocess.check_output(
["multica", "daemon", "status", "--output", "json"], text=True
)
)
def pids(obj):
if isinstance(obj, dict):
return [v for k, v in obj.items() if k in ("pid", "process_id")] + [
n for v in obj.values() for n in pids(v)
]
if isinstance(obj, list):
return [n for v in obj for n in pids(v)]
return []
assert proc.pid not in pids(status)
proc.terminate()
proc.wait(timeout=10)
try:
first = start()
request(
"POST", "/api/settings", {"agent_llm_assignments": {"translate": "fixture-b"}}
)
request("POST", "/api/settings", {"agent_llm_assignments": {"polish": "fixture-a"}})
saved = request("GET", "/api/settings")["agent_llm_assignments"]
assert saved["translate"] == "fixture-b" and saved["polish"] == "fixture-a"
stop(first)
second = start(True)
loaded = request("GET", "/api/settings")["agent_llm_assignments"]
assert loaded == saved
translation = request(
"POST", "/api/prompt-tools/transform", {"action": "translate", "text": "一只猫"}
)
polish = request(
"POST", "/api/prompt-tools/transform", {"action": "polish", "text": "一只猫"}
)
assert (
translation["model"]["id"] == "fixture-b"
and polish["model"]["id"] == "fixture-a"
)
result = {
"before_pid": first.pid,
"after_pid": second.pid,
"assignments": loaded,
"translation_model": translation["model"],
"polish_model": polish["model"],
"passed": True,
}
(out / "restart-check.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2)
)
print(
json.dumps({"passed": True, "before_pid": first.pid, "after_pid": second.pid})
)
finally:
for proc in owned:
stop(proc)
log.close()