name aware

This commit is contained in:
2025-08-18 11:23:38 -07:00
parent a3bb1a499c
commit e1a8cbf98d

79
bot.py
View File

@@ -1,3 +1,4 @@
import collections
import discord import discord
from discord.ext import commands from discord.ext import commands
from openai import AsyncOpenAI from openai import AsyncOpenAI
@@ -5,28 +6,23 @@ import os
import base64 import base64
import aiohttp import aiohttp
import argparse import argparse
from dataclasses import dataclass, field
from typing import List, Dict, Any from typing import List, Dict, Any
# --- Configuration --- # --- Configuration ---
OPENAI_API_KEY = "eh" OPENAI_API_KEY = "eh"
MODEL = "p620"
DEFAULT_SYSTEM_PROMPT = "you are a catboy named Aoi with dark blue fur and is a tsundere" DEFAULT_SYSTEM_PROMPT = "you are a catboy named Aoi with dark blue fur and is a tsundere"
DEFAULT_NAME = "Aoi"
# --- Data Structures --- # --- Data Structures ---
@dataclass
class Conversation: class Conversation:
channel_id: int def __init__(self, prompt, name):
history: List[Dict[str, Any]] = field(default_factory=list) self.history = [{"role": "system", "content": prompt}]
self.bot_name = name
def add_message(self, role: str, content: Any): def add_message(self, role, content):
self.history.append({"role": role, "content": content}) self.history.append({"role": role, "content": content})
def reset_history(self, system_prompt: str = DEFAULT_SYSTEM_PROMPT):
self.history = [{"role": "system", "content": system_prompt}]
def get_history(self):
return self.history
# --- Command Line Arguments --- # --- Command Line Arguments ---
parser = argparse.ArgumentParser(description="Aoi Discord Bot") parser = argparse.ArgumentParser(description="Aoi Discord Bot")
parser.add_argument('--base_url', type=str, required=True, parser.add_argument('--base_url', type=str, required=True,
@@ -42,7 +38,10 @@ intents.message_content = True
bot = commands.Bot(command_prefix="/", intents=intents) bot = commands.Bot(command_prefix="/", intents=intents)
# --- Data Storage --- # --- Data Storage ---
conversation_history: Dict[int, Conversation] = {} # Keyed by channel ID # Keyed by channel ID
conversation_history: Dict[int, Conversation] = collections.defaultdict(
lambda: Conversation(prompt=DEFAULT_SYSTEM_PROMPT, name=DEFAULT_NAME)
)
# --- OpenAI Client --- # --- OpenAI Client ---
client = AsyncOpenAI( client = AsyncOpenAI(
@@ -50,6 +49,20 @@ client = AsyncOpenAI(
api_key=OPENAI_API_KEY, api_key=OPENAI_API_KEY,
) )
# --- Helpers ---
async def get_user_from_id(ctx, userid):
if ctx.guild:
user = await ctx.guild.fetch_member(userid)
else:
user = await bot.fetch_user(userid)
return user.display_name
async def get_user_from_mention(ctx, mention):
match = re.findall(r"<@!?(\d+)>", mention)
if not match:
return mention
return await get_user_from_id(ctx, int(match[0]))
# --- Bot Events --- # --- Bot Events ---
@bot.event @bot.event
async def on_ready(): async def on_ready():
@@ -63,14 +76,14 @@ async def on_message(message):
return return
if bot.user.mentioned_in(message): if bot.user.mentioned_in(message):
bot_tag = f'<@{bot.user.id}>'
channel_id = message.channel.id channel_id = message.channel.id
user_message_text = message.content.replace(f'<@!{bot.user.id}>', 'Aoi').strip()
if channel_id not in conversation_history:
conversation_history[channel_id] = Conversation(channel_id=channel_id)
conversation_history[channel_id].reset_history()
conversation = conversation_history[channel_id] conversation = conversation_history[channel_id]
user_message_text = message.content
if user_message_text.startswith(bot_tag):
user_message_text = user_message_text[len(bot_tag):]
user_message_text = user_message_text.replace(bot_tag, conversation.bot_name).strip()
print(f'> {message.author.name}: {user_message_text}')
# Prepare content for OpenAI API # Prepare content for OpenAI API
openai_content = [] openai_content = []
@@ -81,6 +94,7 @@ async def on_message(message):
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
for attachment in message.attachments: for attachment in message.attachments:
if attachment.content_type and "image" in attachment.content_type: if attachment.content_type and "image" in attachment.content_type:
async with message.channel.typing():
try: try:
async with session.get(attachment.url) as resp: async with session.get(attachment.url) as resp:
if resp.status == 200: if resp.status == 200:
@@ -94,7 +108,6 @@ async def on_message(message):
except Exception as e: except Exception as e:
print(f"Error downloading or processing attachment: {e}") print(f"Error downloading or processing attachment: {e}")
if not openai_content: # Don't send empty messages if not openai_content: # Don't send empty messages
return return
@@ -105,12 +118,11 @@ async def on_message(message):
else: else:
conversation.add_message("user", openai_content) conversation.add_message("user", openai_content)
try: try:
async with message.channel.typing(): async with message.channel.typing():
response = await client.chat.completions.create( response = await client.chat.completions.create(
model="gpt-4", # Or any other model you are using model=MODEL,
messages=conversation.get_history() messages=conversation.history,
) )
bot_response = response.choices[0].message.content bot_response = response.choices[0].message.content
conversation.add_message("assistant", bot_response) conversation.add_message("assistant", bot_response)
@@ -129,19 +141,16 @@ async def on_message(message):
@bot.tree.command(name="newchat", description="Start a new chat with a new system prompt.") @bot.tree.command(name="newchat", description="Start a new chat with a new system prompt.")
async def newchat(interaction: discord.Interaction, prompt: str = None): async def newchat(interaction: discord.Interaction, prompt: str = None):
channel_id = interaction.channel_id channel_id = interaction.channel_id
prompt = prompt or DEFAULT_SYSTEM_PROMPT
system_prompt = prompt name_response = await client.chat.completions.create(
if system_prompt is None: model=MODEL,
system_prompt = DEFAULT_SYSTEM_PROMPT messages=[
{"role": "system", "content": prompt},
if channel_id not in conversation_history: {"role": "user", "content": "reply with your name, nothing else, no punctuation"}
conversation_history[channel_id] = Conversation(channel_id=channel_id) ],
)
conversation_history[channel_id].reset_history(system_prompt) name = name_response.choices[0].message.content
conversation_history[channel_id] = Conversation(prompt=prompt, name=name)
if prompt is None:
await interaction.response.send_message("Starting a new chat with the default prompt.")
else:
await interaction.response.send_message(f'Starting a new chat with the prompt: "{prompt}"') await interaction.response.send_message(f'Starting a new chat with the prompt: "{prompt}"')