agent-Specialization/config/__init__.py
JOJO f43025047e refactor(config): 统一配置源,迁移数据到 ~/.agents/agents/
- config/paths.py: data_root 改为 ~/.agents/agents,config/ 提至根目录共享
- config/__init__.py: 统一加载 .env + settings.json,注入 legacy 环境变量
- 移除 4 处独立 .env 读取 (auth/model_profiles/api_client/chat_flow/balance)
- 新增 docs/config_refactor_plan.md 完整改造计划
- 数据已从 ~/.agents/host/ 迁移至 ~/.agents/agents/
2026-06-13 21:37:02 +08:00

149 lines
6.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Config package initializer保持对旧 `from config import ...` 的兼容。"""
import json
import os
from pathlib import Path
def _load_dotenv():
"""加载配置:.env仓库根+ settings.json数据根
1. 先读仓库根目录 .env若存在不覆盖已有的环境变量
2. 再读 {data_root}/settings.json将其中的 env_vars 注入 os.environ
并将非 env_vars 的顶级字段也注入为 AGENT_CFG_<KEY> 环境变量(供 config/auth.py 等使用);
3. settings.json 的加载依赖 data_root 路径,若 settings.json 不存在则静默跳过。
"""
import sys
pre_existing_keys = set(os.environ.keys())
# 1) 仓库根 .env开发便利不覆盖已有环境变量
if getattr(sys, 'frozen', False):
env_path = Path.home() / '.agents' / 'agents' / '.env'
else:
env_path = Path(__file__).resolve().parents[1] / '.env'
if env_path.exists():
try:
for raw_line in env_path.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if not line or line.startswith("#"):
continue
if "=" not in line:
continue
key, value = line.split("=", 1)
key = key.strip()
value = value.strip().strip('"').strip("'")
if not key:
continue
if key in pre_existing_keys:
continue
os.environ[key] = value
except Exception:
pass
# 2) settings.json数据根下的统一配置
data_root = os.environ.get("AGENTS_DATA_ROOT", str(Path.home() / ".agents" / "agents"))
settings_path = Path(data_root) / "settings.json"
if settings_path.exists():
try:
settings = json.loads(settings_path.read_text(encoding="utf-8"))
# 注入 env_varsAPI key 等)
env_vars = settings.get("env_vars", {})
if isinstance(env_vars, dict):
for k, v in env_vars.items():
if k not in pre_existing_keys and v:
os.environ[k] = str(v)
# 映射 settings.json 字段 → 旧版环境变量名(兼容现有 config/*.py 模块)
_LEGACY_MAP = {
"terminal.sandbox_mode": "TERMINAL_SANDBOX_MODE",
"terminal.execution_mode_default": "HOST_EXECUTION_MODE_DEFAULT",
"terminal.direct_ttl_seconds": "HOST_EXECUTION_DIRECT_TTL_SECONDS",
"terminal.macos_writable_paths": "HOST_SANDBOX_MACOS_WRITABLE_PATHS",
"terminal.max_active_containers": "MAX_ACTIVE_USER_CONTAINERS",
"terminal.project_max_storage_mb": "PROJECT_MAX_STORAGE_MB",
"server.port": "WEB_SERVER_PORT",
"server.host": "WEB_SERVER_HOST",
"admin.username": "AGENT_ADMIN_USERNAME",
"admin.password_hash": "AGENT_ADMIN_PASSWORD_HASH",
"admin.secondary_password_hash": "ADMIN_SECONDARY_PASSWORD_HASH",
"secrets.web_secret_key": "WEB_SECRET_KEY",
"secrets.api_token_secret": "API_TOKEN_SECRET",
"search.tavily_api_key": "AGENT_TAVILY_API_KEY",
"search.tavily_api_key_2": "AGENT_TAVILY_API_KEY_2",
"balance.aliyun_access_key_id": "ALIYUN_ACCESS_KEY_ID",
"balance.aliyun_access_key_secret": "ALIYUN_ACCESS_KEY_SECRET",
"balance.usd_cny_rate": "USD_CNY_RATE",
"models.default_response_max_tokens": "AGENT_DEFAULT_RESPONSE_MAX_TOKENS",
}
for dotted_key, env_name in _LEGACY_MAP.items():
if env_name in pre_existing_keys:
continue
parts = dotted_key.split(".")
val = settings
for p in parts:
val = val.get(p) if isinstance(val, dict) else None
if val is None:
break
if val is not None:
os.environ[env_name] = str(val)
# 注入非 env_vars 的顶级配置为 AGENT_CFG_* 环境变量(供 config/auth.py 等使用)
for k, v in settings.items():
if k == "env_vars":
continue
env_key = f"AGENT_CFG_{k.upper()}"
if isinstance(v, dict):
for sub_k, sub_v in v.items():
flat_key = f"AGENT_CFG_{k.upper()}_{sub_k.upper()}"
if flat_key not in pre_existing_keys:
os.environ[flat_key] = str(sub_v)
elif env_key not in pre_existing_keys:
os.environ[env_key] = str(v)
except Exception:
pass
_load_dotenv()
from . import api as _api
from . import search as _search
from . import paths as _paths
from . import limits as _limits
from . import terminal as _terminal
from . import conversation as _conversation
from . import security as _security
from . import ui as _ui
from . import memory as _memory
from . import ocr as _ocr
from . import todo as _todo
from . import auth as _auth
from . import uploads as _uploads
from . import sub_agent as _sub_agent
from . import custom_tools as _custom_tools
from . import mcp as _mcp
from . import server as _server
from .api import *
from .search import *
from .paths import *
from .limits import *
from .terminal import *
from .conversation import *
from .security import *
from .ui import *
from .memory import *
from .ocr import *
from .todo import *
from .auth import *
from .uploads import *
from .sub_agent import *
from .custom_tools import *
from .mcp import *
from .server import *
__all__ = []
for module in (_api, _search, _paths, _limits, _terminal, _conversation, _security, _ui, _memory, _ocr, _todo, _auth, _uploads, _sub_agent, _custom_tools, _mcp, _server):
__all__ += getattr(module, "__all__", [])
del _api, _search, _paths, _limits, _terminal, _conversation, _security, _ui, _memory, _ocr, _todo, _auth, _uploads, _sub_agent, _custom_tools, _mcp, _server