# task-1587.1 완료 보고서: 네이버 블로그 모델 4종 선택 기능

**S**: 네이버 블로그 글 생성 기능이 Claude Sonnet 모델만 사용하도록 하드코딩되어 있어, 모델별 글 스타일/품질 비교가 불가능하다.

**C**: 인슈로 네이버블로그 기능 적용 시 다양한 모델(Sonnet/Haiku/Gemini/GPT)을 선택하여 생성 품질을 비교해야 하나, 현재 구조에서는 모델 변경이 불가능하다.

**Q**: 기존 네이버 블로그 생성 API와 UI에 모델 4종 선택 기능을 추가하여, 사용자가 모델을 선택하고 글을 생성할 수 있는가?

**A**: 백엔드 `/api/naver-blog/generate` 핸들러에 `model` 파라미터 처리를 추가하고, 프론트엔드 `BlogGenerateStep`에 모델 선택 드롭다운을 구현하여 4종 모델 선택이 가능하도록 완료했다. Sonnet/Haiku는 Claude CLI, Gemini는 Gemini CLI, GPT는 OpenAI API로 호출한다.

---

## 변경 상세

### 백엔드 (server.py)

**1. import 추가 (line 46)**
- `import openai` — GPT 모델 호출용

**2. `/api/naver-blog/generate` 핸들러 수정 (line 4608~4668)**
- `model` 파라미터 수신 (기본값: `"sonnet"`)
- 유효성 검사: `{"sonnet", "haiku", "gemini", "gpt"}` 외 값은 400 에러
- 모델별 호출 분기:
  - **sonnet/haiku**: Claude CLI (`/home/jay/.local/bin/claude -p ... --model {model}`)
  - **gemini**: Gemini CLI (`/home/jay/.nvm/versions/node/v24.14.0/bin/gemini -p ...`) — 기본 모델 사용
  - **gpt**: OpenAI API (`openai.OpenAI()`, model=`gpt-4o`) — OPENAI_API_KEY 환경변수 자동 로드
- 모델별 timeout: haiku=120초, 그 외=300초
- 에러 메시지에 모델명 포함

### 프론트엔드 (NaverBlogView.js)

**1. state 추가 (line 539)**
- `const [model, setModel] = React.useState('sonnet');`

**2. payload 수정 (line 551)**
- `model: model` 필드 추가

**3. 모델 선택 드롭다운 UI (line 700~714)**
- 어투 선택 아래, 에러/생성 버튼 위에 배치
- 기존 UI 스타일과 동일한 카드 레이아웃
- 옵션: Sonnet(기본) / Haiku(빠름) / Gemini(Google AI) / GPT(OpenAI)

---

## Gemini/GPT 호출 방식 상세

### Gemini
- **방식**: Gemini CLI (v0.31.0, `/home/jay/.nvm/versions/node/v24.14.0/bin/gemini`)
- **호출**: `gemini -p "{prompt}"` (비대화식 모드)
- **모델**: 기본 모델 사용 (`-m` 플래그 없음 — 특정 모델 지정 시 ModelNotFoundError 발생 확인)
- **인증**: 캐시된 OAuth 자격증명 자동 사용

### GPT
- **방식**: OpenAI Python SDK (v2.24.0)
- **호출**: `openai.OpenAI().chat.completions.create(model="gpt-4o", ...)`
- **인증**: `OPENAI_API_KEY` 환경변수에서 자동 로드 (`.env.keys`에 설정됨)
- **CLI 부재**: GPT CLI 미설치 → API 방식 채택

---

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **Pyright: `generated_content` possibly unbound** — try 블록 전에 `generated_content = ""` 초기화 추가
   - 상세: server.py:4633 — if/elif 분기에 else가 없어 Pyright가 미할당 가능성 감지
2. **Pyright: `.strip()` on None** — GPT 응답의 `message.content`가 None일 수 있음 → `content.strip() if content else ""` 패턴 적용
   - 상세: server.py:4661-4662
3. **Gemini CLI `-m` 플래그 ModelNotFoundError** — 기본 모델(플래그 없음)로 정상 동작 확인 → `-m` 플래그 미사용으로 결정

---

## 수정 파일 목록

- `/home/jay/workspace/dashboard/server.py`
- `/home/jay/workspace/dashboard/components/NaverBlogView.js`

## API 변경

```
POST /api/naver-blog/generate
{
  "keywords": ["보험료 비교"],
  "additionalContent": "",
  "tone": "mixed",
  "model": "sonnet"  ← 신규 필드 (기본값: "sonnet")
}
```

## 모델 사용 기록

- 팀원: 토르(백엔드) / 작업: server.py 모델 분기 구현 / 사용 모델: sonnet
- 팀원: 프레이야(프론트) / 작업: NaverBlogView.js 모델 선택 UI / 사용 모델: sonnet
- 팀원: 오딘(팀장) / 작업: Pyright 에러 3건 직접 수정 / 사용 모델: opus
