feat(mma): Implement track-scoped history and optimized sub-agent toolsets
This commit is contained in:
13
gui_2.py
13
gui_2.py
@@ -754,6 +754,12 @@ class App:
|
||||
self.active_track = None
|
||||
self.active_tickets = []
|
||||
|
||||
# Load track-scoped history if track is active
|
||||
if self.active_track:
|
||||
track_history = project_manager.load_track_history(self.active_track.id, self.ui_files_base_dir)
|
||||
if track_history:
|
||||
self.disc_entries = _parse_history_entries(track_history, self.disc_roles)
|
||||
|
||||
def _save_active_project(self):
|
||||
if self.active_project_path:
|
||||
try:
|
||||
@@ -790,6 +796,10 @@ class App:
|
||||
|
||||
def _flush_disc_entries_to_project(self):
|
||||
history_strings = [project_manager.entry_to_str(e) for e in self.disc_entries]
|
||||
if self.active_track:
|
||||
project_manager.save_track_history(self.active_track.id, history_strings, self.ui_files_base_dir)
|
||||
return
|
||||
|
||||
disc_sec = self.project.setdefault("discussion", {})
|
||||
discussions = disc_sec.setdefault("discussions", {})
|
||||
disc_data = discussions.setdefault(self.active_discussion, project_manager.default_discussion())
|
||||
@@ -1398,7 +1408,8 @@ class App:
|
||||
self._save_active_project()
|
||||
self._flush_to_config()
|
||||
save_config(self.config)
|
||||
flat = project_manager.flat_config(self.project, self.active_discussion)
|
||||
track_id = self.active_track.id if self.active_track else None
|
||||
flat = project_manager.flat_config(self.project, self.active_discussion, track_id=track_id)
|
||||
full_md, path, file_items = aggregate.run(flat)
|
||||
# Build stable markdown (no history) for Gemini caching
|
||||
screenshot_base_dir = Path(flat.get("screenshots", {}).get("base_dir", "."))
|
||||
|
||||
@@ -225,11 +225,17 @@ def migrate_from_legacy_config(cfg: dict) -> dict:
|
||||
|
||||
# ── flat config for aggregate.run() ─────────────────────────────────────────
|
||||
|
||||
def flat_config(proj: dict, disc_name: str | None = None) -> dict:
|
||||
def flat_config(proj: dict, disc_name: str | None = None, track_id: str | None = None) -> dict:
|
||||
"""Return a flat config dict compatible with aggregate.run()."""
|
||||
disc_sec = proj.get("discussion", {})
|
||||
name = disc_name or disc_sec.get("active", "main")
|
||||
disc_data = disc_sec.get("discussions", {}).get(name, {})
|
||||
|
||||
if track_id:
|
||||
history = load_track_history(track_id, proj.get("files", {}).get("base_dir", "."))
|
||||
else:
|
||||
name = disc_name or disc_sec.get("active", "main")
|
||||
disc_data = disc_sec.get("discussions", {}).get(name, {})
|
||||
history = disc_data.get("history", [])
|
||||
|
||||
return {
|
||||
"project": proj.get("project", {}),
|
||||
"output": proj.get("output", {}),
|
||||
@@ -237,7 +243,7 @@ def flat_config(proj: dict, disc_name: str | None = None) -> dict:
|
||||
"screenshots": proj.get("screenshots", {}),
|
||||
"discussion": {
|
||||
"roles": disc_sec.get("roles", []),
|
||||
"history": disc_data.get("history", []),
|
||||
"history": history,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -267,3 +273,39 @@ def load_track_state(track_id: str, base_dir: str | Path = ".") -> 'TrackState':
|
||||
with open(state_file, "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
return TrackState.from_dict(data)
|
||||
|
||||
|
||||
def load_track_history(track_id: str, base_dir: str | Path = ".") -> list:
|
||||
"""
|
||||
Loads the discussion history for a specific track from its state.toml.
|
||||
Returns a list of entry strings formatted with @timestamp.
|
||||
"""
|
||||
from models import TrackState
|
||||
state = load_track_state(track_id, base_dir)
|
||||
if not state:
|
||||
return []
|
||||
|
||||
history = []
|
||||
for entry in state.discussion:
|
||||
e = dict(entry)
|
||||
ts = e.get("ts")
|
||||
if isinstance(ts, datetime.datetime):
|
||||
e["ts"] = ts.strftime(TS_FMT)
|
||||
history.append(entry_to_str(e))
|
||||
return history
|
||||
|
||||
|
||||
def save_track_history(track_id: str, history: list, base_dir: str | Path = "."):
|
||||
"""
|
||||
Saves the discussion history for a specific track to its state.toml.
|
||||
'history' is expected to be a list of formatted strings.
|
||||
"""
|
||||
from models import TrackState
|
||||
state = load_track_state(track_id, base_dir)
|
||||
if not state:
|
||||
return
|
||||
|
||||
roles = ["User", "AI", "Vendor API", "System", "Reasoning"]
|
||||
entries = [str_to_entry(h, roles) for h in history]
|
||||
state.discussion = entries
|
||||
save_track_state(track_id, state, base_dir)
|
||||
|
||||
Reference in New Issue
Block a user