feat(mma): Implement dynamic ticket parsing and dispatcher loop in ConductorEngine

This commit is contained in:
2026-02-26 20:40:16 -05:00
parent 0acd1ea442
commit 1dacd3613e
2 changed files with 104 additions and 1 deletions

View File

@@ -1,4 +1,5 @@
import ai_client
import json
from typing import List, Optional
from models import Ticket, Track, WorkerContext
from file_cache import ASTParser
@@ -10,10 +11,39 @@ class ConductorEngine:
def __init__(self, track: Track):
self.track = track
def parse_json_tickets(self, json_str: str):
"""
Parses a JSON string of ticket definitions (Godot ECS Flat List format)
and populates the Track's ticket list.
"""
try:
data = json.loads(json_str)
if not isinstance(data, list):
print("Error: JSON input must be a list of ticket definitions.")
return
for ticket_data in data:
# Construct Ticket object, using defaults for optional fields
ticket = Ticket(
id=ticket_data["id"],
description=ticket_data["description"],
status=ticket_data.get("status", "todo"),
assigned_to=ticket_data.get("assigned_to", "unassigned"),
depends_on=ticket_data.get("depends_on", []),
step_mode=ticket_data.get("step_mode", False)
)
self.track.tickets.append(ticket)
except json.JSONDecodeError as e:
print(f"Error parsing JSON tickets: {e}")
except KeyError as e:
print(f"Missing required field in ticket definition: {e}")
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.
"""
while True:
executable = self.track.get_executable_tickets()
@@ -23,10 +53,21 @@ class ConductorEngine:
if all_done:
print("Track completed successfully.")
else:
print("No more executable tickets. Track may be blocked or finished.")
# 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.")
else:
print(f"No more executable tickets. {len(incomplete)} tickets remain incomplete.")
break
for ticket in executable:
# We re-check status in case it was modified by a parallel/dynamic process
# (though run_linear is currently single-threaded)
if ticket.status != "todo":
continue
print(f"Executing ticket {ticket.id}: {ticket.description}")
# For now, we use a default model name or take it from config
context = WorkerContext(