89 lines
3.7 KiB
Python
89 lines
3.7 KiB
Python
from pydantic_settings import BaseSettings
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
# Plane
|
|
plane_api_url: str = "http://localhost:8091"
|
|
plane_api_token: str = ""
|
|
plane_workspace_slug: str = ""
|
|
plane_webhook_secret: str = ""
|
|
plane_project_id: str = ""
|
|
|
|
# Gitea
|
|
gitea_url: str = "http://localhost:3000"
|
|
gitea_token: str = ""
|
|
gitea_webhook_secret: str = ""
|
|
gitea_owner: str = "admin"
|
|
default_repo: str = "enduro-trails"
|
|
|
|
# ORCH-6: multi-repo project registry. JSON array of
|
|
# {plane_project_id, repo, work_item_prefix, name}.
|
|
# Empty -> built-in default registry in src/projects.py.
|
|
projects_json: str = ""
|
|
|
|
# Claude CLI
|
|
claude_bin: str = "/opt/claude-code/bin/claude.exe"
|
|
repos_dir: str = "/repos"
|
|
host_repos_dir: str = "/home/slin/repos"
|
|
worktrees_dir: str = "/repos/_wt" # ORCH-2 / S-4: isolated worktree per task/branch
|
|
|
|
# DB
|
|
db_path: str = "/app/data/orchestrator.db"
|
|
|
|
# ORCH-1 (F-2b): persistent job queue / background worker.
|
|
# max_concurrency -> max agent jobs running in parallel (env ORCH_MAX_CONCURRENCY)
|
|
# queue_poll_interval -> worker loop poll seconds (env ORCH_QUEUE_POLL_INTERVAL)
|
|
max_concurrency: int = 1
|
|
queue_poll_interval: float = 2.0
|
|
|
|
# ORCH-1b (resilience): preflight + 429/rate-limit + backoff + circuit breaker.
|
|
# preflight_cache_ttl -> cache the cheap CLI/network preflight result (seconds);
|
|
# the worker does NOT re-run `claude --version` more often
|
|
# than this (env ORCH_PREFLIGHT_CACHE_TTL).
|
|
# backoff_base_seconds -> base for exponential transient backoff.
|
|
# backoff_max_seconds -> ceiling for the transient backoff.
|
|
# transient_max_attempts -> retry budget for transient (429/overload/network)
|
|
# failures, separate from code-fault `attempts`.
|
|
# breaker_threshold -> consecutive transient failures that OPEN the breaker.
|
|
# breaker_pause_seconds -> how long the breaker stays open before half-open.
|
|
preflight_cache_ttl: int = 45
|
|
backoff_base_seconds: int = 10
|
|
backoff_max_seconds: int = 600
|
|
transient_max_attempts: int = 5
|
|
breaker_threshold: int = 3
|
|
breaker_pause_seconds: int = 300
|
|
|
|
# ORCH-7 (M-2): agent timeout + graceful kill.
|
|
# agent_timeout_seconds -> default per-agent wall-clock budget; the watchdog
|
|
# kills the run after this (env ORCH_AGENT_TIMEOUT_SECONDS).
|
|
# agent_kill_grace_seconds-> pause between SIGTERM and SIGKILL so claude can
|
|
# flush artifacts before the hard kill
|
|
# (env ORCH_AGENT_KILL_GRACE_SECONDS).
|
|
# agent_timeout_overrides_json -> optional per-agent override JSON object,
|
|
# e.g. {"reviewer": 3600, "architect": 2700}
|
|
# (env ORCH_AGENT_TIMEOUT_OVERRIDES_JSON).
|
|
agent_timeout_seconds: int = 1800
|
|
agent_kill_grace_seconds: int = 20
|
|
agent_timeout_overrides_json: str = ""
|
|
|
|
# L-2: run-log rotation. Old per-run logs in <data>/runs/*.log are pruned at
|
|
# app startup (best-effort). A *.log is removed if it is older than
|
|
# log_keep_days OR not within the log_keep_max most-recent logs (whichever
|
|
# hits first). Only *.log files are touched; the active run log is skipped.
|
|
# log_keep_days -> max age in days (env ORCH_LOG_KEEP_DAYS).
|
|
# log_keep_max -> max number of newest logs to retain (env ORCH_LOG_KEEP_MAX).
|
|
log_keep_days: int = 30
|
|
log_keep_max: int = 500
|
|
|
|
|
|
# Telegram notifications
|
|
telegram_bot_token: str = ""
|
|
telegram_chat_id: str = ""
|
|
|
|
class Config:
|
|
env_prefix = "ORCH_"
|
|
env_file = ".env"
|
|
|
|
|
|
settings = Settings()
|