Phase 4 구현: Ollama LLM 연동 (다듬기, 번역, 스트리밍)

- LocalLLMService: Ollama REST API, 스트리밍 NDJSON 파싱, 5초 가용성 폴링
- 시스템 프롬프트: refine/translate/summarize/grammar/expand/custom 6개 액션
- VoiceModeService: 전사→LLM 후처리→텍스트 삽입, LLM 실패 시 원본 폴백
- LLM IPC 핸들러: status/models/process/cancel/serverUrl 8개
- StatusBar: Ollama 연결 상태 + 활성 모델 표시
- Preload: llm API 섹션 추가
- Bootstrap: llm-polling 초기화 단계 추가
This commit is contained in:
Yun Chan 2026-04-05 02:18:26 +09:00
parent 517210af2f
commit 4a5cf6c819
10 changed files with 663 additions and 9 deletions

View file

@ -39,6 +39,14 @@ import type {
SetHotkeyParams,
SetEnabledParams,
HotkeyTriggeredEvent,
LLMStatus,
LLMModel,
LLMProcessParams,
LLMProcessResult,
SetLLMModelParams,
SetServerUrlParams,
LLMStatusChangedEvent,
LLMProcessProgressEvent,
PermissionStatus
} from '@shared/types'
import type { IPCResult } from '@shared/errors'
@ -142,6 +150,25 @@ const electronAPI = {
on(IPC_CHANNELS.HOTKEY.TRIGGERED, cb)
},
// ── LLM ────────────────────────────────────────────────
llm: {
getStatus: () => invoke<LLMStatus>(IPC_CHANNELS.LLM.GET_STATUS),
getModels: () => invoke<LLMModel[]>(IPC_CHANNELS.LLM.GET_MODELS),
getActiveModel: () => invoke<string | null>(IPC_CHANNELS.LLM.GET_ACTIVE_MODEL),
setModel: (params: SetLLMModelParams) =>
invoke<void>(IPC_CHANNELS.LLM.SET_MODEL, params),
process: (params: LLMProcessParams) =>
invoke<LLMProcessResult>(IPC_CHANNELS.LLM.PROCESS, params),
cancelProcess: () => invoke<void>(IPC_CHANNELS.LLM.CANCEL_PROCESS),
getServerUrl: () => invoke<string>(IPC_CHANNELS.LLM.GET_SERVER_URL),
setServerUrl: (params: SetServerUrlParams) =>
invoke<void>(IPC_CHANNELS.LLM.SET_SERVER_URL, params),
onStatusChanged: (cb: (e: LLMStatusChangedEvent) => void): Unsubscribe =>
on(IPC_CHANNELS.LLM.STATUS_CHANGED, cb),
onProcessProgress: (cb: (e: LLMProcessProgressEvent) => void): Unsubscribe =>
on(IPC_CHANNELS.LLM.PROCESS_PROGRESS, cb)
},
// ── Window ─────────────────────────────────────────────
window: {
minimize: () => send(IPC_CHANNELS.WINDOW.MINIMIZE),