feat(mma): Implement MMA Dashboard, Event Handling, and Step Approval Modal in gui_2.py

This commit is contained in:
2026-02-26 21:46:05 -05:00
parent 51918d9bc3
commit 63a82e0d15
2 changed files with 171 additions and 2 deletions

View File

@@ -1,6 +1,9 @@
import ai_client
import json
import asyncio
from typing import List, Optional
from dataclasses import asdict
import events
from models import Ticket, Track, WorkerContext
from file_cache import ASTParser
@@ -8,8 +11,24 @@ class ConductorEngine:
"""
Orchestrates the execution of tickets within a track.
"""
def __init__(self, track: Track):
def __init__(self, track: Track, event_queue: Optional[events.AsyncEventQueue] = None):
self.track = track
self.event_queue = event_queue
async def _push_state(self, status: str = "running", active_tier: str = None):
if not self.event_queue:
return
payload = {
"status": status,
"active_tier": active_tier,
"track": {
"id": self.track.id,
"title": self.track.description,
},
"tickets": [asdict(t) for t in self.track.tickets]
}
await self.event_queue.put("mma_state_update", payload)
def parse_json_tickets(self, json_str: str):
"""
@@ -38,13 +57,15 @@ class ConductorEngine:
except KeyError as e:
print(f"Missing required field in ticket definition: {e}")
def run_linear(self):
async def run_linear(self):
"""
Executes tickets sequentially according to their dependencies.
Iterates through the track's executable tickets until no more can be run.
Supports dynamic execution as tickets added during runtime will be picked up
in the next iteration of the main loop.
"""
await self._push_state(status="running", active_tier="Tier 2 (Tech Lead)")
while True:
executable = self.track.get_executable_tickets()
if not executable:
@@ -52,14 +73,17 @@ class ConductorEngine:
all_done = all(t.status == "completed" for t in self.track.tickets)
if all_done:
print("Track completed successfully.")
await self._push_state(status="done", active_tier=None)
else:
# If we have no executable tickets but some are not completed, we might be blocked
# or there are simply no more tickets to run at this moment.
incomplete = [t for t in self.track.tickets if t.status != "completed"]
if not incomplete:
print("Track completed successfully.")
await self._push_state(status="done", active_tier=None)
else:
print(f"No more executable tickets. {len(incomplete)} tickets remain incomplete.")
await self._push_state(status="blocked", active_tier=None)
break
for ticket in executable:
@@ -69,6 +93,9 @@ class ConductorEngine:
continue
print(f"Executing ticket {ticket.id}: {ticket.description}")
ticket.status = "running"
await self._push_state(active_tier=f"Tier 3 (Worker): {ticket.id}")
# For now, we use a default model name or take it from config
context = WorkerContext(
ticket_id=ticket.id,
@@ -76,6 +103,7 @@ class ConductorEngine:
messages=[]
)
run_worker_lifecycle(ticket, context)
await self._push_state(active_tier="Tier 2 (Tech Lead)")
def confirm_execution(payload: str) -> bool:
"""