feat(debate): Wiki.js 연동 — Working Document + Round Log 자동 업로드

This commit is contained in:
2026-03-20 06:46:48 +09:00
parent fd6a88ae7b
commit a1315f90e5

View File

@@ -47,13 +47,14 @@ FILE_STABLE_DELAY = 5 # 파일 작성 완료 대기 (초)
@dataclass @dataclass
class DebateSession: class DebateSession:
topic: str = "" topic: str = ""
topic_slug: str = "" # Wiki 경로용
round: int = 0 round: int = 0
max_rounds: int = MAX_ROUNDS max_rounds: int = MAX_ROUNDS
active: bool = False active: bool = False
paused: bool = False # 사용자 응답 대기 중 paused: bool = False
current_speaker: str = "" current_speaker: str = ""
history: list = field(default_factory=list) history: list = field(default_factory=list)
pending_question: str = "" # 사용자에게 보낸 질문 pending_question: str = ""
class DebateHandler: class DebateHandler:
@@ -72,8 +73,16 @@ class DebateHandler:
await ctx.reply("⚠️ 이미 진행 중. `!debate-stop`으로 먼저 종료.") await ctx.reply("⚠️ 이미 진행 중. `!debate-stop`으로 먼저 종료.")
return return
# slug 생성
try:
from tools.wiki_client import WikiClient
slug = WikiClient.slugify(topic)
except Exception:
slug = topic[:15].replace(" ", "-").lower()
self.session = DebateSession( self.session = DebateSession(
topic=topic, active=True, max_rounds=MAX_ROUNDS, topic=topic, topic_slug=slug,
active=True, max_rounds=MAX_ROUNDS,
) )
# 폴더 초기화 # 폴더 초기화
@@ -179,7 +188,10 @@ class DebateHandler:
"speaker": speaker, "content": response, "speaker": speaker, "content": response,
}) })
# ⑤ Working Document 통합 편집 (Flash) # ⑤ Round Log에 대화 전문 기록 (로컬 + Wiki.js)
await self._append_round_log(speaker, response)
# ⑥ Working Document 통합 편집 (Flash + Wiki.js)
await self._update_working_document(speaker, response) await self._update_working_document(speaker, response)
# ⑥ 양쪽 wiki/ 동기화 # ⑥ 양쪽 wiki/ 동기화
@@ -448,8 +460,7 @@ class DebateHandler:
# ═══════════════════════════════════════════ # ═══════════════════════════════════════════
async def _update_working_document(self, speaker: str, response: str): async def _update_working_document(self, speaker: str, response: str):
"""Flash가 AG 의견을 Working Document에 통합 편집.""" """Flash가 AG 의견을 Working Document에 통합 편집 + Wiki.js 업로드."""
# 현재 working document 읽기
wd_path = AGENT_PATHS["gemini"] / "wiki" / "working_document.md" wd_path = AGENT_PATHS["gemini"] / "wiki" / "working_document.md"
current_doc = "" current_doc = ""
if wd_path.exists(): if wd_path.exists():
@@ -485,15 +496,58 @@ class DebateHandler:
caller = GeminiCaller() caller = GeminiCaller()
updated = await caller.call_simple(merge_prompt, timeout=120) updated = await caller.call_simple(merge_prompt, timeout=120)
if updated and len(updated) > 50: if updated and len(updated) > 50:
# gemini 폴더에 저장 (sync에서 양쪽 복사)
wd_path.parent.mkdir(parents=True, exist_ok=True) wd_path.parent.mkdir(parents=True, exist_ok=True)
wd_path.write_text(updated, encoding="utf-8") wd_path.write_text(updated, encoding="utf-8")
logger.info(f"Working Document 업데이트: {len(updated)}") logger.info(f"Working Document 업데이트: {len(updated)}")
# Wiki.js에 업로드
await self._wiki_upsert(
f"debates/{self.session.topic_slug}/working-document",
f"{self.session.topic} — Working Document",
updated,
)
else: else:
logger.warning("Working Document 업데이트 실패 — Flash 응답 부족") logger.warning("Working Document 업데이트 실패")
except Exception as e: except Exception as e:
logger.error(f"Working Document 업데이트 오류: {e}") logger.error(f"Working Document 업데이트 오류: {e}")
async def _append_round_log(self, speaker: str, response: str):
"""Round Log에 대화 전문 append + Wiki.js 업로드."""
log_path = AGENT_PATHS["gemini"] / "wiki" / "round_log.md"
# 기존 내용 읽기
existing = ""
if log_path.exists():
existing = log_path.read_text(encoding="utf-8")
emoji = AGENT_EMOJI.get(speaker, "👤")
entry = (
f"\n---\n\n"
f"## Round {self.session.round}{emoji} {speaker}\n\n"
f"{response}\n"
)
updated_log = existing + entry
log_path.parent.mkdir(parents=True, exist_ok=True)
log_path.write_text(updated_log, encoding="utf-8")
# Wiki.js에 업로드
await self._wiki_upsert(
f"debates/{self.session.topic_slug}/round-log",
f"{self.session.topic} — Round Log",
updated_log,
)
async def _wiki_upsert(self, path: str, title: str, content: str):
"""Wiki.js에 페이지 upsert."""
try:
from tools.wiki_client import WikiClient
client = WikiClient()
await client.upsert_page(
path=path, title=title, content=content,
tags=["debate", self.session.topic_slug],
)
logger.info(f"Wiki.js 업로드: {path}")
except Exception as e:
logger.warning(f"Wiki.js 업로드 실패 ({path}): {e}")
def _sync_wiki(self): def _sync_wiki(self):
"""gemini wiki/ 폴더 내용을 opus wiki/에 동기화.""" """gemini wiki/ 폴더 내용을 opus wiki/에 동기화."""
src = AGENT_PATHS["gemini"] / "wiki" src = AGENT_PATHS["gemini"] / "wiki"