Files
hunjing/backend/app/core/config/settings.py
T
chenxin 462d570751 M4b:ai_provider 删除手术①-⑥——神识全面接管模型出口
- ① 后端删除 app/ai_provider/(38 文件,含 anthropic/openai 格式、billing、audio、embedding)、services/ai_provider_admin.py、core/config/model_config.py、tests/ai_provider/(21 文件)
- ② 连带退役 application/agent/(旧 Agent 循环/steer/follow-up/确认注册表)、application/skill_executor.py、app/skills/(python skills 孤儿)、endpoints/audio.py、application/imports.py(ProviderManager 消费方);settings 端点收敛为生成偏好
- ③ runs.py 修剪:AgentRunRegistry/steer/follow-up/confirmations 端点退役,保留 list/get/events/cancel/stream;safety 确认改为直接落库裁决(pending→approved/denied)
- ④ 前端删除:models 页、ModelGatewayView、gateway.ts、GatewayPanel(玄关)、ModelGatewayPanel/ModelStrategyForm、audio.ts/useVoiceInput、网关类型与 mock;设置页收敛为外观/语言/通知
- ⑤ 配置收敛:config/models|providers|pricing.example.yaml 归档 shenshi/config/;.env.example 删 provider keys/MODEL_ENDPOINT_POOL/MODEL_CONFIG_PATH,收敛 SHENSHI_*
- ⑥ 验收:rg 审计灵台 Provider SDK import 与 ai_provider 引用归零;后端 528 passed(2 个预存失败经 HEAD 复跑验证与本手术无关)、前端 type-check+201 passed、神识 go vet+test、BFF 4 passed
2026-08-27 10:02:44 +08:00

128 lines
4.2 KiB
Python

"""主 Settings:多继承所有子配置,统一以绝对路径 ``_env_file`` 加载 ``.env``。
子配置见同目录下的 ``app_config`` / ``auth_config`` / ``database_config`` / ``log_config`` /
``runtime_config`` / ``sandbox_config``。本文件聚合字段,并承载
跨子配置的路径解析与计算属性。
配置优先级(自高到低):命令行参数 > 系统环境变量 > ``.env`` > 类属性默认值。
"""
from __future__ import annotations
from functools import cached_property
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
from app.core.config.app_config import AppConfig
from app.core.config.auth_config import AuthConfig
from app.core.config.database_config import DatabaseConfig
from app.core.config.log_config import LogConfig
from app.core.config.runtime_config import RuntimeConfig
from app.core.config.sandbox_config import SandboxSettings
from app.core.config.time_config import TimeConfig
# backend 目录:app/core/config/settings.py → parents[3] = backend/
_BACKEND_DIR = Path(__file__).resolve().parents[3]
# .env 永远在项目根目录(backend 父级),以绝对路径定位
_ENV_FILE = _BACKEND_DIR.parent / ".env"
class Settings(
AppConfig,
AuthConfig,
DatabaseConfig,
LogConfig,
RuntimeConfig,
SandboxSettings,
TimeConfig,
BaseSettings,
):
"""应用配置类。
所有配置项可通过 ``.env`` 文件或环境变量覆盖。路径配置会自动解析为绝对路径。
"""
model_config = SettingsConfigDict(
env_file=str(_ENV_FILE), # 绝对路径,不使用 python-dotenv
env_file_encoding="utf-8",
case_sensitive=False, # 环境变量名不区分大小写
extra="ignore", # 忽略未定义的额外字段
)
# ==================== 路径解析 ====================
@cached_property
def backend_dir(self) -> Path:
"""backend 目录路径。"""
return _BACKEND_DIR
@cached_property
def project_root(self) -> Path:
"""项目根目录路径(backend 的父级)。"""
return _BACKEND_DIR.parent
def resolve_from_backend(self, value: str) -> Path:
"""解析相对于 backend 目录的路径为绝对路径。
Args:
value: 相对路径或绝对路径字符串
Returns:
解析后的绝对路径
"""
path = Path(value)
if path.is_absolute():
return path
return (self.backend_dir / path).resolve()
# ==================== 计算属性 ====================
@property
def resolved_database_url(self) -> str:
"""解析数据库连接 URL。
如果设置了 ``database_url`` 则直接使用,否则根据 ``database_type`` 构建。
"""
if self.database_url:
return self.database_url
if self.database_type == "sqlite":
db_path = self.resolve_from_backend(self.sqlite_database_path)
return f"sqlite+aiosqlite:///{db_path}"
password = self.postgres_password
ssl = "?ssl=require" if self.postgres_ssl else ""
return (
f"postgresql+asyncpg://{self.postgres_user}:{password}"
f"@{self.postgres_host}:{self.postgres_port}/{self.postgres_db}{ssl}"
)
@cached_property
def resolved_log_dir(self) -> Path:
"""解析日志目录为绝对路径。"""
return self.resolve_from_backend(self.log_dir)
@cached_property
def resolved_character_templates_path(self) -> Path:
"""解析人物模板配置文件路径。
如果配置文件不存在,尝试使用示例配置文件。
"""
configured = self.resolve_from_backend(self.character_templates_path)
if configured.exists():
return configured
example = self.project_root / "config" / "character_templates.example.yaml"
if example.exists():
return example
return configured
@cached_property
def resolved_avatar_dir(self) -> Path:
"""解析角色头像存储目录为绝对路径。"""
path = self.resolve_from_backend(self.avatar_dir)
path.mkdir(parents=True, exist_ok=True)
return path
# 全局配置实例
settings = Settings()