Files
werewolf/backend/app/config.py
T

68 lines
2.1 KiB
Python

"""配置加载:backend/config.json(可从 config.example.json 复制修改)。
未配置 api_key 时,AI 玩家自动回退为内置启发式 AI,游戏依然完整可玩。
支持环境变量覆盖:WEREWOLF_LLM_BASE_URL / WEREWOLF_LLM_API_KEY / WEREWOLF_LLM_MODEL。
"""
from __future__ import annotations
import json
import os
from dataclasses import dataclass, field
from pathlib import Path
BACKEND_DIR = Path(__file__).resolve().parent.parent
CONFIG_PATH = BACKEND_DIR / "config.json"
EXAMPLE_PATH = BACKEND_DIR / "config.example.json"
@dataclass
class LLMConfig:
base_url: str = ""
api_key: str = ""
model: str = ""
temperature: float = 0.8
@property
def configured(self) -> bool:
return bool(self.base_url and self.api_key and self.model)
@dataclass
class ServerConfig:
host: str = "0.0.0.0"
port: int = 8000
@dataclass
class AppConfig:
llm: LLMConfig = field(default_factory=LLMConfig)
server: ServerConfig = field(default_factory=ServerConfig)
def load_config() -> AppConfig:
cfg = AppConfig()
source = CONFIG_PATH
if not source.exists() and EXAMPLE_PATH.exists():
source = EXAMPLE_PATH
if source.exists():
try:
raw = json.loads(source.read_text(encoding="utf-8"))
except (json.JSONDecodeError, OSError):
raw = {}
llm = raw.get("llm", {})
cfg.llm.base_url = llm.get("base_url", cfg.llm.base_url)
cfg.llm.api_key = llm.get("api_key", cfg.llm.api_key)
cfg.llm.model = llm.get("model", cfg.llm.model)
cfg.llm.temperature = float(llm.get("temperature", cfg.llm.temperature))
srv = raw.get("server", {})
cfg.server.host = srv.get("host", cfg.server.host)
cfg.server.port = int(srv.get("port", cfg.server.port))
cfg.llm.base_url = os.environ.get("WEREWOLF_LLM_BASE_URL", cfg.llm.base_url).strip()
cfg.llm.api_key = os.environ.get("WEREWOLF_LLM_API_KEY", cfg.llm.api_key).strip()
cfg.llm.model = os.environ.get("WEREWOLF_LLM_MODEL", cfg.llm.model).strip()
return cfg
CONFIG = load_config()