from __future__ import annotations import re from dataclasses import dataclass from .models import IssueRecord, RepositoryRecord VALID_VERDICTS = {"APPROVE", "REQUEST_CHANGES", "NEEDS_HUMAN_DECISION"} @dataclass(frozen=True) class ReviewReport: verdict: str raw: str suggested_pr_comment: str def render_implementer_prompt(repo: RepositoryRecord, issue: IssueRecord, branch_name: str) -> str: return f"""# Agent Implementation Task Repository: {repo.full_name} Base branch: {repo.default_branch} Working branch: {branch_name} Issue: #{issue.issue_number} {issue.title} Issue URL: {issue.html_url} ## Issue Body {issue.body or "(no issue body)"} ## Instructions Implement the requested change in this workspace. Keep the change scoped to this issue. Run the relevant tests before finishing. Write `.agent-output/AGENT_IMPLEMENTATION_REPORT.md` using this exact section contract. Keep the section headings exactly as written below, but write the section content in Chinese: - Summary - Files changed - Test commands run - Test results - Known risks - Follow-up suggestions """ def render_reviewer_prompt(repo: RepositoryRecord, issue: IssueRecord, pr_number: int) -> str: return f"""# Agent Review Task Repository: {repo.full_name} Pull request: #{pr_number} Issue: #{issue.issue_number} {issue.title} Review the implementation currently checked out in this workspace. Focus on correctness, scope control, test evidence, and human risks. Do not modify code. Write `.agent-output/AGENT_REVIEW_REPORT.md` using this exact section contract. Keep the section headings exactly as written below. Keep the Verdict token in English, but write the section content and Suggested PR Comment in Chinese: - Verdict: APPROVE, REQUEST_CHANGES, or NEEDS_HUMAN_DECISION - Summary - Correctness - Scope Control - Test Evidence - Risks - Required Human Checks - Suggested PR Comment """ def render_pr_body(issue: IssueRecord, implementation_report: str) -> str: return f"""关联 Issue:#{issue.issue_number} ## 代理实现报告 {implementation_report.strip()} ## 人工审核 此 PR 由本地 agent-manager 自动创建,但不会自动合并。 请维护者人工审核、决策并手动合并。 """ def parse_review_report(raw: str) -> ReviewReport: verdict_match = re.search(r"(?im)^\s*(?:[-*]\s*)?(?:##\s*)?Verdict\s*:?\s*`?([A-Z_]+)`?", raw) verdict = verdict_match.group(1) if verdict_match else "NEEDS_HUMAN_DECISION" if verdict not in VALID_VERDICTS: verdict = "NEEDS_HUMAN_DECISION" suggested = extract_section(raw, "Suggested PR Comment").strip() if not suggested: suggested = extract_inline_field(raw, "Suggested PR Comment").strip() if not suggested: suggested = raw.strip() return ReviewReport(verdict=verdict, raw=raw, suggested_pr_comment=suggested) def extract_section(raw: str, title: str) -> str: pattern = re.compile( rf"(?ims)^\s*##\s+{re.escape(title)}\s*$\n(?P.*?)(?=^\s*##\s+|\Z)" ) match = pattern.search(raw) return match.group("body") if match else "" def extract_inline_field(raw: str, title: str) -> str: pattern = re.compile(rf"(?im)^\s*(?:[-*]\s*)?{re.escape(title)}\s*:\s*(?P.+?)\s*$") match = pattern.search(raw) return match.group("body") if match else "" def render_human_review_summary(review: ReviewReport) -> str: return f"""## 代理评审摘要 结论:`{review.verdict}` {review.suggested_pr_comment.strip()} ## 需要人工处理 请人工审核该 PR。agent-manager 不会自动合并、关闭 PR 或提交变更请求。 """