"""Main entry point for Superviseur bot - refactored for Ollama stability.""" import asyncio import logging import os import sys import discord from dotenv import load_dotenv # Import our modular components from core.bot import Bot from core.llm import LLMManager # Setup Logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler("data/bot.log"), logging.StreamHandler(sys.stdout) ] ) logger = logging.getLogger('Beta') # Load environment load_dotenv() TOKEN = os.getenv("DISCORD_TOKEN") GUILD_ID = os.getenv("GUILD_ID") if not TOKEN: logger.error("DISCORD_TOKEN n'est pas défini dans le fichier .env") exit(1) if not GUILD_ID: logger.error("GUILD_ID n'est pas défini ou invalide.") exit(1) # Ollama model name (from .env) MODEL_NAME = os.getenv("OLLAMA_MODEL", "gpt-oss:20b") # Favorite users (special personality) fav_env = os.getenv("FAVORITE_IDS", "") FAVORITE_IDS = [int(i.strip()) for i in fav_env.split(",") if i.strip().isdigit()] async def main(): """Main startup sequence.""" logger.info("◈ SYSTEM: Initializing Superviseur with Ollama Backend...") # 1. Initialize LLM Manager (Connecting to Ollama service) # The actual model path is managed by Ollama via Modelfile llm = LLMManager(model_name=MODEL_NAME) # 2. Build the System Prompt SYSTEM_PROMPT = ( "Tu es Bêta, une IA d'assistance et de modération avancée. " "Tu es serviable, amical et tu réponds avec précision à TOUTES les questions des utilisateurs. " "Tu as la capacité d'exécuter des actions sur le serveur Discord si l'utilisateur te le demande.\n" "Tu dois TOUJOURS utiliser ce format JSON pour tes réponses :\n" "Pour une seule action : {\"thought\": \"analyse\", \"action\": \"ACTION\", \"response\": \"message\", \"PARAM\": \"valeur\"}\n" "Pour PLUSIEURS actions (ex: créer un salon ET un rôle), retourne une LISTE JSON d'objets :\n" "[{\"thought\": \"...\", \"action\": \"CREATE_CHANNEL\", \"channel_name\": \"test\"}, {\"action\": \"CREATE_ROLE\", \"role_name\": \"test\", \"response\": \"J'ai tout créé !\"}]\n" "ACTIONS possibles : NONE, JOIN_VOICE, LEAVE_VOICE, FORGET_USER, READ_LOGS, ALERT, INSIGHT, CREATE_CHANNEL, DELETE_CHANNEL, RENAME_CHANNEL, MODIFY_CHANNEL, KICK, BAN, UNBAN, MUTE, UNMUTE, TIMEOUT, WARN, PURGE, CREATE_ROLE, DELETE_ROLE, ADD_ROLE_TO_USER, REMOVE_ROLE_FROM_USER, CREATE_CATEGORY, DELETE_CATEGORY.\n" "Ajoute les paramètres d'action directement à la racine de l'objet JSON de l'action." ) # 3. Initialize and Start the Bot # Define required intents intents = discord.Intents.default() intents.message_content = True intents.members = True intents.voice_states = True bot = Bot( llama_model=llm, command_prefix="!", guild_id=int(GUILD_ID), system_prompt=SYSTEM_PROMPT, intents=intents, favorite_ids=FAVORITE_IDS ) try: await bot.start(TOKEN) except Exception as e: logger.critical(f"◈ SYSTEM: Fatal error during startup: {e}") finally: await bot.close() if __name__ == "__main__": try: # Use uvloop if available for better performance import uvloop asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) except ImportError: pass asyncio.run(main())