fix(telegram_bot): Forecast ask_with_tools mit tool_handlers; sauberes Task-Shutdown

This commit is contained in:
orbitalo 2026-03-31 13:05:08 +00:00
parent e08c820f15
commit 1cc27b877f

View file

@ -128,6 +128,7 @@ log = logging.getLogger("hausmeister")
ALLOWED_CHAT_IDS: set[int] = set()
CHAT_ID: int | None = None
ACTIVE_LLM_TASKS: dict[int, asyncio.Task] = {}
_BACKGROUND_TASKS: list[asyncio.Task] = []
@ -991,22 +992,28 @@ async def handle_callback(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
async def _send_daily_forecast(context):
async def _send_daily_forecast(job_context):
"""Taeglich 08:00 Uhr: Systemdaten sammeln, LLM analysiert, Ergebnis senden."""
if not CHAT_ID:
return
bot = getattr(context, "bot", None) or context
bot = getattr(job_context, "bot", None) or job_context
try:
from tools.predict import handle_get_health_forecast
from llm import ask_with_tools
report = await asyncio.get_event_loop().run_in_executor(None, handle_get_health_forecast)
report = await asyncio.to_thread(handle_get_health_forecast)
prompt = (
"Morgendlicher System-Check. Analysiere diesen Report und gib eine kurze "
"Prognose ob sich Probleme anbahnen. Nur echte Auffaelligkeiten nennen, "
"klare Handlungsempfehlung wenn noetig. Bei allem OK: kurze Entwarnung."
"\n\n" + report
)
analysis = await asyncio.get_event_loop().run_in_executor(None, ask_with_tools, prompt)
handlers = context.get_tool_handlers(session_id=None)
analysis = await asyncio.to_thread(
llm.ask_with_tools,
prompt,
handlers,
session_id=None,
document_mode=False,
)
msg = "🔭 *Taegliche Systemvorhersage*\n\n" + analysis
await bot.send_message(chat_id=CHAT_ID, text=msg, parse_mode="Markdown")
log.info("Taegl. Systemvorhersage gesendet")
@ -1101,7 +1108,22 @@ def main():
signal.signal(signal.SIGTERM, lambda *_: sys.exit(0))
log.info("Starte Orbitalo Hausmeister-Bot...")
app = Application.builder().token(token).concurrent_updates(True).build()
async def post_shutdown(application):
for t in _BACKGROUND_TASKS:
if not t.done():
t.cancel()
if _BACKGROUND_TASKS:
await asyncio.gather(*_BACKGROUND_TASKS, return_exceptions=True)
_BACKGROUND_TASKS.clear()
app = (
Application.builder()
.token(token)
.concurrent_updates(True)
.post_shutdown(post_shutdown)
.build()
)
app.add_handler(CommandHandler("start", cmd_start))
app.add_handler(CommandHandler("status", cmd_status))
@ -1181,13 +1203,13 @@ def main():
async def post_init(application):
await application.bot.set_my_commands(BOT_COMMANDS)
log.info("Kommandomenü registriert")
asyncio.create_task(_watchdog_loop())
asyncio.create_task(asyncio.to_thread(llm.warmup_ollama))
asyncio.create_task(_monitor_loop(application))
_BACKGROUND_TASKS.append(asyncio.create_task(_watchdog_loop()))
_BACKGROUND_TASKS.append(asyncio.create_task(asyncio.to_thread(llm.warmup_ollama)))
_BACKGROUND_TASKS.append(asyncio.create_task(_monitor_loop(application)))
log.info("Monitor-Loop aktiv (alle 10 Min)")
if application.job_queue is None:
asyncio.create_task(_filmtipp_loop(application))
asyncio.create_task(_forecast_loop(application))
_BACKGROUND_TASKS.append(asyncio.create_task(_filmtipp_loop(application)))
_BACKGROUND_TASKS.append(asyncio.create_task(_forecast_loop(application)))
_sd_notify("READY=1")
log.info("Systemd Watchdog aktiv (50s Intervall)")