It is an issue reader in fact
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
### 2026-09-19
|
||||
1. Created an agent that can accept YouTrack™ task ID, read an issue, create a context for a task (body, comments, image attachments) and decompose it for implementing
|
||||
2. **[missing]** extract a decomposing because it's manner depends on the task context (i.e. backend-dev, frontend-dev, seller, marketing, ad, design, ...) so an issue_reader agent should listen for not delivered tasks, create a context and delegate a decomposition for specific agent. If there is no agent can create this work - add comment that it cannot be resolved until appropriate agent will be created, assign a task to admin and change status to "To Be Discussed". There should be an agent that has information about all the rest of agents and can provide the information, who can do that task and how (in case of confusing - ask another agents if they can do the task). As this architecture is a very future automatization, it is enough to have just a registry of agents and omit the conversation of issue reader with another agents.
|
||||
+8
-11
@@ -1,25 +1,22 @@
|
||||
|
||||
"""
|
||||
Backend Developer Agent
|
||||
This agent specializes in backend development tasks including:
|
||||
- API development with FastAPI
|
||||
- Database design and management
|
||||
- Server-side programming
|
||||
- System architecture
|
||||
Issue Decomposing Agent
|
||||
This agent specializes in development tasks including:
|
||||
- Web systems architecture
|
||||
"""
|
||||
|
||||
from typing import Dict, Any
|
||||
import json
|
||||
|
||||
from agents.backend_dev.models import TaskPlan
|
||||
from agents.backend_dev.decomposer import IssueDecomposer
|
||||
from agents.backend_dev.validator import enforce
|
||||
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 BackendDeveloperAgent:
|
||||
class IssueReaderAgent:
|
||||
def __init__(self, context_builder, llm):
|
||||
self.name = "Backend Developer"
|
||||
self.name = "Issue decomposing agent"
|
||||
self.ctx_builder = context_builder
|
||||
self.decomposer = IssueDecomposer(llm)
|
||||
|
||||
@@ -5,8 +5,8 @@ import re
|
||||
|
||||
import httpx
|
||||
|
||||
from agents.backend_dev.models import IssueContext
|
||||
from agents.backend_dev.project_loader import load_project
|
||||
from agents.issue_reader.models import IssueContext
|
||||
from agents.issue_reader.project_loader import load_project
|
||||
from common.as_type import _as_dict, _as_list, _first, _extract_base64
|
||||
from common.youtrack_mcp_client import IssueNotFound
|
||||
|
||||
@@ -3,10 +3,10 @@ import json
|
||||
|
||||
from openai import images
|
||||
|
||||
from agents.backend_dev.models import IssueContext, Task, TaskPlan, TaskKind, Atomicity
|
||||
from agents.issue_reader.models import IssueContext, Task, TaskPlan, TaskKind, Atomicity
|
||||
|
||||
|
||||
SYSTEM_PROMPT = """You are a senior backend engineer.
|
||||
SYSTEM_PROMPT = """You are a senior engineer.
|
||||
Your job: given a YouTrack issue, its comments, and the project context,
|
||||
produce the SMALLEST possible sequence of tasks to resolve it.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
from agents.backend_dev.models import ProjectContext
|
||||
from agents.issue_reader.models import ProjectContext
|
||||
|
||||
|
||||
PROJECTS_DIR = Path(__file__).parent.parent.parent / "projects"
|
||||
@@ -1,5 +1,5 @@
|
||||
# validator.py
|
||||
from agents.backend_dev.models import Task, TaskPlan, Atomicity
|
||||
from agents.issue_reader.models import Task, TaskPlan, Atomicity
|
||||
|
||||
MAX_HOURS = 8
|
||||
VAGUE_VERBS = ("handle", "support", "improve", "refactor", "manage", "deal with")
|
||||
@@ -5,8 +5,8 @@ from contextlib import asynccontextmanager
|
||||
import httpx
|
||||
from dotenv import load_dotenv
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from agents.backend_dev.BackendDeveloperAgent import BackendDeveloperAgent
|
||||
from agents.backend_dev.context_builder import YouTrackContextBuilder
|
||||
from agents.issue_reader.IssueReaderAgent import IssueReaderAgent
|
||||
from agents.issue_reader.context_builder import YouTrackContextBuilder
|
||||
from common.llm_client import LLMClient
|
||||
from common.youtrack_mcp_client import YouTrackMCPClient, IssueNotFound
|
||||
|
||||
@@ -34,7 +34,7 @@ async def lifespan(app: FastAPI):
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
app.state.backend_agent = BackendDeveloperAgent(
|
||||
app.state.issue_reader_agent = IssueReaderAgent(
|
||||
YouTrackContextBuilder(mcp, http_for_attachments),
|
||||
LLMClient(
|
||||
base_url=env("LLM_ADDRESS"),
|
||||
@@ -59,18 +59,18 @@ async def say_hello(name: str):
|
||||
return {"message": f"Hello {name}"}
|
||||
|
||||
|
||||
@app.get("/backend")
|
||||
async def backend_task(task: str):
|
||||
agent: BackendDeveloperAgent = app.state.backend_agent
|
||||
@app.get("/decomposing")
|
||||
async def decomposing_issue(issue: str):
|
||||
agent: IssueReaderAgent = app.state.issue_reader_agent
|
||||
try:
|
||||
logger.info(f"Received task: {task}")
|
||||
plan = await agent.plan_issue(task)
|
||||
logger.info(f"Received an issue: {issue}")
|
||||
plan = await agent.plan_issue(issue)
|
||||
logger.info("Task planning successful.")
|
||||
print(agent.render(plan))
|
||||
return {"plan": plan}
|
||||
except IssueNotFound:
|
||||
logger.error(f"Issue {task} not found.")
|
||||
raise HTTPException(status_code=404, detail=f"Issue {task} not found")
|
||||
logger.error(f"Issue {issue} not found.")
|
||||
raise HTTPException(status_code=404, detail=f"Issue {issue} not found")
|
||||
except Exception as e:
|
||||
logger.exception("An unexpected error occurred")
|
||||
return {"error": str(e)}
|
||||
|
||||
Reference in New Issue
Block a user