feat(investigation): preserve cumulative reference graphs

Accumulate investigation paths and preserve failed attempts across rounds. Keep graph annotations separate from execution state, synchronize the API contract, and consolidate documentation.
This commit is contained in:
2026-11-11 19:10:41 +08:00
parent e47c61c121
commit b853b61a0b
38 changed files with 2445 additions and 147 deletions
@@ -104,6 +104,19 @@ class TaskRepository:
async def get_latest_progress(self, task_id, generation):
return self.progress.get((task_id, generation))
async def get_latest_graph_progress(self, task_id):
snapshots = [value for (stored_id, _), value in self.progress.items()
if stored_id == task_id
and (value["progress"].get("diagram") or {}).get("edges") is not None]
return max(snapshots, key=lambda row: (row["execution_generation"], row["revision"])) if snapshots else None
async def get_latest_diagram(self, task_id):
diagrams = [(row["published_at"], row["progress"].get("diagram"))
for (stored_id, _), row in self.progress.items() if stored_id == task_id]
diagrams.extend((row["published_at"], row["report"].get("diagram")) for row in self.reports)
return next((diagram for _, diagram in sorted(diagrams, key=lambda item: item[0], reverse=True)
if diagram is not None), None)
async def save_progress(self, task_id, snapshot):
self.progress[(task_id, snapshot["execution_generation"])] = snapshot