45 lines
1.5 KiB
Python
45 lines
1.5 KiB
Python
|
|
"""
|
|
Issue Decomposing Agent
|
|
This agent specializes in development tasks including:
|
|
- Web systems architecture
|
|
"""
|
|
|
|
from typing import Dict, Any
|
|
import json
|
|
|
|
from agents.issue_reader.models import TaskPlan
|
|
from agents.issue_reader.decomposer import IssueDecomposer
|
|
from agents.issue_reader.validator import enforce
|
|
from common.youtrack_mcp_client import IssueNotFound
|
|
|
|
|
|
class IssueReaderAgent:
|
|
def __init__(self, context_builder, llm):
|
|
self.name = "Issue decomposing agent"
|
|
self.ctx_builder = context_builder
|
|
self.decomposer = IssueDecomposer(llm)
|
|
|
|
async def plan_issue(self, issue_id: str) -> TaskPlan:
|
|
ctx = await self.ctx_builder.build(issue_id)
|
|
if ctx is None:
|
|
raise IssueNotFound(f"Issue {issue_id} was not found in YouTrack")
|
|
|
|
plan = self.decomposer.decompose(ctx)
|
|
plan.issue_id = ctx.issue_id
|
|
return enforce(plan)
|
|
|
|
def render(self, plan) -> str:
|
|
lines = [f"# Plan for {plan.issue_id}", plan.summary, ""]
|
|
for t in plan.tasks:
|
|
deps = f" (after {', '.join(t.depends_on)})" if t.depends_on else ""
|
|
lines.append(f"- [{t.kind.value}] {t.id}: {t.title}{deps}")
|
|
for ac in t.acceptance_criteria:
|
|
lines.append(f" ✓ {ac}")
|
|
for q in t.open_questions:
|
|
lines.append(f" ? {q}")
|
|
if plan.unknowns:
|
|
lines.append("\nUnknowns:")
|
|
lines += [f" - {u}" for u in plan.unknowns]
|
|
return "\n".join(lines)
|