from flask import Flask, render_template import json import os import time import datetime import logging from model.brainmap import get_brainmap from model.journal import read_journal_entries from model.memory import load_dreams from model.tokenizer import Tokenizer from model.abstraction import cluster_vocab from model.memory import load_dreams from model.scheduler import get_time_until_next_action, get_next_action_label from context.context import load_context from reader.reader import get_books, load_progress app = Flask(__name__) tokenizer = Tokenizer() next_cycle_time = time.time() + 900 # Example: 15 minutes from now def load_loss_data(): path = "data/logs/loss.log" if not os.path.exists(path): return [] with open(path, "r", encoding="utf-8") as f: lines = f.readlines() return [float(line.strip().split(",")[1]) for line in lines[-50:]] def load_vocab_growth(): path = "data/logs/vocab_growth.log" if not os.path.exists(path): return [] with open(path, "r", encoding="utf-8") as f: lines = f.readlines() data = [] for line in lines: timestamp, vocab_size = line.strip().split(",") # Reformat timestamp to human-readable readable_time = datetime.datetime.fromtimestamp(float(timestamp)).strftime("%H:%M:%S") data.append((readable_time, int(vocab_size))) return data def get_vocab_size(): path = "data/memory/vocab.json" if not os.path.exists(path): return 0 with open(path, "r", encoding="utf-8") as f: vocab = json.load(f) return len(vocab) def update_next_cycle(seconds): global next_cycle_time next_cycle_time = time.time() + seconds @app.route("/") def index(): dreams = load_dreams() top_dreams = dreams[:5] memory_size = len(load_context()) loss_data = load_loss_data() progress = load_progress() books = get_books() current_book = books[0] if books else None current_line = progress.get(current_book, 0) next_cycle = get_time_until_next_action() next_action_label = get_next_action_label() return render_template("index.html", vocab_size=get_vocab_size(), top_dreams=top_dreams, memory_size=memory_size, loss_data=loss_data, current_book=current_book, current_line=current_line, next_cycle=next_cycle, next_action_label=next_action_label) @app.route("/growth") def growth(): brainmap_size = len(get_brainmap()) memory_size = len(load_context()) vocab_growth = load_vocab_growth() return render_template("growth.html", vocab_size=get_vocab_size(), brainmap_size=brainmap_size, memory_size=memory_size, vocab_growth=vocab_growth) @app.route("/brainmap") def brainmap(): map_data = get_brainmap() nodes = [] links = [] MIN_LINK_WEIGHT = 2 # only show links seen at least 2 times seen_words = set() for word, connections in map_data.items(): for linked_word, weight in connections.items(): if weight >= MIN_LINK_WEIGHT: links.append({ "source": word, "target": linked_word, "value": weight }) seen_words.add(word) seen_words.add(linked_word) for word in seen_words: nodes.append({"id": word}) return render_template("brainmap.html", nodes=json.dumps(nodes), links=json.dumps(links)) @app.route("/journal") def journal(): entries = read_journal_entries() return render_template("journal.html", entries=entries) @app.route("/concepts") def concepts(): clusters = cluster_vocab(n_clusters=10) return render_template("concepts.html", clusters={i: cluster for i, cluster in enumerate(clusters)}) @app.route("/dreams") def dreams(): dreams = load_dreams() recent = dreams[-20:][::-1] # Last 20 dreams, newest first return render_template("dreams.html", dreams=recent) @app.route("/health") def health(): # Load vocab size vocab_size = get_vocab_size() # Load brainmap size brainmap_size = len(get_brainmap()) # Load dreams dreams = load_dreams() dream_count = len(dreams) last_dream = dreams[-1]["sentence"] if dreams else "No dreams yet." # Load journal try: with open("data/memory/journal.json", "r", encoding="utf-8") as f: journal_entries = json.load(f) except Exception: journal_entries = [] journal_count = len(journal_entries) last_journal = journal_entries[-1] if journal_entries else "No journal entries yet." # Load books books = get_books() book_count = len(books) progress = load_progress() books_finished = sum(1 for b in books if progress.get(b, 0) > 0) return render_template("health.html", vocab_size=vocab_size, brainmap_size=brainmap_size, book_count=book_count, books_finished=books_finished, dream_count=dream_count, journal_count=journal_count, last_dream=last_dream, last_journal=last_journal) def run_dashboard(): log = logging.getLogger('werkzeug') log.setLevel(logging.ERROR) app.run(host="0.0.0.0", port=5000, debug=False, use_reloader=False)