import pickle from io import BytesIO from google.genai.chats import AsyncChat from pyrogram.enums import ParseMode from app import BOT, Convo, Message, bot from app.plugins.ai.media_query import handle_media from app.plugins.ai.models import ( Settings, async_client, get_response_text, run_basic_check, ) CONVO_CACHE: dict[str, Convo] = {} @bot.add_cmd(cmd="ai") @run_basic_check async def question(bot: BOT, message: Message): """ CMD: AI INFO: Ask a question to Gemini AI or get info about replied message / media. FLAGS: -s: to use Search USAGE: .ai what is the meaning of life. .ai [reply to a message] (sends replied text as query) .ai [reply to message] [extra prompt relating to replied text] .ai [reply to image | video | gif] .ai [reply to image | video | gif] [custom prompt] """ reply = message.replied prompt = message.filtered_input if reply and reply.media: message_response = await message.reply( "Processing... this may take a while." ) response_text = await handle_media( prompt=prompt, media_message=reply, **Settings.get_kwargs(use_search="-s" in message.flags), ) else: message_response = await message.reply( "Input received... generating response." ) if reply and reply.text: prompts = [str(reply.text), message.input or "answer"] else: prompts = [message.input] response = await async_client.models.generate_content( contents=prompts, **Settings.get_kwargs(use_search="-s" in message.flags), ) response_text = get_response_text(response, quoted=True) await message_response.edit( text=f"**>\n•> {prompt}<**\n{response_text}", parse_mode=ParseMode.MARKDOWN, disable_preview=True, ) @bot.add_cmd(cmd="aic") @run_basic_check async def ai_chat(bot: BOT, message: Message): """ CMD: AICHAT INFO: Have a Conversation with Gemini AI. USAGE: .aic hello keep replying to AI responses After 5 mins of Idle bot will export history and stop chat. use .load_history to continue """ chat = async_client.chats.create(**Settings.get_kwargs()) await do_convo(chat=chat, message=message) @bot.add_cmd(cmd="lh") @run_basic_check async def history_chat(bot: BOT, message: Message): """ CMD: LOAD_HISTORY INFO: Load a Conversation with Gemini AI from previous session. USAGE: .lh {question} [reply to history document] """ reply = message.replied if not message.input: await message.reply(f"Ask a question along with {message.trigger}{message.cmd}") return try: assert reply.document.file_name == "AI_Chat_History.pkl" except (AssertionError, AttributeError): await message.reply("Reply to a Valid History file.") return resp = await message.reply("`Loading History...`") doc = await reply.download(in_memory=True) doc.seek(0) history = pickle.load(doc) await resp.edit("__History Loaded... Resuming chat__") chat = async_client.chats.create(**Settings.get_kwargs(), history=history) await do_convo(chat=chat, message=message) async def do_convo(chat: AsyncChat, message: Message): prompt = message.input reply_to_id = message.id chat_id = message.chat.id old_convo = CONVO_CACHE.get(message.unique_chat_user_id) if old_convo in Convo.CONVO_DICT[chat_id]: Convo.CONVO_DICT[chat_id].remove(old_convo) convo_obj = Convo( client=message._client, chat_id=chat_id, timeout=300, check_for_duplicates=False, from_user=message.from_user.id, reply_to_user_id=message._client.me.id, ) CONVO_CACHE[message.unique_chat_user_id] = convo_obj try: async with convo_obj: while True: ai_response = await chat.send_message(prompt) ai_response_text = get_response_text(ai_response, quoted=True) text = f"**GENAI:**\n{ai_response_text}" _, prompt_message = await convo_obj.send_message( text=text, reply_to_id=reply_to_id, parse_mode=ParseMode.MARKDOWN, get_response=True, disable_preview=True, ) prompt, reply_to_id = prompt_message.text, prompt_message.id except TimeoutError: await export_history(chat, message) CONVO_CACHE.pop(message.unique_chat_user_id, 0) async def export_history(chat: AsyncChat, message: Message): doc = BytesIO(pickle.dumps(chat._curated_history)) doc.name = "AI_Chat_History.pkl" caption = get_response_text( await chat.send_message("Summarize our Conversation into one line.") ) await bot.send_document(chat_id=message.from_user.id, document=doc, caption=caption)