From fcbb10d2f56c8ff08e28b4e00ce1eb368e7da3a2 Mon Sep 17 00:00:00 2001 From: Jerryplusy Date: Sat, 6 Dec 2025 01:30:11 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20refactor(aiCaller):=20improve=20?= =?UTF-8?q?logging=20for=20user=20OpenAI=20instance=20retrieval=20?= =?UTF-8?q?=F0=9F=94=A7=20fix(userConfigManager):=20update=20user=20config?= =?UTF-8?q?=20path=20and=20improve=20error=20handling=20during=20load/save?= =?UTF-8?q?=20operations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/ai/aiCaller.js | 4 +++- lib/ai/userConfigManager.js | 21 +++++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/ai/aiCaller.js b/lib/ai/aiCaller.js index 7ff5812..801c8ef 100644 --- a/lib/ai/aiCaller.js +++ b/lib/ai/aiCaller.js @@ -263,12 +263,14 @@ class AiCaller { * @param {Object} config - 用户配置 * @returns {OpenaiChat} OpenAI实例 */ - async getUserOpenaiInstance(userId, config) { + async getUserOpenaiInstance(userId, config) { if (config.apiKey === this.config.apiKey && config.baseApi === this.config.baseApi) { + logger.info(`[crystelf-ai] 用户 ${userId} 使用全局OpenAI实例`); return this.openaiChat; } const cacheKey = `${userId}_${config.apiKey}_${config.baseApi}`; if (this.userOpenaiInstances.has(cacheKey)) { + logger.info(`[crystelf-ai] 用户 ${userId} 使用缓存的OpenAI实例`); return this.userOpenaiInstances.get(cacheKey); } const userOpenaiChat = new OpenaiChat(); diff --git a/lib/ai/userConfigManager.js b/lib/ai/userConfigManager.js index a773059..dd5090d 100644 --- a/lib/ai/userConfigManager.js +++ b/lib/ai/userConfigManager.js @@ -8,7 +8,7 @@ import ConfigControl from '../config/configControl.js'; */ class UserConfigManager { constructor() { - this.basePath = path.join(process.cwd(), 'data', 'crystelf', 'ai'); + this.basePath = path.join(process.cwd(), 'data', 'crystelf'); this.userConfigs = new Map(); this.globalConfig = null; } @@ -30,20 +30,25 @@ class UserConfigManager { async getUserConfig(userId) { try { if (this.userConfigs.has(userId)) { - return this.userConfigs.get(userId); + const cachedConfig = this.userConfigs.get(userId); + logger.info(`[crystelf-ai] 使用缓存的用户配置 ${userId}: apiKey=${!!cachedConfig.apiKey}, model=${cachedConfig.modelType}`); + return cachedConfig; } - const userConfigPath = path.join(this.basePath, `${userId}.json`); + const userConfigPath = path.join(this.basePath, 'ai', userId, 'ai.json'); + logger.info(`[crystelf-ai] 尝试加载用户配置: ${userConfigPath}`); let userConfig = {}; try { const configData = await fs.readFile(userConfigPath, 'utf-8'); userConfig = JSON.parse(configData); } catch (error) { - if (error.code !== 'ENOENT') { + if (error.code === 'ENOENT') { + } else { logger.warn(`[crystelf-ai] 用户 ${userId} 的配置文件解析失败,使用默认配置: ${error.message}`); } } + const mergedConfig = this.mergeConfigs(this.globalConfig, userConfig); this.userConfigs.set(userId, mergedConfig); @@ -61,12 +66,16 @@ class UserConfigManager { */ async saveUserConfig(userId, config) { try { - const userConfigPath = path.join(this.basePath, `${userId}.json`); + const userConfigDir = path.join(this.basePath, 'ai', userId); + const userConfigPath = path.join(userConfigDir, 'ai.json'); const filteredConfig = this.filterUserConfig(config); + await fs.mkdir(userConfigDir, { recursive: true }); await fs.writeFile(userConfigPath, JSON.stringify(filteredConfig, null, 2)); + const mergedConfig = this.mergeConfigs(this.globalConfig, filteredConfig); this.userConfigs.set(userId, mergedConfig); + } catch (error) { logger.error(`[crystelf-ai] 保存用户 ${userId} 配置失败: ${error.message}`); throw error; @@ -158,7 +167,7 @@ class UserConfigManager { */ async hasUserConfig(userId) { try { - const userConfigPath = path.join(this.basePath, `${userId}.json`); + const userConfigPath = path.join(this.basePath, 'ai', userId, 'ai.json'); await fs.access(userConfigPath); return true; } catch {