From ba85328c4f6a6a5a27da5600a7e678e4b5f5e63f Mon Sep 17 00:00:00 2001 From: thzxx Date: Wed, 1 Jul 2026 20:04:05 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20LLM=20=E9=85=8D=E7=BD=AE=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=E5=90=8E=E7=AB=8B=E5=8D=B3=E7=94=9F=E6=95=88=20?= =?UTF-8?q?=E2=80=94=20=E7=83=AD=E9=87=8D=E8=BD=BD=20Provider=20Adapter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AgentLoopEngine 新增 setAdapter() 热切换方法 - main.ts 提取 createAdapter 工厂函数 - IPC config:set 监听 LLM 相关 key 变更,触发热重载 - 覆盖 provider/model/apiKey/baseURL/numCtx 五个关键配置 --- electron/harness/agent-loop/engine.ts | 7 +++++ electron/ipc/handlers.ts | 7 +++++ electron/main.ts | 43 ++++++++++++++++----------- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/electron/harness/agent-loop/engine.ts b/electron/harness/agent-loop/engine.ts index 2e43340..61e27af 100644 --- a/electron/harness/agent-loop/engine.ts +++ b/electron/harness/agent-loop/engine.ts @@ -94,6 +94,13 @@ export class AgentLoopEngine extends EventEmitter { return [...this.tools]; } + /** + * 热切换 Provider Adapter(设置变更时调用) + */ + setAdapter(adapter: IMetonaProviderAdapter): void { + this.adapter = adapter; + } + /** * 执行完整的 ReAct 循环(流式模式) * diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index 3e6e613..10efafc 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -40,6 +40,7 @@ export function registerAllIPCHandlers( sessionRecorder: SessionRecorder, memoryManager: MemoryManager, mcpManager: MCPManager, + reloadAdapter: () => void, ): void { // ===== Agent 交互 ===== @@ -322,6 +323,12 @@ export function registerAllIPCHandlers( outcome: 'success', }); + // LLM 相关配置变更时热重载 Adapter + if (['llm.provider', 'llm.model', 'llm.apiKey', 'llm.baseURL', 'ollama.numCtx'].includes(key)) { + reloadAdapter(); + log.info(`[CONFIG] LLM config changed (${key}), adapter reloaded`); + } + return { success: true }; }); diff --git a/electron/main.ts b/electron/main.ts index 2efc6e9..e60ab04 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -87,23 +87,26 @@ async function initialize(): Promise { const memoryManager = new MemoryManager(() => db); memoryManager.initialize(); - // ===== 步骤 4: Provider Adapter ===== - const provider = configService.get('llm.provider') ?? ''; - const model = configService.get('llm.model') ?? ''; - const apiKey = configService.get('llm.apiKey') ?? ''; - const baseURL = configService.get('llm.baseURL') ?? ''; + // ===== 步骤 4: Provider Adapter 工厂 ===== + const createAdapter = () => { + const provider = configService.get('llm.provider') ?? ''; + const model = configService.get('llm.model') ?? ''; + const apiKey = configService.get('llm.apiKey') ?? ''; + const baseURL = configService.get('llm.baseURL') ?? ''; - if (!provider || !baseURL || !model) { - log.warn('LLM not configured. Please set provider, baseURL, and model in Settings.'); - } + if (!provider || !baseURL || !model) { + log.warn('LLM not configured. Please set provider, baseURL, and model in Settings.'); + } - const adapterConfig = { provider, baseURL, apiKey, defaultModel: model }; - let adapter; - switch (provider) { - case 'agnes': adapter = new AgnesAdapter(adapterConfig); break; - case 'ollama': adapter = new OllamaAdapter(adapterConfig); break; - default: adapter = new DeepSeekAdapter(adapterConfig); break; - } + const adapterConfig = { provider, baseURL, apiKey, defaultModel: model }; + switch (provider) { + case 'agnes': return new AgnesAdapter(adapterConfig); + case 'ollama': return new OllamaAdapter(adapterConfig); + default: return new DeepSeekAdapter(adapterConfig); + } + }; + + const adapter = createAdapter(); // ===== 步骤 5: 工作空间文件 + System Prompt ===== const contextBuilder = new ContextBuilder(); @@ -161,6 +164,12 @@ async function initialize(): Promise { agentLoop.setTools(toolRegistry.listTools()); agentLoop.setWorkspacePath(workspaceInfo.path); + // ===== 热重载 Adapter 回调(设置变更时触发)===== + const reloadAdapter = () => { + const newAdapter = createAdapter(); + agentLoop.setAdapter(newAdapter); + }; + // ===== 窗口管理 ===== windowManager = new WindowManager(); const mainWindow = windowManager.createWindow({ @@ -200,7 +209,7 @@ async function initialize(): Promise { registerAllIPCHandlers( mainWindow, sessionService, configService, workspaceService, contextBuilder, agentLoop, toolRegistry, auditService, - sessionRecorder, memoryManager, mcpManager, + sessionRecorder, memoryManager, mcpManager, createAdapter, ); // ===== 应用生命周期 ===== @@ -227,7 +236,7 @@ async function initialize(): Promise { if (databaseService) { databaseService.close(); databaseService = null; } }); - log.info(`MetonaAI Desktop initialized [Provider: ${provider}, Model: ${model}, Tools: ${toolRegistry.size}]`); + log.info(`MetonaAI Desktop initialized [Provider: ${configService.get('llm.provider') ?? 'none'}, Model: ${configService.get('llm.model') ?? 'none'}, Tools: ${toolRegistry.size}]`); } app.whenReady().then(initialize);