fix: LLM 配置变更后立即生效 — 热重载 Provider Adapter

- AgentLoopEngine 新增 setAdapter() 热切换方法
- main.ts 提取 createAdapter 工厂函数
- IPC config:set 监听 LLM 相关 key 变更,触发热重载
- 覆盖 provider/model/apiKey/baseURL/numCtx 五个关键配置
This commit is contained in:
thzxx
2026-07-01 20:04:05 +08:00
parent 97a3d3d53b
commit ba85328c4f
3 changed files with 40 additions and 17 deletions
+7
View File
@@ -94,6 +94,13 @@ export class AgentLoopEngine extends EventEmitter {
return [...this.tools]; return [...this.tools];
} }
/**
* 热切换 Provider Adapter(设置变更时调用)
*/
setAdapter(adapter: IMetonaProviderAdapter): void {
this.adapter = adapter;
}
/** /**
* 执行完整的 ReAct 循环(流式模式) * 执行完整的 ReAct 循环(流式模式)
* *
+7
View File
@@ -40,6 +40,7 @@ export function registerAllIPCHandlers(
sessionRecorder: SessionRecorder, sessionRecorder: SessionRecorder,
memoryManager: MemoryManager, memoryManager: MemoryManager,
mcpManager: MCPManager, mcpManager: MCPManager,
reloadAdapter: () => void,
): void { ): void {
// ===== Agent 交互 ===== // ===== Agent 交互 =====
@@ -322,6 +323,12 @@ export function registerAllIPCHandlers(
outcome: 'success', 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 }; return { success: true };
}); });
+26 -17
View File
@@ -87,23 +87,26 @@ async function initialize(): Promise<void> {
const memoryManager = new MemoryManager(() => db); const memoryManager = new MemoryManager(() => db);
memoryManager.initialize(); memoryManager.initialize();
// ===== 步骤 4: Provider Adapter ===== // ===== 步骤 4: Provider Adapter 工厂 =====
const provider = configService.get<string>('llm.provider') ?? ''; const createAdapter = () => {
const model = configService.get<string>('llm.model') ?? ''; const provider = configService.get<string>('llm.provider') ?? '';
const apiKey = configService.get<string>('llm.apiKey') ?? ''; const model = configService.get<string>('llm.model') ?? '';
const baseURL = configService.get<string>('llm.baseURL') ?? ''; const apiKey = configService.get<string>('llm.apiKey') ?? '';
const baseURL = configService.get<string>('llm.baseURL') ?? '';
if (!provider || !baseURL || !model) { if (!provider || !baseURL || !model) {
log.warn('LLM not configured. Please set provider, baseURL, and model in Settings.'); log.warn('LLM not configured. Please set provider, baseURL, and model in Settings.');
} }
const adapterConfig = { provider, baseURL, apiKey, defaultModel: model }; const adapterConfig = { provider, baseURL, apiKey, defaultModel: model };
let adapter; switch (provider) {
switch (provider) { case 'agnes': return new AgnesAdapter(adapterConfig);
case 'agnes': adapter = new AgnesAdapter(adapterConfig); break; case 'ollama': return new OllamaAdapter(adapterConfig);
case 'ollama': adapter = new OllamaAdapter(adapterConfig); break; default: return new DeepSeekAdapter(adapterConfig);
default: adapter = new DeepSeekAdapter(adapterConfig); break; }
} };
const adapter = createAdapter();
// ===== 步骤 5: 工作空间文件 + System Prompt ===== // ===== 步骤 5: 工作空间文件 + System Prompt =====
const contextBuilder = new ContextBuilder(); const contextBuilder = new ContextBuilder();
@@ -161,6 +164,12 @@ async function initialize(): Promise<void> {
agentLoop.setTools(toolRegistry.listTools()); agentLoop.setTools(toolRegistry.listTools());
agentLoop.setWorkspacePath(workspaceInfo.path); agentLoop.setWorkspacePath(workspaceInfo.path);
// ===== 热重载 Adapter 回调(设置变更时触发)=====
const reloadAdapter = () => {
const newAdapter = createAdapter();
agentLoop.setAdapter(newAdapter);
};
// ===== 窗口管理 ===== // ===== 窗口管理 =====
windowManager = new WindowManager(); windowManager = new WindowManager();
const mainWindow = windowManager.createWindow({ const mainWindow = windowManager.createWindow({
@@ -200,7 +209,7 @@ async function initialize(): Promise<void> {
registerAllIPCHandlers( registerAllIPCHandlers(
mainWindow, sessionService, configService, workspaceService, mainWindow, sessionService, configService, workspaceService,
contextBuilder, agentLoop, toolRegistry, auditService, contextBuilder, agentLoop, toolRegistry, auditService,
sessionRecorder, memoryManager, mcpManager, sessionRecorder, memoryManager, mcpManager, createAdapter,
); );
// ===== 应用生命周期 ===== // ===== 应用生命周期 =====
@@ -227,7 +236,7 @@ async function initialize(): Promise<void> {
if (databaseService) { databaseService.close(); databaseService = null; } 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<string>('llm.provider') ?? 'none'}, Model: ${configService.get<string>('llm.model') ?? 'none'}, Tools: ${toolRegistry.size}]`);
} }
app.whenReady().then(initialize); app.whenReady().then(initialize);