fix: 리뷰어가 실제 파일 읽기로 변경
- batch_review: Gemini stdout 대신 프로젝트의 최근 변경 파일(60초)을 읽어 리뷰 - 파일 삭제/변경 없는 작업은 자동 통과 - 에이전트 보고 + 실제 파일 내용을 함께 전달 - 최대 10개 파일, 파일당 3000자 제한
This commit is contained in:
@@ -118,23 +118,63 @@ class TaskPipeline:
|
|||||||
# ──────────────────────────────────────────
|
# ──────────────────────────────────────────
|
||||||
|
|
||||||
async def batch_review(self, tasks: list[dict], code_outputs: list[str]) -> dict:
|
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}"))
|
title = task.get("title", task.get("description", f"Task {i+1}"))
|
||||||
combined.append(
|
task_summaries.append(f"### Task {i+1}: {title}")
|
||||||
f"### Task {i+1}: {title}\n"
|
|
||||||
f"{output[:2000]}\n"
|
# 에이전트 보고 요약
|
||||||
|
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 = (
|
prompt = (
|
||||||
f"## All Code Changes\n\n"
|
f"## 요청된 태스크\n{chr(10).join(task_summaries)}\n\n"
|
||||||
f"{'---'.join(combined)}\n\n"
|
f"## 에이전트 보고\n{chr(10).join(agent_reports)}\n\n"
|
||||||
f"Review ALL changes above as a whole."
|
f"## 실제 생성/수정된 파일\n{files_section}\n\n"
|
||||||
|
f"위 파일들이 태스크 요구사항을 충족하는지 리뷰하세요."
|
||||||
)
|
)
|
||||||
|
|
||||||
response = await self.gemini.call("reviewer", prompt, timeout=180)
|
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)
|
review = self._extract_json(response)
|
||||||
return review or {"passed": True, "summary": response, "raw": response}
|
return review or {"passed": True, "summary": response, "raw": response}
|
||||||
|
|||||||
Reference in New Issue
Block a user