fix(desktop): harden session, meeting, caption and LLM lifecycles; route LLM calls through the gateway

This commit is contained in:
Yun Chan 2026-09-28 02:16:15 +09:00
parent 3a46437f28
commit ddc78546f0
62 changed files with 4786 additions and 648 deletions

View file

@ -8,8 +8,10 @@ import fs from 'fs'
import { app, dialog } from 'electron'
import { eq } from 'drizzle-orm'
import { getLogger } from './LoggerService'
import { getPremiumLLMService } from './PremiumLLMService'
import { getLlmGateway } from './llm/LlmGateway'
import { getCloudSyncService } from './CloudSyncService'
import { condenseTranscriptToBudget } from './meeting/transcript-condenser'
import { LLM_PROXY_CHAT_LIMITS } from '@d3ro/core/llm-chat'
import { getDatabase } from '../db'
import { history } from '../db/schema'
import { getMainWindow } from '../windows/WindowManager'
@ -76,9 +78,22 @@ class MeetingSummaryService extends EventEmitter {
this._sendProgress(historyId, 'generating')
try {
// LLM 요약 생성
const llmService = getPremiumLLMService()
const result = await llmService.generate(transcript, {
// LLM 요약 생성 — 백엔드 선택은 게이트웨이가 한다(llmBackend='local' 이면 로컬 Ollama).
// 예전엔 설정과 무관하게 Premium 에 고정돼, 로컬을 고른 로그인 사용자의 자막 전사가 클라우드로 가고
// 쿼터를 썼으며, 로그인하지 않은 사용자는 요약을 전혀 받지 못했다.
const gateway = getLlmGateway()
const llm = {
generate: (text: string, options?: { systemPrompt?: string; temperature?: number; maxTokens?: number }) =>
gateway.generate(text, options, {
onFallback: (reason) => logger.warn(`Meeting summary LLM fallback: ${reason}`),
}),
}
// 긴 전사는 한 메시지 한도(8,000자)를 넘어 거부된다 — 구간별로 정리한 뒤 요약한다.
const fitted = await condenseTranscriptToBudget(llm, transcript, LLM_PROXY_CHAT_LIMITS.maxMessageChars)
if (fitted.condensed) {
logger.info(`Summary input condensed in ${fitted.rounds} round(s): ${historyId}`)
}
const result = await llm.generate(fitted.text, {
systemPrompt: MEETING_SUMMARY_PROMPT,
temperature: 0.3,
})