hopefully fix repetition with higher temperature and frequency penalty
This commit is contained in:
129
main.py
129
main.py
@@ -1,12 +1,18 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import requests
|
||||
import os
|
||||
import base64
|
||||
from io import BytesIO
|
||||
from openai import OpenAI
|
||||
import logging
|
||||
from database import get_database, CustomBotManager
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN", "placeholder")
|
||||
|
||||
OPENAI_API_ENDPOINT = os.getenv("OPENAI_API_ENDPOINT")
|
||||
@@ -35,7 +41,9 @@ OPENAI_COMPLETIONS_URL = f"{OPENAI_API_ENDPOINT}/chat/completions"
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
logger.info("Bot is starting up...")
|
||||
print(f"Bot logged in as {bot.user}")
|
||||
logger.info(f"Bot logged in as {bot.user}")
|
||||
|
||||
|
||||
@bot.command(name="custom-bot")
|
||||
@@ -45,51 +53,86 @@ async def custom_bot(ctx, bot_name: str, *, personality: str):
|
||||
Usage: !custom-bot <bot_name> <personality_description>
|
||||
Example: !custom-bot alfred you are a proper british butler
|
||||
"""
|
||||
logger.info(
|
||||
f"Custom bot command initiated by {ctx.author.name}: name='{bot_name}', personality length={len(personality)}"
|
||||
)
|
||||
|
||||
# Validate bot name
|
||||
if not bot_name or len(bot_name) < 2 or len(bot_name) > 50:
|
||||
logger.warning(
|
||||
f"Invalid bot name from {ctx.author.name}: '{bot_name}' (length: {len(bot_name) if bot_name else 0})"
|
||||
)
|
||||
await ctx.send("❌ Invalid bot name. Name must be between 2 and 50 characters.")
|
||||
return
|
||||
|
||||
logger.info(f"Bot name validation passed for '{bot_name}'")
|
||||
|
||||
# Validate personality
|
||||
if not personality or len(personality) < 10:
|
||||
logger.warning(
|
||||
f"Invalid personality from {ctx.author.name}: length={len(personality) if personality else 0}"
|
||||
)
|
||||
await ctx.send(
|
||||
"❌ Invalid personality. Description must be at least 10 characters."
|
||||
)
|
||||
return
|
||||
|
||||
logger.info(f"Personality validation passed for bot '{bot_name}'")
|
||||
|
||||
# Create custom bot manager
|
||||
logger.info(f"Initializing CustomBotManager for user {ctx.author.name}")
|
||||
custom_bot_manager = CustomBotManager()
|
||||
|
||||
# Create the custom bot
|
||||
logger.info(
|
||||
f"Attempting to create custom bot '{bot_name}' for user {ctx.author.name}"
|
||||
)
|
||||
success = custom_bot_manager.create_custom_bot(
|
||||
bot_name=bot_name, system_prompt=personality, created_by=str(ctx.author.id)
|
||||
)
|
||||
|
||||
if success:
|
||||
logger.info(
|
||||
f"Successfully created custom bot '{bot_name}' for user {ctx.author.name}"
|
||||
)
|
||||
await ctx.send(
|
||||
f"✅ Custom bot **'{bot_name}'** has been created with personality: *{personality}*"
|
||||
)
|
||||
await ctx.send(f"\nYou can now use this bot with: `!{bot_name} <your message>`")
|
||||
else:
|
||||
logger.warning(
|
||||
f"Failed to create custom bot '{bot_name}' for user {ctx.author.name}"
|
||||
)
|
||||
await ctx.send("❌ Failed to create custom bot. It may already exist.")
|
||||
|
||||
|
||||
@bot.command(name="list-custom-bots")
|
||||
async def list_custom_bots(ctx):
|
||||
"""List all custom bots available in the server"""
|
||||
logger.info(f"Listing custom bots requested by {ctx.author.name}")
|
||||
|
||||
# Create custom bot manager
|
||||
logger.info("Initializing CustomBotManager to list custom bots")
|
||||
custom_bot_manager = CustomBotManager()
|
||||
|
||||
logger.info("Fetching list of custom bots from database")
|
||||
bots = custom_bot_manager.list_custom_bots()
|
||||
|
||||
if not bots:
|
||||
logger.info(f"No custom bots found for user {ctx.author.name}")
|
||||
await ctx.send(
|
||||
"No custom bots have been created yet. Use `!custom-bot <name> <personality>` to create one."
|
||||
)
|
||||
return
|
||||
|
||||
logger.info(
|
||||
f"Found {len(bots)} custom bots, displaying top 10 for {ctx.author.name}"
|
||||
)
|
||||
bot_list = "🤖 **Available Custom Bots**:\n\n"
|
||||
for name, prompt, creator in bots[:10]: # Limit to 10 bots
|
||||
bot_list += f"• **{name}** (created by {creator})\n"
|
||||
|
||||
logger.info(f"Sending bot list response to {ctx.author.name}")
|
||||
await ctx.send(bot_list)
|
||||
|
||||
|
||||
@@ -99,22 +142,48 @@ async def delete_custom_bot(ctx, bot_name: str):
|
||||
|
||||
Usage: !delete-custom-bot <bot_name>
|
||||
"""
|
||||
logger.info(
|
||||
f"Delete custom bot command initiated by {ctx.author.name}: bot_name='{bot_name}'"
|
||||
)
|
||||
|
||||
# Create custom bot manager
|
||||
logger.info("Initializing CustomBotManager for delete operation")
|
||||
custom_bot_manager = CustomBotManager()
|
||||
|
||||
# Get bot info
|
||||
logger.info(f"Looking up custom bot '{bot_name}' in database")
|
||||
bot_info = custom_bot_manager.get_custom_bot(bot_name)
|
||||
|
||||
if not bot_info:
|
||||
logger.warning(f"Custom bot '{bot_name}' not found by user {ctx.author.name}")
|
||||
await ctx.send(f"❌ Custom bot '{bot_name}' not found.")
|
||||
return
|
||||
|
||||
logger.info(f"Custom bot '{bot_name}' found, owned by user {bot_info[2]}")
|
||||
|
||||
# Check ownership
|
||||
if bot_info[2] != str(ctx.author.id):
|
||||
logger.warning(
|
||||
f"User {ctx.author.name} attempted to delete bot '{bot_name}' they don't own"
|
||||
)
|
||||
await ctx.send("❌ You can only delete your own custom bots.")
|
||||
return
|
||||
|
||||
logger.info(f"User {ctx.author.name} is authorized to delete bot '{bot_name}'")
|
||||
|
||||
# Delete the bot
|
||||
logger.info(f"Deleting custom bot '{bot_name}' from database")
|
||||
success = custom_bot_manager.delete_custom_bot(bot_name)
|
||||
|
||||
if success:
|
||||
logger.info(
|
||||
f"Successfully deleted custom bot '{bot_name}' by user {ctx.author.name}"
|
||||
)
|
||||
await ctx.send(f"✅ Custom bot '{bot_name}' has been deleted.")
|
||||
else:
|
||||
logger.warning(
|
||||
f"Failed to delete custom bot '{bot_name}' by user {ctx.author.name}"
|
||||
)
|
||||
await ctx.send("❌ Failed to delete custom bot.")
|
||||
|
||||
|
||||
@@ -125,19 +194,34 @@ async def on_message(message):
|
||||
if message.author == bot.user:
|
||||
return
|
||||
|
||||
logger.debug(
|
||||
f"Processing message from {message.author.name}: '{message.content[:50]}...'"
|
||||
)
|
||||
|
||||
ctx = await bot.get_context(message)
|
||||
|
||||
# Check if the message starts with a custom bot command
|
||||
content = message.content.lower()
|
||||
|
||||
logger.info(f"Initializing CustomBotManager to check for custom bot commands")
|
||||
custom_bot_manager = CustomBotManager()
|
||||
|
||||
logger.info("Fetching list of custom bots to check for matching commands")
|
||||
custom_bots = custom_bot_manager.list_custom_bots()
|
||||
|
||||
logger.info(f"Checking {len(custom_bots)} custom bots for command match")
|
||||
for bot_name, system_prompt, _ in custom_bots:
|
||||
# Check if message starts with the custom bot name followed by a space
|
||||
if content.startswith(f"!{bot_name} "):
|
||||
logger.info(
|
||||
f"Custom bot command detected: '{bot_name}' triggered by {message.author.name}"
|
||||
)
|
||||
|
||||
# Extract the actual message (remove the bot name prefix)
|
||||
user_message = message.content[len(f"!{bot_name} ") :]
|
||||
logger.debug(
|
||||
f"Extracted user message for bot '{bot_name}': '{user_message[:50]}...'"
|
||||
)
|
||||
|
||||
# Prepare the payload with custom personality
|
||||
payload = {
|
||||
@@ -154,6 +238,7 @@ async def on_message(message):
|
||||
|
||||
response_prefix = f"**{bot_name} response**"
|
||||
|
||||
logger.info(f"Sending request to OpenAI API for bot '{bot_name}'")
|
||||
await handle_chat(
|
||||
ctx=ctx,
|
||||
message=user_message,
|
||||
@@ -259,12 +344,6 @@ async def handle_chat(ctx, *, message: str, payload: dict, response_prefix: str)
|
||||
)
|
||||
return
|
||||
|
||||
# Set headers
|
||||
headers = {
|
||||
"Authorization": f"Bearer {OPENAI_API_KEY}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
# Get database instance
|
||||
db = get_database()
|
||||
|
||||
@@ -283,16 +362,22 @@ async def handle_chat(ctx, *, message: str, payload: dict, response_prefix: str)
|
||||
print(payload)
|
||||
|
||||
try:
|
||||
# Send request to OpenAI API
|
||||
response = requests.post(
|
||||
OPENAI_COMPLETIONS_URL, json=payload, headers=headers, timeout=300
|
||||
)
|
||||
response.raise_for_status()
|
||||
# Initialize OpenAI client
|
||||
client = OpenAI(api_key=OPENAI_API_KEY, base_url=OPENAI_API_ENDPOINT)
|
||||
|
||||
result = response.json()
|
||||
# Call OpenAI API
|
||||
response = client.chat.completions.create(
|
||||
model=payload["model"],
|
||||
messages=payload["messages"],
|
||||
max_completion_tokens=MAX_COMPLETION_TOKENS,
|
||||
frequency_penalty=1.5,
|
||||
presence_penalty=1.5,
|
||||
temperature=1,
|
||||
seed=-1,
|
||||
)
|
||||
|
||||
# Extract the generated text
|
||||
generated_text = result["choices"][0]["message"]["content"].strip()
|
||||
generated_text = response.choices[0].message.content.strip()
|
||||
|
||||
# Store both user message and bot response in the database
|
||||
db.add_message(
|
||||
@@ -343,16 +428,18 @@ async def call_llm(ctx, payload: dict) -> str:
|
||||
}
|
||||
|
||||
try:
|
||||
# Send request to OpenAI API
|
||||
response = requests.post(
|
||||
OPENAI_COMPLETIONS_URL, json=payload, headers=headers, timeout=300
|
||||
)
|
||||
response.raise_for_status()
|
||||
# Initialize OpenAI client
|
||||
client = OpenAI(api_key=OPENAI_API_KEY, base_url=OPENAI_API_ENDPOINT)
|
||||
|
||||
result = response.json()
|
||||
# Call OpenAI API
|
||||
response = client.chat.completions.create(
|
||||
model=payload["model"],
|
||||
messages=payload["messages"],
|
||||
max_tokens=MAX_COMPLETION_TOKENS,
|
||||
)
|
||||
|
||||
# Extract the generated text
|
||||
generated_text = result["choices"][0]["message"]["content"].strip()
|
||||
generated_text = response.choices[0].message.content.strip()
|
||||
print(generated_text)
|
||||
|
||||
return generated_text
|
||||
|
||||
Reference in New Issue
Block a user