- 기본 STT 모델 base → large-v3-turbo (6배 빠름, 1.6GB) - 사이드카: /download, /download/status, /download/cancel + --models-dir - LocalSTTService: downloadModel/cancelDownload + download-progress 이벤트 - IPC: 설계서 02의 stt:downloadModel/cancelDownload/downloadProgress 구현 - OnboardingModal: LLM(gemma4:e4b) → STT(turbo) 2단계 순차 다운로드 UI - SettingsModal turbo 선택지 + settings.model.largeTurbo 12 locale - 테스트: 모노레포 잔재 import 수정 (src/shared → @d3ro/core), 41/41 통과
90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
// src/main/ipc/stt-handlers.ts
|
|
|
|
import { ipcMain } from 'electron'
|
|
import { IPC_CHANNELS } from '@d3ro/core/ipc-channels'
|
|
import { ipcSuccess, ipcError, ErrorCode, D3ROError } from '@d3ro/core/errors'
|
|
import { getLocalSTTService } from '../services/LocalSTTService'
|
|
import { configGet, configSet } from '../services/ConfigService'
|
|
import { getMainWindow } from '../windows/WindowManager'
|
|
import type {
|
|
SetSTTModelParams,
|
|
SetSTTLanguageParams,
|
|
DownloadModelParams,
|
|
} from '@d3ro/core/types'
|
|
|
|
function safeSendToRenderer(channel: string, data: unknown): void {
|
|
const win = getMainWindow()
|
|
if (win && !win.isDestroyed()) {
|
|
win.webContents.send(channel, data)
|
|
}
|
|
}
|
|
|
|
export function registerSTTHandlers(): void {
|
|
// 다운로드 진행률 → 렌더러
|
|
getLocalSTTService().on('download-progress', (payload) => {
|
|
safeSendToRenderer(IPC_CHANNELS.STT.DOWNLOAD_PROGRESS, payload)
|
|
})
|
|
|
|
ipcMain.handle(IPC_CHANNELS.STT.GET_STATUS, async () => {
|
|
try {
|
|
const stt = getLocalSTTService()
|
|
return ipcSuccess(stt.getStatus())
|
|
} catch {
|
|
return ipcError(ErrorCode.STTSidecarCommunicationFailed, 'Failed to get STT status')
|
|
}
|
|
})
|
|
|
|
ipcMain.handle(IPC_CHANNELS.STT.GET_MODELS, async () => {
|
|
try {
|
|
const stt = getLocalSTTService()
|
|
return ipcSuccess(await stt.getModels())
|
|
} catch {
|
|
return ipcError(ErrorCode.STTModelNotFound, 'Failed to get models')
|
|
}
|
|
})
|
|
|
|
ipcMain.handle(IPC_CHANNELS.STT.GET_ACTIVE_MODEL, async () => {
|
|
return ipcSuccess(configGet('sttModelId'))
|
|
})
|
|
|
|
ipcMain.handle(IPC_CHANNELS.STT.SET_MODEL, async (_event, params: SetSTTModelParams) => {
|
|
try {
|
|
configSet('sttModelId', params.modelId)
|
|
const stt = getLocalSTTService()
|
|
await stt.initialize(params.modelId)
|
|
return ipcSuccess(undefined)
|
|
} catch {
|
|
return ipcError(ErrorCode.STTModelLoadFailed, 'Failed to set STT model')
|
|
}
|
|
})
|
|
|
|
ipcMain.handle(
|
|
IPC_CHANNELS.STT.DOWNLOAD_MODEL,
|
|
async (_event, params: DownloadModelParams) => {
|
|
try {
|
|
await getLocalSTTService().downloadModel(params.modelId)
|
|
return ipcSuccess(undefined)
|
|
} catch (err) {
|
|
if (err instanceof D3ROError) {
|
|
return ipcError(err.code, err.message)
|
|
}
|
|
const msg = err instanceof Error ? err.message : String(err)
|
|
return ipcError(ErrorCode.STTModelDownloadFailed, `Model download failed: ${msg}`)
|
|
}
|
|
},
|
|
)
|
|
|
|
ipcMain.handle(IPC_CHANNELS.STT.CANCEL_DOWNLOAD, async () => {
|
|
await getLocalSTTService().cancelDownload()
|
|
return ipcSuccess(undefined)
|
|
})
|
|
|
|
ipcMain.handle(IPC_CHANNELS.STT.GET_LANGUAGE, async () => {
|
|
return ipcSuccess(configGet('sttLanguage'))
|
|
})
|
|
|
|
ipcMain.handle(IPC_CHANNELS.STT.SET_LANGUAGE, async (_event, params: SetSTTLanguageParams) => {
|
|
configSet('sttLanguage', params.language)
|
|
return ipcSuccess(undefined)
|
|
})
|
|
}
|