37 lines
1.0 KiB
Python
37 lines
1.0 KiB
Python
from dataclasses import dataclass, field
|
|||
|
|
from datetime import datetime
|
||
|
|
from typing import Optional
|
||
|
|
|
||
|
|
from contracts.Task import Task
|
||
|
|
from contracts.base import BaseContract
|
||
|
|
|
||
|
|
|
||
|
|
class TaskPlan(BaseContract):
|
||
|
|
issue_id: str
|
||
|
|
summary: str
|
||
|
|
tasks: list[Task]
|
||
|
|
parallel_groups: list[list[str]]
|
||
|
|
critical_path: list[str]
|
||
|
|
total_p50: int
|
||
|
|
total_p90: int
|
||
|
|
assumptions: list[str]
|
||
|
|
total_estimate_minutes: Optional[float] = None
|
||
|
|
unknowns: list[str] = field(default_factory=list)
|
||
|
|
created_at: datetime = field(default_factory=datetime.utcnow)
|
||
|
|
|
||
|
|
def render_dbg(self) -> str:
|
||
|
|
lines = [f"# Plan for {self.issue_id}", self.summary, ""]
|
||
|
|
for t in self.tasks:
|
||
|
|
lines.extend(t.render_dbg())
|
||
|
|
if self.unknowns:
|
||
|
|
lines.append("\nUnknowns:")
|
||
|
|
lines += [f" - {u}" for u in self.unknowns]
|
||
|
|
return "\n".join(lines)
|
||
|
|
|
||
|
|
|
||
|
|
def to_prompt_text(self) -> str:
|
||
|
|
return self.render_dbg()
|
||
|
|
|
||
|
|
|
||
|
|
def is_filled(self) -> bool:
|
||
|
|
return self.unknowns == []
|