import os from dataclasses import dataclass, field from pathlib import Path from dotenv import load_dotenv load_dotenv(Path(__file__).resolve().parent.parent / ".env") @dataclass(frozen=True) class Settings: # LLM 配置 llm_api_key: str = field( default_factory=lambda: os.getenv("LLM_API_KEY", ""), repr=False, ) llm_model: str = field(default_factory=lambda: os.getenv("LLM_MODEL", "")) llm_base_url: str | None = field( default_factory=lambda: os.getenv("LLM_BASE_URL") or None ) llm_timeout: float = 60.0 llm_max_retries: int = 2 # Jev typesafe_api_key: str = field( default_factory=lambda: os.getenv("TYPESAFE_API_KEY", ""), repr=False ) typesafe_model: str = field( default_factory=lambda: os.getenv("TYPESAFE_DEFAULT_MODEL") or "jev-latest" ) typesafe_base_url: str = field( default_factory=lambda: ( os.getenv("TYPESAFE_BASE_URL") or "https://api.typesafe.ai" ) ) typesafe_timeout: float = field( default_factory=lambda: float(os.getenv("TYPESAFE_TIMEOUT", "30")) ) typesafe_max_retries: int = field( default_factory=lambda: int(os.getenv("TYPESAFE_MAX_RETRIES", "2")) ) # 意图门控使用 Jev confidence,阈值需按真实语料校准 intent_min_confidence: float = field( default_factory=lambda: float(os.getenv("INTENT_MIN_CONFIDENCE", "0.7")) ) # 动作自动修正次数,不含首次生成,0 表示不重试,与用户澄清轮数无关 max_action_retries: int = field( default_factory=lambda: int(os.getenv("MAX_ACTION_RETRIES", "2")) ) # 没有任何对话的空会话保留时长(秒),超时后视为不存在 conversation_empty_ttl: int = field( default_factory=lambda: int(os.getenv("CONVERSATION_EMPTY_TTL", "7200")) ) # 每次请求带入模型的最近对话轮数 conversation_history_turns: int = field( default_factory=lambda: int(os.getenv("CONVERSATION_HISTORY_TURNS", "6")) ) def __post_init__(self): if self.conversation_empty_ttl <= 0: raise ValueError("CONVERSATION_EMPTY_TTL 必须是正整数") if self.conversation_history_turns < 0: raise ValueError("CONVERSATION_HISTORY_TURNS 必须是非负整数") if type(self.max_action_retries) is not int or self.max_action_retries < 0: raise ValueError("MAX_ACTION_RETRIES 必须是非负整数") if not 0 <= self.intent_min_confidence <= 1: raise ValueError("INTENT_MIN_CONFIDENCE 必须在 0 到 1 之间") settings = Settings()