fixed some things

This commit is contained in:
2024-02-21 19:27:19 -05:00
parent a9581335c9
commit 07b9503c2c
2 changed files with 11 additions and 12 deletions

166
main.py Normal file
View File

@@ -0,0 +1,166 @@
import discord
from discord.ext import commands
from openai import AsyncOpenAI
import logging
import asyncio
import time
from collections import defaultdict
from datetime import datetime, timedelta
import os
# Configuration and Constants
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
DISCORD_BOT_TOKEN = os.getenv("DISCORD_BOT_TOKEN")
ASSISTANT_ID = os.getenv("ASSISTANT_ID")
MESSAGE_CHUNK_SIZE = 2000
THREAD_INACTIVITY_TIMEOUT_HOURS = 1
# Setting up logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# OpenAI Client Setup
openai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)
# Discord Bot Setup
intents = discord.Intents.default()
bot = commands.Bot(command_prefix="!", intents=intents)
# Thread Management
thread_ids = defaultdict(lambda: {"thread_id": None, "last_used": datetime.now()})
# Function to create a new thread
async def create_new_thread(identifier):
global thread_ids
try:
thread = await openai_client.beta.threads.create()
thread_ids[identifier] = {"thread_id": thread.id, "last_used": datetime.now()}
logging.info(f"New thread created for {identifier} with ID: {thread.id}")
except Exception as e:
logging.error(f"Error during thread creation for {identifier}: {e}")
raise
# Function to send messages in chunks
async def send_in_chunks(channel, message):
logging.info("Sending message in chunks")
try:
while message:
split_index = (message.rfind(' ', 0, MESSAGE_CHUNK_SIZE) + 1) if len(message) > MESSAGE_CHUNK_SIZE else len(message)
chunk = message[:split_index].strip()
await channel.send(chunk)
message = message[split_index:]
logging.info("All chunks sent successfully")
except Exception as e:
logging.error(f"Error sending message in chunks: {e}")
raise
# Function to send message to OpenAI
async def send_message_to_openai(clean_message, thread_id):
try:
await openai_client.beta.threads.messages.create(
thread_id=thread_id,
role="user",
content=clean_message
)
except Exception as e:
logging.error(f"Error sending message to OpenAI: {e}")
raise
# Function to check OpenAI response
async def check_openai_response(thread_id, run_id):
try:
start_time = time.time()
while True:
updated_run = await openai_client.beta.threads.runs.retrieve(
thread_id=thread_id,
run_id=run_id
)
if updated_run.status == "completed":
break
elapsed_time = time.time() - start_time
sleep_time = min(1 + elapsed_time / 10, 5)
await asyncio.sleep(sleep_time)
except Exception as e:
logging.error(f"Error checking OpenAI response: {e}")
raise
# Function to retrieve the latest response from OpenAI
async def retrieve_latest_response(thread_id):
try:
messages = await openai_client.beta.threads.messages.list(thread_id=thread_id)
assistant_messages = [msg for msg in messages.data if msg.role == "assistant"]
if assistant_messages:
latest_message = max(assistant_messages, key=lambda x: x.created_at)
return latest_message.content[0].text.value
else:
return "No response from the assistant."
except Exception as e:
logging.error(f"Error retrieving response from OpenAI: {e}")
raise
# Function to interact with OpenAI
async def interact_with_openai(clean_message, identifier):
global thread_ids
thread_info = thread_ids[identifier]
thread_id = thread_info["thread_id"]
if thread_id is None:
await create_new_thread(identifier)
thread_id = thread_ids[identifier]["thread_id"]
try:
await send_message_to_openai(clean_message, thread_id)
run = await openai_client.beta.threads.runs.create(
thread_id=thread_id,
assistant_id=ASSISTANT_ID
)
await check_openai_response(thread_id, run.id)
return await retrieve_latest_response(thread_id)
except Exception as e:
logging.error(f"Error during OpenAI interaction: {e}")
return "I'm having trouble processing your request right now."
# Function for cleaning up old threads
def cleanup_old_threads():
now = datetime.now()
for key, value in list(thread_ids.items()):
if now - value["last_used"] > timedelta(hours=THREAD_INACTIVITY_TIMEOUT_HOURS):
del thread_ids[key]
# Bot event: on_ready
@bot.event
async def on_ready():
try:
logging.info(f"Logged in as {bot.user.name}")
except Exception as e:
logging.error(f"Error in on_ready: {e}")
# Bot event: on_message
@bot.event
async def on_message(message):
try:
if message.author == bot.user:
return
identifier = message.channel.id
thread_ids[identifier]["last_used"] = datetime.now()
cleanup_old_threads()
bot_mention = f'<@{bot.user.id}>'
if message.content.startswith(bot_mention):
clean_message = discord.utils.remove_markdown(message.clean_content)
logging.info(f"Received message from {message.author.name}: {clean_message}")
async with message.channel.typing():
response = await interact_with_openai(clean_message, identifier)
logging.info(f"OpenAI response: {response}")
await send_in_chunks(message.channel, response)
except Exception as e:
logging.error(f"Error in on_message for {message.content}: {e}")
# Running the bot
bot.run(DISCORD_BOT_TOKEN)