from __future__ import annotations from collections import Counter from django.db.models import Count, Q from agents.control_room import AgentControlRoomService from agents.lifecycle import LifecycleInspectionService from agents.roadmap import RoadmapService from agents.scenario_lab import ScenarioLabService from control_plane.agents.models import AgentRun, AgentVersion, ProgenyExperiment, ProgenyInvestigation, ProgenySignal, PromotionStatus from control_plane.events.models import Event from control_plane.projects.models import ExplorationOpportunity, Project, RoadmapHorizon, ScenarioFinding, ScenarioRun, ScenarioSuite, StewardFinding, StewardRun, Task, TaskStatus from control_plane.resources.models import ModelRequest, Resource from graph.models import ExecutionGraphVersionStatus, GraphApproval, GraphApprovalStatus, GraphRun, GraphRunStatus class ControlPlaneUIService: def dashboard(self) -> dict[str, object]: projects = Project.objects.all() graph_runs = GraphRun.objects.select_related("execution_graph_version__graph", "project").order_by("-created_at") steward_findings = StewardFinding.objects.all() progeny_signals = ProgenySignal.objects.all() control_room = AgentControlRoomService() agent_health = [control_room.get_agent_health(version.id)["status"] for version in AgentVersion.objects.filter(promotion_status=PromotionStatus.CHAMPION)] return { "project_summary": {"total": projects.count(), "active": projects.exclude(status__in=["FINISHED", "FAILED"]).count(), "blocked_failed": projects.filter(status__in=["BLOCKED", "FAILED"]).count(), "recent_completed": projects.filter(status="FINISHED").order_by("-updated_at")[:5]}, "execution_summary": {"active": graph_runs.filter(status__in=[GraphRunStatus.PENDING, GraphRunStatus.RUNNING, GraphRunStatus.PAUSED]).count(), "failed": graph_runs.filter(status=GraphRunStatus.FAILED).count(), "recent_success": graph_runs.filter(status=GraphRunStatus.COMPLETE)[:5], "champion_task_graph": self._champion_graph("task_execution")}, "steward_summary": {"enrolled_projects": Project.objects.filter(steward_enrollments__status="ACTIVE").distinct().count(), "open_findings": steward_findings.exclude(status__in=["RESOLVED", "DISMISSED"]).count(), "high_findings": steward_findings.filter(severity__in=["HIGH", "CRITICAL"]).exclude(status__in=["RESOLVED", "DISMISSED"]).count()}, "progeny_summary": {"unresolved_signals": progeny_signals.filter(status="OPEN").count(), "open_investigations": ProgenyInvestigation.objects.filter(status="OPEN").count(), "challengers": AgentVersion.objects.filter(promotion_status=PromotionStatus.CHALLENGER).count(), "pending_experiment_decisions": ProgenyExperiment.objects.filter(status__in=["DRAFT", "RUNNING"]).count()}, "agent_summary": {"agent_count": AgentVersion.objects.values("agent").distinct().count(), "watch_degraded": sum(1 for status in agent_health if status in ["WATCH", "DEGRADED"]), "active_runs": AgentRun.objects.filter(status__in=["QUEUED", "RUNNING"]).count()}, "approval_count": GraphApproval.objects.filter(status=GraphApprovalStatus.PENDING).count(), "recent": {"events": Event.objects.order_by("-created_at")[:10], "tasks": Task.objects.order_by("-updated_at")[:10], "graph_runs": graph_runs[:10], "findings": steward_findings.order_by("-updated_at")[:10], "investigations": ProgenyInvestigation.objects.order_by("-updated_at")[:10]}, } def project_list(self) -> list[dict[str, object]]: rows = [] for project in Project.objects.order_by("name"): rows.append({"project": project, "current_milestone": project.milestones.order_by("order", "created_at").last(), "task_total": project.tasks.count(), "task_complete": project.tasks.filter(status=TaskStatus.COMPLETE).count(), "steward_state": project.steward_enrollments.order_by("-created_at").first(), "open_findings": project.steward_findings.exclude(status__in=["RESOLVED", "DISMISSED"]).count(), "latest_graph_run": project.graph_runs.order_by("-created_at").first(), "warnings": self.project_warnings(project)}) return rows def project_workspace(self, project: Project) -> dict[str, object]: lifecycle = LifecycleInspectionService().project_lifecycle_view(project) return {"project": project, "plan": project.plans.order_by("-version").first(), "milestones": project.milestones.prefetch_related("features__tasks", "tasks").order_by("order", "created_at"), "tasks": project.tasks.select_related("milestone", "feature").order_by("milestone__order", "priority", "created_at"), "graph_runs": project.graph_runs.select_related("execution_graph_version__graph", "task").order_by("-created_at")[:20], "commits": project.commits.order_by("-created_at")[:10], "roadmap": RoadmapService().project_roadmap_view(project), "lifecycle": lifecycle, "scenario_coverage": ScenarioLabService().coverage(project), "activity": Event.objects.filter(project=project).order_by("-created_at")[:20], "warnings": self.project_warnings(project)} def graph_run_detail(self, graph_run: GraphRun) -> dict[str, object]: nodes = list(graph_run.node_runs.select_related("agent_version__agent", "model_request").order_by("created_at", "visit_index")) traversals = list(graph_run.edge_traversals.order_by("created_at")) return {"graph_run": graph_run, "nodes": nodes, "traversals": traversals, "approvals": graph_run.approvals.order_by("-created_at"), "model_request_count": sum(1 for node in nodes if node.model_request_id)} def task_detail(self, task: Task) -> dict[str, object]: return {"task": task, "dependencies": [edge.depends_on for edge in task.dependency_edges.select_related("depends_on")], "attempts": task.attempts.select_related("coder").order_by("attempt_number"), "graph_runs": task.graph_runs.select_related("execution_graph_version__graph").order_by("-created_at"), "tests": task.test_runs.order_by("-created_at"), "reviews": task.reviews.order_by("-created_at"), "commits": task.commits.order_by("-created_at")} def steward(self, project: Project | None = None) -> dict[str, object]: findings = StewardFinding.objects.select_related("project").order_by("-updated_at") runs = StewardRun.objects.select_related("project").order_by("-created_at") if project: findings = findings.filter(project=project) runs = runs.filter(project=project) return {"findings": findings[:100], "runs": runs[:50]} def progeny(self) -> dict[str, object]: signals = ProgenySignal.objects.select_related("project", "agent_version__agent", "execution_graph_version__graph", "graph_node_run").order_by("-created_at") grouped = Counter(signals.filter(status="OPEN").values_list("grouping_key", flat=True)) return {"signals": signals[:100], "groups": grouped.most_common(50), "investigations": ProgenyInvestigation.objects.order_by("-created_at")[:50], "experiments": ProgenyExperiment.objects.order_by("-created_at")[:50]} def roadmap_board(self, project: Project | None = None) -> dict[str, object]: items = Project.objects.none() qs = project.roadmap_items if project else None board = {} for horizon in RoadmapHorizon.values: board[horizon] = (qs.filter(horizon=horizon) if qs else __import__("control_plane.projects.models", fromlist=["RoadmapItem"]).RoadmapItem.objects.filter(horizon=horizon)).select_related("project").order_by("-composite_score", "-priority") return board def scenario_lab(self, project: Project | None = None) -> dict[str, object]: suites = ScenarioSuite.objects.select_related("project").order_by("-created_at") runs = ScenarioRun.objects.select_related("project", "scenario").order_by("-created_at") findings = ScenarioFinding.objects.select_related("project", "scenario").order_by("-created_at") if project: suites = suites.filter(project=project) runs = runs.filter(project=project) findings = findings.filter(project=project) coverage = Counter(ScenarioRun.objects.filter(project=project).values_list("scenario__scenario_type", flat=True) if project else ScenarioRun.objects.values_list("scenario__scenario_type", flat=True)) return {"suites": suites[:50], "runs": runs[:100], "findings": findings[:100], "coverage": dict(coverage)} def resources(self) -> dict[str, object]: rows = [] for resource in Resource.objects.order_by("name"): requests = resource.model_requests.order_by("-created_at") latencies = [value for value in requests.exclude(latency_ms=None).values_list("latency_ms", flat=True)[:50]] rows.append({"resource": resource, "recent_requests": requests[:10], "request_count": requests.count(), "median_latency": sorted(latencies)[len(latencies) // 2] if latencies else None}) return {"resources": rows} def approvals(self) -> dict[str, object]: return {"approvals": GraphApproval.objects.select_related("graph_run__project", "graph_run__execution_graph_version__graph", "node_run").filter(status=GraphApprovalStatus.PENDING).order_by("created_at")} def activity(self, project: Project | None = None) -> dict[str, object]: events = Event.objects.select_related("project", "task").order_by("-created_at") if project: events = events.filter(project=project) return {"events": events[:200]} def project_brain(self, project: Project) -> dict[str, object]: return {"project": project, "decisions": project.decisions.order_by("-created_at"), "plans": project.plans.order_by("-version"), "artifacts": project.artifacts.filter(artifact_type__icontains="PLAN").order_by("-created_at")} def archaeologist(self, project: Project) -> dict[str, object]: archaeology = project.artifacts.filter(artifact_type__icontains="ARCH").order_by("-created_at") return {"project": project, "observed": project.architecture_summary, "artifacts": archaeology, "findings": project.findings.order_by("-created_at")[:50]} def project_warnings(self, project: Project) -> list[str]: warnings = [] if project.graph_runs.filter(status=GraphRunStatus.FAILED).exists(): warnings.append("failed graph runs") if project.tasks.filter(status__in=[TaskStatus.BLOCKED, TaskStatus.FAILED]).exists(): warnings.append("blocked or failed tasks") if project.steward_findings.filter(severity__in=["HIGH", "CRITICAL"]).exclude(status__in=["RESOLVED", "DISMISSED"]).exists(): warnings.append("high severity findings") return warnings def _champion_graph(self, name: str): return __import__("graph.models", fromlist=["ExecutionGraphVersion"]).ExecutionGraphVersion.objects.filter(graph__name=name, status=ExecutionGraphVersionStatus.CHAMPION).select_related("graph").first()