feat(mma): Implement dynamic ticket parsing and dispatcher loop in ConductorEngine
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user