From 4829ec038e1f43aa72dc27a9b152ee9519cc167d Mon Sep 17 00:00:00 2001 From: bucolucas Date: Sun, 18 Aug 2024 17:25:30 -0500 Subject: [PATCH] Add always-on keyboard for common commands --- telegram_inference_bot.py | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/telegram_inference_bot.py b/telegram_inference_bot.py index 798eb12..639ea60 100644 --- a/telegram_inference_bot.py +++ b/telegram_inference_bot.py @@ -6,7 +6,7 @@ import logging import sys import subprocess import requests -from telegram import Update, __version__ as telegram_version, InlineKeyboardButton, InlineKeyboardMarkup +from telegram import Update, __version__ as telegram_version, InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes, CallbackQueryHandler from dotenv import load_dotenv from tools.base_tool import BaseTool @@ -59,9 +59,19 @@ functions = [] for tool in tools: functions.extend(tool.get_functions()) +def get_keyboard(): + keyboard = [ + ['/switch', '/toggle'], + ['/status', '/reset'] + ] + return ReplyKeyboardMarkup(keyboard, resize_keyboard=True) + async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: logging.info("Bot started") - await update.message.reply_text("Hello! I'm your AI assistant. How can I help you today? You can send me images and then ask questions about them.") + await update.message.reply_text( + "Hello! I'm your AI assistant. How can I help you today? You can send me images and then ask questions about them.", + reply_markup=get_keyboard() + ) async def clear(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: user_id = update.effective_user.id @@ -71,7 +81,7 @@ async def clear(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: tool.clear() logging.info(f"Cleared conversation history and image for user {user_id}") - await update.message.reply_text("Conversation history and image cleared. Let's start fresh!") + await update.message.reply_text("Conversation history and image cleared. Let's start fresh!", reply_markup=get_keyboard()) async def update_status_message(context: ContextTypes.DEFAULT_TYPE, chat_id: int, message_id: int, status: str): keyboard = [ @@ -151,11 +161,11 @@ async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> await context.bot.delete_message(chat_id=update.effective_chat.id, message_id=status_message.message_id) del processing_status[user_id] - await update.message.reply_text(messages[-1]["content"][0].text) + await update.message.reply_text(messages[-1]["content"][0].text, reply_markup=get_keyboard()) except Exception as e: logging.error(f"An error occurred: {str(e)}") - await update.message.reply_text("Sorry, an error occurred while processing your request.") + await update.message.reply_text("Sorry, an error occurred while processing your request.", reply_markup=get_keyboard()) def call_tool(function_call): function_name = function_call.name @@ -191,7 +201,7 @@ def get_claude_response(messages): return response async def status(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: - await update.message.reply_text("Currently using claude-3-5-sonnet-20240620") + await update.message.reply_text("Currently using claude-3-5-sonnet-20240620", reply_markup=get_keyboard()) async def abort_processing(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: query = update.callback_query @@ -214,9 +224,9 @@ async def handover(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: # Daemon bot initiating handover apprentice_chat_id = os.getenv('APPRENTICE_CHAT_ID') await context.bot.send_message(chat_id=apprentice_chat_id, text="Handover initiated. Taking control.") - await update.message.reply_text("Handover initiated. Apprentice bot is now in control.") + await update.message.reply_text("Handover initiated. Apprentice bot is now in control.", reply_markup=get_keyboard()) else: - await update.message.reply_text("Handover can only be initiated by the daemon bot.") + await update.message.reply_text("Handover can only be initiated by the daemon bot.", reply_markup=get_keyboard()) async def update_apprentice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: if context.bot.token == APPRENTICE_BOT_TOKEN: @@ -228,12 +238,12 @@ async def update_apprentice(update: Update, context: ContextTypes.DEFAULT_TYPE) os.execv(sys.executable, ['python'] + sys.argv) except subprocess.CalledProcessError as e: logging.error(f"Failed to pull latest changes: {e}") - await update.message.reply_text("Failed to update. Please check the logs.") + await update.message.reply_text("Failed to update. Please check the logs.", reply_markup=get_keyboard()) except Exception as e: logging.error(f"Failed to restart the bot: {e}") - await update.message.reply_text("Failed to restart. Please check the logs.") + await update.message.reply_text("Failed to restart. Please check the logs.", reply_markup=get_keyboard()) else: - await update.message.reply_text("Update can only be performed by the apprentice bot.") + await update.message.reply_text("Update can only be performed by the apprentice bot.", reply_markup=get_keyboard()) async def check_for_updates(context: ContextTypes.DEFAULT_TYPE) -> None: url = f"https://api.github.com/repos/{GITHUB_REPO_OWNER}/{GITHUB_REPO_NAME}/pulls" @@ -259,6 +269,9 @@ def main() -> None: app.add_handler(CommandHandler("start", start)) app.add_handler(CommandHandler("clear", clear)) app.add_handler(CommandHandler("status", status)) + app.add_handler(CommandHandler("switch", start)) # Placeholder for /switch command + app.add_handler(CommandHandler("toggle", start)) # Placeholder for /toggle command + app.add_handler(CommandHandler("reset", clear)) # Use clear function for /reset command app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message)) app.add_handler(CallbackQueryHandler(abort_processing, pattern='^abort$'))