From fd6a88ae7b30db201baf14e0ca22d874406b7734 Mon Sep 17 00:00:00 2001 From: Variet Agent Date: Fri, 20 Mar 2026 06:41:58 +0900 Subject: [PATCH] =?UTF-8?q?feat(debate):=20Working=20Document=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9=20=ED=8E=B8=EC=A7=91=20=E2=80=94=20Flash=EA=B0=80=20A?= =?UTF-8?q?G=20=EC=9D=98=EA=B2=AC=EC=9D=84=20=EC=82=B0=EC=B6=9C=EB=AC=BC?= =?UTF-8?q?=EB=A1=9C=20merge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/debate_handler.py | 83 +++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/handlers/debate_handler.py b/handlers/debate_handler.py index 93adf31..756fd22 100644 --- a/handlers/debate_handler.py +++ b/handlers/debate_handler.py @@ -179,10 +179,16 @@ class DebateHandler: "speaker": speaker, "content": response, }) - # ⑤ #debate에 요약 게시 + # ⑤ Working Document 통합 편집 (Flash) + await self._update_working_document(speaker, response) + + # ⑥ 양쪽 wiki/ 동기화 + self._sync_wiki() + + # ⑦ #debate에 요약 게시 await self._post_summary(speaker, response) - # ⑥ 합의 판정 + # ⑧ 합의 판정 decision = await self._judge_consensus(speaker, response) if decision == "conclude": @@ -441,19 +447,68 @@ class DebateHandler: # 유틸 # ═══════════════════════════════════════════ + async def _update_working_document(self, speaker: str, response: str): + """Flash가 AG 의견을 Working Document에 통합 편집.""" + # 현재 working document 읽기 + wd_path = AGENT_PATHS["gemini"] / "wiki" / "working_document.md" + current_doc = "" + if wd_path.exists(): + current_doc = wd_path.read_text(encoding="utf-8").strip() + + merge_prompt = f"""당신은 문서 편집자입니다. + +## 작업 +아래 '현재 문서'에 토론자({speaker})의 의견을 **통합**하여 문서를 업데이트하세요. + +## 규칙 +1. 단순 대화 기록이 아니라 **구체적인 설계 문서/보고서** 형태로 작성 +2. 토론자가 제안한 구체적 내용(아키텍처, 기술 선택, 구현 방안 등)을 문서에 반영 +3. 이전에 합의된 내용과 충돌하면 **최신 의견을 우선** 반영하되 변경 이유를 명시 +4. 아직 합의되지 않은 쟁점은 '미결 사항' 섹션에 정리 +5. 문서는 깔끔한 마크다운으로 작성 +6. **전체 문서를 출력** (변경 부분만이 아니라) + +## 주제: {self.session.topic} +## 현재 라운드: {self.session.round}/{self.session.max_rounds} + +## 현재 문서: +{current_doc if current_doc else '(아직 없음 — 새로 작성하세요)'} + +## {speaker}의 이번 라운드 의견: +{response[:6000]} + +--- +업데이트된 전체 문서를 출력하세요. +""" + try: + from core.gemini_caller import GeminiCaller + caller = GeminiCaller() + updated = await caller.call_simple(merge_prompt, timeout=120) + if updated and len(updated) > 50: + # gemini 폴더에 저장 (sync에서 양쪽 복사) + wd_path.parent.mkdir(parents=True, exist_ok=True) + wd_path.write_text(updated, encoding="utf-8") + logger.info(f"Working Document 업데이트: {len(updated)}자") + else: + logger.warning("Working Document 업데이트 실패 — Flash 응답 부족") + except Exception as e: + logger.error(f"Working Document 업데이트 오류: {e}") + + def _sync_wiki(self): + """gemini wiki/ 폴더 내용을 opus wiki/에 동기화.""" + src = AGENT_PATHS["gemini"] / "wiki" + dst = AGENT_PATHS["opus"] / "wiki" + dst.mkdir(parents=True, exist_ok=True) + + for f in src.iterdir(): + if f.is_file(): + (dst / f.name).write_text( + f.read_text(encoding="utf-8"), encoding="utf-8", + ) + def _build_working_document(self) -> str: - """현재까지 합의/논의 사항을 working document로 생성.""" - lines = [f"# {self.session.topic} — Working Document\n"] - lines.append(f"라운드: {self.session.round}/{self.session.max_rounds}\n") - lines.append("---\n") - - for h in self.session.history: - emoji = AGENT_EMOJI.get(h["speaker"], "👤") - lines.append(f"## {emoji} {h['speaker']} (Round {self.session.history.index(h)+1})") - lines.append(h["content"][:3000]) - lines.append("\n---\n") - - return "\n".join(lines) + """초기 working document 생성 (첫 라운드용).""" + return f"# {self.session.topic}\n\n*(토론 진행 중 — 내용이 채워집니다)*\n" def _fallback_prompt(self, speaker: str) -> str: """Flash 실패 시 기본 프롬프트."""