import { contextBridge, ipcRenderer } from 'electron' console.log('[preload] 正在注册 electronAPI...') contextBridge.exposeInMainWorld('electronAPI', { // 文件选择 selectFiles: (): Promise => ipcRenderer.invoke('select-files'), selectDirectory: (): Promise => ipcRenderer.invoke('select-directory'), // 入库 indexDocuments: (payload: { paths: string[]; mode: 'append' | 'rebuild' }): Promise => ipcRenderer.invoke('index-documents', payload), // 查询 query: (payload: { question: string; systemPrompt: string; topK: number }): Promise => ipcRenderer.invoke('query', payload), // 拍照提问(不走检索,直接把图片+问题发给多模态生成服务) visionQuery: (payload: { question: string; imageDataUrl: string }): Promise => ipcRenderer.invoke('vision-query', payload), // 状态 & 配置 getDbStatus: (): Promise<{ count: number; ready: boolean }> => ipcRenderer.invoke('get-db-status'), getConfig: () => ipcRenderer.invoke('get-config'), saveConfig: (config: unknown) => ipcRenderer.invoke('save-config', config), testEmbedConnection: (embedConfig: unknown): Promise<{ ok: boolean; message: string }> => ipcRenderer.invoke('embed-test', embedConfig), testChatConnection: (chatConfig: unknown): Promise<{ ok: boolean; message: string }> => ipcRenderer.invoke('chat-test', chatConfig), // 本地嵌入模型 selectModelDir: (): Promise => ipcRenderer.invoke('select-model-dir'), checkModelPath: (dirPath: string): Promise => ipcRenderer.invoke('check-model-path', dirPath), // 退出程序 quitApp: (): Promise => ipcRenderer.invoke('quit-app'), // 批量问题导入导出 importBatchQuestions: (): Promise => ipcRenderer.invoke('batch:import'), exportBatchQuestions: (questions: string[]): Promise => ipcRenderer.invoke('batch:export', questions), // 硬件探测 hardwareGetDetected: (): Promise<'er160' | 'er25' | 'none' | null> => ipcRenderer.invoke('hardware:get-detected'), // 平台信息 platform: process.platform, // 语音输入(ASR) asrSelectModelDir: (): Promise => ipcRenderer.invoke('asr:select-model-dir'), asrSelectExecutable: (): Promise => ipcRenderer.invoke('asr:select-executable'), asrCheckModelDir: (dirPath: string): Promise => ipcRenderer.invoke('asr:check-model-dir', dirPath), asrInitModel: (): Promise => ipcRenderer.invoke('asr:init-model'), asrStartStream: (): Promise => ipcRenderer.invoke('asr:start-stream'), asrFeedChunk: (samples: number[]): Promise => ipcRenderer.invoke('asr:feed-chunk', samples), asrStopStream: (): Promise => ipcRenderer.invoke('asr:stop-stream'), asrUnloadModel: (): Promise => ipcRenderer.invoke('asr:unload-model'), // 语音输出(系统 TTS 兜底) ttsAvailable: (): Promise => ipcRenderer.invoke('tts:available'), ttsConfigure: (options: unknown): Promise => ipcRenderer.invoke('tts:configure', options), ttsSpeak: (text: string): Promise => ipcRenderer.invoke('tts:speak', text), ttsStop: (): Promise => ipcRenderer.invoke('tts:stop'), // er-backend 管理服务(Linux NPU) erBackendEnsure: (): Promise<{ ok: boolean; message: string }> => ipcRenderer.invoke('er-backend:ensure'), erBackendStatus: (): Promise => ipcRenderer.invoke('er-backend:status'), // 事件监听(ASR/TTS 推送事件) on: (channel: string, callback: (...args: unknown[]) => void) => { ipcRenderer.removeAllListeners(channel) ipcRenderer.on(channel, (_event, ...args) => callback(...args)) }, off: (channel: string) => { ipcRenderer.removeAllListeners(channel) } })