fix: 리뷰어가 실제 파일 읽기로 변경

- batch_review: Gemini stdout 대신 프로젝트의 최근 변경 파일(60초)을 읽어 리뷰
- 파일 삭제/변경 없는 작업은 자동 통과
- 에이전트 보고 + 실제 파일 내용을 함께 전달
- 최대 10개 파일, 파일당 3000자 제한
This commit is contained in:
2026-03-06 22:25:26 +09:00
parent a54a9096ef
commit 8140f75c7f

View File

@@ -118,23 +118,63 @@ class TaskPipeline:
# ──────────────────────────────────────────
async def batch_review(self, tasks: list[dict], code_outputs: list[str]) -> dict:
"""모든 코드 출력을 한 번에 리뷰."""
combined = []
for i, (task, output) in enumerate(zip(tasks, code_outputs)):
"""에이전트가 생성/수정한 실제 파일을 리뷰.
code_outputs(에이전트 보고)와 함께 실제 프로젝트 파일 내용을 읽어서 리뷰합니다.
"""
import os
import time as _time
# 태스크 요약
task_summaries = []
for i, task in enumerate(tasks):
title = task.get("title", task.get("description", f"Task {i+1}"))
combined.append(
f"### Task {i+1}: {title}\n"
f"{output[:2000]}\n"
task_summaries.append(f"### Task {i+1}: {title}")
# 에이전트 보고 요약
agent_reports = []
for i, output in enumerate(code_outputs):
agent_reports.append(f"--- Agent {i+1} 보고 ---\n{output[:1000]}")
# 최근 변경된 파일 읽기 (60초 이내)
recent_files = []
cutoff = _time.time() - 60
project_root = Path(self.project_path)
skip_dirs = {".git", "__pycache__", "node_modules", ".venv", "venv"}
for root, dirs, files in os.walk(self.project_path):
dirs[:] = [d for d in dirs if d not in skip_dirs]
for fname in files:
fpath = Path(root) / fname
try:
if fpath.stat().st_mtime > cutoff:
rel = fpath.relative_to(project_root)
content = fpath.read_text(encoding="utf-8", errors="replace")
recent_files.append(
f"### {rel}\n```\n{content[:3000]}\n```"
)
except (OSError, UnicodeDecodeError):
continue
if not recent_files:
# 변경 파일 없음 → 자동 통과 (삭제 작업 등)
return {
"passed": True,
"summary": "파일 변경 없음 또는 삭제 작업 — 자동 통과",
"issues": [],
}
files_section = "\n\n".join(recent_files[:10]) # 최대 10개
prompt = (
f"## All Code Changes\n\n"
f"{'---'.join(combined)}\n\n"
f"Review ALL changes above as a whole."
f"## 요청된 태스크\n{chr(10).join(task_summaries)}\n\n"
f"## 에이전트 보고\n{chr(10).join(agent_reports)}\n\n"
f"## 실제 생성/수정된 파일\n{files_section}\n\n"
f"위 파일들이 태스크 요구사항을 충족하는지 리뷰하세요."
)
response = await self.gemini.call("reviewer", prompt, timeout=180)
self._log("batch_review", f"{len(tasks)} tasks", response)
self._log("batch_review", f"{len(tasks)} tasks, {len(recent_files)} files", response)
review = self._extract_json(response)
return review or {"passed": True, "summary": response, "raw": response}