chore: 빅뱅 Phase 5 Part 5 wrap-up — /simplify + Voice Conversation 파이프라인 복구 + UX 설계 이월
이번 세션 범위: - Part 5-A: /simplify 패스 — isImeComposingEvent helper 추출, 8곳 IME 가드 통합 (커밋3b77be0) - Part 5-B: Voice Conversation 파이프라인 복구 — Bug 10.5/11/12 3개 버그 연쇄 fix (커밋ee6ac3d) - Part 5-C: Voice Conversation UX 개선 인터뷰 설계 — 몰입 패널 + 사운드 피드백 + 상태 분기 (ASCII 와이어프레임 + 구현 작업 리스트 handoff에 저장, 다음 세션 이월) - Part 5-D: Bug 13 신규 발견 — 빈 STT 결과 시 피드백 부재 (U6 몰입 패널과 함께 처리 예정) 갱신 파일: - memory/project_status.md — SaaS [13] 엔트리 (Bug 10.5/11/12/13, UX 설계 스펙) - memory/handoff-latest.md — Part 5 전체 요약 + Part 5-C 와이어프레임 + 다음 세션 프롬프트 - memory/handoff-archive/2026-04-11-2200-phase5-part5a-simplify.md — 직전 Part 5-A 스냅샷 아카이브 다음 세션 우선 작업: 1. Voice Conversation 몰입 패널 구현 (handoff의 Part 5-C 작업 리스트 8번까지) 2. Bug 13 피드백 훅 추가 (몰입 패널과 함께) 3. Phase 3.2 PREMIUM_LLM (선행: Anthropic/OpenAI API key 주입) 빅뱅 성공 기준: 8개 중 7개 완료 (Phase 3.2 PREMIUM_LLM만 잔존).
This commit is contained in:
parent
ee6ac3dbfc
commit
e328eb1117
3 changed files with 455 additions and 148 deletions
|
|
@ -208,6 +208,59 @@ OAuth provider도 아직 Supabase에 설정 안 된 상태. 강제 게이트는
|
|||
- `~/Library/Application Support/d3ro-voice/users/${uuid}/d3ro.db` 파일 생성 확인
|
||||
- 기존 `d3ro-voice.db`가 있는 환경에서 archive rename 동작 확인
|
||||
|
||||
### SaaS [13] Voice Conversation 파이프라인 복구 + UX 개선 설계 (Phase 5 Part 5, 2026-04-11)
|
||||
|
||||
> **Voice Conversation이 Mac에서 한 번도 end-to-end 동작한 적 없었음을 발견.** 세 개의 독립된 버그가 합쳐져 있었고 진단 로그를 추가해 하나씩 분해해 해결. UX 개선은 사용자와 인터뷰로 설계서만 확정하고 구현은 다음 세션으로 이월.
|
||||
|
||||
**Bug 10.5 — TTS `spawn powershell ENOENT` (Mac)**
|
||||
- 원인: `TTSPlaybackService.ts:105`가 `spawn('powershell', ...)` 하드코딩. 파일 주석부터 "Windows SAPI (PowerShell) 기반" — V2-5 플랫폼 감사 때 이 파일 누락.
|
||||
- Fix: `_speakOne`를 dispatcher로 바꾸고 `_speakOneMac`(macOS `say -r <wpm>`) / `_speakOneWindows`(기존 PowerShell) 분리. 공통 close/error 핸들러는 `_bindProcessHandlers`로 추출. `_getMacRate`(WPM 기준 180×speed) / `_getWindowsRate`(-10~10 SAPI) 분리.
|
||||
- 파급: 음성 대화뿐 아니라 TTS를 쓰는 모든 경로가 Mac에서 벙어리였음. 이제 `/usr/bin/say`로 한/영/자동 판별 voice.
|
||||
|
||||
**Bug 11 — `finishListening` 오디오 버퍼 스냅샷 순서 (진짜 root cause, OS 무관)**
|
||||
- 증상: 녹음 후 "생각 중" 진입은커녕 조용히 listening으로 복귀, STT 한 번도 안 탐. 진단 로그로 추적 시 `finishListening called: bufferCount=311, totalBytes=597120` 직후 1ms 뒤 `audio too short: 0 bytes`로 찍힘.
|
||||
- 원인: `_stopListening()` 내부에 `this._audioBuffers = []` 리셋이 있는데 `finishListening`이 concat **이후**에 stop을 부르는 게 아니라 **이전**에 불러서, Buffer.concat 시점엔 이미 빈 배열. 19초짜리 오디오가 매번 날아감. Windows에서도 동일 버그였을 가능성 높음.
|
||||
- Fix (`VoiceConversationService.ts:193`): `_stopListening()` **전**에 `const audioBuffer = Buffer.concat(this._audioBuffers)` 스냅샷 저장. `this._audioBuffers = []` 재설정도 제거(이미 stop에서 하므로 중복).
|
||||
|
||||
**Bug 12 — Whisper 모델 사전 로드 누락**
|
||||
- 증상: Bug 11 fix 후 `finishListening`이 STT로 진입은 하지만 "모델 로딩 중, 오디오 버퍼에 적재"에서 영원히 pending. state가 'thinking'에 고정.
|
||||
- 원인: `LocalSTTService.initialize()`가 모델을 로드하는데, MeetingMode/CaptionService는 startRecording 시 이걸 명시적으로 호출하지만 VoiceConversationService는 호출 안 함. 첫 transcribe가 내부 pending 큐에 쌓이지만 아무도 로드를 트리거하지 않아 deadlock.
|
||||
- Fix (`VoiceConversationService.ts:84`): `startSession`에서 `void getLocalSTTService().initialize().catch(...)` fire-and-forget. initialize는 이미 Ready 같은 모델이면 즉시 return하므로 idempotent.
|
||||
|
||||
**검증**
|
||||
- desktop `tsc --noEmit` EXIT=0
|
||||
- Mac `/usr/bin/say -r 180` 직접 호출 시 스피커로 소리 확인 (사용자 증언 "오 들린다!")
|
||||
- 사용자 재시연에서 Mic 클릭 → 말함 → ⏹ Stop → 전사 → LLM 스트리밍 → TTS 소리 → 자동 listening 복귀 연속 대화 성공
|
||||
|
||||
**Bug 13 (신규 발견, 미수정) — 빈 STT 결과 시 사용자 피드백 부재**
|
||||
- 증상: 재시연 중 사용자가 ⏹ Stop 버튼 눌러도 "반응 없음"으로 느낌. 로그 추적 결과 finishListening → transcribe → `faster_whisper VAD filter removed 00:22.740 of audio` → 전사 `''` 빈 텍스트 → 조용히 listening 복귀 (에러 없음). 사용자 관점에선 버튼 먹통.
|
||||
- 원인 조합:
|
||||
1. Mac 시스템 마이크 입력 볼륨 너무 낮거나 `coreaudio input clipped` 왜곡으로 VAD가 전체 오디오를 무음 판정
|
||||
2. `VoiceConversationService.finishListening`에서 빈 STT 결과를 조용히 삼키고 listening으로 복귀 — **사용자 피드백 없음**
|
||||
- Fix 방향 (다음 세션): `_emitError('stt', 'No speech detected...')` 토스트 + 몰입 패널 내 "음성이 감지되지 않았습니다. 마이크 볼륨을 확인하세요." 힌트. 근본적으로는 UX 개선(몰입 패널)과 함께 처리.
|
||||
- 워크어라운드: Mac 시스템 설정 → 사운드 → 입력 볼륨 조정 (중간 이상).
|
||||
|
||||
**UX 개선 설계 (구현 미완, 다음 세션 이월)**
|
||||
사용자 피드백: 녹음 상태 불명확 / 텍스트 입력 방치 / 종료·응답 완료 피드백 부재. 인터뷰로 확정한 결정:
|
||||
1. **녹음 모드 = 풀 몰입 계측기 패널** — 메시지 영역을 REC LED + 9바 phosphor waveform + 0:04 타이머 + "SPEAK NOW · PRESS ⏹ TO SEND" 힌트로 완전 대체 (listening 상태에서만)
|
||||
2. **thinking/speaking 상태 = 메시지 리스트로 복귀** — 대화 맥락 유지. typing indicator 버블 추가. TextField는 disabled "응답 대기 중…"
|
||||
3. **연속 대화** — 응답 후 자동 listening 복귀 (기존 코드 동작 유지)
|
||||
4. **사운드 4개 전부** — recording-start/recording-stop/chime(recording-stop 재사용)/error
|
||||
5. **Audio level IPC 신규 채널** — `VOICE_CONVERSATION.AUDIO_LEVEL`로 AudioCaptureService 'audio-level' 이벤트 listening 상태에서만 forward
|
||||
6. **SoundEffectService SoundName에 'chime' 추가** — 파일은 `recording-stop.wav` 재사용 (cancel=error 패턴과 동일). 나중에 전용 WAV로 교체 예정
|
||||
|
||||
설계 ASCII 와이어프레임 + 작업 리스트는 이번 세션 대화 말미에 존재. 다음 세션 우선 구현 대상.
|
||||
|
||||
**남은 미해결 이슈**
|
||||
- U1 — Realtime TIMED_OUT (블로커 아님)
|
||||
- U3 — Refresh token 간헐적 소진 (블로커 아님)
|
||||
- U4 — `package-lock.json` optional dep 정리
|
||||
- **Phase 3.2** — PREMIUM_LLM quota 게이트 (Anthropic/OpenAI key 주입 대기, 빅뱅 성공 기준 8번 중 마지막 1개)
|
||||
- **Voice Conversation UX** — 위 설계 대로 다음 세션 구현
|
||||
- **AudioCaptureService.getDevices()** — Mac에서 PowerShell 호출 실패 경고 로그 (1개 device fallback 동작, 블로커 아님)
|
||||
|
||||
---
|
||||
|
||||
### SaaS [12] /simplify 패스 — IME 가드 helper 추출 + 8곳 일괄 적용 (Phase 5 Part 5, 2026-04-11)
|
||||
|
||||
> **Bug 10의 한글 IME Enter 중복 가드를 `isImeComposingEvent` helper로 추출**. MeetingModePage 기존 인라인 가드 교체 + 7개 사이트 신규 적용 → 총 8곳 통합. Phase 3.3 훅 8곳은 품질 리뷰 결과 이미 최적 상태로 판정(수정 없음).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue