From 721f75613b20a3af36f02a377725881ed1990338 Mon Sep 17 00:00:00 2001 From: Marco Guaspari Worms Date: Fri, 24 Nov 2023 01:22:25 +0100 Subject: [PATCH] add preaudit --- bot.py | 122 ++++++++++++++++++++++++++++++++++++----------- requirements.txt | 3 +- 2 files changed, 95 insertions(+), 30 deletions(-) diff --git a/bot.py b/bot.py index 870e17c..c71a637 100644 --- a/bot.py +++ b/bot.py @@ -3,8 +3,9 @@ import datetime from threading import Lock from telegram import Update, ParseMode -from telegram.ext import Updater, CommandHandler, CallbackContext +from telegram.ext import Updater, CommandHandler, CallbackContext, MessageHandler, Filters import openai +import requests # Load your OpenAI API key and Telegram token from environment variables or direct string assignment OPENAI_API_KEY = os.getenv('OPENAI_API_KEY') @@ -80,10 +81,53 @@ def add_group(update: Update, context: CallbackContext) -> None: else: update.message.reply_text('You are not authorized to add groups.') -# Define the message handler +# Define the preaudit command handler +def preaudit(update: Update, context: CallbackContext) -> None: + url = context.args[0] if context.args else '' + if not url: + update.message.reply_text('Please provide a URL.') + return + + try: + response = requests.get(url) + response.raise_for_status() + code_content = response.text + + prompt = ''' +/- Match the natspec documentation made for each function in the code above with its code, for each function tell me if it perfectly matches one another, if not list the differences. Make it a list with function signatures and assessments. +''' + messages = [ + { + "role": "user", + "content": prompt + }, + { + "role": "user", + "content": code_content + } + ] + + openai_response = openai.chat.completions.create( + model="gpt-4-1106-preview", + temperature=0, + messages=messages, + ) + + bot_response = openai_response.choices[0].message.content + # Split the message into chunks of 4096 characters + max_length = 4096 + messages = [bot_response[i:i+max_length] for i in range(0, len(bot_response), max_length)] + for msg in messages: + update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN) + + except requests.RequestException as e: + update.message.reply_text(f"Error fetching data from the URL: {e}") + + + # Define the message handler def handle_message(update: Update, context: CallbackContext) -> None: group_id = str(update.message.chat_id) - + if group_id in groups: # Check if the daily limit has been reached group_data = groups[group_id] @@ -98,38 +142,55 @@ def handle_message(update: Update, context: CallbackContext) -> None: command_to_remove = update.message.text.split()[0] # This will be either /p or /prompt user_message = user_message.replace(command_to_remove, '', 1).strip() + # Prepare the list of messages for OpenAI + messages = [ + { + "role": "user", + "content": ''' +/- You are a bot helping people understand Ape. +/- I have prefixed a KNOWLEDGE BASE that help you understand what is Ape. +/- The answer must exist within the source files, otherwise don't answer. +/- You can use ```language to write code that shows in a pretty way. +/- Do not invent anything about ape that is not in source files unless you said you were going creative. +/- False certanty about what ape can do is the worse thing you can do, avoid it at all costs. +/- ALWAYS Answer the user question using the source files and tell the source of your answer. +/- ALWAYS provide a % score of how much of your answer matches the KNOWLEDGE BASE. +/- If the task is of creative nature it's ok to go wild and beyond just the sources, but you MUST state that confidence score is -1 in that case. +''' + }, + { + "role": "user", + "content": "---START OF KNOWLEDGE BASE---\n\n" + knowledge_base + "\n\n---END OF KNOWLEDGE BASE---" + } + ] + + # Check if the message is a reply to a previous message + if update.message.reply_to_message: + # Include the replied-to message content as an assistant message + messages.append({ + "role": "assistant", + "content": update.message.reply_to_message.text + }) + + # Add the user's message + messages.append({ + "role": "user", + "content": user_message + }) + try: response = openai.chat.completions.create( model="gpt-4-1106-preview", temperature=0, - messages=[ - { - "role": "user", - "content": ''' - /- You are a bot helping people understand Ape. - /- I have prefixed a KNOWLEDGE BASE that help you understand what is Ape. - /- The answer must exist within the source files, otherwise don't answer. - /- You can use ```language to write code that shows in a pretty way. - /- Do not invent anything about ape that is not in source files unless you said you were going creative. - /- False certanty about what ape can do is the worse thing you can do, avoid it at all costs. - /- ALWAYS Answer the user question using the source files and tell the source of your answer. - /- ALWAYS provide a % score of how much of your answer matches the KNOWLEDGE BASE. - /- If the task is of creative nature it's ok to go wild and beyond just the sources, but you MUST state that confidence score is -1 in that case. - ''' - }, - { - "role": "user", - "content": "---START OF KNOWLEDGE BASE---\n\n" + knowledge_base + "\n\n---END OF KNOWLEDGE BASE---" - }, - { - "role": "user", - "content": user_message - } - ], + messages=messages, ) bot_response = response.choices[0].message.content - update.message.reply_text(bot_response, parse_mode=ParseMode.MARKDOWN) + # Split the message into chunks of 4096 characters + max_length = 4096 + messages = [bot_response[i:i+max_length] for i in range(0, len(bot_response), max_length)] + for msg in messages: + update.message.reply_text(msg, parse_mode=ParseMode.MARKDOWN) # After getting the response from OpenAI, update the usage if not admins.get(str(update.message.from_user.id)): @@ -143,6 +204,8 @@ def handle_message(update: Update, context: CallbackContext) -> None: update.message.reply_text(f"OpenAIError: {e}") + + # Main function to start the bot def main() -> None: load_data() @@ -154,7 +217,8 @@ def main() -> None: dispatcher.add_handler(CommandHandler("start", start)) dispatcher.add_handler(CommandHandler("add_admin", add_admin)) dispatcher.add_handler(CommandHandler("add_group", add_group)) - + dispatcher.add_handler(CommandHandler("preaudit", preaudit)) + dispatcher.add_handler(MessageHandler(Filters.text & Filters.regex(r'^y\s'), handle_message)) updater.start_polling() updater.idle() diff --git a/requirements.txt b/requirements.txt index 2603bbe..f47d090 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ openai==1.1.1 python-telegram-bot==13.7 -PyYAML==6.0.1 \ No newline at end of file +PyYAML==6.0.1 +requests \ No newline at end of file