Artifex/control_plane/agents/models.py
2026-08-15 13:50:24 +07:00

82 lines
3.6 KiB
Python

from __future__ import annotations
from django.db import models
from control_plane.common import TimestampedModel
class AgentRole(models.TextChoices):
PROJECT_ARCHAEOLOGIST = "PROJECT_ARCHAEOLOGIST"
PLANNER = "PLANNER"
CODER = "CODER"
REVIEWER = "REVIEWER"
PROJECT_JUDGE = "PROJECT_JUDGE"
class PromotionStatus(models.TextChoices):
CANDIDATE = "CANDIDATE"
CHALLENGER = "CHALLENGER"
CHAMPION = "CHAMPION"
REJECTED = "REJECTED"
class Agent(TimestampedModel):
name = models.CharField(max_length=200, unique=True)
role = models.CharField(max_length=80, choices=AgentRole.choices)
description = models.TextField(blank=True)
champion_version = models.ForeignKey(
"AgentVersion", on_delete=models.SET_NULL, null=True, blank=True, related_name="championed_by"
)
class AgentVersion(TimestampedModel):
agent = models.ForeignKey(Agent, on_delete=models.CASCADE, related_name="versions")
version = models.PositiveIntegerField()
model = models.CharField(max_length=120)
system_contract = models.TextField()
capabilities = models.JSONField(default=list, blank=True)
tools = models.JSONField(default=list, blank=True)
permissions = models.JSONField(default=dict, blank=True)
context_policy = models.JSONField(default=dict, blank=True)
workflow = models.JSONField(default=dict, blank=True)
retry_policy = models.JSONField(default=dict, blank=True)
evaluator = models.JSONField(default=dict, blank=True)
benchmark_status = models.CharField(max_length=32, default="UNBENCHMARKED")
promotion_status = models.CharField(max_length=32, choices=PromotionStatus.choices, default=PromotionStatus.CANDIDATE)
class Meta:
constraints = [models.UniqueConstraint(fields=["agent", "version"], name="unique_agent_version")]
class AgentPlan(TimestampedModel):
agent = models.ForeignKey(Agent, on_delete=models.CASCADE, related_name="plans", null=True, blank=True)
name = models.CharField(max_length=200)
role = models.CharField(max_length=80, choices=AgentRole.choices)
model = models.CharField(max_length=120)
system_contract = models.TextField()
capabilities = models.JSONField(default=list, blank=True)
tools = models.JSONField(default=list, blank=True)
permissions = models.JSONField(default=dict, blank=True)
context_policy = models.JSONField(default=dict, blank=True)
workflow = models.JSONField(default=dict, blank=True)
benchmarks = models.JSONField(default=list, blank=True)
success_criteria = models.JSONField(default=dict, blank=True)
created_by = models.CharField(max_length=120, default="sol")
class AgentRun(TimestampedModel):
agent_version = models.ForeignKey(AgentVersion, on_delete=models.PROTECT, related_name="runs")
project = models.ForeignKey("projects.Project", on_delete=models.CASCADE, null=True, blank=True)
task = models.ForeignKey("projects.Task", on_delete=models.SET_NULL, null=True, blank=True)
status = models.CharField(max_length=32, default="QUEUED")
input_contract = models.JSONField(default=dict, blank=True)
output_contract = models.JSONField(default=dict, blank=True)
metrics = models.JSONField(default=dict, blank=True)
class BenchmarkRun(TimestampedModel):
champion = models.ForeignKey(AgentVersion, on_delete=models.PROTECT, related_name="champion_benchmarks")
challenger = models.ForeignKey(AgentVersion, on_delete=models.PROTECT, related_name="challenger_benchmarks")
benchmark_set = models.JSONField(default=list, blank=True)
metrics = models.JSONField(default=dict, blank=True)
decision = models.CharField(max_length=32, default="PENDING")