Delegate task execution to native graph runtime
This commit is contained in:
parent
fde298a1b5
commit
8109d01992
6 changed files with 73 additions and 0 deletions
|
|
@ -0,0 +1,19 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("graph", "0002_graphnoderun_visit_index"),
|
||||||
|
("projects", "0002_commitrecord_coder_commitrecord_judge_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="commitrecord",
|
||||||
|
name="graph_run",
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="commits", to="graph.graphrun"),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -173,6 +173,9 @@ class CommitRecord(TimestampedModel):
|
||||||
verification = models.ForeignKey(
|
verification = models.ForeignKey(
|
||||||
"verification.Verification", on_delete=models.SET_NULL, null=True, blank=True, related_name="commits"
|
"verification.Verification", on_delete=models.SET_NULL, null=True, blank=True, related_name="commits"
|
||||||
)
|
)
|
||||||
|
graph_run = models.ForeignKey(
|
||||||
|
"graph.GraphRun", on_delete=models.SET_NULL, null=True, blank=True, related_name="commits"
|
||||||
|
)
|
||||||
sha = models.CharField(max_length=64)
|
sha = models.CharField(max_length=64)
|
||||||
branch_name = models.CharField(max_length=255)
|
branch_name = models.CharField(max_length=255)
|
||||||
message = models.TextField()
|
message = models.TextField()
|
||||||
|
|
|
||||||
29
graph/bootstrap.py
Normal file
29
graph/bootstrap.py
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from graph.models import ExecutionGraphDefinition, ExecutionGraphVersion, ExecutionGraphVersionStatus
|
||||||
|
from graph.task_execution import task_execution_graph_v1
|
||||||
|
|
||||||
|
|
||||||
|
def champion_task_execution_graph_v1() -> ExecutionGraphVersion:
|
||||||
|
spec = task_execution_graph_v1()
|
||||||
|
definition, _ = ExecutionGraphDefinition.objects.get_or_create(
|
||||||
|
name=spec.name,
|
||||||
|
defaults={"graph_type": spec.graph_type, "description": str(spec.metadata.get("description", ""))},
|
||||||
|
)
|
||||||
|
version, created = ExecutionGraphVersion.objects.get_or_create(
|
||||||
|
graph=definition,
|
||||||
|
version=spec.version,
|
||||||
|
defaults={
|
||||||
|
"status": ExecutionGraphVersionStatus.CHAMPION,
|
||||||
|
"graph_spec": spec.to_dict(),
|
||||||
|
"metadata": {"immutable_after_use": True},
|
||||||
|
"promoted_at": timezone.now(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if not created and version.status != ExecutionGraphVersionStatus.CHAMPION:
|
||||||
|
version.status = ExecutionGraphVersionStatus.CHAMPION
|
||||||
|
version.promoted_at = timezone.now()
|
||||||
|
version.save(update_fields=["status", "promoted_at"])
|
||||||
|
return version
|
||||||
|
|
@ -130,6 +130,8 @@ class BuildContextNode(TaskNode):
|
||||||
attempt.save(update_fields=["context_snapshot", "updated_at"])
|
attempt.save(update_fields=["context_snapshot", "updated_at"])
|
||||||
metadata["current_attempt_id"] = str(attempt.id)
|
metadata["current_attempt_id"] = str(attempt.id)
|
||||||
self.save_metadata(context, metadata)
|
self.save_metadata(context, metadata)
|
||||||
|
context.graph_run.task_attempt = attempt
|
||||||
|
context.graph_run.save(update_fields=["task_attempt", "updated_at"])
|
||||||
return NodeResult("COMPLETE", "success", {"attempt_id": str(attempt.id), "attempt_number": attempt.attempt_number})
|
return NodeResult("COMPLETE", "success", {"attempt_id": str(attempt.id), "attempt_number": attempt.attempt_number})
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -306,6 +308,7 @@ class CommitNode(TaskNode):
|
||||||
test_run=test_run,
|
test_run=test_run,
|
||||||
review_id=metadata.get("review_id"),
|
review_id=metadata.get("review_id"),
|
||||||
verification_id=metadata.get("verification_id"),
|
verification_id=metadata.get("verification_id"),
|
||||||
|
graph_run=context.graph_run,
|
||||||
sha=sha,
|
sha=sha,
|
||||||
branch_name=worktree.branch_name,
|
branch_name=worktree.branch_name,
|
||||||
message=f"Artifex task: {task.goal[:80]}",
|
message=f"Artifex task: {task.goal[:80]}",
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,11 @@ from control_plane.events.bus import EventBus
|
||||||
from control_plane.events.models import EventType
|
from control_plane.events.models import EventType
|
||||||
from control_plane.projects.models import CommitRecord, Task, TaskAttempt, TaskStatus, Worktree
|
from control_plane.projects.models import CommitRecord, Task, TaskAttempt, TaskStatus, Worktree
|
||||||
from control_plane.verification.models import VerificationResult
|
from control_plane.verification.models import VerificationResult
|
||||||
|
from graph.bootstrap import champion_task_execution_graph_v1
|
||||||
|
from graph.models import GraphRun
|
||||||
|
from graph.native_runtime import NativeGraphRuntime
|
||||||
from graph.scheduler import TaskScheduler
|
from graph.scheduler import TaskScheduler
|
||||||
|
from graph.task_nodes import TaskExecutionServices, task_execution_registry
|
||||||
from knowledge.context_builder import WorkerContextBuilder
|
from knowledge.context_builder import WorkerContextBuilder
|
||||||
from model_router.router import ModelRouter
|
from model_router.router import ModelRouter
|
||||||
from tools.capabilities import Capability
|
from tools.capabilities import Capability
|
||||||
|
|
@ -45,6 +49,19 @@ class AutonomousTaskLoop:
|
||||||
return task
|
return task
|
||||||
|
|
||||||
def _execute_task(self, task: Task, test_command: list[str]) -> None:
|
def _execute_task(self, task: Task, test_command: list[str]) -> None:
|
||||||
|
graph_version = champion_task_execution_graph_v1()
|
||||||
|
graph_run = GraphRun.objects.create(
|
||||||
|
execution_graph_version=graph_version,
|
||||||
|
project=task.project,
|
||||||
|
milestone=task.milestone,
|
||||||
|
feature=task.feature,
|
||||||
|
task=task,
|
||||||
|
current_node=graph_version.graph_spec["entry"],
|
||||||
|
)
|
||||||
|
services = TaskExecutionServices(self.router, bus=self.bus, test_command=test_command)
|
||||||
|
NativeGraphRuntime(task_execution_registry(services), bus=self.bus).run_until_terminal_or_paused(graph_run)
|
||||||
|
return
|
||||||
|
|
||||||
coder_version = self._champion(AgentRole.CODER)
|
coder_version = self._champion(AgentRole.CODER)
|
||||||
reviewer_version = self._champion(AgentRole.REVIEWER)
|
reviewer_version = self._champion(AgentRole.REVIEWER)
|
||||||
judge_version = self._champion(AgentRole.PROJECT_JUDGE)
|
judge_version = self._champion(AgentRole.PROJECT_JUDGE)
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,8 @@ def assert_accepted_trace(task: Task) -> CommitRecord:
|
||||||
assert review.status == "PASS"
|
assert review.status == "PASS"
|
||||||
assert verification.result == VerificationResult.PASS
|
assert verification.result == VerificationResult.PASS
|
||||||
assert commit.sha
|
assert commit.sha
|
||||||
|
assert commit.graph_run_id is not None
|
||||||
|
assert commit.graph_run.execution_graph_version.graph.name == "task_execution"
|
||||||
assert commit.coder.agent.role == "CODER"
|
assert commit.coder.agent.role == "CODER"
|
||||||
assert commit.reviewer.agent.role == "REVIEWER"
|
assert commit.reviewer.agent.role == "REVIEWER"
|
||||||
assert commit.judge.agent.role == "PROJECT_JUDGE"
|
assert commit.judge.agent.role == "PROJECT_JUDGE"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue