config.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from __future__ import annotations
  2. import os
  3. from dataclasses import dataclass
  4. from pathlib import Path
  5. try:
  6. from dotenv import load_dotenv
  7. except ImportError: # pragma: no cover - optional dependency
  8. load_dotenv = None
  9. ROOT_DIR = Path(__file__).resolve().parents[1]
  10. ENV_FILE = ROOT_DIR / ".env"
  11. if load_dotenv and ENV_FILE.exists():
  12. load_dotenv(ENV_FILE, override=False)
  13. for proxy_key in ("HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy", "all_proxy"):
  14. proxy_value = os.getenv(proxy_key, "")
  15. if proxy_value in {"http://127.0.0.1:9", "https://127.0.0.1:9"}:
  16. os.environ.pop(proxy_key, None)
  17. def _bool_env(name: str, default: bool) -> bool:
  18. value = os.getenv(name)
  19. if value is None:
  20. return default
  21. return value.strip().lower() in {"1", "true", "yes", "y", "on"}
  22. def _int_env(name: str, default: int) -> int:
  23. value = os.getenv(name)
  24. if value is None or not value.strip():
  25. return default
  26. return int(value)
  27. def _path_env(name: str, default: Path) -> str:
  28. value = os.getenv(name)
  29. path = Path(value) if value else default
  30. if not path.is_absolute():
  31. path = ROOT_DIR / path
  32. return str(path.resolve())
  33. def _chapter14_backend_default() -> Path:
  34. chapter14_root = ROOT_DIR.parents[1] / "chapter14"
  35. candidates = [
  36. ROOT_DIR / "agents" / "deep_research" / "src",
  37. chapter14_root / "helloagents-deepresearch" / "backend" / "src",
  38. chapter14_root / "helloagents-deepresearch-fixed" / "backend" / "src",
  39. ]
  40. for candidate in candidates:
  41. if candidate.exists():
  42. return candidate
  43. return candidates[0]
  44. @dataclass(frozen=True)
  45. class Settings:
  46. app_name: str = os.getenv("APP_NAME", "Agent Platform Base")
  47. app_host: str = os.getenv("APP_HOST", "127.0.0.1")
  48. app_port: int = int(os.getenv("APP_PORT", "8016"))
  49. chapter14_backend_path: str = _path_env("CHAPTER14_BACKEND_PATH", _chapter14_backend_default())
  50. llm_provider: str | None = os.getenv("LLM_PROVIDER") or None
  51. llm_model_id: str | None = os.getenv("LLM_MODEL_ID") or None
  52. llm_api_key: str | None = os.getenv("LLM_API_KEY") or None
  53. llm_base_url: str | None = os.getenv("LLM_BASE_URL") or None
  54. llm_timeout: str | None = os.getenv("LLM_TIMEOUT") or None
  55. search_api: str | None = os.getenv("SEARCH_API") or None
  56. max_web_research_loops: str | None = os.getenv("MAX_WEB_RESEARCH_LOOPS") or None
  57. fetch_full_page: str | None = os.getenv("FETCH_FULL_PAGE") or None
  58. enable_notes: str | None = os.getenv("ENABLE_NOTES") or None
  59. persist_runs: str | None = os.getenv("PERSIST_RUNS") or None
  60. cleanup_intermediate_files: str | None = os.getenv("CLEANUP_INTERMEDIATE_FILES") or None
  61. notes_workspace: str = os.getenv(
  62. "NOTES_WORKSPACE",
  63. str((ROOT_DIR / "data" / "deep_research" / "notes").resolve()),
  64. )
  65. run_workspace: str = os.getenv(
  66. "RUN_WORKSPACE",
  67. str((ROOT_DIR / "data" / "deep_research" / "runs").resolve()),
  68. )
  69. rss_digest_root: str = os.getenv(
  70. "RSS_DIGEST_ROOT",
  71. str((ROOT_DIR / "agents" / "rss_digest").resolve()),
  72. )
  73. rss_digest_data_root: str = os.getenv(
  74. "RSS_DIGEST_DATA_ROOT",
  75. str((ROOT_DIR / "data" / "rss_digest").resolve()),
  76. )
  77. maintenance_cleanup_enabled: bool = _bool_env("MAINTENANCE_CLEANUP_ENABLED", True)
  78. maintenance_cleanup_interval_hours: int = _int_env("MAINTENANCE_CLEANUP_INTERVAL_HOURS", 6)
  79. research_run_retention_days: int = _int_env("RESEARCH_RUN_RETENTION_DAYS", 7)
  80. rss_digest_retention_days: int = _int_env("RSS_DIGEST_RETENTION_DAYS", 7)
  81. rss_cache_retention_days: int = _int_env("RSS_CACHE_RETENTION_DAYS", 7)
  82. settings = Settings()