fix: gpt-oss:20b ollama, streaming, tableaux JSON, recherche flexible salons/categories
This commit is contained in:
parent
14985f6dbb
commit
189d56026b
21 changed files with 2824 additions and 491 deletions
93
main.py
Normal file
93
main.py
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
"""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 Superviseur
|
||||
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('Superviseur')
|
||||
|
||||
# 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")
|
||||
|
||||
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 = Superviseur(
|
||||
llama_model=llm,
|
||||
command_prefix="!",
|
||||
guild_id=int(GUILD_ID),
|
||||
system_prompt=SYSTEM_PROMPT,
|
||||
intents=intents
|
||||
)
|
||||
|
||||
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())
|
||||
Loading…
Add table
Add a link
Reference in a new issue