diff --git a/main.py b/main.py index 6fe373c..2be5c47 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ import threading from dotenv import load_dotenv import os from model.trainer import train_on_message -from model.brain import generate_response +from model.brain import generate_response, daydream from model.cleanup import full_cleanup from model.dream_replay import replay_dreams from model.rehearsal import simulate_conversation @@ -22,6 +22,8 @@ intents.message_content = True client = discord.Client(intents=intents) +empty_response_counter = 0 + @client.event async def on_ready(): @@ -30,12 +32,24 @@ async def on_ready(): @client.event async def on_message(message): - if message.author.bot: + global empty_response_counter + + if message.author == client.user: return - content = message.content.strip() - train_on_message(content) + if not message.content.strip(): + return + + train_on_message(message.content, source="user") response = generate_response() + + if not response.strip(): + empty_response_counter += 1 + if empty_response_counter % 10 == 0: # only every 10 failures + print(f"[Brain] Skipped {empty_response_counter} empty replies so far.") + return + + empty_response_counter = 0 # reset counter when Ruby replies await message.channel.send(response) @@ -49,15 +63,16 @@ async def background_cleanup_loop(): async def dream_replay_loop(): while True: replay_dreams() - set_next_action(900, "Dreaming new dreams") - await asyncio.sleep(900) # Replay every 15 minutes + set_next_action(90, "Dreaming new dreams") + await asyncio.sleep(90) # Replay every 15 minutes + daydream() async def rehearsal_loop(): while True: simulate_conversation() - set_next_action(1200, "Practicing Conversations") - await asyncio.sleep(1200) # Every 20 minutes + set_next_action(120, "Practicing Conversations") + await asyncio.sleep(120) # Every 20 minutes # Start Ruby's Brain Loops in a separate thread diff --git a/model/trainer.py b/model/trainer.py index cc70982..e462f1b 100644 --- a/model/trainer.py +++ b/model/trainer.py @@ -2,7 +2,8 @@ import torch import time from model.dynamic_expand import expand_model_if_needed, _last_expansion_time, get_optimizer, expand_lock from model.brain_state import model, tokenizer, DEVICE, loss_fn -from model.brainmap import add_to_brainmap +from model.brainmap import add_to_brainmap, save_brainmap +from model.tokenizer import save_vocab from context.context import add_to_context, get_recent_context LOSS_FILE = "data/logs/loss.log" @@ -70,6 +71,8 @@ def train_on_message(text: str, source: str = "user"): log_vocab_growth() add_to_context(text, source=source) add_to_brainmap(augmented_text.split()) + save_brainmap() + save_vocab(tokenizer.vocab) finally: expand_lock.release() diff --git a/reader/reader.py b/reader/reader.py index 632a5bc..c26ebe0 100644 --- a/reader/reader.py +++ b/reader/reader.py @@ -1,6 +1,8 @@ import os import asyncio import json +from model.tokenizer import save_vocab, Tokenizer +from model.brainmap import save_brainmap from model.trainer import train_on_message from model.scheduler import set_next_action from reader.filter import is_valid_line @@ -10,6 +12,7 @@ PROGRESS_FILE = "data/memory/book_progress.json" READ_DELAY = 0.2 # seconds between paragraphs PARAGRAPH_MIN_LENGTH = 20 END_PUNCTUATION = {".", "!", "?"} +tokenizer = Tokenizer() def get_books(): @@ -18,8 +21,15 @@ def get_books(): def load_progress(): if os.path.exists(PROGRESS_FILE): - with open(PROGRESS_FILE, "r", encoding="utf-8") as f: - return json.load(f) + try: + with open(PROGRESS_FILE, "r", encoding="utf-8") as f: + data = f.read().strip() + if not data: + return {"progress": {}, "completed": []} + return json.loads(data) + except Exception as e: + print(f"[Reader] Failed to load progress file: {e}") + return {"progress": {}, "completed": []} return {"progress": {}, "completed": []} @@ -81,7 +91,10 @@ async def read_books_forever(): await asyncio.sleep(READ_DELAY) set_next_action(READ_DELAY, "Reading") - print(f"[Reader] Finished reading {book}.") + print(f"[Reader] Finished reading {book}. Taking a break to dream...") + save_vocab(tokenizer.vocab) + save_brainmap() + await asyncio.sleep(120) # 💤 2 minute nap after each book completed_books.append(book) progress_data["completed"] = list(set(completed_books)) save_progress(progress_data)