feat(mma): Enable manual ticket approval via Hook API for Step Mode
This commit is contained in:
@@ -267,3 +267,7 @@ class ApiHookClient:
|
||||
"""Mutates the MMA DAG (Directed Acyclic Graph) structure."""
|
||||
return self._make_request('POST', '/api/mma/dag/mutate', data=data) or {}
|
||||
|
||||
def approve_mma_ticket(self, ticket_id: str) -> dict:
|
||||
"""Manually approves a specific ticket for execution in Step Mode."""
|
||||
return self._make_request('POST', '/api/mma/ticket/approve', data={"ticket_id": ticket_id}) or {}
|
||||
|
||||
|
||||
+18
-1
@@ -605,7 +605,7 @@ class HookHandler(BaseHTTPRequestHandler):
|
||||
elif self.path == "/api/mma/dag/mutate":
|
||||
def mutate_dag():
|
||||
try:
|
||||
func = _get_app_attr(app, "_mutate_dag")
|
||||
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")
|
||||
@@ -618,6 +618,23 @@ class HookHandler(BaseHTTPRequestHandler):
|
||||
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/ticket/approve":
|
||||
ticket_id = data.get("ticket_id")
|
||||
def approve_ticket():
|
||||
try:
|
||||
func = _get_app_attr(app, "approve_ticket")
|
||||
if func: func(ticket_id)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"[DEBUG] Hook API approve_ticket 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": approve_ticket})
|
||||
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()
|
||||
|
||||
@@ -2780,6 +2780,18 @@ class AppController:
|
||||
self.files.append(item)
|
||||
self._refresh_from_project()
|
||||
|
||||
def approve_ticket(self, ticket_id: str) -> None:
|
||||
"""Manually approves a ticket for execution."""
|
||||
if self.engine and self.engine.engine:
|
||||
self.engine.engine.approve_task(ticket_id)
|
||||
else:
|
||||
# Fallback if engine not running
|
||||
for t in self.active_tickets:
|
||||
if t.get('id') == ticket_id:
|
||||
t['status'] = 'in_progress'
|
||||
break
|
||||
self._push_mma_state_update()
|
||||
|
||||
def mutate_dag(self, data: dict) -> None:
|
||||
"""Modifies task dependencies."""
|
||||
ticket_id = data.get("ticket_id")
|
||||
|
||||
+1
-1
@@ -3450,7 +3450,7 @@ def hello():
|
||||
def bulk_execute(self) -> None:
|
||||
for tid in self.ui_selected_tickets:
|
||||
t = next((t for t in self.active_tickets if str(t.get('id', '')) == tid), None)
|
||||
if t: t['status'] = 'ready'
|
||||
if t: t['status'] = 'in_progress'
|
||||
self._push_mma_state_update()
|
||||
|
||||
def bulk_skip(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user