Hearth/hearth/settings.py
ilia 751e0da2a1 Restrict default send window to Mon–Fri 10–17 Toronto.
Stop overnight and weekend warmup mail by aligning defaults with the live quiet-hours policy.
2026-07-21 10:13:04 -04:00

52 lines
2.5 KiB
Python

"""Global runtime settings, sourced from environment variables only.
Nothing in here can name a recipient — that only ever comes from the
participant allow-list loaded in config.py.
"""
from __future__ import annotations
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(extra="ignore")
enabled: bool = Field(default=True, validation_alias="HEARTH_ENABLED")
config_path: str = Field(default="./hearth.yml", validation_alias="HEARTH_CONFIG")
db_path: str = Field(default="./data/hearth.db", validation_alias="HEARTH_DB_PATH")
timezone: str = Field(default="America/Toronto", validation_alias="HEARTH_TIMEZONE")
poll_interval_seconds: int = Field(default=300, validation_alias="HEARTH_POLL_INTERVAL_SECONDS")
business_hours_start: int = Field(default=10, validation_alias="HEARTH_BUSINESS_HOURS_START")
business_hours_end: int = Field(default=17, validation_alias="HEARTH_BUSINESS_HOURS_END")
active_weekdays_only: bool = Field(default=True, validation_alias="HEARTH_ACTIVE_WEEKDAYS_ONLY")
daily_cap_start: int = Field(default=2, validation_alias="HEARTH_DAILY_CAP_START")
daily_cap_max: int = Field(default=20, validation_alias="HEARTH_DAILY_CAP_MAX")
ramp_step_per_day: float = Field(default=1.0, validation_alias="HEARTH_RAMP_STEP_PER_DAY")
min_reply_delay_min: int = Field(default=5, validation_alias="HEARTH_MIN_REPLY_DELAY_MIN")
max_reply_delay_min: int = Field(default=180, validation_alias="HEARTH_MAX_REPLY_DELAY_MIN")
llm_url: str = Field(default="", validation_alias="HEARTH_LLM_URL")
llm_model: str = Field(default="llama3.1", validation_alias="HEARTH_LLM_MODEL")
ntfy_url: str = Field(default="https://push.levkin.ca", validation_alias="NTFY_URL")
ntfy_token: str = Field(default="", validation_alias="NTFY_TOPIC_TOKEN")
ntfy_publish_token: str = Field(default="", validation_alias="NTFY_PUBLISH_TOKEN")
ntfy_topic: str = Field(default="hearth-digest", validation_alias="NTFY_TOPIC")
dry_run: bool = Field(default=False, validation_alias="HEARTH_DRY_RUN")
# Only these domains may *start* new warmup threads. Personal inboxes
# (e.g. Gmail) stay full_duplex so they can receive + auto-reply, but they
# must not originate Gmail→Gmail traffic that does nothing for domain rep.
warmup_sender_domains: str = Field(
default="levkine.ca",
validation_alias="HEARTH_WARMUP_SENDER_DOMAINS",
)
settings = Settings()