fix: LLM 配置变更后立即生效 — 热重载 Provider Adapter
- AgentLoopEngine 新增 setAdapter() 热切换方法 - main.ts 提取 createAdapter 工厂函数 - IPC config:set 监听 LLM 相关 key 变更,触发热重载 - 覆盖 provider/model/apiKey/baseURL/numCtx 五个关键配置
This commit is contained in:
@@ -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 循环(流式模式)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user