Spaces:
Runtime error
A newer version of the Gradio SDK is available:
5.21.0
ο»Ώ 1. Project Structure
First, let's organize the project into logical modules. Here's a suggested directory structure:
Chatter/ βββ .gitignore βββ .env βββ requirements.txt βββ app.py βββ ChatAI/ β βββ chat_ai.py β βββ init.py βββ core/ β βββ init.py β βββ bot.py β β βββ init.py β βββ message_handler.py β βββ init.py βββ logging/ β βββ init.py β βββ handlers.py βββ utils/ β βββ init.py β βββ constants.py β βββ decorators.py βββ .env.local
2. Move Code to Modules
Let's break down the existing code into these modules:
a) core/bot.py
Move the bot initialization, command setup, and basic functionality here.
import commands from .message_handler import on_message, respond_to_chat from .utils import split_string, generate, generate_response
bot = commands.Bot(command_prefix="!")
def setup_commands(): # Command definitions pass
async def on_ready(): print(f'Logged in as {bot.user}') # Initialize channels and message counts pass
@bot.event async def on_message(message): # Verification logic pass
@bot.event async def on_ready(): # Bot initialization and setup pass
Initialize message counts and channels
message_counts = {} channel = get_default_channel()
b) core/message_handler.py
Move the message handling logic here.
import discord from .utils import split_string, generate, generate_response
@bot.event async def on_message(message): guild = message.guild channel = get_default_channel()
if message.channel != channel or message.author.bot:
return
if message.channel.id not in message_counts:
message_counts[message.channel.id] = 0
message_counts[message.channel.id] += 1
print(message_counts[message.channel.id])
await respond_to_chat(message.content)
if message_counts[message.channel.id] >= 10:
messages = [message.content]
# Get previous messages from history
async for msg in channel.history(limit=10):
messages.append(msg.content)
messages = "\n".join(messages)
await respond_to_chat(messages)
message_counts[message.channel.id] = 0
async def respond_to_chat(content: str) -> str: response = generate(content) parts = split_string(response) # Send parts to channel await send_split_message(parts, channel) return "\n".join(parts)
def split_string(text: str) -> list[str]: return [text[i:i+1900] for i in range(0, len(text), 1900)]
def generate( prompt, temperature=0.0, max_new_tokens=2048, top_p=0.95, repetition_penalty=1.0 ): # Use MistralAI model pass
def generate_response(prompt): # Use MistralAI model pass
async def send_split_message(parts, channel): for part in parts: await channel.send(part)
c) core/utils.py
Move the utility functions here.
import os from huggingface_hub import InferenceClient
def split_string(text: str) -> list[str]: """Helper function to split text into chunks""" return [text[i:i+1900] for i in range(0, len(text), 1900)]
def generate( prompt, temperature=0.0, max_new_tokens=2048, top_p=0.95, repetition_penalty=1.0 ): """Generate response using MistralAI model""" if temperature == 0.0: temperature = random.uniform(1e-2, 0.9) temperature = float(temperature)
top_p = float(top_p)
generate_kwargs = dict(
temperature=temperature,
max_new_tokens=max_new_tokens,
top_p=top_p,
repetition_penalty=repetition_penalty,
do_sample=True,
seed=42,
)
return ai.text_generation(prompt, **generate_kwargs, stream=False, details=False,
return_full_text=True)
def generate_response(prompt): """Generate and format response""" response = generate(prompt) formatted_response = "\n".join(response) return formatted_response
def get_default_channel(): return discord.utils.get(guild.channels, name="PrzebieralniaKoedukacyjna")
d) ChatAI/chat_ai.py
Move the AI configuration here.
from huggingface_hub import InferenceClient
class ChatAI: def init(self): self.pipe = InferenceClient("mistralai/Mistral-7B-Instruct-v0.3")
async def generate(self, prompt):
return self.pipe.generate(prompt)
3. Dependency Management
Update the requirements.txt to use a modern package manager like Poetry:
requirements.txt
<<<<<<< SEARCH
transformers
huggingface_hub==0.25.2
discord.py=2.4.0
discord=2.3.2
torch
six
python-dotenv=1.0.1
huggingface-hub=0.25.2
discord=2.4.0
discord.py=2.4.0
transformers
huggingface_hub>=0.25.0
torch
six
python-dotenv>=1.0.0
poetry
REPLACE
Run:
poetry install
4. Add Logging
Create a logging module:
utils/logging.py
import logging from datetime import datetime
logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[logging.FileHandler('chat.log')] )
logger = logging.getLogger(name)
5. Initialize the Bot
Create a main.py to initialize and run the bot:
main.py
from core.bot import commands from core.message_handler import on_ready, on_message, respond_to_chat from core.utils import split_string, generate, generate_response from ChatAI.chat_ai import ChatAI import logging
Initialize logging
logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[logging.FileHandler('chat.log')] )
logger = logging.getLogger(name)
Initialize bot
bot = commands.Bot(command_prefix="!")
Initialize AI
ai = ChatAI()
Initialize message handler
async def setup(): logger.info("Initializing bot and message handler") await on_ready() logger.info("Bot initialized")
async def run_bot(): try: await setup() logger.info("Bot running...") while True: await bot.process_commands() except Exception as e: logger.error(f"Error in bot loop: {str(e)}") logger.info("Bot shutdown") finally: logger.info("Bot shutdown complete")
if name == "main": try: logger.info("Starting bot") await bot.start(DISCORD_TOKEN_CHATTER) logger.info("Bot running") except Exception as e: logger.error(f"Error starting bot: {str(e)}") logger.info("Bot shutdown")
6. Testing
Add tests to ensure the bot works as expected.
tests/ βββ .gitignore βββ test_message_handler.py βββ test_chat_ai.py
7. Deployment
For production, consider:
β’ Using a server (like Heroku or Railway) β’ Implementing proper security β’ Adding monitoring β’ Implementing rate limiting
8. Documentation
Add documentation to your project for future developers.
9. Deployment Setup
Set up a deployment environment with:
poetry run --build
Then deploy to your chosen platform.
Summary
This structured approach organizes the project into modular components, manages dependencies effectively, and provides logging and error handling for reliability. By following these steps, you'll have a maintainable, scalable, and robust project structure.