# task-596.2 완료 보고서: AI집단지성 대화 메모리 지능화 (Phase 2/2)

**S**: Phase 1에서 JSONL 영속화, 50개 자동 요약, /정리 명령어를 구현하여 봇 재시작 후 대화 맥락 유지가 가능해졌다. 그러나 요약 트리거가 50개 메시지 도달 시에만 작동하고, key_topics가 빈 배열이며, /정리 결과가 그룹챗에만 표시되어 아누 시스템과 연동이 없는 상태다.

**C**: 그룹챗이 소규모 대화(50개 미만)로 끝나면 요약이 전혀 생성되지 않고, /정리 결과를 아누가 참조할 경로가 없어 봇 간 지식 공유가 단절된다.

**Q**: 30분 무활동 타이머, key_topics 추출, 아누 DM 전송, 이벤트 파일 연동을 추가하여 대화 메모리 지능화를 완성할 수 있는가?

**A**: 4개 작업 항목 모두 구현 완료. 30분 무활동 시 asyncio 타이머로 자동 요약 트리거, call_claude JSON 프롬프트로 key_topics 3~5개 추출, /정리 시 OWNER DM 자동 전송 + 3봇 모두 /정리 지원, groupchat-insight-{date}.event 이벤트 파일 생성. pytest 64개 전체 통과(기존 50 + 신규 14), pyright 0 에러.

---

## 수행 내역

### 2-1. 30분 무활동 자동 요약 트리거
- `INACTIVITY_TIMEOUT = 1800` 모듈 상수 추가
- `_last_activity: dict[int, datetime]` — chat_id별 마지막 활동 시간 추적
- `_inactivity_tasks: dict[int, asyncio.Task]` — chat_id별 타이머 태스크 관리
- `add_message()` 수정: 매 메시지마다 `_last_activity` 갱신 + `_schedule_inactivity_check()` 호출
- `_schedule_inactivity_check()`: 기존 타이머 cancel 후 새 asyncio.Task 생성 (동기 환경 RuntimeError 핸들링)
- `_check_inactivity()`: sleep 전후 `_last_activity` 비교로 새 메시지 감지, 메시지 5개 미만 시 skip

### 2-2. key_topics 자동 추출
- `_generate_summary()` 프롬프트 변경: JSON 형식 응답 명시적 요청 (`{"summary": "...", "key_topics": [...]}`)
- `json.loads()` 파싱 시도 → 성공 시 summary/key_topics 분리, 실패 시 전체 텍스트 = summary + 빈 key_topics (하위호환)

### 2-3. /정리 결과 아누 DM 전송
- `_send_insight_to_owner(bot, chat_id, insight_text)` 함수 추가
- `OWNER_USER_ID`(6937032012) lazy import로 DM 전송 (4096자 제한 고려)
- 전송 실패 시 `logger.warning` (비치명적, graceful degradation)
- /정리 커맨드를 3개 봇 모두에 등록 (기존 claude_app만 → gemini_app, codex_app, claude_app)

### 2-4. 아누 참조 연결고리
- `_create_insight_event(events_dir)` 메서드 추가
- 기본 경로: `/home/jay/workspace/memory/events/`
- 파일명: `groupchat-insight-{YYYY-MM-DD}.event`
- JSON 구조: `{"type": "groupchat-insight", "timestamp": "...", "insights_dir": "..."}`
- `generate_insight()` 끝에서 자동 호출
- `events_dir` 파라미터로 테스트 주입 가능

---

## 생성/수정 파일

- `/home/jay/workspace/services/multimodel-bot/conversation_memory.py` — 30분 타이머, key_topics, 이벤트 파일 추가 (84→511 lines)
- `/home/jay/workspace/services/multimodel-bot/main_bot.py` — DM 전송, 3봇 /정리 등록 (184→205 lines)
- `/home/jay/workspace/services/multimodel-bot/tests/test_conversation_memory.py` — 14개 테스트 추가 (50→64 tests)

---

## 테스트 결과

- **pytest**: 64 passed in 0.39s (기존 50 + 신규 14, 회귀 0)
- **pyright**: conversation_memory.py 0 errors, main_bot.py 0 errors, tests 0 errors
- **포매팅**: black + isort 준수

### 신규 테스트 분포 (14개)
- TestInactivityTimer: 6개 (활동시간 갱신, 딕셔너리 초기화, 무활동 요약 트리거, 새 메시지 시 skip, 메시지 부족 시 skip, 기존 타이머 취소)
- TestKeyTopicsExtraction: 3개 (JSON 응답 파싱, 비JSON 하위호환, JSON 프롬프트 확인)
- TestInsightDMSending: 1개 (cleanup 통합 확인)
- TestInsightEvent: 4개 (이벤트 호출 확인, 파일 생성, JSON 구조, 실패 처리)

---

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **pyright 경로 해석 문제** — `run_pyright.sh`가 디렉토리 외부에서 실행되어 로컬 모듈 import 에러 발생. pyrightconfig.json이 있는 multimodel-bot/ 디렉토리 내에서 직접 실행하여 0 에러 확인.
   - 해결: `cd /home/jay/workspace/services/multimodel-bot && pyright` 방식 사용
2. **두 병렬 에이전트의 동일 파일 수정 충돌 가능성** — conversation_memory.py를 2개 에이전트가 수정. 첫 에이전트가 타이머+key_topics+이벤트까지 모두 구현, 두 번째 에이전트는 main_bot.py 수정 + 이벤트 테스트 추가. 결과적으로 충돌 없이 64개 테스트 통과.
3. **_create_insight_event 테스트 가능성** — 하드코딩된 `/home/jay/workspace/memory/events/` 경로 문제 → `events_dir` 파라미터 추가로 테스트 주입 가능하게 설계.
   - conversation_memory.py:423

---

## QC 자동 검증

```json
{
  "task_id": "task-596.2",
  "overall": "WARN",
  "checks": {
    "file_check": "PASS",
    "data_integrity": "PASS",
    "test_runner": "PASS (154 passed in 0.68s)",
    "tdd_check": "PASS",
    "pyright_check": "WARN (10 reportMissingImports — pyrightconfig.json 경로 외 실행, Phase 1부터 동일한 기존 이슈. 로컬 디렉토리 내 실행 시 0 에러)",
    "style_check": "PASS (black + isort 적용 완료)",
    "critical_gap": "PASS"
  }
}
```
