86 lines
2.8 KiB
Python
86 lines
2.8 KiB
Python
"""Steward application entry point."""
|
||
|
||
import logging
|
||
import sys
|
||
from datetime import time
|
||
|
||
from telegram.ext import ContextTypes
|
||
|
||
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
|
||
from steward.tools.client import ToolClient
|
||
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
|
||
)
|
||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
async def _run_scheduled_analysis(context: ContextTypes.DEFAULT_TYPE) -> None:
|
||
"""Scheduled job: run analysis and push proposal via Telegram."""
|
||
logger.info("Running scheduled analysis")
|
||
generator: ProposalGenerator = context.bot_data["generator"]
|
||
user_ids: list[int] = context.bot_data["user_ids"]
|
||
proposal = await generator.run()
|
||
if proposal:
|
||
await send_proposal(context.application, 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)
|
||
|
||
tool_client: ToolClient | None = None
|
||
if settings.mcp_server_url:
|
||
tool_client = ToolClient(
|
||
base_url=settings.mcp_server_url,
|
||
api_key=settings.mcp_server_api_key,
|
||
)
|
||
logger.info("MCP tool server configured: %s", settings.mcp_server_url)
|
||
else:
|
||
logger.info("No MCP_SERVER_URL configured – tool calling disabled")
|
||
|
||
app = build_application(settings, llm, thread_store, tool_client)
|
||
generator = ProposalGenerator(settings, llm)
|
||
app.bot_data["generator"] = generator
|
||
app.bot_data["user_ids"] = settings.telegram_allowed_user_ids
|
||
|
||
if app.job_queue is not None:
|
||
app.job_queue.run_daily(
|
||
_run_scheduled_analysis,
|
||
time=time(hour=settings.analysis_cron_hour, minute=settings.analysis_cron_minute),
|
||
)
|
||
else:
|
||
logger.warning("JobQueue not available – scheduled analysis disabled")
|
||
|
||
logger.info(
|
||
"Steward starting: model=%s analysis_url=%s tools=%s",
|
||
settings.openai_model,
|
||
settings.analysis_target_url or "(none)",
|
||
settings.mcp_server_url or "(none)",
|
||
)
|
||
app.run_polling(allowed_updates=["message"])
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|