From 7dcc37e71483b5bb39d21fd25bcb7b58b4e8ee07 Mon Sep 17 00:00:00 2001 From: digua Date: Mon, 1 Jun 2026 21:45:58 +0800 Subject: [PATCH] refactor(electron): remove session index IPC --- apps/desktop/main/ipc/chat.ts | 152 +------------------------ apps/desktop/preload/apis/utils.ts | 144 +---------------------- apps/desktop/preload/index.ts | 5 +- src/services/registry.ts | 2 +- src/services/session-index/electron.ts | 73 ------------ src/services/session-index/types.ts | 2 +- 6 files changed, 8 insertions(+), 370 deletions(-) delete mode 100644 src/services/session-index/electron.ts diff --git a/apps/desktop/main/ipc/chat.ts b/apps/desktop/main/ipc/chat.ts index 559b31d4..544ff0a9 100644 --- a/apps/desktop/main/ipc/chat.ts +++ b/apps/desktop/main/ipc/chat.ts @@ -234,153 +234,7 @@ export function registerChatHandlers(ctx: IpcContext): void { } }) - // ==================== 会话索引(ElectronSessionIndexAdapter 依赖) ==================== - - ipcMain.handle('session:generate', async (_, sessionId: string, gapThreshold?: number) => { - try { - return await worker.generateSessions(sessionId, gapThreshold) - } catch (error) { - console.error('Failed to generate session index:', error) - throw error - } - }) - - ipcMain.handle('session:generateIncremental', async (_, sessionId: string, gapThreshold?: number) => { - try { - return await worker.generateIncrementalSessions(sessionId, gapThreshold) - } catch (error) { - console.error('Failed to generate incremental session index:', error) - throw error - } - }) - - ipcMain.handle('session:hasIndex', async (_, sessionId: string) => { - try { - return await worker.hasSessionIndex(sessionId) - } catch (error) { - console.error('Failed to check session index:', error) - return false - } - }) - - ipcMain.handle('session:getStats', async (_, sessionId: string) => { - try { - return await worker.getSessionStats(sessionId) - } catch (error) { - console.error('Failed to get session stats:', error) - return { sessionCount: 0, hasIndex: false, gapThreshold: 1800 } - } - }) - - ipcMain.handle('session:getAllIndexStats', async () => { - try { - return await worker.getAllIndexStats() - } catch (error) { - console.error('Failed to get all index stats:', error) - return [] - } - }) - - ipcMain.handle('session:clear', async (_, sessionId: string) => { - try { - await worker.clearSessions(sessionId) - return true - } catch (error) { - console.error('Failed to clear session index:', error) - return false - } - }) - - ipcMain.handle('session:updateGapThreshold', async (_, sessionId: string, gapThreshold: number | null) => { - try { - await worker.updateSessionGapThreshold(sessionId, gapThreshold) - return true - } catch (error) { - console.error('Failed to update threshold:', error) - return false - } - }) - - ipcMain.handle('session:getSessions', async (_, sessionId: string) => { - try { - return await worker.getSessions(sessionId) - } catch (error) { - console.error('Failed to get session list:', error) - return [] - } - }) - - ipcMain.handle('session:getByTimeRange', async (_, dbSessionId: string, startTs: number, endTs: number) => { - try { - return await worker.getSessionsByTimeRange(dbSessionId, startTs, endTs) - } catch (error) { - console.error('Failed to query sessions by time range:', error) - return [] - } - }) - - ipcMain.handle('session:getRecent', async (_, dbSessionId: string, limit: number) => { - try { - return await worker.getRecentChatSessions(dbSessionId, limit) - } catch (error) { - console.error('Failed to query recent sessions:', error) - return [] - } - }) - - // ==================== 会话摘要(依赖 LLM,无共享路由) ==================== - - ipcMain.handle( - 'session:generateSummary', - async ( - _, - dbSessionId: string, - chatSessionId: number, - locale?: string, - forceRegenerate?: boolean, - strategy?: 'brief' | 'standard' - ) => { - try { - const { generateSessionSummary } = await import('../ai/summary') - return await generateSessionSummary( - dbSessionId, - chatSessionId, - locale || 'zh-CN', - forceRegenerate || false, - strategy - ) - } catch (error) { - console.error('[IPC] Failed to generate session summary:', error) - return { success: false, error: String(error) } - } - } - ) - - ipcMain.handle( - 'session:generateSummaries', - async (_, dbSessionId: string, chatSessionIds: number[], locale?: string) => { - try { - const { generateSessionSummaries } = await import('../ai/summary') - return await generateSessionSummaries(dbSessionId, chatSessionIds, locale || 'zh-CN') - } catch (error) { - console.error('Failed to batch generate session summaries:', error) - return { success: 0, failed: chatSessionIds.length, skipped: 0 } - } - } - ) - - ipcMain.handle('session:checkCanGenerateSummary', async (_, dbSessionId: string, chatSessionIds: number[]) => { - try { - const { checkSessionsCanGenerateSummary } = await import('../ai/summary') - const results = checkSessionsCanGenerateSummary(dbSessionId, chatSessionIds) - const obj: Record = {} - for (const [id, result] of results) { - obj[id] = result - } - return obj - } catch (error) { - console.error('Failed to batch check session summaries:', error) - return {} - } - }) + // Session index and summary IPC handlers have been removed. + // All session-index operations now go through shared HTTP routes + // (FetchSessionIndexAdapter via /_web/sessions/* endpoints). } diff --git a/apps/desktop/preload/apis/utils.ts b/apps/desktop/preload/apis/utils.ts index b2a53937..6c4d5de2 100644 --- a/apps/desktop/preload/apis/utils.ts +++ b/apps/desktop/preload/apis/utils.ts @@ -13,21 +13,6 @@ export interface ProxyConfig { url: string // 仅 manual 模式使用 } -// Session API 类型 -export interface SessionStats { - sessionCount: number - hasIndex: boolean - gapThreshold: number -} - -export interface ChatSessionItem { - id: number - startTs: number - endTs: number - messageCount: number - firstMessageId: number -} - // ==================== Network API ==================== export const networkApi = { @@ -76,130 +61,5 @@ export const cacheApi = { }, } -// ==================== Session API ==================== - -export const sessionApi = { - /** - * 生成会话索引 - * @param sessionId 数据库会话ID - * @param gapThreshold 时间间隔阈值(秒) - * @returns 生成的会话数量 - */ - generate: (sessionId: string, gapThreshold?: number): Promise => { - return ipcRenderer.invoke('session:generate', sessionId, gapThreshold) - }, - - generateIncremental: (sessionId: string, gapThreshold?: number): Promise => { - return ipcRenderer.invoke('session:generateIncremental', sessionId, gapThreshold) - }, - - hasIndex: (sessionId: string): Promise => { - return ipcRenderer.invoke('session:hasIndex', sessionId) - }, - - /** - * 获取会话索引统计信息 - */ - getStats: (sessionId: string): Promise => { - return ipcRenderer.invoke('session:getStats', sessionId) - }, - - /** - * 批量获取所有会话的索引状态 - */ - getAllIndexStats: (): Promise> => { - return ipcRenderer.invoke('session:getAllIndexStats') - }, - - /** - * 清空会话索引 - */ - clear: (sessionId: string): Promise => { - return ipcRenderer.invoke('session:clear', sessionId) - }, - - /** - * 更新会话切分阈值 - */ - updateGapThreshold: (sessionId: string, gapThreshold: number | null): Promise => { - return ipcRenderer.invoke('session:updateGapThreshold', sessionId, gapThreshold) - }, - - /** - * 获取会话列表(用于时间线导航) - */ - getSessions: (sessionId: string): Promise => { - return ipcRenderer.invoke('session:getSessions', sessionId) - }, - - /** - * 生成单个会话摘要 - */ - generateSummary: ( - dbSessionId: string, - chatSessionId: number, - locale?: string, - forceRegenerate?: boolean, - strategy?: 'brief' | 'standard' - ): Promise<{ success: boolean; summary?: string; error?: string }> => { - return ipcRenderer.invoke('session:generateSummary', dbSessionId, chatSessionId, locale, forceRegenerate, strategy) - }, - - /** - * 批量生成会话摘要 - */ - generateSummaries: ( - dbSessionId: string, - chatSessionIds: number[], - locale?: string - ): Promise<{ success: number; failed: number; skipped: number }> => { - return ipcRenderer.invoke('session:generateSummaries', dbSessionId, chatSessionIds, locale) - }, - - /** - * 批量检查会话是否可以生成摘要 - */ - checkCanGenerateSummary: ( - dbSessionId: string, - chatSessionIds: number[] - ): Promise> => { - return ipcRenderer.invoke('session:checkCanGenerateSummary', dbSessionId, chatSessionIds) - }, - - /** - * 根据时间范围查询会话列表 - */ - getByTimeRange: ( - dbSessionId: string, - startTs: number, - endTs: number - ): Promise< - Array<{ - id: number - startTs: number - endTs: number - messageCount: number - summary: string | null - }> - > => { - return ipcRenderer.invoke('session:getByTimeRange', dbSessionId, startTs, endTs) - }, - - /** - * 获取最近 N 条会话 - */ - getRecent: ( - dbSessionId: string, - limit: number - ): Promise< - Array<{ - id: number - startTs: number - endTs: number - messageCount: number - summary: string | null - }> - > => { - return ipcRenderer.invoke('session:getRecent', dbSessionId, limit) - }, -} +// Session index API has been migrated to shared HTTP routes (FetchSessionIndexAdapter). +// All session:* IPC handlers have been removed. diff --git a/apps/desktop/preload/index.ts b/apps/desktop/preload/index.ts index 2dd80d05..9fef1ef4 100644 --- a/apps/desktop/preload/index.ts +++ b/apps/desktop/preload/index.ts @@ -9,7 +9,7 @@ import { electronAPI } from '@electron-toolkit/preload' import { extendedApi } from './apis/core' import { chatApi } from './apis/chat' import { aiApi } from './apis/ai' -import { networkApi, cacheApi, sessionApi } from './apis/utils' +import { networkApi, cacheApi } from './apis/utils' import { apiServerApi } from './apis/api-server' import { internalApi } from './apis/internal-api' @@ -39,7 +39,6 @@ if (process.contextIsolated) { contextBridge.exposeInMainWorld('aiApi', aiApi) contextBridge.exposeInMainWorld('cacheApi', cacheApi) contextBridge.exposeInMainWorld('networkApi', networkApi) - contextBridge.exposeInMainWorld('sessionApi', sessionApi) contextBridge.exposeInMainWorld('apiServerApi', apiServerApi) contextBridge.exposeInMainWorld('internalApi', internalApi) } catch (error) { @@ -59,8 +58,6 @@ if (process.contextIsolated) { // @ts-ignore (define in dts) window.networkApi = networkApi // @ts-ignore (define in dts) - window.sessionApi = sessionApi - // @ts-ignore (define in dts) window.apiServerApi = apiServerApi // @ts-ignore (define in dts) window.internalApi = internalApi diff --git a/src/services/registry.ts b/src/services/registry.ts index 3fecb878..b2757178 100644 --- a/src/services/registry.ts +++ b/src/services/registry.ts @@ -62,7 +62,7 @@ export async function initServices(): Promise { /** * Electron adapters: Internal HTTP Server is a hard dependency. - * data/message/preferences use Fetch; import/session-index/ai stay on IPC. + * data/message/preferences/ai-streaming use Fetch/SSE; import stays on IPC. */ async function initElectronAdapters(): Promise { const { FetchDataAdapter } = await import('./data/fetch') diff --git a/src/services/session-index/electron.ts b/src/services/session-index/electron.ts deleted file mode 100644 index a8d2092f..00000000 --- a/src/services/session-index/electron.ts +++ /dev/null @@ -1,73 +0,0 @@ -/** - * ElectronSessionIndexAdapter — wrap window.sessionApi IPC - */ - -import type { - SessionIndexAdapter, - SessionStats, - SessionIndexStatusItem, - ChatSessionItem, - SummaryResult, - BatchSummaryResult, - CanGenerateInfo, -} from './types' - -export class ElectronSessionIndexAdapter implements SessionIndexAdapter { - generate(sessionId: string, gapThreshold?: number): Promise { - return window.sessionApi.generate(sessionId, gapThreshold) - } - - generateIncremental(sessionId: string, gapThreshold?: number): Promise { - return window.sessionApi.generateIncremental(sessionId, gapThreshold) - } - - hasIndex(sessionId: string): Promise { - return window.sessionApi.hasIndex(sessionId) - } - - getStats(sessionId: string): Promise { - return window.sessionApi.getStats(sessionId) - } - - async getAllIndexStats(): Promise { - return window.sessionApi.getAllIndexStats() - } - - clear(sessionId: string): Promise { - return window.sessionApi.clear(sessionId) - } - - updateGapThreshold(sessionId: string, gapThreshold: number | null): Promise { - return window.sessionApi.updateGapThreshold(sessionId, gapThreshold) - } - - getSessions(sessionId: string): Promise { - return window.sessionApi.getSessions(sessionId) - } - - getByTimeRange(sessionId: string, startTs: number, endTs: number): Promise { - return window.sessionApi.getByTimeRange(sessionId, startTs, endTs) as Promise - } - - getRecent(sessionId: string, limit: number): Promise { - return window.sessionApi.getRecent(sessionId, limit) as Promise - } - - generateSummary( - dbSessionId: string, - chatSessionId: number, - locale?: string, - forceRegenerate?: boolean, - strategy?: 'brief' | 'standard' - ): Promise { - return window.sessionApi.generateSummary(dbSessionId, chatSessionId, locale, forceRegenerate, strategy) - } - - generateSummaries(dbSessionId: string, chatSessionIds: number[], locale?: string): Promise { - return window.sessionApi.generateSummaries(dbSessionId, chatSessionIds, locale) - } - - checkCanGenerateSummary(dbSessionId: string, chatSessionIds: number[]): Promise> { - return window.sessionApi.checkCanGenerateSummary(dbSessionId, chatSessionIds) - } -} diff --git a/src/services/session-index/types.ts b/src/services/session-index/types.ts index 3a90c623..6fb39527 100644 --- a/src/services/session-index/types.ts +++ b/src/services/session-index/types.ts @@ -2,7 +2,7 @@ * SessionIndexAdapter — 会话索引领域适配器接口 * * 负责会话切分索引的生成、查询、摘要等操作。 - * 来源:window.sessionApi(Electron IPC)/ web-api-shim 垫片(Web SQL) + * 统一通过 FetchSessionIndexAdapter 消费共享 HTTP 路由。 */ export interface SessionStats {