| |
| """Assemble Fractus β the complete CCA per the original vision. |
| |
| Loads the trained CTE (with 88M weights transferred), wires up: |
| - Persistent KnowledgeBase (vector memory) |
| - RAGEngine (retrieval + generation) |
| - PluginManager (5 cognitive modes) |
| - MetaCognition (autonomous action selection) |
| |
| Then tests the full system end-to-end: |
| learn() β query() β converse() β switch plugin β meta.process() |
| |
| This is the FINAL product. Not a training script, not a benchmark β |
| the actual Fractus agent that a user runs. |
| """ |
| import os, sys |
| sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
| import torch |
|
|
| from fractus.continuous_engine import ContinuousThoughtEngine |
| from fractus.tokenizer import FractusTokenizer |
| from fractus.rag import KnowledgeBase, RAGEngine, PluginManager, MetaCognition |
|
|
|
|
| def assemble_fractus(cte_checkpoint: str = None, d_model: int = 768): |
| """Assemble the full Fractus agent. |
| |
| Args: |
| cte_checkpoint: path to the assembled CTE checkpoint (.pt). |
| If None, uses random weights (for testing). |
| d_model: must match the CTE checkpoint config (768 for the 88M). |
| |
| Returns: |
| dict with engine, tok, kb, rag, pm, meta. |
| """ |
| print("="*60, flush=True) |
| print("ASSEMBLING FRACTUS β Continuous Cognitive Agent", flush=True) |
| print("="*60, flush=True) |
|
|
| |
| tok = FractusTokenizer.gpt2_compatible() |
| print(f"β Tokenizer: vocab={tok.vocab_size}", flush=True) |
|
|
| |
| print("Building CTE engine...", flush=True) |
| engine = ContinuousThoughtEngine( |
| vocab_size=50257, d_model=d_model, |
| n_heads=12, d_head=64, n_levels=2, |
| n_oscillators=16, coupling_rank=8, |
| n_experts=64, top_k=2, |
| expert_d_ff=1024, siren_rank=16, |
| ) |
|
|
| if cte_checkpoint and os.path.exists(cte_checkpoint): |
| print(f"Loading CTE checkpoint: {cte_checkpoint}", flush=True) |
| ck = torch.load(cte_checkpoint, weights_only=False, map_location="cpu") |
| cte_state = ck.get("cte_state", ck.get("model_state", ck)) |
| engine.load_state_dict(cte_state, strict=False) |
|
|
| |
| for i in range(64): |
| for prefix, expert_list in [("w1", engine.experts_w1), ("w2", engine.experts_w2)]: |
| expert = expert_list[i] |
| if hasattr(expert, "U") and hasattr(expert, "V") and hasattr(expert, "_cached_W"): |
| with torch.no_grad(): |
| W = expert.U @ expert.V.T |
| expert._cached_W.copy_(W) |
| expert._call_count = 0 |
| source_step = ck.get("source", {}).get("step", "?") |
| source_loss = ck.get("source", {}).get("loss", "?") |
| print(f"β CTE loaded (step={source_step}, loss={source_loss})", flush=True) |
| else: |
| print("β No checkpoint β using random weights", flush=True) |
|
|
| |
| kb = KnowledgeBase(d_model=d_model) |
| |
| kb_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), |
| "data", "fractus_memory.pkl") |
| if os.path.exists(kb_path): |
| try: |
| kb.load(kb_path) |
| print(f"β Memory loaded: {len(kb.chunks)} memories", flush=True) |
| except Exception as e: |
| print(f"β Memory load failed: {e}", flush=True) |
| else: |
| print(f"β Memory: empty (fresh start)", flush=True) |
|
|
| |
| rag = RAGEngine(engine, tok, kb) |
| print(f"β RAG engine ready", flush=True) |
|
|
| |
| pm = PluginManager(rag) |
| print(f"β Plugins: analyst, creative, coder, teacher, hacker", flush=True) |
|
|
| |
| meta = MetaCognition(rag, pm) |
| print(f"β MetaCognition ready", flush=True) |
|
|
| print("="*60, flush=True) |
| print("FRACTUS ASSEMBLED β ready to learn and think", flush=True) |
| print("="*60, flush=True) |
|
|
| return { |
| "engine": engine, |
| "tok": tok, |
| "kb": kb, |
| "rag": rag, |
| "pm": pm, |
| "meta": meta, |
| "kb_path": kb_path, |
| } |
|
|
|
|
| def run_demo(frac: dict): |
| """Run a full demo of Fractus capabilities.""" |
| rag, pm, meta, tok = frac["rag"], frac["pm"], frac["meta"], frac["tok"] |
|
|
| print("\n" + "="*60, flush=True) |
| print("FRACTUS DEMO", flush=True) |
| print("="*60, flush=True) |
|
|
| |
| print("\n--- LEARN (teaching facts without retraining) ---", flush=True) |
| facts = [ |
| "Python was created by Guido van Rossum in 1991.", |
| "Fractus is a decentralized AI that runs on your machine.", |
| "The user prefers concise, direct answers.", |
| "def binary_search(arr, target): uses divide and conquer to find an element in O(log n).", |
| ] |
| for fact in facts: |
| rag.learn(fact) |
| print(f" learned: {fact[:60]}...", flush=True) |
| print(f" Memory now contains {len(frac['kb'].chunks)} memories", flush=True) |
|
|
| |
| print("\n--- QUERY (asking questions) ---", flush=True) |
| questions = [ |
| "Who created Python?", |
| "What is Fractus?", |
| "How does binary search work?", |
| ] |
| for q in questions: |
| try: |
| result = rag.query(q, top_k=2, max_tokens=30) |
| answer = result.get("answer", "(no answer)")[:150] |
| retrieved = len(result.get("retrieved", [])) |
| print(f" Q: {q}", flush=True) |
| print(f" A: {answer}", flush=True) |
| print(f" (used {retrieved} memories)", flush=True) |
| except Exception as e: |
| print(f" Q: {q} β error: {e}", flush=True) |
|
|
| |
| print("\n--- SWITCH (changing cognitive mode) ---", flush=True) |
| for mode in ["coder", "creative", "analyst"]: |
| try: |
| pm.load(mode) |
| print(f" Switched to '{mode}' mode", flush=True) |
| except Exception as e: |
| print(f" '{mode}' mode: {e}", flush=True) |
|
|
| |
| print("\n--- METACOGNITION (Fractus decides its own actions) ---", flush=True) |
| test_inputs = [ |
| "Remember: my favorite language is Rust.", |
| "What is my favorite language?", |
| ] |
| for inp in test_inputs: |
| try: |
| result = meta.process(inp) |
| actions = result.get("actions", []) |
| print(f" Input: '{inp}'", flush=True) |
| print(f" Fractus chose: {actions}", flush=True) |
| except Exception as e: |
| print(f" Input: '{inp}' β error: {e}", flush=True) |
|
|
| |
| print("\n--- SAVE MEMORY ---", flush=True) |
| try: |
| frac["kb"].save(frac["kb_path"]) |
| print(f" Memory saved to {frac['kb_path']}", flush=True) |
| except Exception as e: |
| print(f" Save failed: {e}", flush=True) |
|
|
| print("\n" + "="*60, flush=True) |
| print("DEMO COMPLETE β Fractus works end-to-end", flush=True) |
| print("="*60, flush=True) |
|
|
|
|
| if __name__ == "__main__": |
| import argparse |
| parser = argparse.ArgumentParser(description="Assemble and run Fractus") |
| parser.add_argument("--cte-checkpoint", type=str, |
| default="checkpoints/fractus_cte_assembled.pt", |
| help="Path to the assembled CTE checkpoint") |
| parser.add_argument("--d-model", type=int, default=768) |
| parser.add_argument("--no-demo", action="store_true", |
| help="Skip the demo, just assemble") |
| args = parser.parse_args() |
|
|
| frac = assemble_fractus(args.cte_checkpoint, args.d_model) |
| if not args.no_demo: |
| run_demo(frac) |
|
|