78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
"""Bot configuration.
|
|
|
|
All settings can be overridden with environment variables prefixed with
|
|
``PROCUREMENT_BOT_`` (e.g. ``PROCUREMENT_BOT_BOT_TOKEN=...``) or a local
|
|
``.env`` file. Docker/compose passes them in directly (same convention as
|
|
the api service's ``PROCUREMENT_*`` prefix).
|
|
"""
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(
|
|
env_prefix="PROCUREMENT_BOT_",
|
|
env_file=".env",
|
|
env_file_encoding="utf-8",
|
|
extra="ignore",
|
|
)
|
|
|
|
# Bale Bot API — Telegram-compatible clone hosted at tapi.bale.ai.
|
|
BALE_API_BASE: str = "https://tapi.bale.ai"
|
|
BOT_TOKEN: str = "" # from Bale's BotFather
|
|
POLL_TIMEOUT_SECONDS: int = 25 # getUpdates long-poll window
|
|
POLL_ERROR_SLEEP_SECONDS: float = 3.0
|
|
|
|
# ERP API (in-network service URL inside Docker).
|
|
API_BASE_URL: str = "http://localhost:8000/api/v1"
|
|
API_TIMEOUT_SECONDS: float = 30.0
|
|
# Optional bearer for the day procurement endpoints start enforcing auth.
|
|
SERVICE_TOKEN: str = ""
|
|
|
|
# Frontend URL (for opening Wizard from Bale bot)
|
|
FRONTEND_URL: str = "http://localhost:8081"
|
|
|
|
# OpenAI-compatible AI provider (LLM), e.g. OpenAI / GLM / DeepSeek / OpenRouter.
|
|
AI_BASE_URL: str = "" # e.g. https://api.openai.com/v1
|
|
AI_API_KEY: str = ""
|
|
LLM_MODEL: str = "gpt-4o-mini"
|
|
LLM_TIMEOUT_SECONDS: float = 60.0
|
|
|
|
# STT provider — any OpenAI-compatible /audio/transcriptions endpoint.
|
|
# Falls back to the LLM provider when unset. Note: some providers
|
|
# (e.g. DeepSeek) have no audio API — voice stays disabled gracefully.
|
|
STT_BASE_URL: str = ""
|
|
STT_API_KEY: str = ""
|
|
STT_MODEL: str = "whisper-1"
|
|
STT_LANGUAGE: str = "fa"
|
|
|
|
@property
|
|
def stt_base_url(self) -> str:
|
|
return self.STT_BASE_URL or self.AI_BASE_URL
|
|
|
|
@property
|
|
def stt_api_key(self) -> str:
|
|
return self.STT_API_KEY or self.AI_API_KEY
|
|
|
|
# PostgreSQL — same instance/database as the api service.
|
|
DATABASE_URL: str = "postgresql+asyncpg://postgres:postgres@localhost:5432/procurement"
|
|
|
|
# Chats that may use the bot without Casdoor linking (comma separated).
|
|
ADMIN_CHAT_IDS: str = ""
|
|
|
|
# Drafts older than this are marked expired by the sweeper loop.
|
|
DRAFT_TTL_HOURS: int = 24
|
|
|
|
LOG_LEVEL: str = "INFO"
|
|
|
|
@property
|
|
def admin_chat_ids(self) -> set[int]:
|
|
out: set[int] = set()
|
|
for part in self.ADMIN_CHAT_IDS.replace(";", ",").split(","):
|
|
part = part.strip()
|
|
if part.isdigit():
|
|
out.add(int(part))
|
|
return out
|
|
|
|
|
|
settings = Settings()
|