import os
from dotenv import load_dotenv
load_dotenv()
class Settings:
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MODEL_CONFIG = {
"deepseek": {
"name": "deepseek-v4-flash",
"base_url": os.getenv("DEEPSEEK_BASE_URL", "https://llm-api.atomgit.com/v1"),
"api_key": os.getenv("DEEPSEEK_API_KEY", ""),
"model_name": os.getenv("DEEPSEEK_MODEL_NAME", "deepseek-v4-flash")
},
"glm": {
"name": "GLM-5.2",
"base_url": os.getenv("GLM_BASE_URL", "https://llm-api.atomgit.com/v1"),
"api_key": os.getenv("GLM_API_KEY", ""),
"model_name": os.getenv("GLM_MODEL_NAME", "GLM-5.2")
},
"qwen": {
"name": "Qwen3",
"base_url": os.getenv("QWEN_BASE_URL", "https://llm-api.atomgit.com/v1"),
"api_key": os.getenv("QWEN_API_KEY", ""),
"model_name": os.getenv("QWEN_MODEL_NAME", "Qwen/Qwen3-VL-8B-Instruct")
},
"modelarts": {
"name": "ModelArts-Qwen3",
"base_url": os.getenv("MODELARTS_ENDPOINT", ""),
"api_key": os.getenv("MODELARTS_API_KEY", ""),
"model_name": os.getenv("MODELARTS_MODEL_NAME", "Qwen3-8B"),
"direct_endpoint": True,
"auth_type": os.getenv("MODELARTS_AUTH_TYPE", "bearer"),
}
}
CURRENT_MODEL = os.getenv("CURRENT_MODEL", "deepseek")
DATA_DIR = os.path.join(PROJECT_ROOT, "data")
TEST_REPORTS_DIR = os.path.join(DATA_DIR, "test_reports")
RULES_DIR = os.path.join(DATA_DIR, "rules")
STANDARDS_DIR = os.path.join(DATA_DIR, "standards")
CACHE_ENABLED = os.getenv("CACHE_ENABLED", "true").lower() == "true"
REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0")
EVIDENCE_TRACING = {
"enabled": os.getenv("EVIDENCE_TRACING_ENABLED", "false").lower() == "true",
"max_evidences_per_flag": int(os.getenv("EVIDENCE_MAX_EVIDENCES", "3")),
"snippet_max_chars": int(os.getenv("EVIDENCE_SNIPPET_MAX_CHARS", "200")),
"fuzz_threshold": int(os.getenv("EVIDENCE_FUZZ_THRESHOLD", "60")),
"llm_enrichment_enabled": os.getenv("EVIDENCE_LLM_ENRICHMENT", "false").lower() == "true",
}
HITL_WORKFLOW = {
"enabled": os.getenv("HITL_ENABLED", "false").lower() == "true",
"audit_db_path": os.getenv("HITL_AUDIT_DB",
os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
"data", "hitl_audit", "audit_log.db")),
"db_encryption_enabled": os.getenv("HITL_DB_ENCRYPTION", "false").lower() == "true",
"auto_promote_min_flags": int(os.getenv("HITL_AUTO_PROMOTE_MIN_FLAGS", "1")),
"auto_promote_hybrid_levels": os.getenv("HITL_AUTO_PROMOTE_LEVELS", "高风险,中风险").split(","),
"retain_full_snapshot": True,
"min_reason_chars": {
"AUTO_PROMOTE": 5, "CONFIRM": 50, "REJECT": 50, "APPEAL": 80,
"CANCEL": 20, "ROLLBACK": 50, "ARBITRATE": 30,
},
"committee_member_ids": {
item.strip()
for item in os.getenv("HITL_COMMITTEE_MEMBER_IDS", "").split(",")
if item.strip()
},
"phase3b_rule_review_enabled": False,
"phase3b_reject_rate_threshold": float(os.getenv("HITL_3B_REJECT_RATE", "0.6")),
"phase3b_min_window_size": int(os.getenv("HITL_3B_WINDOW_SIZE", "30")),
}
SCAN_CORRECTOR = {
"enabled": os.getenv("SCAN_CORRECTOR_ENABLED", "false").lower() == "true",
"max_file_size_mb": float(os.getenv("SCAN_CORRECTOR_MAX_MB", "3.0")),
"timeout_seconds": int(os.getenv("SCAN_CORRECTOR_TIMEOUT", "10")),
"debug_log": os.getenv("SCAN_CORRECTOR_DEBUG", "false").lower() == "true",
}
LLM_ASCEND = {
'enabled': os.getenv("LLM_ASCEND_ENABLED", "true").lower() == "true",
'provider': os.getenv("LLM_ASCEND_PROVIDER", "glm"),
'api_key': os.getenv("ATOMGIT_LLM_API_KEY", ""),
'model_name': os.getenv("LLM_ASCEND_MODEL", ""),
'timeout_seconds': int(os.getenv("LLM_ASCEND_TIMEOUT", "60")),
'max_tokens': int(os.getenv("LLM_ASCEND_MAX_TOKENS", "512")),
'temperature': float(os.getenv("LLM_ASCEND_TEMPERATURE", "0.3")),
'top_p': float(os.getenv("LLM_ASCEND_TOP_P", "0.8")),
'direct_endpoint': os.getenv("LLM_ASCEND_DIRECT_ENDPOINT", "false").lower() == "true",
'auth_type': os.getenv("LLM_ASCEND_AUTH_TYPE", "bearer"),
}
ALTMAN_Z_THRESHOLDS = {
"listed": {
"safe": 2.99,
"grey": 1.81,
"crisis": 1.81,
},
"private": {
"safe": 2.9,
"grey": 1.23,
"crisis": 1.23,
},
}
settings = Settings()