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:
parent
983c60cda2
commit
8f7d300b89
15 changed files with 762 additions and 40 deletions
|
|
@ -137,6 +137,7 @@ export enum ErrorCode {
|
|||
ConversationNoActiveSession = 796,
|
||||
ConversationTTSFailed = 797,
|
||||
ConversationLLMFailed = 798,
|
||||
ConversationRealtimeTokenFailed = 799,
|
||||
|
||||
// === Phase 13: Local RAG (870-874) ===
|
||||
RAGDocumentNotFound = 870,
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -372,6 +372,12 @@ export interface AppConfig {
|
|||
* 'premium' — PremiumLLMService (Supabase llm-proxy → Claude, 로그인+구독 필요)
|
||||
*/
|
||||
llmBackend: 'local' | 'premium'
|
||||
/**
|
||||
* 음성 대화 백엔드 선택.
|
||||
* 'local' — VoiceConversationService (STT→LLM→TTS 파이프라인, 기본값)
|
||||
* '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)
|
||||
// ============================================================
|
||||
|
|
|
|||
|
|
@ -133,6 +133,11 @@
|
|||
"settings.backend.premium": "Premium (Claude AI, Subscription)",
|
||||
"settings.backend.localHint": "Polish text with local Ollama server. Fully free, no internet needed.",
|
||||
"settings.backend.premiumHint": "High-quality polishing with Anthropic Claude AI. Login + subscription required. Auto-fallback to Local on network failure.",
|
||||
"settings.conversationBackend": "Voice Chat Engine",
|
||||
"settings.convBackend.local": "Local (STT→LLM→TTS, Free)",
|
||||
"settings.convBackend.realtime": "Live (OpenAI gpt-realtime, Subscription)",
|
||||
"settings.convBackend.localHint": "Converse via the local pipeline. Fully free, no internet needed.",
|
||||
"settings.convBackend.realtimeHint": "Real-time voice conversation with OpenAI Realtime models. Sub-second responses + interruption support. Login + Pro subscription required. Auto-fallback to Local on failure.",
|
||||
"settings.llmModel": "LLM Model",
|
||||
"settings.postProcess": "Voice Post-Processing",
|
||||
"settings.defaultAction": "Default Post-Processing Command",
|
||||
|
|
@ -407,6 +412,9 @@
|
|||
"conversation.error.phase.llm": "Response",
|
||||
"conversation.error.phase.tts": "Voice Playback",
|
||||
"conversation.error.noSpeech": "No speech detected. Check your microphone and try again.",
|
||||
"conversation.realtime.badge": "LIVE",
|
||||
"conversation.realtime.connecting": "Connecting",
|
||||
"conversation.realtime.fallback": "Live connection failed — switched to local conversation.",
|
||||
"nav.knowledge": "Knowledge",
|
||||
"rag.title": "Knowledge Base",
|
||||
"rag.addDocument": "Add Document",
|
||||
|
|
|
|||
|
|
@ -134,6 +134,11 @@
|
|||
"settings.backend.premium": "Premium (Claude AI, 구독)",
|
||||
"settings.backend.localHint": "로컬 Ollama 서버로 텍스트를 다듬습니다. 완전 무료, 인터넷 불필요.",
|
||||
"settings.backend.premiumHint": "Anthropic Claude AI로 고품질 다듬기. 로그인 + 구독 필요. 네트워크 실패 시 Local로 자동 전환.",
|
||||
"settings.conversationBackend": "음성 대화 엔진",
|
||||
"settings.convBackend.local": "Local (STT→LLM→TTS, 무료)",
|
||||
"settings.convBackend.realtime": "Live (OpenAI gpt-realtime, 구독)",
|
||||
"settings.convBackend.localHint": "로컬 파이프라인으로 대화합니다. 완전 무료, 인터넷 불필요.",
|
||||
"settings.convBackend.realtimeHint": "OpenAI Realtime 모델과 실시간 음성 대화. 1초 미만 응답 + 말 끊기 지원. 로그인 + Pro 구독 필요. 연결 실패 시 Local로 자동 전환.",
|
||||
"settings.llmModel": "LLM 모델",
|
||||
"settings.postProcess": "음성 후처리",
|
||||
"settings.defaultAction": "기본 후처리 명령어",
|
||||
|
|
@ -408,6 +413,9 @@
|
|||
"conversation.error.phase.llm": "응답 생성",
|
||||
"conversation.error.phase.tts": "음성 재생",
|
||||
"conversation.error.noSpeech": "음성이 감지되지 않았습니다. 마이크를 확인하고 다시 말씀해 주세요.",
|
||||
"conversation.realtime.badge": "LIVE",
|
||||
"conversation.realtime.connecting": "연결 중",
|
||||
"conversation.realtime.fallback": "라이브 연결 실패 — 로컬 대화로 전환했습니다.",
|
||||
"rag.title": "지식 베이스",
|
||||
"rag.addDocument": "문서 추가",
|
||||
"rag.documents": "문서",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue