feat(conversation): OpenAI gpt-realtime-2.1 라이브 음성 대화 Premium 백엔드

- realtime-token Edge Function: 티어 검증 + realtime_session 쿼터 + ephemeral key 발급
- useRealtimeConversation 훅: WebRTC 직결 (마이크 → OpenAI, 오디오 자동 재생)
- VoiceConversationPage: conversationBackend 분기 + 연결 실패 시 로컬 fallback
- AppConfig.conversationBackend + SettingsModal 음성 대화 엔진 선택
- ErrorCode 799 ConversationRealtimeTokenFailed, i18n ko/en
This commit is contained in:
Yun Chan 2026-07-21 12:10:13 +09:00
parent 983c60cda2
commit 8f7d300b89
15 changed files with 762 additions and 40 deletions

View file

@ -137,6 +137,7 @@ export enum ErrorCode {
ConversationNoActiveSession = 796,
ConversationTTSFailed = 797,
ConversationLLMFailed = 798,
ConversationRealtimeTokenFailed = 799,
// === Phase 13: Local RAG (870-874) ===
RAGDocumentNotFound = 870,

View file

@ -276,6 +276,8 @@ export const IPC_CHANNELS = {
GET_HISTORY: 'voiceConversation:getHistory',
CLEAR_HISTORY: 'voiceConversation:clearHistory',
CANCEL_RESPONSE: 'voiceConversation:cancelResponse',
/** OpenAI Realtime ephemeral token 발급 (Supabase realtime-token 경유) */
GET_REALTIME_TOKEN: 'voiceConversation:getRealtimeToken',
// Main → Renderer events
STATE_CHANGED: 'voiceConversation:stateChanged',
USER_MESSAGE: 'voiceConversation:userMessage',

View file

@ -372,6 +372,12 @@ export interface AppConfig {
* 'premium' PremiumLLMService (Supabase llm-proxy Claude, + )
*/
llmBackend: 'local' | 'premium'
/**
* .
* 'local' VoiceConversationService (STTLLMTTS , )
* 'realtime' OpenAI Realtime API (gpt-realtime-2.1, WebRTC , + )
*/
conversationBackend: 'local' | 'realtime'
defaultLLMAction: LLMAction
dictationShortcut: HotkeyBinding
handsFreeShortcut: HotkeyBinding
@ -1179,6 +1185,25 @@ export interface ConversationError {
phase: 'stt' | 'llm' | 'tts'
}
// ── OpenAI Realtime (라이브 음성 대화) ──
export interface RealtimeTokenParams {
/** 미지정 시 서버가 티어 기본 모델 선택 (pro=mini, pro_plus=full) */
model?: string
voice?: string
/** 시스템 프롬프트 (서버에서 2000자 제한) */
instructions?: string
}
export interface RealtimeTokenResult {
/** ephemeral client secret (ek_...) — WebRTC 연결에 사용 */
value: string
/** epoch seconds */
expiresAt: number
model: string
tier: 'free' | 'pro' | 'pro_plus'
}
// ============================================================
// Phase 13: Local RAG (13.2)
// ============================================================