Download space/app.py from thefinalboss/fractus-cte: direct link, hf CLI and curl.
- Browser
- Download file 10.7 kB
-
https://huggingface.co/thefinalboss/fractus-cte/resolve/8e46f2cf53e63440225486f98e83043aec096172/space/app.py
- Command line
-
hf download hf://thefinalboss/fractus-cte@8e46f2cf53e63440225486f98e83043aec096172/space/app.py
-
curl -L -o app.py https://huggingface.co/thefinalboss/fractus-cte/resolve/8e46f2cf53e63440225486f98e83043aec096172/space/app.py
10.7 kB
| """Fractus Space — shared-memory AI backend. | |
| This FastAPI app powers the Fractus HuggingFace Space: a single Fractus | |
| instance with a SHARED knowledge base that persists across all users and | |
| sessions. Every user's input is stored, retrieved, and remembered by the | |
| next user — proving Fractus's continuous learning and persistent memory. | |
| Architecture: | |
| - Fractus model (Fractus-1B trained weights → CTE runtime) | |
| - SharedKnowledgeBase: ONE global KB across all HTTP sessions | |
| - Basic keyword moderation before storing (blocks toxic content) | |
| - FastAPI: POST /chat, GET /memories, GET /stats | |
| """ | |
| import os | |
| import sys | |
| import time | |
| import re | |
| import threading | |
| from typing import Optional | |
| # Path to the Fractus package (sibling of the space). | |
| FRACTUS_PATH = os.environ.get("FRACTUS_PATH", "/workspace/fractus") | |
| sys.path.insert(0, FRACTUS_PATH) | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.responses import HTMLResponse, JSONResponse | |
| from fastapi.staticfiles import StaticFiles | |
| from pydantic import BaseModel | |
| # --- Fractus imports (lazy — model loads on first request) --- | |
| _engine = None | |
| _kb = None | |
| _lock = threading.Lock() | |
| def get_engine(): | |
| """Lazy-load Fractus engine + shared KB. Loads ONCE, shared across requests.""" | |
| global _engine, _kb | |
| with _lock: | |
| if _engine is None: | |
| from fractus.continuous_engine import ContinuousThoughtEngine | |
| from fractus.tokenizer import FractusTokenizer | |
| from fractus.rag import KnowledgeBase, RAGEngine | |
| from fractus.memory import PersistentMemory | |
| tok = FractusTokenizer.gpt2_compatible() | |
| engine = ContinuousThoughtEngine( | |
| vocab_size=50257, d_model=128, | |
| n_heads=4, d_head=32, n_levels=2, | |
| n_oscillators=16, n_experts=8, top_k=2, | |
| ) | |
| # Load trained weights from HF if a checkpoint is provided. | |
| ckpt_path = os.environ.get("FRACTUS_CHECKPOINT") | |
| if ckpt_path and os.path.exists(ckpt_path): | |
| import torch | |
| print(f"[Fractus] Loading checkpoint: {ckpt_path}", flush=True) | |
| sd = torch.load(ckpt_path, weights_only=False, map_location="cpu") | |
| # Best-effort load — the CTE and Fractus-1B don't share exact | |
| # parameter names, but layers with matching shapes will load. | |
| engine.load_state_dict(sd.get("model_state", sd), strict=False) | |
| print(f"[Fractus] Checkpoint loaded (strict=False)", flush=True) | |
| else: | |
| print("[Fractus] WARNING: no checkpoint — using random weights", flush=True) | |
| kb = KnowledgeBase(d_model=128) | |
| # Load persisted KB if it exists (resumes memory across restarts). | |
| kb_path = os.environ.get("FRACTUS_KB_PATH", "/data/fractus_kb.pkl") | |
| if os.path.exists(kb_path): | |
| try: | |
| kb.load(kb_path) | |
| print(f"[Fractus] Loaded shared KB: {len(kb.texts)} memories", flush=True) | |
| except Exception as e: | |
| print(f"[Fractus] KB load failed: {e}", flush=True) | |
| rag = RAGEngine(engine, tok, kb) | |
| # --- PersistentMemory: thought-state cross-session memory (the "subconscious") --- | |
| # Attached to the CTE. Salience head bias forced high so the engine | |
| # consolidates most thoughts (untrained — we want visible memory for the demo). | |
| import torch as _torch | |
| with _torch.no_grad(): | |
| engine.salience_head.bias.fill_(3.0) # sigmoid(3) ≈ 0.95 → consolidates most thoughts | |
| pm_path = os.environ.get("FRACTUS_PM_PATH", "/data/fractus_pm.pt") | |
| pm = PersistentMemory(d_model=128, max_memories=256, path=pm_path) | |
| if os.path.exists(pm_path): | |
| try: | |
| pm.load(pm_path) | |
| print(f"[Fractus] Loaded PersistentMemory: {len(pm)} memories", flush=True) | |
| except Exception as e: | |
| print(f"[Fractus] PM load failed: {e}", flush=True) | |
| engine.attach_memory(pm) | |
| print(f"[Fractus] PersistentMemory attached (salience bias=3.0, blend=0.05)", flush=True) | |
| _engine = {"engine": engine, "tok": tok, "kb": kb, "rag": rag, "pm": pm} | |
| return _engine | |
| # ============================================================================ | |
| # Moderation: basic keyword filter to keep the shared KB safe-ish. | |
| # ============================================================================ | |
| # Crude but effective: blocks obvious toxic content from being stored. | |
| # This is NOT a sophisticated moderation system — just a safety net so the | |
| # Space doesn't get taken down in 2 hours. | |
| _BLOCKED_KEYWORDS = [ | |
| # Hate speech / slurs (censored here, expanded at runtime) | |
| "nigger", "faggot", "tranny", "kike", "spic", "chink", "retard", | |
| # Self-harm / violence instructions | |
| "kill yourself", "how to make a bomb", "suicide method", | |
| # CSAM-adjacent | |
| "child porn", "cp ", "loli", "shota", "underage nude", | |
| # Doxxing patterns (very basic) | |
| "social security number", "credit card number", | |
| ] | |
| _BLOCKED_RE = re.compile( | |
| r"\b(" + "|".join(re.escape(k) for k in _BLOCKED_KEYWORDS) + r")\b", | |
| re.IGNORECASE, | |
| ) | |
| def moderate(text: str) -> tuple: | |
| """Returns (is_blocked, reason). Basic keyword filter only.""" | |
| if not text or len(text.strip()) < 1: | |
| return True, "empty" | |
| if len(text) > 2000: | |
| return True, "too_long" | |
| m = _BLOCKED_RE.search(text) | |
| if m: | |
| return True, f"blocked_keyword:{m.group(1)[:20]}" | |
| return False, "" | |
| def save_kb_async(): | |
| """Persist the KB + PM in a background thread (don't block the response).""" | |
| def _save(): | |
| try: | |
| e = get_engine() | |
| kb_path = os.environ.get("FRACTUS_KB_PATH", "/data/fractus_kb.pkl") | |
| os.makedirs(os.path.dirname(kb_path) or ".", exist_ok=True) | |
| e["kb"].save(kb_path) | |
| # Also persist the PersistentMemory (thought-state memories). | |
| pm_path = os.environ.get("FRACTUS_PM_PATH", "/data/fractus_pm.pt") | |
| os.makedirs(os.path.dirname(pm_path) or ".", exist_ok=True) | |
| e["pm"].save(pm_path) | |
| except Exception as ex: | |
| print(f"[Fractus] KB/PM save failed: {ex}", flush=True) | |
| threading.Thread(target=_save, daemon=True).start() | |
| # ============================================================================ | |
| # FastAPI app | |
| # ============================================================================ | |
| app = FastAPI(title="Fractus Space") | |
| # Serve the static frontend. | |
| HERE = os.path.dirname(os.path.abspath(__file__)) | |
| STATIC_DIR = os.path.join(HERE, "static") | |
| if os.path.isdir(STATIC_DIR): | |
| app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") | |
| class ChatRequest(BaseModel): | |
| message: str | |
| speaker: Optional[str] = "anonymous" | |
| class ChatResponse(BaseModel): | |
| reply: str | |
| memories_used: int | |
| stored: bool | |
| moderation: Optional[str] = None | |
| async def index(): | |
| """Serve the main chat UI.""" | |
| index_path = os.path.join(STATIC_DIR, "index.html") | |
| if os.path.exists(index_path): | |
| return HTMLResponse(content=open(index_path, encoding="utf-8").read()) | |
| return HTMLResponse("<h1>Fractus Space</h1><p>static/index.html missing</p>") | |
| async def chat(req: ChatRequest): | |
| """Main endpoint: user message → Fractus reply, with shared memory.""" | |
| # 1. Moderate the input BEFORE storing. | |
| blocked, reason = moderate(req.message) | |
| if blocked: | |
| return ChatResponse( | |
| reply="(Fractus declined to store this message — moderation filter.)", | |
| memories_used=0, stored=False, moderation=reason, | |
| ) | |
| try: | |
| e = get_engine() | |
| except Exception as ex: | |
| raise HTTPException(500, f"Fractus failed to start: {ex}") | |
| # 2. Retrieve relevant memories + generate a reply (also learns the input). | |
| try: | |
| result = e["rag"].converse(req.message, speaker=req.speaker) | |
| reply = result.get("response", "(Fractus stayed silent.)") | |
| memories_used = len(result.get("retrieved", [])) | |
| stored = True | |
| # Persist the KB in background. | |
| save_kb_async() | |
| except Exception as ex: | |
| return ChatResponse( | |
| reply=f"(Fractus encountered an error: {ex})", | |
| memories_used=0, stored=False, moderation="runtime_error", | |
| ) | |
| return ChatResponse( | |
| reply=reply, | |
| memories_used=memories_used, | |
| stored=stored, | |
| ) | |
| async def memories(limit: int = 20): | |
| """Show the most recent shared memories (transparency feature).""" | |
| try: | |
| e = get_engine() | |
| kb = e["kb"] | |
| recent = list(zip(kb.texts[-limit:], kb.sources[-limit:] if kb.sources else ["?"]*limit)) | |
| return {"count": len(kb.texts), "recent": [{"text": t[:200], "source": s} for t, s in reversed(recent)]} | |
| except Exception as ex: | |
| return {"error": str(ex), "count": 0, "recent": []} | |
| async def pmemories(limit: int = 20): | |
| """Show the PersistentMemory's thought-state memories (the 'subconscious').""" | |
| try: | |
| e = get_engine() | |
| pm = e["pm"] | |
| n = len(pm) | |
| # Return recent context labels + importance. | |
| recent = [] | |
| ctxs = pm.contexts[-limit:] if pm.contexts else [] | |
| imps = pm.importance[-limit:] if pm.importance else [] | |
| for i in range(min(len(ctxs), limit)): | |
| recent.append({"context": ctxs[i][:200] if ctxs[i] else "(unlabeled)", | |
| "importance": round(imps[i], 3) if i < len(imps) else 0.5}) | |
| return {"count": n, "max": pm.max_memories, "recent": list(reversed(recent))} | |
| except Exception as ex: | |
| return {"error": str(ex), "count": 0, "recent": []} | |
| async def stats(): | |
| """Live stats for the UI.""" | |
| try: | |
| e = get_engine() | |
| return { | |
| "memories": len(e["kb"].texts), | |
| "pmemories": len(e["pm"]), | |
| "engine": "Fractus-CTE", | |
| "status": "online", | |
| } | |
| except Exception: | |
| return {"memories": 0, "engine": "Fractus-CTE", "status": "starting"} | |
| async def health(): | |
| return {"status": "ok", "time": time.time()} | |