import discord import asyncio import threading from dotenv import load_dotenv import os from ego.trainer import train_on_message from brain.brain import generate_response from utils.cleanup import full_cleanup from ego.dreamer import replay_dreams, daydream from ego.rehearsal import simulate_conversation from utils.scheduler import set_next_action from ego.reweaver import memory_reweaver_loop from reader.reader import read_books_forever from dashboard.dashboard import run_dashboard load_dotenv() TOKEN = os.getenv("DISCORD_TOKEN") intents = discord.Intents.default() intents.messages = True intents.message_content = True client = discord.Client(intents=intents) empty_response_counter = 0 @client.event async def on_ready(): print(f"Ruby is online as {client.user}.") # ✅ Start async loops on Discord's own event loop client.loop.create_task(read_books_forever()) client.loop.create_task(dream_replay_loop()) client.loop.create_task(background_cleanup_loop()) client.loop.create_task(rehearsal_loop()) client.loop.create_task(memory_reweaver_loop()) @client.event async def on_message(message): global empty_response_counter if message.author == client.user: return if not message.content.strip(): return await train_on_message(message.content, source="user") response = generate_response() if not response.strip(): empty_response_counter += 1 if empty_response_counter % 10 == 0: print(f"[Brain] Skipped {empty_response_counter} empty replies so far.") return empty_response_counter = 0 await message.channel.send(response) async def background_cleanup_loop(): while True: full_cleanup() set_next_action(300, "Cleaning up") await asyncio.sleep(300) async def dream_replay_loop(): while True: await replay_dreams() set_next_action(90, "Dreaming new dreams") await asyncio.sleep(90) await daydream() async def rehearsal_loop(): while True: await simulate_conversation() set_next_action(120, "Practicing Conversations") await asyncio.sleep(120) # ✅ Launch dashboard in background thread threading.Thread(target=run_dashboard, daemon=True).start() # ✅ Launch Discord bot (this owns the event loop now) client.run(TOKEN)