refactor(electron): remove orphaned LLM/Assistant/Skill IPC handlers

Delete 40 IPC handlers in ipc/ai.ts whose preload bridges were
removed in the previous commit. These handlers are dead code since
the frontend now uses HTTP service layer (FetchLLMAdapter,
FetchAssistantAdapter, FetchSkillAdapter) via the Internal Server.

Removed:
- 20 llm:* CRUD handlers (config, provider registry, model catalog,
  custom provider/model, validate, remote models)
- 11 assistant:* handlers (CRUD, builtin catalog, import/reimport)
- 9 skill:* handlers (CRUD, builtin catalog, import/reimport)

Retained on IPC (still used):
- llm:chat, llm:chatStream (streaming)
- agent:runStream, agent:abort (streaming)
- All ai:* handlers (conversation CRUD, tool testing, compression,
  desensitize rules, debug SQL, filter/export)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
diguaandCursor committed 2026-06-02 15:41:21 +08:00
1 parent 3ab162162b
commit 65fb5179cd
1 file changed
+7 -440
+7 -440
View File
@@ -360,262 +360,8 @@ export function registerAIHandlers({ win }: IpcContext): void {
return mergeRulesForLocale(existingRules as any[], locale)
})
// ==================== LLM 服务(多配置管理)====================
/**
* 获取所有支持的 LLM 提供商
*/
ipcMain.handle('llm:getProviders', async () => {
return llm.PROVIDERS
})
/**
* 获取所有配置列表
*/
ipcMain.handle('llm:getAllConfigs', async () => {
const configs = llm.getAllConfigs()
// 返回 API Key
return configs.map((c) => ({
...c,
apiKeySet: !!c.apiKey,
}))
})
/**
* 获取默认助手 slot
*/
ipcMain.handle('llm:getDefaultAssistantSlot', async () => {
return llm.getDefaultAssistantSlot()
})
/**
* 获取快速模型 slot
*/
ipcMain.handle('llm:getFastModelSlot', async () => {
return llm.getFastModelSlot()
})
/**
* 添加新配置
*/
ipcMain.handle(
'llm:addConfig',
async (
_,
config: {
name: string
provider: llm.LLMProvider
apiKey: string
model?: string
baseUrl?: string
maxTokens?: number
apiFormat?: string
customModels?: Array<{ id: string; name: string }>
}
) => {
try {
const result = llm.addConfig(config)
if (result.success && result.config) {
return {
success: true,
config: {
...result.config,
apiKeySet: !!result.config.apiKey,
},
}
}
return result
} catch (error) {
console.error('Failed to add LLM config:', error)
return { success: false, error: String(error) }
}
}
)
/**
* 更新配置
*/
ipcMain.handle(
'llm:updateConfig',
async (
_,
id: string,
updates: {
name?: string
provider?: llm.LLMProvider
apiKey?: string
model?: string
baseUrl?: string
maxTokens?: number
apiFormat?: string
customModels?: Array<{ id: string; name: string }>
}
) => {
try {
// 如果 apiKey 为空字符串,表示不更新 API Key
const cleanUpdates = { ...updates }
if (cleanUpdates.apiKey === '') {
delete cleanUpdates.apiKey
}
return llm.updateConfig(id, cleanUpdates)
} catch (error) {
console.error('Failed to update LLM config:', error)
return { success: false, error: String(error) }
}
}
)
/**
* 删除配置
*/
ipcMain.handle('llm:deleteConfig', async (_, id?: string) => {
try {
if (!id) {
const defaultConfig = llm.getDefaultAssistantConfig()
if (defaultConfig) {
return llm.deleteConfig(defaultConfig.id)
}
return { success: false, error: t('llm.noActiveConfig') }
}
return llm.deleteConfig(id)
} catch (error) {
console.error('Failed to delete LLM config:', error)
return { success: false, error: String(error) }
}
})
/**
* 设置默认助手模型(configId + modelId)
*/
ipcMain.handle('llm:setDefaultAssistantModel', async (_, configId: string, modelId: string) => {
try {
return llm.setDefaultAssistantModel(configId, modelId)
} catch (error) {
console.error('Failed to set default assistant model:', error)
return { success: false, error: String(error) }
}
})
/**
* 设置快速模型
*/
ipcMain.handle('llm:setFastModel', async (_, slot: { configId: string; modelId: string } | null) => {
try {
return llm.setFastModel(slot)
} catch (error) {
console.error('Failed to set fast model:', error)
return { success: false, error: String(error) }
}
})
/**
* 验证 API Key(支持自定义 baseUrl 和 model)
* 返回对象格式:{ success: boolean, error?: string }
*/
ipcMain.handle(
'llm:validateApiKey',
async (_, provider: llm.LLMProvider, apiKey: string, baseUrl?: string, model?: string) => {
aiLogger.info('IPC', 'llm:validateApiKey validating', {
provider,
baseUrl,
model,
apiKeyLength: apiKey?.length,
})
try {
const result = await llm.validateApiKey(provider, apiKey, baseUrl, model)
aiLogger.info('IPC', 'llm:validateApiKey result', result)
return result
} catch (error) {
aiLogger.error('IPC', 'llm:validateApiKey failed', { error: String(error), provider, baseUrl, model })
const errorMessage = error instanceof Error ? error.message : String(error)
return { success: false, error: errorMessage }
}
}
)
/**
* 获取远程模型列表
*/
ipcMain.handle(
'llm:fetchRemoteModels',
async (_, provider: string, apiKey: string, baseUrl?: string, apiFormat?: string) => {
aiLogger.info('IPC', 'llm:fetchRemoteModels', { provider, baseUrl, apiFormat })
try {
return await llm.fetchRemoteModels(provider, apiKey, baseUrl, apiFormat)
} catch (error) {
aiLogger.error('IPC', 'llm:fetchRemoteModels failed', { error: String(error) })
return { success: false, error: error instanceof Error ? error.message : String(error) }
}
}
)
/**
* 检查是否已配置 LLM(是否有激活的配置)
*/
ipcMain.handle('llm:hasConfig', async () => {
return llm.hasActiveConfig()
})
// ==================== Provider Registry / Model Catalog ====================
ipcMain.handle('llm:getProviderRegistry', async () => {
return llm.getProviderRegistry()
})
ipcMain.handle('llm:getModelCatalog', async () => {
return llm.getModelCatalog()
})
ipcMain.handle('llm:addCustomProvider', async (_, input) => {
try {
const provider = llm.addCustomProvider(input)
return { success: true, provider }
} catch (error) {
return { success: false, error: String(error) }
}
})
ipcMain.handle('llm:updateCustomProvider', async (_, id: string, updates) => {
try {
return llm.updateCustomProvider(id, updates)
} catch (error) {
return { success: false, error: String(error) }
}
})
ipcMain.handle('llm:deleteCustomProvider', async (_, id: string) => {
try {
return llm.deleteCustomProvider(id)
} catch (error) {
return { success: false, error: String(error) }
}
})
ipcMain.handle('llm:addCustomModel', async (_, input) => {
try {
const model = llm.addCustomModel(input)
return { success: true, model }
} catch (error) {
return { success: false, error: String(error) }
}
})
ipcMain.handle('llm:updateCustomModel', async (_, providerId: string, modelId: string, updates) => {
try {
return llm.updateCustomModel(providerId, modelId, updates)
} catch (error) {
return { success: false, error: String(error) }
}
})
ipcMain.handle('llm:deleteCustomModel', async (_, providerId: string, modelId: string) => {
try {
return llm.deleteCustomModel(providerId, modelId)
} catch (error) {
return { success: false, error: String(error) }
}
})
// LLM CRUD (config, provider, model, validate, etc.) has been migrated to
// HTTP service layer via shared routes. Only chat APIs remain on IPC.
// ==================== LLM 直接调用 API(SQLLab 等非 Agent 场景使用) ====================
@@ -708,189 +454,7 @@ export function registerAIHandlers({ win }: IpcContext): void {
}
)
// ==================== 助手管理 API ====================
ipcMain.handle('assistant:getAll', async () => {
try {
return assistantManager.getAllAssistants()
} catch (error) {
console.error('Failed to get assistants:', error)
return []
}
})
ipcMain.handle('assistant:getConfig', async (_, id: string) => {
try {
return assistantManager.getAssistantConfig(id)
} catch (error) {
console.error('Failed to get assistant config:', error)
return null
}
})
ipcMain.handle('assistant:update', async (_, id: string, updates: Partial<AssistantConfig>) => {
try {
return assistantManager.updateAssistant(id, updates)
} catch (error) {
console.error('Failed to update assistant:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('assistant:create', async (_, config: Omit<AssistantConfig, 'id' | 'version'>) => {
try {
return assistantManager.createAssistant(config)
} catch (error) {
console.error('Failed to create assistant:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('assistant:delete', async (_, id: string) => {
try {
return assistantManager.deleteAssistant(id)
} catch (error) {
console.error('Failed to delete assistant:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('assistant:reset', async (_, id: string) => {
try {
return assistantManager.resetAssistant(id)
} catch (error) {
console.error('Failed to reset assistant:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('assistant:getBuiltinToolCatalog', async () => {
try {
return assistantManager.getBuiltinToolCatalog()
} catch (error) {
console.error('Failed to get builtin tool catalog:', error)
return []
}
})
ipcMain.handle('assistant:getBuiltinCatalog', async () => {
try {
return assistantManager.getBuiltinCatalog()
} catch (error) {
console.error('Failed to get builtin catalog:', error)
return []
}
})
ipcMain.handle('assistant:import', async (_, builtinId: string) => {
try {
return assistantManager.importAssistant(builtinId)
} catch (error) {
console.error('Failed to import assistant:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('assistant:reimport', async (_, id: string) => {
try {
return assistantManager.reimportAssistant(id)
} catch (error) {
console.error('Failed to reimport assistant:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('assistant:importFromMd', async (_, rawMd: string) => {
try {
return assistantManager.importAssistantFromMd(rawMd)
} catch (error) {
console.error('Failed to import assistant from markdown:', error)
return { success: false, error: String(error) }
}
})
// ==================== 技能管理 API ====================
ipcMain.handle('skill:getAll', async () => {
try {
return skillManager.getAllSkills()
} catch (error) {
console.error('Failed to get skills:', error)
return []
}
})
ipcMain.handle('skill:getConfig', async (_, id: string) => {
try {
return skillManager.getSkillConfig(id)
} catch (error) {
console.error('Failed to get skill config:', error)
return null
}
})
ipcMain.handle('skill:update', async (_, id: string, rawMd: string) => {
try {
return skillManager.updateSkill(id, rawMd)
} catch (error) {
console.error('Failed to update skill:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('skill:create', async (_, rawMd: string) => {
try {
return skillManager.createSkill(rawMd)
} catch (error) {
console.error('Failed to create skill:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('skill:delete', async (_, id: string) => {
try {
return skillManager.deleteSkill(id)
} catch (error) {
console.error('Failed to delete skill:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('skill:getBuiltinCatalog', async () => {
try {
return skillManager.getBuiltinCatalog()
} catch (error) {
console.error('Failed to get builtin catalog:', error)
return []
}
})
ipcMain.handle('skill:import', async (_, builtinId: string) => {
try {
return skillManager.importSkill(builtinId)
} catch (error) {
console.error('Failed to import skill:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('skill:reimport', async (_, id: string) => {
try {
return skillManager.reimportSkill(id)
} catch (error) {
console.error('Failed to reimport skill:', error)
return { success: false, error: String(error) }
}
})
ipcMain.handle('skill:importFromMd', async (_, rawMd: string) => {
try {
return skillManager.importSkillFromMd(rawMd)
} catch (error) {
console.error('Failed to import skill from markdown:', error)
return { success: false, error: String(error) }
}
})
// Assistant and Skill CRUD has been migrated to HTTP service layer via shared routes.
// ==================== 工具测试 API(实验室 - 基础工具) ====================
@@ -1166,7 +730,10 @@ export function registerAIHandlers({ win }: IpcContext): void {
enrichedContext,
piModel,
activeAIConfig.apiKey,
{ abortSignal: abortController.signal, thinkingLevel: thinkingLevel as import('@openchatlab/core').ThinkingLevel | undefined },
{
abortSignal: abortController.signal,
thinkingLevel: thinkingLevel as import('@openchatlab/core').ThinkingLevel | undefined,
},
chatType ?? 'group',
locale ?? 'zh-CN',
assistantConfig,