"""Steward application entry point.""" import logging import sys from apscheduler.schedulers.asyncio import AsyncIOScheduler from steward.bot.telegram import build_application, send_proposal from steward.config import get_settings from steward.llm.client import LLMClient from steward.memory.thread_store import ThreadMemoryStore from steward.proposals.generator import ProposalGenerator logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s", ) logger = logging.getLogger(__name__) async def _run_scheduled_analysis( generator: ProposalGenerator, app, # type: ignore[type-arg] user_ids: list[int], ) -> None: """Scheduled job: run analysis and push proposal via Telegram.""" logger.info("Running scheduled analysis") proposal = await generator.run() if proposal: await send_proposal(app, proposal, user_ids) else: logger.info("No proposal generated (generator returned None)") def main() -> None: """Start Steward.""" settings = get_settings() if not settings.telegram_bot_token: logger.error("TELEGRAM_BOT_TOKEN is not set – cannot start") sys.exit(1) if not settings.openai_api_key: logger.error("OPENAI_API_KEY is not set – cannot start") sys.exit(1) llm = LLMClient(settings) thread_store = ThreadMemoryStore(settings.thread_memory_path) app = build_application(settings, llm, thread_store) generator = ProposalGenerator(settings, llm) scheduler = AsyncIOScheduler() scheduler.add_job( _run_scheduled_analysis, "cron", hour=settings.analysis_cron_hour, minute=settings.analysis_cron_minute, args=[generator, app, settings.telegram_allowed_user_ids], ) scheduler.start() logger.info( "Steward starting: model=%s analysis_url=%s", settings.openai_model, settings.analysis_target_url or "(none)", ) app.run_polling(allowed_updates=["message"]) if __name__ == "__main__": main()