import os from dataclasses import dataclass from pathlib import Path @dataclass class Settings: # Paths openclaw_agents_root: Path openclaw_state_dir: Path db_path: Path # Agent allowlist (comma-separated; empty = watch all) agents_allowlist: list[str] # Glob exclusion patterns for session files (comma-separated; e.g. "*.trajectory.jsonl,*.lock") session_glob_exclude: list[str] # Spooler max_toolresult_chars: int spooler_batch_size: int spooler_redact_patterns: str tool_noise_patterns: str # Reviewer review_confidence_threshold: float # API api_port: int def _env_path(name: str, default: str) -> Path: return Path(os.environ.get(name, default)).expanduser() def load_settings() -> Settings: state_dir = _env_path("OPENCLAW_STATE_DIR", "~/.openclaw/workspace/ops/state") state_dir.mkdir(parents=True, exist_ok=True) raw_allowlist = os.environ.get("AGENTS_ALLOWLIST", "") parsed_allowlist = [a.strip() for a in raw_allowlist.split(",") if a.strip()] if raw_allowlist else [] raw_exclude = os.environ.get("SESSION_GLOB_EXCLUDE", "") parsed_exclude = [e.strip() for e in raw_exclude.split(",") if e.strip()] if raw_exclude else [] return Settings( agents_allowlist=parsed_allowlist, session_glob_exclude=parsed_exclude, openclaw_agents_root=_env_path("OPENCLAW_AGENTS_ROOT", "~/.openclaw/agents"), openclaw_state_dir=state_dir, db_path=_env_path("SESSION_AMPLIFIER_DB_PATH", str(state_dir / "session_amplifier.sqlite")), max_toolresult_chars=int(os.environ.get("MAX_TOOLRESULT_CHARS", "2000")), spooler_batch_size=int(os.environ.get("SPOOLER_BATCH_SIZE", "100")), spooler_redact_patterns=os.environ.get("SPOOLER_REDACT_PATTERNS", "api_key,path,base64"), tool_noise_patterns=os.environ.get("TOOL_NOISE_PATTERNS", "ENOENT,no output,command exited"), review_confidence_threshold=float(os.environ.get("REVIEW_CONFIDENCE_THRESHOLD", "0.5")), api_port=int(os.environ.get("API_PORT", "8477")), ) settings = load_settings()