上传文件至 /
This commit is contained in:
168
config.py
Normal file
168
config.py
Normal file
@ -0,0 +1,168 @@
|
||||
# config.py
|
||||
|
||||
import configparser
|
||||
import os
|
||||
import logging
|
||||
|
||||
# 获取根日志器,确保日志配置已在utils.py中完成
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_FILE = "config.ini"
|
||||
|
||||
# 定义默认配置,如果config.ini不存在或缺失,将使用这些值
|
||||
DEFAULT_CONFIG = {
|
||||
"API": {
|
||||
"GEMINI_API_BASE_URL": "https://generativelanguage.googleapis.com/v1beta",
|
||||
"GEMINI_API_KEY": "YOUR_GEMINI_API_KEY_HERE", # 默认值,强烈建议用户手动修改
|
||||
"DEFAULT_GEMINI_MODEL": "gemini-pro",
|
||||
"MEMORY_UPDATE_MODEL": "gemini-pro",
|
||||
},
|
||||
"Application": {
|
||||
"CONTEXT_WINDOW_SIZE": "6",
|
||||
"MEMORY_RETENTION_TURNS": "18",
|
||||
"MAX_SHORT_TERM_EVENTS": "20",
|
||||
"FEATURES_DIR": "data/features",
|
||||
"MEMORIES_DIR": "data/memories",
|
||||
"CHAT_LOGS_DIR": "data/chat_logs",
|
||||
"APP_LOG_FILE_PATH": "logs/app.log",
|
||||
},
|
||||
"Session": {
|
||||
"CURRENT_ROLE_ID": "default_role",
|
||||
"CURRENT_MEMORY_ID": "default_memory",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def load_config():
|
||||
"""
|
||||
从 config.ini 文件加载配置。
|
||||
如果文件不存在或某些配置项缺失,则使用默认值并尝试创建/更新文件。
|
||||
:return: 包含所有配置的字典。
|
||||
"""
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
# 检查config.ini是否存在,如果不存在则创建并写入默认配置
|
||||
if not os.path.exists(CONFIG_FILE):
|
||||
logger.info(f"config.ini 文件不存在,正在创建默认配置文件:{CONFIG_FILE}")
|
||||
for section, options in DEFAULT_CONFIG.items():
|
||||
config.add_section(section)
|
||||
for key, value in options.items():
|
||||
config.set(section, key, value)
|
||||
try:
|
||||
with open(CONFIG_FILE, "w", encoding="utf-8") as f:
|
||||
config.write(f)
|
||||
logger.info("默认 config.ini 文件创建成功。")
|
||||
except IOError as e:
|
||||
logger.error(f"无法写入 config.ini 文件: {e}")
|
||||
# 即使写入失败,也继续使用内存中的默认配置
|
||||
else:
|
||||
logger.info(f"从 {CONFIG_FILE} 加载配置...")
|
||||
|
||||
# 读取配置
|
||||
try:
|
||||
config.read(CONFIG_FILE, encoding="utf-8")
|
||||
except Exception as e:
|
||||
logger.error(f"读取 config.ini 文件时发生错误: {e},将使用默认配置。")
|
||||
# 如果读取失败,清空 configparser 对象,让后续逻辑使用默认值
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
# 将配置转换为字典格式,并确保所有默认值都存在
|
||||
app_config = {}
|
||||
for section, options in DEFAULT_CONFIG.items():
|
||||
app_config[section] = {}
|
||||
for key, default_value in options.items():
|
||||
# 使用 get() 方法获取值,如果不存在则使用默认值
|
||||
# 对于整型或布尔型配置,需要手动转换
|
||||
value = config.get(section, key, fallback=default_value)
|
||||
|
||||
# 尝试将特定配置项转换为数字类型
|
||||
if section == "Application" and key in [
|
||||
"CONTEXT_WINDOW_SIZE",
|
||||
"MEMORY_RETENTION_TURNS",
|
||||
"MAX_SHORT_TERM_EVENTS",
|
||||
]:
|
||||
try:
|
||||
app_config[section][key] = int(value)
|
||||
except ValueError:
|
||||
logger.warning(
|
||||
f"配置项 {section}.{key} 的值 '{value}' 不是有效数字,使用默认值 {default_value}。"
|
||||
)
|
||||
app_config[section][key] = int(default_value)
|
||||
elif section == "API" and key == "GEMINI_API_KEY":
|
||||
# 优先从环境变量读取 GEMINI_API_KEY
|
||||
env_key = os.getenv("GEMINI_API_KEY")
|
||||
if env_key:
|
||||
app_config[section][key] = env_key
|
||||
logger.info("已从环境变量加载 GEMINI_API_KEY。")
|
||||
else:
|
||||
app_config[section][key] = value
|
||||
else:
|
||||
app_config[section][key] = value
|
||||
|
||||
# 如果存在config.ini但缺少某些默认值,更新它
|
||||
try:
|
||||
updated = False
|
||||
for section, options in DEFAULT_CONFIG.items():
|
||||
if not config.has_section(section):
|
||||
config.add_section(section)
|
||||
updated = True
|
||||
for key, default_value in options.items():
|
||||
if not config.has_option(section, key):
|
||||
config.set(section, key, str(default_value)) # 确保写入的是字符串
|
||||
updated = True
|
||||
if updated:
|
||||
with open(CONFIG_FILE, "w", encoding="utf-8") as f:
|
||||
config.write(f)
|
||||
logger.info("config.ini 文件已更新,补齐缺失配置项。")
|
||||
except IOError as e:
|
||||
logger.error(f"无法更新 config.ini 文件以补齐缺失配置项: {e}")
|
||||
|
||||
logger.info("配置加载完成。")
|
||||
return app_config
|
||||
|
||||
|
||||
def save_config(new_config):
|
||||
"""
|
||||
将给定的配置字典保存到 config.ini 文件。
|
||||
它会读取现有配置,然后只更新 new_config 中提供的部分。
|
||||
:param new_config: 包含要保存的所有配置的字典。
|
||||
"""
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
# 首先读取现有配置,以保留未在 new_config 中提供的项
|
||||
if os.path.exists(CONFIG_FILE):
|
||||
try:
|
||||
config.read(CONFIG_FILE, encoding="utf-8")
|
||||
except Exception as e:
|
||||
logger.error(f"读取现有 config.ini 文件时发生错误: {e},将只保存新配置。")
|
||||
|
||||
for section, options in new_config.items():
|
||||
if not config.has_section(section):
|
||||
config.add_section(section)
|
||||
for key, value in options.items():
|
||||
# 确保将值转换为字符串,因为 configparser 存储的是字符串
|
||||
config.set(section, key, str(value))
|
||||
|
||||
try:
|
||||
with open(CONFIG_FILE, "w", encoding="utf-8") as f:
|
||||
config.write(f)
|
||||
logger.info(f"配置已成功保存到 {CONFIG_FILE}")
|
||||
except IOError as e:
|
||||
logger.error(f"保存配置到 {CONFIG_FILE} 失败: {e}")
|
||||
|
||||
|
||||
# 全局变量,存储当前加载的配置
|
||||
app_config = load_config()
|
||||
|
||||
|
||||
def get_config():
|
||||
"""获取当前加载的配置"""
|
||||
return app_config
|
||||
|
||||
|
||||
def set_config(new_config):
|
||||
"""更新内存中的配置并保存到文件"""
|
||||
global app_config
|
||||
app_config = new_config
|
||||
save_config(app_config)
|
||||
logger.info("内存配置已更新并保存。")
|
Reference in New Issue
Block a user