feat(api): implement phase 3 comprehensive control endpoints

This commit is contained in:
2026-03-11 23:14:09 -04:00
parent e88f0f1831
commit 4777dd957a
4 changed files with 132 additions and 9 deletions

View File

@@ -519,6 +519,90 @@ class HookHandler(BaseHTTPRequestHandler):
else:
self.send_response(404)
self.end_headers()
elif self.path == "/api/mma/workers/spawn":
def spawn_worker():
try:
func = _get_app_attr(app, "_spawn_worker")
if func: func(data)
except Exception as e:
sys.stderr.write(f"[DEBUG] Hook API spawn_worker error: {e}\n")
sys.stderr.flush()
lock = _get_app_attr(app, "_pending_gui_tasks_lock")
tasks = _get_app_attr(app, "_pending_gui_tasks")
if lock and tasks is not None:
with lock: tasks.append({"action": "custom_callback", "callback": spawn_worker})
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({"status": "queued"}).encode("utf-8"))
elif self.path == "/api/mma/workers/kill":
def kill_worker():
try:
worker_id = data.get("worker_id")
func = _get_app_attr(app, "_kill_worker")
if func: func(worker_id)
except Exception as e:
sys.stderr.write(f"[DEBUG] Hook API kill_worker error: {e}\n")
sys.stderr.flush()
lock = _get_app_attr(app, "_pending_gui_tasks_lock")
tasks = _get_app_attr(app, "_pending_gui_tasks")
if lock and tasks is not None:
with lock: tasks.append({"action": "custom_callback", "callback": kill_worker})
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({"status": "queued"}).encode("utf-8"))
elif self.path == "/api/mma/pipeline/pause":
def pause_pipeline():
_set_app_attr(app, "mma_step_mode", True)
lock = _get_app_attr(app, "_pending_gui_tasks_lock")
tasks = _get_app_attr(app, "_pending_gui_tasks")
if lock and tasks is not None:
with lock: tasks.append({"action": "custom_callback", "callback": pause_pipeline})
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({"status": "queued"}).encode("utf-8"))
elif self.path == "/api/mma/pipeline/resume":
def resume_pipeline():
_set_app_attr(app, "mma_step_mode", False)
lock = _get_app_attr(app, "_pending_gui_tasks_lock")
tasks = _get_app_attr(app, "_pending_gui_tasks")
if lock and tasks is not None:
with lock: tasks.append({"action": "custom_callback", "callback": resume_pipeline})
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({"status": "queued"}).encode("utf-8"))
elif self.path == "/api/context/inject":
def inject_context():
files = _get_app_attr(app, "files")
if isinstance(files, list):
files.extend(data.get("files", []))
lock = _get_app_attr(app, "_pending_gui_tasks_lock")
tasks = _get_app_attr(app, "_pending_gui_tasks")
if lock and tasks is not None:
with lock: tasks.append({"action": "custom_callback", "callback": inject_context})
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({"status": "queued"}).encode("utf-8"))
elif self.path == "/api/mma/dag/mutate":
def mutate_dag():
try:
func = _get_app_attr(app, "_mutate_dag")
if func: func(data)
except Exception as e:
sys.stderr.write(f"[DEBUG] Hook API mutate_dag error: {e}\n")
sys.stderr.flush()
lock = _get_app_attr(app, "_pending_gui_tasks_lock")
tasks = _get_app_attr(app, "_pending_gui_tasks")
if lock and tasks is not None:
with lock: tasks.append({"action": "custom_callback", "callback": mutate_dag})
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({"status": "queued"}).encode("utf-8"))
else:
self.send_response(404)
self.end_headers()