chore: auto-commit from dashboard

This commit is contained in:
MoltBot Service
2026-02-15 23:23:29 +00:00
parent 8ce7ea3bd6
commit fd9d962ad2
3 changed files with 408 additions and 26 deletions

View File

@@ -3,7 +3,7 @@
import asyncio
import logging
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram import BotCommand, Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.constants import ChatAction, ChatType
from telegram.ext import (
Application,
@@ -21,6 +21,7 @@ from src.claude_session import (
set_session_model,
VALID_MODELS,
)
from src.fast_commands import dispatch as fast_dispatch
from src.router import route_message
logger = logging.getLogger("echo-core.telegram")
@@ -106,12 +107,40 @@ async def cmd_help(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Handle /help — list commands."""
lines = [
"*Echo Commands*",
"/start — Welcome message",
"/help — Show this help",
"/clear — Clear the session for this chat",
"/status — Show session status",
"/clear — Clear session",
"/status — Session status",
"/model — View/change AI model",
"/register <alias> — Register this chat (owner only)",
"",
"*Email*",
"/email — Check unread emails",
"/emailsend <to> <subject> :: <body>",
"/emailsave — Save emails to KB",
"",
"*Calendar*",
"/calendar — Today + tomorrow",
"/calendarweek — Week schedule",
"/calendarbusy — Am I busy?",
"",
"*Notes*",
"/note <text> — Quick note",
"/jurnal <text> — Journal entry",
"/search <query> — Memory search",
"/kb [category] — KB notes",
"",
"*Reminders*",
"/remind <HH:MM> <text>",
"",
"*Git*",
"/commit [msg] — Commit changes",
"/push — Push to remote",
"/pull — Pull with rebase",
"/test [pattern] — Run tests",
"",
"*Ops*",
"/logs [N] — Log lines",
"/doctor — Diagnostics",
"/heartbeat — Health checks",
]
await update.message.reply_text("\n".join(lines), parse_mode="Markdown")
@@ -270,6 +299,126 @@ async def cmd_register(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
)
# --- Fast command handlers ---
async def _fast_cmd(update: Update, name: str, args: list[str]) -> None:
"""Run a fast command and reply with the result."""
await update.message.chat.send_action(ChatAction.TYPING)
result = await asyncio.to_thread(fast_dispatch, name, args)
if result:
for chunk in split_message(result):
await update.message.reply_text(chunk)
else:
await update.message.reply_text(f"Unknown command: /{name}")
async def cmd_email(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/email — check unread emails."""
await _fast_cmd(update, "email", list(context.args or []))
async def cmd_emailsend(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/emailsend <to> <subject> :: <body>"""
await _fast_cmd(update, "email", ["send"] + list(context.args or []))
async def cmd_emailsave(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/emailsave — save unread emails to KB."""
await _fast_cmd(update, "email", ["save"])
async def cmd_calendar(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/calendar — today + tomorrow events."""
await _fast_cmd(update, "calendar", list(context.args or []))
async def cmd_calendarweek(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/calendarweek — this week's schedule."""
await _fast_cmd(update, "calendar", ["week"])
async def cmd_calendarbusy(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/calendarbusy — am I in a meeting?"""
await _fast_cmd(update, "calendar", ["busy"])
async def cmd_note(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/note <text>"""
args = list(context.args or [])
if not args:
await update.message.reply_text("Usage: /note <text>")
return
await _fast_cmd(update, "note", args)
async def cmd_jurnal(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/jurnal <text>"""
args = list(context.args or [])
if not args:
await update.message.reply_text("Usage: /jurnal <text>")
return
await _fast_cmd(update, "jurnal", args)
async def cmd_search(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/search <query>"""
args = list(context.args or [])
if not args:
await update.message.reply_text("Usage: /search <query>")
return
await _fast_cmd(update, "search", args)
async def cmd_kb(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/kb [category]"""
await _fast_cmd(update, "kb", list(context.args or []))
async def cmd_remind(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/remind <HH:MM> <text> or /remind <YYYY-MM-DD> <HH:MM> <text>"""
args = list(context.args or [])
if len(args) < 2:
await update.message.reply_text("Usage: /remind <HH:MM> <text>")
return
await _fast_cmd(update, "remind", args)
async def cmd_commit(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/commit [message]"""
await _fast_cmd(update, "commit", list(context.args or []))
async def cmd_push(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/push"""
await _fast_cmd(update, "push", [])
async def cmd_pull(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/pull"""
await _fast_cmd(update, "pull", [])
async def cmd_test(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/test [pattern]"""
await _fast_cmd(update, "test", list(context.args or []))
async def cmd_logs(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/logs [N]"""
await _fast_cmd(update, "logs", list(context.args or []))
async def cmd_doctor(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/doctor"""
await _fast_cmd(update, "doctor", [])
async def cmd_heartbeat_tg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""/heartbeat"""
await _fast_cmd(update, "heartbeat", [])
# --- Message handler ---
@@ -371,6 +520,7 @@ def create_telegram_bot(config: Config, token: str) -> Application:
app = Application.builder().token(token).build()
# Core commands
app.add_handler(CommandHandler("start", cmd_start))
app.add_handler(CommandHandler("help", cmd_help))
app.add_handler(CommandHandler("clear", cmd_clear))
@@ -378,8 +528,59 @@ def create_telegram_bot(config: Config, token: str) -> Application:
app.add_handler(CommandHandler("model", cmd_model))
app.add_handler(CommandHandler("register", cmd_register))
app.add_handler(CallbackQueryHandler(callback_model, pattern="^model:"))
# Fast commands
app.add_handler(CommandHandler("email", cmd_email))
app.add_handler(CommandHandler("emailsend", cmd_emailsend))
app.add_handler(CommandHandler("emailsave", cmd_emailsave))
app.add_handler(CommandHandler("calendar", cmd_calendar))
app.add_handler(CommandHandler("calendarweek", cmd_calendarweek))
app.add_handler(CommandHandler("calendarbusy", cmd_calendarbusy))
app.add_handler(CommandHandler("note", cmd_note))
app.add_handler(CommandHandler("jurnal", cmd_jurnal))
app.add_handler(CommandHandler("search", cmd_search))
app.add_handler(CommandHandler("kb", cmd_kb))
app.add_handler(CommandHandler("remind", cmd_remind))
app.add_handler(CommandHandler("commit", cmd_commit))
app.add_handler(CommandHandler("push", cmd_push))
app.add_handler(CommandHandler("pull", cmd_pull))
app.add_handler(CommandHandler("test", cmd_test))
app.add_handler(CommandHandler("logs", cmd_logs))
app.add_handler(CommandHandler("doctor", cmd_doctor))
app.add_handler(CommandHandler("heartbeat", cmd_heartbeat_tg))
# Text message handler (must be last)
app.add_handler(
MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message)
)
# Register bot menu commands on startup
async def post_init(application: Application) -> None:
await application.bot.set_my_commands([
BotCommand("help", "List commands"),
BotCommand("email", "Check unread emails"),
BotCommand("emailsend", "Send an email"),
BotCommand("emailsave", "Save emails to KB"),
BotCommand("calendar", "Today + tomorrow events"),
BotCommand("calendarweek", "Week schedule"),
BotCommand("calendarbusy", "Am I busy?"),
BotCommand("note", "Quick note"),
BotCommand("jurnal", "Journal entry"),
BotCommand("search", "Memory search"),
BotCommand("kb", "KB notes"),
BotCommand("remind", "Create reminder"),
BotCommand("commit", "Git commit"),
BotCommand("push", "Git push"),
BotCommand("pull", "Git pull"),
BotCommand("test", "Run tests"),
BotCommand("clear", "Clear session"),
BotCommand("status", "Session status"),
BotCommand("model", "View/change model"),
BotCommand("logs", "Show log lines"),
BotCommand("doctor", "Diagnostics"),
BotCommand("heartbeat", "Health checks"),
])
app.post_init = post_init
return app