Coder preparations

This commit is contained in:
2026-09-22 23:21:59 +03:00
parent 3d1df7fee5
commit 1f2dc25e0b
32 changed files with 3205 additions and 26 deletions
+91
View File
@@ -0,0 +1,91 @@
# orchestrator/run_context.py
from __future__ import annotations
import secrets
from dataclasses import dataclass
from datetime import datetime, timezone
from typing import Any
from agents.coders.state import AgentState
from common.gitea_mcp_client import GiteaMCPClient
from common.llm_client import LLMClient
from common.time import now_iso, now_iso_plus
from common.youtrack_mcp_client import YouTrackMCPClient
@dataclass(frozen=True)
class AgentConfig:
# ── project-level ──────────────────────────────────────────
youtrack_project: str
gitea_repo: str
gitea_target_branch: str = "main"
# ── limits (snapshotted into state at run start) ───────────
max_plan_attempts: int = 3
max_act_attempts: int = 5
max_ci_self_resolve_attempts: int = 2
max_clarification_rounds: int = 3
max_rework_rounds: int = 2
wall_clock_minutes: int = 60
token_budget: int = 500_000
# ── human-await timers ─────────────────────────────────────
re_ping_after_days: int = 3
abandon_after_days: int = 5
# ── reviewer policy ────────────────────────────────────────
reviewer_fallback: str = "codeowners" # codeowners | blame | on_call
# ── language hints (for Plan) ──────────────────────────────
language_markers: dict[str, list[str]] = None # filled from project
@dataclass
class RunContext:
"""
Everything a handler needs to do its job: the ports it talks to, the
persisted state for this issue, and the identifiers it must stamp into
comments and state.
"""
# ── identifiers ────────────────────────────────────────────
agent_id: str
issue_id: str
run_id: str # one logical attempt; stable across calls
attempt: int # retry counter within the run
# ── ports (outbound systems) ───────────────────────────────
llm: LLMClient
youtrack: YouTrackMCPClient
gitea: GiteaMCPClient
# ── persisted pipeline state for this issue ────────────────
state: AgentState
# ── static config for this run ─────────────────────────────
config: AgentConfig
# ── convenience (thin, no hidden behavior) ─────────────────
def now(self) -> str:
return now_iso()
def now_plus(self, **delta) -> str:
return now_iso_plus(**delta)
def new_run_id() -> str:
"""
Generate a run id: one logical attempt at a task.
Format: run-YYYYMMDD-HHMMSS-<6 hex chars>
Example: run-20260921-114500-a3f1c2
- Timestamp prefix makes ids sortable and human-readable in logs.
- Random suffix prevents collisions when two runs start in the same
second (e.g., parallel issues, fast retries, tests).
- The "run-" prefix makes it obvious what kind of id this is when it
appears next to a comment marker or in a state file.
"""
ts = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
suffix = secrets.token_hex(3) # 3 bytes -> 6 hex chars
return f"run-{ts}-{suffix}"