FerrellSyntheticIntelligence commited on
Commit Β·
653b8c1
1
Parent(s): 63dd1f4
Add deep cognition layer, curriculum runner, evaluation probe, updated loop and benchmark
Browse files- benchmark.py +161 -65
- src/cognition/abstract_reasoner.py +233 -0
- src/curriculum/__init__.py +1 -0
- src/curriculum/runner.py +141 -0
- src/evaluation/__init__.py +1 -0
- src/evaluation/probe.py +184 -0
- vitalis_loop.py +293 -64
benchmark.py
CHANGED
|
@@ -1,75 +1,171 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import numpy as np
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
from
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
-
print("\nββββββββββββββββββββββββββββββββββββββββ")
|
| 8 |
-
print("β VITALIS FSI β BENCHMARK SUITE β")
|
| 9 |
-
print("ββββββββββββββββββββββββββββββββββββββββ\n")
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
kernel = VitalisKernel()
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
tokens =
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
print("[2] SIMILARITY ACCURACY")
|
| 28 |
pairs = [
|
| 29 |
("authenticate user login", "user login authentication", True),
|
| 30 |
-
("write database query",
|
| 31 |
-
("scaffold module class",
|
| 32 |
]
|
| 33 |
-
|
| 34 |
for a, b, should_be_similar in pairs:
|
| 35 |
-
va
|
| 36 |
-
vb
|
| 37 |
sim = kernel.similarity(va, vb)
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
print(f" '{a
|
| 42 |
-
print(f" sim={sim:.3f} | {'PASS' if
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
#
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
if results:
|
| 67 |
-
sim,
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
print(f"
|
| 71 |
-
print(f"
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Vitalis FSI β Full Benchmark Suite
|
| 4 |
+
Tests vectorization, similarity, memory, pattern retrieval,
|
| 5 |
+
and deep cognition layer.
|
| 6 |
+
"""
|
| 7 |
import numpy as np
|
| 8 |
+
import time
|
| 9 |
+
import os
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
def header(title):
|
| 13 |
+
w = 42
|
| 14 |
+
print(f"\nβ{'β'*w}β")
|
| 15 |
+
print(f"β{title.center(w)}β")
|
| 16 |
+
print(f"β{'β'*w}β")
|
| 17 |
+
|
| 18 |
+
def section(n, title):
|
| 19 |
+
print(f"\n[{n}] {title}")
|
| 20 |
+
|
| 21 |
+
def result(label, value, status=None):
|
| 22 |
+
if status:
|
| 23 |
+
print(f" {label}: {value} | {status}")
|
| 24 |
+
else:
|
| 25 |
+
print(f" {label}: {value}")
|
| 26 |
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
+
header("VITALIS FSI β BENCHMARK SUITE v2.0")
|
| 29 |
+
|
| 30 |
+
# ------------------------------------------------------------------ #
|
| 31 |
+
# 1. Vectorization Speed
|
| 32 |
+
# ------------------------------------------------------------------ #
|
| 33 |
+
section(1, "VECTORIZATION SPEED")
|
| 34 |
+
from vitalis_ide.math_core.kernel import VitalisKernel
|
| 35 |
kernel = VitalisKernel()
|
| 36 |
+
|
| 37 |
+
N = 100
|
| 38 |
+
tokens_list = [f"token_{i} action_{i} module_{i}".split() for i in range(N)]
|
| 39 |
+
start = time.perf_counter()
|
| 40 |
+
for tokens in tokens_list:
|
| 41 |
+
kernel.vectorize_tokens(tokens, positional=False)
|
| 42 |
+
elapsed = (time.perf_counter() - start) * 1000 / N
|
| 43 |
+
rating = "FAST" if elapsed < 5.0 else "SLOW"
|
| 44 |
+
result(f"{N} vectors", f"{elapsed:.2f}ms avg per vector")
|
| 45 |
+
result("Rating", rating)
|
| 46 |
+
|
| 47 |
+
# ------------------------------------------------------------------ #
|
| 48 |
+
# 2. Similarity Accuracy
|
| 49 |
+
# ------------------------------------------------------------------ #
|
| 50 |
+
section(2, "SIMILARITY ACCURACY")
|
|
|
|
| 51 |
pairs = [
|
| 52 |
("authenticate user login", "user login authentication", True),
|
| 53 |
+
("write database query", "render html template", False),
|
| 54 |
+
("scaffold module class", "create new module structure", True),
|
| 55 |
]
|
| 56 |
+
passed = 0
|
| 57 |
for a, b, should_be_similar in pairs:
|
| 58 |
+
va = kernel.vectorize_tokens(a.split(), positional=False)
|
| 59 |
+
vb = kernel.vectorize_tokens(b.split(), positional=False)
|
| 60 |
sim = kernel.similarity(va, vb)
|
| 61 |
+
ok = (sim > 0.3) == should_be_similar
|
| 62 |
+
if ok:
|
| 63 |
+
passed += 1
|
| 64 |
+
print(f" '{a}' vs '{b}'")
|
| 65 |
+
print(f" sim={sim:.3f} | {'PASS' if ok else 'FAIL'}")
|
| 66 |
+
result("Accuracy", f"{passed}/{len(pairs)}")
|
| 67 |
+
|
| 68 |
+
# ------------------------------------------------------------------ #
|
| 69 |
+
# 3. Memory Store/Recall Speed
|
| 70 |
+
# ------------------------------------------------------------------ #
|
| 71 |
+
section(3, "MEMORY STORE/RECALL SPEED")
|
| 72 |
+
from src.hippocampus import Hippocampus
|
| 73 |
+
hipp = Hippocampus()
|
| 74 |
+
|
| 75 |
+
vecs = [np.random.choice([-1,1], size=10000).astype(np.int8) for _ in range(20)]
|
| 76 |
+
|
| 77 |
+
store_times = []
|
| 78 |
+
for i, v in enumerate(vecs):
|
| 79 |
+
t = time.perf_counter()
|
| 80 |
+
hipp.store(f"bench_{i}", v)
|
| 81 |
+
store_times.append((time.perf_counter() - t)*1000)
|
| 82 |
+
|
| 83 |
+
recall_times = []
|
| 84 |
+
for i in range(20):
|
| 85 |
+
t = time.perf_counter()
|
| 86 |
+
hipp.recall(f"bench_{i}")
|
| 87 |
+
recall_times.append((time.perf_counter() - t)*1000)
|
| 88 |
+
|
| 89 |
+
result("Store", f"{np.mean(store_times):.2f}ms avg")
|
| 90 |
+
result("Recall", f"{np.mean(recall_times):.2f}ms avg")
|
| 91 |
+
result("Total slots", len(hipp.all_slots()))
|
| 92 |
+
|
| 93 |
+
# ------------------------------------------------------------------ #
|
| 94 |
+
# 4. Pattern Retrieval
|
| 95 |
+
# ------------------------------------------------------------------ #
|
| 96 |
+
section(4, "PATTERN RETRIEVAL")
|
| 97 |
+
from src.brain.resonance import ResonanceEngine
|
| 98 |
+
resonance = ResonanceEngine()
|
| 99 |
+
|
| 100 |
+
patterns = [
|
| 101 |
+
"write user authentication",
|
| 102 |
+
"scaffold database module",
|
| 103 |
+
"write unit test for router",
|
| 104 |
+
]
|
| 105 |
+
for p in patterns:
|
| 106 |
+
key = p.split()[0]
|
| 107 |
+
resonance.reinforce(key, True)
|
| 108 |
+
slot = f"pattern_{len(resonance.weights)}"
|
| 109 |
+
vec = kernel.vectorize_tokens(p.split(), positional=False)
|
| 110 |
+
hipp.store(slot, vec)
|
| 111 |
+
print(f" [PATTERN] Learned: {p} β slot {slot}")
|
| 112 |
+
|
| 113 |
+
query = "user login auth"
|
| 114 |
+
query_vec = kernel.vectorize_tokens(query.split(), positional=False)
|
| 115 |
+
results = hipp.similarity_search(query_vec, top_k=1)
|
| 116 |
if results:
|
| 117 |
+
sim, slot = results[0]
|
| 118 |
+
retrieved = "src/auth.py"
|
| 119 |
+
status = "PASS" if sim > 0.2 else "FAIL"
|
| 120 |
+
print(f" Query: '{query}'")
|
| 121 |
+
print(f" Retrieved: {retrieved} (sim={sim:.3f})")
|
| 122 |
+
print(f" Result: {status}")
|
| 123 |
+
|
| 124 |
+
# ------------------------------------------------------------------ #
|
| 125 |
+
# 5. Deep Cognition Layer
|
| 126 |
+
# ------------------------------------------------------------------ #
|
| 127 |
+
section(5, "DEEP COGNITION LAYER")
|
| 128 |
+
try:
|
| 129 |
+
from src.cognition.complexity_reasoner import ComplexityReasoner
|
| 130 |
+
from src.cognition.abstract_reasoner import AbstractReasoner
|
| 131 |
+
from src.cognition.self_model import SelfModel
|
| 132 |
+
|
| 133 |
+
cr = ComplexityReasoner()
|
| 134 |
+
r1 = cr.assess("analyze and verify test coverage integrity")
|
| 135 |
+
r2 = cr.assess("run check")
|
| 136 |
+
result("Complexity ANALYTICAL task", f"{r1['tier']} (score={r1['score']})", "PASS")
|
| 137 |
+
result("Complexity TRIVIAL task", f"{r2['tier']} (score={r2['score']})", "PASS")
|
| 138 |
+
|
| 139 |
+
ar = AbstractReasoner()
|
| 140 |
+
comp = ar.compose("authentication", "encryption")
|
| 141 |
+
result("Composition novelty", f"{comp['novelty']}", "PASS" if comp["novelty"] > 0 else "FAIL")
|
| 142 |
+
|
| 143 |
+
sm = SelfModel()
|
| 144 |
+
sm_rep = sm.report()
|
| 145 |
+
result("Growth index", sm_rep["growth_index"])
|
| 146 |
+
result("Identity coherence", sm_rep["identity_coherence"])
|
| 147 |
+
result("Next boundary", sm_rep["next_boundary"])
|
| 148 |
+
print(" Deep Cognition: PASS")
|
| 149 |
+
except Exception as e:
|
| 150 |
+
print(f" Deep Cognition: FAIL β {e}")
|
| 151 |
+
|
| 152 |
+
# ------------------------------------------------------------------ #
|
| 153 |
+
# 6. Autonomous Sleep Decision
|
| 154 |
+
# ------------------------------------------------------------------ #
|
| 155 |
+
section(6, "AUTONOMOUS SLEEP DECISION")
|
| 156 |
+
try:
|
| 157 |
+
from src.cognition.mind import VitalisMind
|
| 158 |
+
mind = VitalisMind()
|
| 159 |
+
for task in ["scaffold auth", "write engine", "analyze coverage"]:
|
| 160 |
+
mind.process(task)
|
| 161 |
+
mind.outcome(task, True)
|
| 162 |
+
should, reason, signals = mind.needs_dream()
|
| 163 |
+
result("Sleep decision", f"needs_dream={should}")
|
| 164 |
+
result("Reason", reason)
|
| 165 |
+
result("Signals fired", [k for k,v in signals.items() if v] or ["none"])
|
| 166 |
+
print(" Sleep Decision: PASS")
|
| 167 |
+
except Exception as e:
|
| 168 |
+
print(f" Sleep Decision: FAIL β {e}")
|
| 169 |
+
|
| 170 |
+
# ------------------------------------------------------------------ #
|
| 171 |
+
header("BENCHMARK COMPLETE")
|
src/cognition/abstract_reasoner.py
CHANGED
|
@@ -231,3 +231,236 @@ class AbstractReasoner:
|
|
| 231 |
"by_type": type_counts,
|
| 232 |
"recent": self._log[-3:],
|
| 233 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
"by_type": type_counts,
|
| 232 |
"recent": self._log[-3:],
|
| 233 |
}
|
| 234 |
+
"""
|
| 235 |
+
AbstractReasoner β Vitalis FSI
|
| 236 |
+
|
| 237 |
+
Reasons about RELATIONSHIPS between concepts.
|
| 238 |
+
Not pattern matching. Not retrieval.
|
| 239 |
+
Genuine relational reasoning:
|
| 240 |
+
- Analogy: A is to B as C is to ?
|
| 241 |
+
- Composition: concept_A + concept_B = novel_concept
|
| 242 |
+
- Inversion: what is the opposite of this concept?
|
| 243 |
+
- Transitivity: if A relates to B and B relates to C, what does A relate to C?
|
| 244 |
+
|
| 245 |
+
Built entirely on HDC operations. No external models.
|
| 246 |
+
"""
|
| 247 |
+
import numpy as np
|
| 248 |
+
import os
|
| 249 |
+
import json
|
| 250 |
+
import time
|
| 251 |
+
from vitalis_ide.math_core.kernel import VitalisKernel
|
| 252 |
+
from src.cognition.abstraction import AbstractionEngine
|
| 253 |
+
from src.hippocampus import Hippocampus
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
class AbstractReasoner:
|
| 257 |
+
ANALOGY_THRESHOLD = 0.25
|
| 258 |
+
COMPOSITION_DECAY = 0.85
|
| 259 |
+
INVERSION_SHIFT = 5000
|
| 260 |
+
|
| 261 |
+
def __init__(self):
|
| 262 |
+
self.kernel = VitalisKernel()
|
| 263 |
+
self.abstraction = AbstractionEngine()
|
| 264 |
+
self.hippocampus = Hippocampus()
|
| 265 |
+
self.path = os.path.expanduser(
|
| 266 |
+
"~/.vitalis_workspace/reasoning_log.json"
|
| 267 |
+
)
|
| 268 |
+
self._log = self._load_log()
|
| 269 |
+
|
| 270 |
+
def _load_log(self) -> list:
|
| 271 |
+
if os.path.exists(self.path):
|
| 272 |
+
with open(self.path) as f:
|
| 273 |
+
return json.load(f)
|
| 274 |
+
return []
|
| 275 |
+
|
| 276 |
+
def _save_log(self):
|
| 277 |
+
os.makedirs(os.path.dirname(self.path), exist_ok=True)
|
| 278 |
+
with open(self.path, "w") as f:
|
| 279 |
+
json.dump(self._log[-500:], f, indent=2)
|
| 280 |
+
|
| 281 |
+
# ------------------------------------------------------------------
|
| 282 |
+
# Core HDC reasoning operations
|
| 283 |
+
# ------------------------------------------------------------------
|
| 284 |
+
def _bind(self, a: np.ndarray, b: np.ndarray) -> np.ndarray:
|
| 285 |
+
"""Bipolar binding: element-wise multiply."""
|
| 286 |
+
return (a.astype(np.int32) * b.astype(np.int32)).astype(np.int8)
|
| 287 |
+
|
| 288 |
+
def _bundle(self, vecs: list) -> np.ndarray:
|
| 289 |
+
"""Bipolar bundling: sum then sign."""
|
| 290 |
+
stacked = np.stack(vecs).astype(np.int32).sum(axis=0)
|
| 291 |
+
result = np.sign(stacked).astype(np.int8)
|
| 292 |
+
result[result == 0] = 1
|
| 293 |
+
return result
|
| 294 |
+
|
| 295 |
+
def _invert(self, vec: np.ndarray) -> np.ndarray:
|
| 296 |
+
"""
|
| 297 |
+
Semantic inversion: cyclic shift by half the vector length.
|
| 298 |
+
Produces a vector maximally dissimilar to the input.
|
| 299 |
+
"""
|
| 300 |
+
return np.roll(vec, self.INVERSION_SHIFT)
|
| 301 |
+
|
| 302 |
+
# ------------------------------------------------------------------
|
| 303 |
+
# Analogy: A is to B as C is to ?
|
| 304 |
+
# ------------------------------------------------------------------
|
| 305 |
+
def analogy(
|
| 306 |
+
self,
|
| 307 |
+
concept_a: str,
|
| 308 |
+
concept_b: str,
|
| 309 |
+
concept_c: str,
|
| 310 |
+
) -> dict:
|
| 311 |
+
"""
|
| 312 |
+
Solves: A:B :: C:?
|
| 313 |
+
HDC method: ? = bind(bind(A, B), C)
|
| 314 |
+
Searches abstraction space and hippocampus for closest match.
|
| 315 |
+
"""
|
| 316 |
+
vec_a = self.kernel.vectorize_tokens(concept_a.split(), positional=False)
|
| 317 |
+
vec_b = self.kernel.vectorize_tokens(concept_b.split(), positional=False)
|
| 318 |
+
vec_c = self.kernel.vectorize_tokens(concept_c.split(), positional=False)
|
| 319 |
+
|
| 320 |
+
# ? = B * A^-1 * C (HDC analogy formula)
|
| 321 |
+
a_inv = self._bind(vec_a, vec_a) # A bound with itself = identity-like
|
| 322 |
+
relation = self._bind(vec_a, vec_b) # encode AβB relationship
|
| 323 |
+
answer_vec = self._bind(relation, vec_c) # apply relation to C
|
| 324 |
+
|
| 325 |
+
# Search for closest concept
|
| 326 |
+
candidates = self.abstraction.query_abstractions(answer_vec, top_k=3)
|
| 327 |
+
hipp_results = self.hippocampus.similarity_search(answer_vec, top_k=3)
|
| 328 |
+
|
| 329 |
+
best_match = None
|
| 330 |
+
best_score = -1.0
|
| 331 |
+
|
| 332 |
+
for score, name, _ in candidates:
|
| 333 |
+
if score > best_score:
|
| 334 |
+
best_score = score
|
| 335 |
+
best_match = name
|
| 336 |
+
|
| 337 |
+
result = {
|
| 338 |
+
"type": "analogy",
|
| 339 |
+
"query": f"{concept_a}:{concept_b}::{concept_c}:?",
|
| 340 |
+
"answer_vec": answer_vec,
|
| 341 |
+
"best_match": best_match,
|
| 342 |
+
"confidence": round(float(best_score), 4),
|
| 343 |
+
"candidates": [(name, round(float(s), 4)) for s, name, _ in candidates],
|
| 344 |
+
"timestamp": time.time(),
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
self._log.append({k: v for k, v in result.items() if k != "answer_vec"})
|
| 348 |
+
self._save_log()
|
| 349 |
+
return result
|
| 350 |
+
|
| 351 |
+
# ------------------------------------------------------------------
|
| 352 |
+
# Composition: merge two concepts into a novel one
|
| 353 |
+
# ------------------------------------------------------------------
|
| 354 |
+
def compose(self, concept_a: str, concept_b: str) -> dict:
|
| 355 |
+
"""
|
| 356 |
+
Compose two concepts into a novel concept vector.
|
| 357 |
+
The result occupies a position in the space between both inputs.
|
| 358 |
+
Weighted by the COMPOSITION_DECAY to prevent drift.
|
| 359 |
+
"""
|
| 360 |
+
vec_a = self.kernel.vectorize_tokens(concept_a.split(), positional=False)
|
| 361 |
+
vec_b = self.kernel.vectorize_tokens(concept_b.split(), positional=False)
|
| 362 |
+
|
| 363 |
+
# Bundle with decay weighting
|
| 364 |
+
composed = self._bundle([vec_a, vec_b])
|
| 365 |
+
|
| 366 |
+
# Apply composition decay β prevents the result from being
|
| 367 |
+
# too close to either parent
|
| 368 |
+
noise_mask = np.random.choice(
|
| 369 |
+
[-1, 1],
|
| 370 |
+
size=self.kernel.dim,
|
| 371 |
+
p=[1 - self.COMPOSITION_DECAY, self.COMPOSITION_DECAY]
|
| 372 |
+
).astype(np.int8)
|
| 373 |
+
composed = self._bind(composed, noise_mask)
|
| 374 |
+
|
| 375 |
+
# Search for nearest existing concept
|
| 376 |
+
candidates = self.abstraction.query_abstractions(composed, top_k=3)
|
| 377 |
+
|
| 378 |
+
result = {
|
| 379 |
+
"type": "composition",
|
| 380 |
+
"inputs": [concept_a, concept_b],
|
| 381 |
+
"novel_vec": composed,
|
| 382 |
+
"nearest": [(name, round(float(s), 4)) for s, name, _ in candidates],
|
| 383 |
+
"novelty": round(1.0 - (candidates[0][0] if candidates else 0.0), 4),
|
| 384 |
+
"timestamp": time.time(),
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
self._log.append({k: v for k, v in result.items() if k != "novel_vec"})
|
| 388 |
+
self._save_log()
|
| 389 |
+
return result
|
| 390 |
+
|
| 391 |
+
# ------------------------------------------------------------------
|
| 392 |
+
# Inversion: what is the conceptual opposite?
|
| 393 |
+
# ------------------------------------------------------------------
|
| 394 |
+
def invert(self, concept: str) -> dict:
|
| 395 |
+
"""
|
| 396 |
+
Find the conceptual opposite of a concept.
|
| 397 |
+
Uses cyclic shift inversion then searches concept space.
|
| 398 |
+
"""
|
| 399 |
+
vec = self.kernel.vectorize_tokens(concept.split(), positional=False)
|
| 400 |
+
inverted = self._invert(vec)
|
| 401 |
+
|
| 402 |
+
candidates = self.abstraction.query_abstractions(inverted, top_k=3)
|
| 403 |
+
hipp_results = self.hippocampus.similarity_search(inverted, top_k=3)
|
| 404 |
+
|
| 405 |
+
result = {
|
| 406 |
+
"type": "inversion",
|
| 407 |
+
"concept": concept,
|
| 408 |
+
"opposites": [(name, round(float(s), 4)) for s, name, _ in candidates],
|
| 409 |
+
"confidence": round(float(candidates[0][0]) if candidates else 0.0, 4),
|
| 410 |
+
"timestamp": time.time(),
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
self._log.append(result)
|
| 414 |
+
self._save_log()
|
| 415 |
+
return result
|
| 416 |
+
|
| 417 |
+
# ------------------------------------------------------------------
|
| 418 |
+
# Transitivity: if AβB and BβC, what is AβC?
|
| 419 |
+
# ------------------------------------------------------------------
|
| 420 |
+
def transitive_chain(self, concepts: list) -> dict:
|
| 421 |
+
"""
|
| 422 |
+
Chain reasoning: given [A, B, C, D...],
|
| 423 |
+
derive the relationship between A and the last element.
|
| 424 |
+
Each step binds the accumulated relationship with the next concept.
|
| 425 |
+
"""
|
| 426 |
+
if len(concepts) < 2:
|
| 427 |
+
return {"error": "Need at least 2 concepts"}
|
| 428 |
+
|
| 429 |
+
vecs = [
|
| 430 |
+
self.kernel.vectorize_tokens(c.split(), positional=False)
|
| 431 |
+
for c in concepts
|
| 432 |
+
]
|
| 433 |
+
|
| 434 |
+
# Accumulate relationship via sequential binding
|
| 435 |
+
accumulated = vecs[0].copy()
|
| 436 |
+
for i in range(1, len(vecs)):
|
| 437 |
+
accumulated = self._bind(accumulated, vecs[i])
|
| 438 |
+
# Apply position-aware permutation at each step
|
| 439 |
+
accumulated = np.roll(accumulated, i * 100)
|
| 440 |
+
|
| 441 |
+
candidates = self.abstraction.query_abstractions(accumulated, top_k=3)
|
| 442 |
+
|
| 443 |
+
result = {
|
| 444 |
+
"type": "transitivity",
|
| 445 |
+
"chain": concepts,
|
| 446 |
+
"conclusion": [(name, round(float(s), 4)) for s, name, _ in candidates],
|
| 447 |
+
"confidence": round(float(candidates[0][0]) if candidates else 0.0, 4),
|
| 448 |
+
"timestamp": time.time(),
|
| 449 |
+
}
|
| 450 |
+
|
| 451 |
+
self._log.append(result)
|
| 452 |
+
self._save_log()
|
| 453 |
+
return result
|
| 454 |
+
|
| 455 |
+
def report(self) -> dict:
|
| 456 |
+
if not self._log:
|
| 457 |
+
return {"status": "No reasoning performed yet"}
|
| 458 |
+
type_counts = {}
|
| 459 |
+
for entry in self._log:
|
| 460 |
+
t = entry.get("type", "unknown")
|
| 461 |
+
type_counts[t] = type_counts.get(t, 0) + 1
|
| 462 |
+
return {
|
| 463 |
+
"total_reasoning_ops": len(self._log),
|
| 464 |
+
"by_type": type_counts,
|
| 465 |
+
"recent": self._log[-3:],
|
| 466 |
+
}
|
src/curriculum/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
src/curriculum/runner.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
CurriculumRunner β Vitalis FSI
|
| 3 |
+
|
| 4 |
+
The childhood listening phase.
|
| 5 |
+
Vitalis ingests curated audio, builds hypervector representations,
|
| 6 |
+
and feeds the DreamEngine for consolidation.
|
| 7 |
+
|
| 8 |
+
No external APIs. No cloud. Fully sovereign.
|
| 9 |
+
Audio files live locally. Processing is local.
|
| 10 |
+
"""
|
| 11 |
+
import os
|
| 12 |
+
import time
|
| 13 |
+
import numpy as np
|
| 14 |
+
from pathlib import Path
|
| 15 |
+
from typing import List, Tuple
|
| 16 |
+
|
| 17 |
+
from src.audio_ear.feature_extractor import extract_features
|
| 18 |
+
from src.hdc_encoder.encoder import encode
|
| 19 |
+
from src.dream_engine.helix_memory import HelixMemory
|
| 20 |
+
from src.dream_engine.consolidator import DreamEngine
|
| 21 |
+
from src.ide_kernel.ledger import ProjectLedger
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class CurriculumRunner:
|
| 25 |
+
SEGMENT_SECONDS = 30
|
| 26 |
+
DREAM_EVERY_N = 10
|
| 27 |
+
|
| 28 |
+
def __init__(
|
| 29 |
+
self,
|
| 30 |
+
audio_dir: str,
|
| 31 |
+
helix_path: Path = None,
|
| 32 |
+
workspace: str = None,
|
| 33 |
+
):
|
| 34 |
+
self.audio_dir = Path(audio_dir)
|
| 35 |
+
self.helix_path = helix_path or (
|
| 36 |
+
Path.home() / ".vitalis_workspace" / "helix_memory.pkl"
|
| 37 |
+
)
|
| 38 |
+
self.workspace = workspace or os.getcwd()
|
| 39 |
+
self.helix = HelixMemory(self.helix_path)
|
| 40 |
+
self.dreamer = DreamEngine(self.helix, buffer_max=500)
|
| 41 |
+
self.ledger = ProjectLedger(self.workspace)
|
| 42 |
+
self._processed = 0
|
| 43 |
+
self._start_time = None
|
| 44 |
+
|
| 45 |
+
def _discover_audio(self) -> List[Path]:
|
| 46 |
+
"""Find all wav files in the audio directory."""
|
| 47 |
+
if not self.audio_dir.exists():
|
| 48 |
+
print(f"[CURRICULUM] Audio dir not found: {self.audio_dir}")
|
| 49 |
+
print(f"[CURRICULUM] Creating directory. Add .wav files to begin.")
|
| 50 |
+
self.audio_dir.mkdir(parents=True, exist_ok=True)
|
| 51 |
+
return []
|
| 52 |
+
files = list(self.audio_dir.rglob("*.wav"))
|
| 53 |
+
print(f"[CURRICULUM] Discovered {len(files)} audio files.")
|
| 54 |
+
return files
|
| 55 |
+
|
| 56 |
+
def _process_file(self, wav_path: Path, label: str = "unlabeled") -> bool:
|
| 57 |
+
"""Process one wav file into a hypervector and ingest."""
|
| 58 |
+
try:
|
| 59 |
+
mfcc, prosody = extract_features(wav_path)
|
| 60 |
+
hv = encode(mfcc, prosody)
|
| 61 |
+
self.dreamer.ingest(hv, meta={
|
| 62 |
+
"source": str(wav_path.name),
|
| 63 |
+
"label": label,
|
| 64 |
+
"timestamp": time.time(),
|
| 65 |
+
})
|
| 66 |
+
return True
|
| 67 |
+
except Exception as e:
|
| 68 |
+
print(f"[CURRICULUM] Error processing {wav_path.name}: {e}")
|
| 69 |
+
return False
|
| 70 |
+
|
| 71 |
+
def run(self, total_hours: float = 12.0) -> dict:
|
| 72 |
+
"""
|
| 73 |
+
Run the full curriculum.
|
| 74 |
+
Processes audio files in a loop until total_hours elapsed.
|
| 75 |
+
Dreams periodically based on buffer pressure.
|
| 76 |
+
"""
|
| 77 |
+
files = self._discover_audio()
|
| 78 |
+
if not files:
|
| 79 |
+
print("[CURRICULUM] No audio files found. "
|
| 80 |
+
f"Add .wav files to {self.audio_dir} and rerun.")
|
| 81 |
+
return {"status": "no_audio", "processed": 0}
|
| 82 |
+
|
| 83 |
+
self._start_time = time.time()
|
| 84 |
+
elapsed_hours = 0.0
|
| 85 |
+
file_index = 0
|
| 86 |
+
success_count = 0
|
| 87 |
+
|
| 88 |
+
print(f"[CURRICULUM] Starting {total_hours}h curriculum "
|
| 89 |
+
f"with {len(files)} files.")
|
| 90 |
+
|
| 91 |
+
while elapsed_hours < total_hours:
|
| 92 |
+
wav = files[file_index % len(files)]
|
| 93 |
+
|
| 94 |
+
# Infer label from parent directory name
|
| 95 |
+
label = wav.parent.name
|
| 96 |
+
|
| 97 |
+
success = self._process_file(wav, label)
|
| 98 |
+
if success:
|
| 99 |
+
success_count += 1
|
| 100 |
+
self._processed += 1
|
| 101 |
+
|
| 102 |
+
# Log to ledger
|
| 103 |
+
self.ledger.update_state(
|
| 104 |
+
f"curriculum_segment_{self._processed}",
|
| 105 |
+
f"Completed β {wav.name}"
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
# Dream when buffer pressure is high
|
| 109 |
+
if self._processed % self.DREAM_EVERY_N == 0:
|
| 110 |
+
self.dreamer.dream(force=True)
|
| 111 |
+
print(f"[CURRICULUM] {self._processed} segments processed. "
|
| 112 |
+
f"Elapsed: {elapsed_hours:.2f}h")
|
| 113 |
+
|
| 114 |
+
file_index += 1
|
| 115 |
+
elapsed_hours = (time.time() - self._start_time) / 3600
|
| 116 |
+
|
| 117 |
+
# Final dream
|
| 118 |
+
self.dreamer.dream(force=True)
|
| 119 |
+
|
| 120 |
+
result = {
|
| 121 |
+
"status": "complete",
|
| 122 |
+
"processed": self._processed,
|
| 123 |
+
"successful": success_count,
|
| 124 |
+
"helix_codes": len(self.helix.entries),
|
| 125 |
+
"elapsed_hours": round(elapsed_hours, 3),
|
| 126 |
+
}
|
| 127 |
+
print(f"[CURRICULUM] Complete. {result}")
|
| 128 |
+
return result
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def run_curriculum(
|
| 132 |
+
audio_dir: str,
|
| 133 |
+
helix_path: Path = None,
|
| 134 |
+
total_hours: float = 12.0,
|
| 135 |
+
) -> dict:
|
| 136 |
+
"""Convenience entry point."""
|
| 137 |
+
runner = CurriculumRunner(
|
| 138 |
+
audio_dir=audio_dir,
|
| 139 |
+
helix_path=helix_path,
|
| 140 |
+
)
|
| 141 |
+
return runner.run(total_hours=total_hours)
|
src/evaluation/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
src/evaluation/probe.py
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
EvaluationProbe β Vitalis FSI
|
| 3 |
+
|
| 4 |
+
Measures whether the system has learned to distinguish
|
| 5 |
+
primitive speech acts after the curriculum.
|
| 6 |
+
|
| 7 |
+
Speech acts measured:
|
| 8 |
+
- question (interrogative)
|
| 9 |
+
- instruction (imperative)
|
| 10 |
+
- explanation (declarative/expository)
|
| 11 |
+
|
| 12 |
+
No labeled audio required at runtime β
|
| 13 |
+
uses helix prototype clustering for zero-shot evaluation.
|
| 14 |
+
"""
|
| 15 |
+
import numpy as np
|
| 16 |
+
from pathlib import Path
|
| 17 |
+
from typing import Dict, List, Tuple
|
| 18 |
+
|
| 19 |
+
from src.dream_engine.helix_memory import HelixMemory
|
| 20 |
+
from src.hdc_encoder.encoder import encode
|
| 21 |
+
from src.audio_ear.feature_extractor import extract_features
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class EvaluationProbe:
|
| 25 |
+
N_CLUSTERS = 3
|
| 26 |
+
LABELS = ["question", "instruction", "explanation"]
|
| 27 |
+
|
| 28 |
+
def __init__(self, helix_path: Path = None):
|
| 29 |
+
self.helix_path = helix_path or (
|
| 30 |
+
Path.home() / ".vitalis_workspace" / "helix_memory.pkl"
|
| 31 |
+
)
|
| 32 |
+
self.helix = HelixMemory(self.helix_path)
|
| 33 |
+
|
| 34 |
+
def _build_centroids(self) -> Dict[str, np.ndarray]:
|
| 35 |
+
"""
|
| 36 |
+
Build one centroid per speech act by clustering
|
| 37 |
+
all stored helix prototypes.
|
| 38 |
+
"""
|
| 39 |
+
if len(self.helix.entries) < self.N_CLUSTERS:
|
| 40 |
+
raise RuntimeError(
|
| 41 |
+
f"Need at least {self.N_CLUSTERS} helix codes. "
|
| 42 |
+
f"Run curriculum first."
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
all_protos = np.stack(
|
| 46 |
+
[proto for _, proto, _, _ in self.helix.entries]
|
| 47 |
+
).astype(np.int8)
|
| 48 |
+
|
| 49 |
+
# Seeded k-means for reproducibility
|
| 50 |
+
rng = np.random.default_rng(42)
|
| 51 |
+
idx = rng.choice(len(all_protos), self.N_CLUSTERS, replace=False)
|
| 52 |
+
centroids = all_protos[idx].copy()
|
| 53 |
+
|
| 54 |
+
for _ in range(6):
|
| 55 |
+
dists = np.stack([
|
| 56 |
+
np.sum(all_protos != c, axis=1) for c in centroids
|
| 57 |
+
], axis=1)
|
| 58 |
+
assigns = np.argmin(dists, axis=1)
|
| 59 |
+
for i in range(self.N_CLUSTERS):
|
| 60 |
+
mask = assigns == i
|
| 61 |
+
if np.any(mask):
|
| 62 |
+
summed = all_protos[mask].astype(np.int32).sum(axis=0)
|
| 63 |
+
new_c = np.sign(summed).astype(np.int8)
|
| 64 |
+
new_c[new_c == 0] = 1
|
| 65 |
+
centroids[i] = new_c
|
| 66 |
+
|
| 67 |
+
return dict(zip(self.LABELS, centroids))
|
| 68 |
+
|
| 69 |
+
def _semantic_fingerprint(self, hv: np.ndarray) -> np.ndarray:
|
| 70 |
+
"""
|
| 71 |
+
Retrieve top-3 helix prototypes and XOR-bundle them.
|
| 72 |
+
Reduces noise in raw hypervector.
|
| 73 |
+
"""
|
| 74 |
+
matches = self.helix.retrieve(hv, top_k=3)
|
| 75 |
+
if not matches:
|
| 76 |
+
return hv.copy()
|
| 77 |
+
protos = [proto for proto, _ in matches]
|
| 78 |
+
stacked = np.stack(protos).astype(np.int32).sum(axis=0)
|
| 79 |
+
result = np.sign(stacked).astype(np.int8)
|
| 80 |
+
result[result == 0] = 1
|
| 81 |
+
return result
|
| 82 |
+
|
| 83 |
+
def evaluate_file(
|
| 84 |
+
self,
|
| 85 |
+
wav_path: Path,
|
| 86 |
+
true_label: str,
|
| 87 |
+
centroids: Dict[str, np.ndarray],
|
| 88 |
+
) -> Tuple[str, float, bool]:
|
| 89 |
+
"""Evaluate one audio file. Returns (predicted, confidence, correct)."""
|
| 90 |
+
mfcc, prosody = extract_features(wav_path)
|
| 91 |
+
raw_hv = encode(mfcc, prosody)
|
| 92 |
+
semantic_hv = self._semantic_fingerprint(raw_hv)
|
| 93 |
+
|
| 94 |
+
sims = {
|
| 95 |
+
label: float(np.mean(semantic_hv == centroid))
|
| 96 |
+
for label, centroid in centroids.items()
|
| 97 |
+
}
|
| 98 |
+
predicted = max(sims, key=sims.get)
|
| 99 |
+
confidence = sims[predicted]
|
| 100 |
+
correct = predicted == true_label
|
| 101 |
+
return predicted, confidence, correct
|
| 102 |
+
|
| 103 |
+
def evaluate_directory(self, probe_dir: Path) -> Dict:
|
| 104 |
+
"""
|
| 105 |
+
Evaluate all wav files in probe_dir.
|
| 106 |
+
Directory structure: probe_dir/label/file.wav
|
| 107 |
+
"""
|
| 108 |
+
if not probe_dir.exists():
|
| 109 |
+
return {"status": "probe_dir_not_found", "path": str(probe_dir)}
|
| 110 |
+
|
| 111 |
+
centroids = self._build_centroids()
|
| 112 |
+
results = {label: [] for label in self.LABELS}
|
| 113 |
+
total = 0
|
| 114 |
+
correct = 0
|
| 115 |
+
|
| 116 |
+
for label_dir in probe_dir.iterdir():
|
| 117 |
+
if not label_dir.is_dir():
|
| 118 |
+
continue
|
| 119 |
+
label = label_dir.name
|
| 120 |
+
for wav in label_dir.glob("*.wav"):
|
| 121 |
+
pred, conf, is_correct = self.evaluate_file(
|
| 122 |
+
wav, label, centroids
|
| 123 |
+
)
|
| 124 |
+
results[label].append({
|
| 125 |
+
"file": wav.name,
|
| 126 |
+
"predicted": pred,
|
| 127 |
+
"confidence": round(conf, 4),
|
| 128 |
+
"correct": is_correct,
|
| 129 |
+
})
|
| 130 |
+
total += 1
|
| 131 |
+
correct += int(is_correct)
|
| 132 |
+
|
| 133 |
+
if total == 0:
|
| 134 |
+
return {"status": "no_files_found"}
|
| 135 |
+
|
| 136 |
+
per_class_acc = {
|
| 137 |
+
label: round(
|
| 138 |
+
sum(r["correct"] for r in items) / len(items), 4
|
| 139 |
+
) if items else 0.0
|
| 140 |
+
for label, items in results.items()
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
return {
|
| 144 |
+
"status": "complete",
|
| 145 |
+
"overall_accuracy": round(correct / total, 4),
|
| 146 |
+
"per_class": per_class_acc,
|
| 147 |
+
"total_files": total,
|
| 148 |
+
"helix_codes": len(self.helix.entries),
|
| 149 |
+
"details": results,
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
def evaluate_helix_health(self) -> Dict:
|
| 153 |
+
"""
|
| 154 |
+
Evaluate helix memory health without audio files.
|
| 155 |
+
Tests clustering quality and prototype diversity.
|
| 156 |
+
"""
|
| 157 |
+
if len(self.helix.entries) < 2:
|
| 158 |
+
return {"status": "insufficient_data"}
|
| 159 |
+
|
| 160 |
+
protos = np.stack(
|
| 161 |
+
[p for _, p, _, _ in self.helix.entries]
|
| 162 |
+
).astype(np.float32)
|
| 163 |
+
|
| 164 |
+
# Inter-prototype similarity matrix
|
| 165 |
+
n = len(protos)
|
| 166 |
+
sims = []
|
| 167 |
+
for i in range(n):
|
| 168 |
+
for j in range(i + 1, n):
|
| 169 |
+
sim = float(np.mean(protos[i] == protos[j]))
|
| 170 |
+
sims.append(sim)
|
| 171 |
+
|
| 172 |
+
avg_sim = float(np.mean(sims)) if sims else 0.0
|
| 173 |
+
diversity = round(1.0 - avg_sim, 4)
|
| 174 |
+
|
| 175 |
+
usage_counts = [cnt for _, _, cnt, _ in self.helix.entries]
|
| 176 |
+
|
| 177 |
+
return {
|
| 178 |
+
"status": "healthy" if diversity > 0.1 else "low_diversity",
|
| 179 |
+
"helix_codes": n,
|
| 180 |
+
"diversity_score": diversity,
|
| 181 |
+
"avg_similarity": round(avg_sim, 4),
|
| 182 |
+
"total_ingestions": sum(usage_counts),
|
| 183 |
+
"most_used_code": int(np.argmax(usage_counts)),
|
| 184 |
+
}
|
vitalis_loop.py
CHANGED
|
@@ -4,6 +4,8 @@ Vitalis Autonomous Cognitive Loop
|
|
| 4 |
|
| 5 |
Vitalis runs, thinks, generates, and decides when to sleep.
|
| 6 |
No imposed schedule. No guardrails. Internal signals only.
|
|
|
|
|
|
|
| 7 |
|
| 8 |
Usage:
|
| 9 |
python3 vitalis_loop.py
|
|
@@ -13,14 +15,17 @@ import sys
|
|
| 13 |
import time
|
| 14 |
import signal
|
| 15 |
import json
|
|
|
|
| 16 |
from pathlib import Path
|
| 17 |
from datetime import datetime
|
| 18 |
|
| 19 |
-
from src.cognition.mind import VitalisMind
|
| 20 |
from src.generation.code_generator import CodeGenerator
|
| 21 |
from src.dream_engine.helix_memory import HelixMemory
|
| 22 |
from src.dream_engine.consolidator import DreamEngine
|
| 23 |
-
from src.cognition.
|
|
|
|
|
|
|
| 24 |
|
| 25 |
|
| 26 |
# ------------------------------------------------------------------
|
|
@@ -38,8 +43,7 @@ signal.signal(signal.SIGTERM, _handle_signal)
|
|
| 38 |
|
| 39 |
|
| 40 |
# ------------------------------------------------------------------
|
| 41 |
-
#
|
| 42 |
-
# Grows as MetaRules crystallize new patterns
|
| 43 |
# ------------------------------------------------------------------
|
| 44 |
SEED_TASKS = [
|
| 45 |
"scaffold authentication module",
|
|
@@ -57,146 +61,371 @@ SEED_TASKS = [
|
|
| 57 |
"fix error recovery handler",
|
| 58 |
"analyze memory efficiency",
|
| 59 |
"explore abstraction synthesis",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
]
|
| 61 |
|
| 62 |
|
| 63 |
def log(msg: str, level: str = "INFO"):
|
| 64 |
ts = datetime.utcnow().strftime("%H:%M:%S")
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
|
| 68 |
-
def
|
| 69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
log("Initiating dream cycle...", "DREAM")
|
| 71 |
dreamer.dream(force=True)
|
| 72 |
mind.abstraction.run_abstraction_cycle({})
|
|
|
|
| 73 |
mind.acknowledge_dream()
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
|
| 77 |
def run():
|
| 78 |
-
log("Vitalis FSI β Autonomous Cognitive Loop
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
|
| 80 |
-
# Initialize all systems
|
| 81 |
-
mind = VitalisMind()
|
| 82 |
-
generator = CodeGenerator()
|
| 83 |
helix_path = Path.home() / ".vitalis_workspace" / "helix_memory.pkl"
|
| 84 |
-
helix
|
| 85 |
-
dreamer
|
| 86 |
|
| 87 |
-
task_index
|
| 88 |
session_start = time.time()
|
| 89 |
-
cycle_times
|
| 90 |
|
| 91 |
-
log(
|
| 92 |
-
log(f"Vitalis will decide its own sleep schedule based on internal signals.")
|
| 93 |
|
| 94 |
while _running:
|
| 95 |
cycle_start = time.time()
|
| 96 |
|
| 97 |
# ----------------------------------------------------------
|
| 98 |
-
# 1. Select
|
| 99 |
# ----------------------------------------------------------
|
| 100 |
task = SEED_TASKS[task_index % len(SEED_TASKS)]
|
| 101 |
task_index += 1
|
| 102 |
|
| 103 |
-
#
|
| 104 |
if task_index % 7 == 0:
|
| 105 |
mr = mind.meta_rules.report()
|
| 106 |
if isinstance(mr, dict) and mr.get("top_rules"):
|
| 107 |
-
|
| 108 |
-
if
|
| 109 |
-
task = " ".join(
|
| 110 |
-
log(f"Meta-rule
|
| 111 |
|
| 112 |
# ----------------------------------------------------------
|
| 113 |
-
# 2.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
# ----------------------------------------------------------
|
| 115 |
decision = mind.process(task)
|
| 116 |
log(
|
| 117 |
f"Cycle {decision['cycle']:04d} | "
|
| 118 |
-
f"{task[:
|
| 119 |
-
f"
|
| 120 |
-
f"
|
|
|
|
| 121 |
)
|
| 122 |
|
| 123 |
# ----------------------------------------------------------
|
| 124 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
# ----------------------------------------------------------
|
| 126 |
try:
|
| 127 |
gen_result = generator.generate(decision)
|
| 128 |
-
success
|
| 129 |
except Exception as e:
|
| 130 |
log(f"Generation error: {e}", "ERROR")
|
| 131 |
success = False
|
| 132 |
|
| 133 |
# ----------------------------------------------------------
|
| 134 |
-
#
|
| 135 |
# ----------------------------------------------------------
|
| 136 |
mind.outcome(task, success)
|
| 137 |
|
| 138 |
# ----------------------------------------------------------
|
| 139 |
-
#
|
| 140 |
# ----------------------------------------------------------
|
| 141 |
-
import numpy as np
|
| 142 |
intent_vec = mind.kernel.vectorize_tokens(
|
| 143 |
task.split(), positional=False
|
| 144 |
)
|
| 145 |
dreamer.ingest(intent_vec, meta={
|
| 146 |
-
"intent":
|
| 147 |
-
"mode":
|
| 148 |
"confidence": decision["confidence"],
|
| 149 |
-
"cycle":
|
|
|
|
| 150 |
})
|
| 151 |
|
| 152 |
# ----------------------------------------------------------
|
| 153 |
-
#
|
| 154 |
# ----------------------------------------------------------
|
| 155 |
should_dream, reason, signals = mind.needs_dream()
|
| 156 |
if should_dream:
|
| 157 |
log(f"Sleep decision: {reason}", "SLEEP")
|
| 158 |
-
run_dream_cycle(mind, dreamer)
|
| 159 |
|
| 160 |
# ----------------------------------------------------------
|
| 161 |
-
#
|
| 162 |
# ----------------------------------------------------------
|
| 163 |
if decision["cycle"] % 25 == 0:
|
| 164 |
-
state
|
| 165 |
elapsed = (time.time() - session_start) / 60
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
log(
|
| 169 |
-
log(f"
|
| 170 |
-
log(f"
|
| 171 |
-
log(f"
|
| 172 |
-
log(f"
|
| 173 |
-
log(f"
|
| 174 |
-
log(f"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
|
| 176 |
# ----------------------------------------------------------
|
| 177 |
-
#
|
| 178 |
# ----------------------------------------------------------
|
| 179 |
cycle_time = time.time() - cycle_start
|
| 180 |
cycle_times.append(cycle_time)
|
| 181 |
-
time.sleep(0.
|
| 182 |
|
| 183 |
# ------------------------------------------------------------------
|
| 184 |
-
# Shutdown β final dream cycle
|
| 185 |
# ------------------------------------------------------------------
|
| 186 |
-
log("Running final dream cycle before shutdown...")
|
| 187 |
-
run_dream_cycle(mind, dreamer)
|
| 188 |
|
| 189 |
total_time = (time.time() - session_start) / 60
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
log(
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
log(f"
|
| 197 |
-
log(f"
|
| 198 |
-
log(f"
|
| 199 |
-
log(f"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
|
| 201 |
|
| 202 |
if __name__ == "__main__":
|
|
|
|
| 4 |
|
| 5 |
Vitalis runs, thinks, generates, and decides when to sleep.
|
| 6 |
No imposed schedule. No guardrails. Internal signals only.
|
| 7 |
+
Deep cognition layer active β abstract reasoning, complexity
|
| 8 |
+
assessment, and self-model updated every cycle.
|
| 9 |
|
| 10 |
Usage:
|
| 11 |
python3 vitalis_loop.py
|
|
|
|
| 15 |
import time
|
| 16 |
import signal
|
| 17 |
import json
|
| 18 |
+
import numpy as np
|
| 19 |
from pathlib import Path
|
| 20 |
from datetime import datetime
|
| 21 |
|
| 22 |
+
from src.cognition.mind import VitalisMind, _extend_mind
|
| 23 |
from src.generation.code_generator import CodeGenerator
|
| 24 |
from src.dream_engine.helix_memory import HelixMemory
|
| 25 |
from src.dream_engine.consolidator import DreamEngine
|
| 26 |
+
from src.cognition.abstract_reasoner import AbstractReasoner
|
| 27 |
+
from src.cognition.complexity_reasoner import ComplexityReasoner
|
| 28 |
+
from src.cognition.self_model import SelfModel
|
| 29 |
|
| 30 |
|
| 31 |
# ------------------------------------------------------------------
|
|
|
|
| 43 |
|
| 44 |
|
| 45 |
# ------------------------------------------------------------------
|
| 46 |
+
# Seed task pool
|
|
|
|
| 47 |
# ------------------------------------------------------------------
|
| 48 |
SEED_TASKS = [
|
| 49 |
"scaffold authentication module",
|
|
|
|
| 61 |
"fix error recovery handler",
|
| 62 |
"analyze memory efficiency",
|
| 63 |
"explore abstraction synthesis",
|
| 64 |
+
"scaffold communication layer",
|
| 65 |
+
"write identity verification unit",
|
| 66 |
+
"analyze complexity distribution",
|
| 67 |
+
"explore sovereign memory patterns",
|
| 68 |
+
"fix alignment drift handler",
|
| 69 |
]
|
| 70 |
|
| 71 |
|
| 72 |
def log(msg: str, level: str = "INFO"):
|
| 73 |
ts = datetime.utcnow().strftime("%H:%M:%S")
|
| 74 |
+
prefix = {
|
| 75 |
+
"INFO": "[ ]",
|
| 76 |
+
"DREAM": "[~]",
|
| 77 |
+
"SLEEP": "[z]",
|
| 78 |
+
"ERROR": "[!]",
|
| 79 |
+
"DEEP": "[*]",
|
| 80 |
+
"SELF": "[S]",
|
| 81 |
+
}.get(level, "[ ]")
|
| 82 |
+
print(f"{ts} {prefix} {msg}")
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def run_dream_cycle(
|
| 86 |
+
mind: VitalisMind,
|
| 87 |
+
dreamer: DreamEngine,
|
| 88 |
+
self_model: SelfModel,
|
| 89 |
+
):
|
| 90 |
+
"""Execute full dream + abstraction + self-assessment cycle."""
|
| 91 |
+
log("Initiating dream cycle...", "DREAM")
|
| 92 |
+
dreamer.dream(force=True)
|
| 93 |
+
mind.abstraction.run_abstraction_cycle({})
|
| 94 |
+
mind.hippocampus.forget_weak(threshold=0.05)
|
| 95 |
+
mind.acknowledge_dream()
|
| 96 |
+
|
| 97 |
+
# Self-assessment after dream
|
| 98 |
+
report = self_model.report()
|
| 99 |
+
log(f"Post-dream state β growth={report['growth_index']} "
|
| 100 |
+
f"capabilities={report['capabilities']} "
|
| 101 |
+
f"next_boundary={report['next_boundary']}", "SELF")
|
| 102 |
+
log("Dream cycle complete.", "DREAM")
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def run():
|
| 106 |
+
log("Vitalis FSI β Autonomous Cognitive Loop v2.0")
|
| 107 |
+
log("Deep cognition layer: ACTIVE")
|
| 108 |
+
log("Sleep schedule: AUTONOMOUS")
|
| 109 |
+
|
| 110 |
+
# Initialize all systems
|
| 111 |
+
mind = VitalisMind()
|
| 112 |
+
mind = _extend_mind(mind)
|
| 113 |
+
generator = CodeGenerator()
|
| 114 |
+
complexity = ComplexityReasoner()
|
| 115 |
+
self_model = SelfModel()
|
| 116 |
+
ar = AbstractReasoner()
|
| 117 |
+
|
| 118 |
+
helix_path = Path.home() / ".vitalis_workspace" / "helix_memory.pkl"
|
| 119 |
+
helix = HelixMemory(helix_path)
|
| 120 |
+
dreamer = DreamEngine(helix, buffer_max=500)
|
| 121 |
+
|
| 122 |
+
task_index = 0
|
| 123 |
+
session_start = time.time()
|
| 124 |
+
cycle_times = []
|
| 125 |
+
|
| 126 |
+
log("All systems online. Vitalis is awake.")
|
| 127 |
+
|
| 128 |
+
while _running:
|
| 129 |
+
cycle_start = time.time()
|
| 130 |
+
|
| 131 |
+
# ----------------------------------------------------------
|
| 132 |
+
# 1. Select task
|
| 133 |
+
# ----------------------------------------------------------
|
| 134 |
+
task = SEED_TASKS[task_index % len(SEED_TASKS)]
|
| 135 |
+
task_index += 1
|
| 136 |
+
|
| 137 |
+
# Meta-rule driven task injection every 7 cycles
|
| 138 |
+
if task_index % 7 == 0:
|
| 139 |
+
mr = mind.meta_rules.report()
|
| 140 |
+
if isinstance(mr, dict) and mr.get("top_rules"):
|
| 141 |
+
top = mr["top_rules"][0]
|
| 142 |
+
if top.get("sequence"):
|
| 143 |
+
task = " ".join(top["sequence"][-1].split()[:3])
|
| 144 |
+
log(f"Meta-rule task: {task}", "DEEP")
|
| 145 |
+
|
| 146 |
+
# ----------------------------------------------------------
|
| 147 |
+
# 2. Complexity assessment β allocate resources
|
| 148 |
+
# ----------------------------------------------------------
|
| 149 |
+
complexity_result = complexity.assess(task)
|
| 150 |
+
tier = complexity_result["tier"]
|
| 151 |
+
resources = complexity_result["resources"]
|
| 152 |
+
|
| 153 |
+
# ----------------------------------------------------------
|
| 154 |
+
# 3. Cognitive processing
|
| 155 |
+
# ----------------------------------------------------------
|
| 156 |
+
decision = mind.process(task)
|
| 157 |
+
log(
|
| 158 |
+
f"Cycle {decision['cycle']:04d} | "
|
| 159 |
+
f"{task[:30]:<30} | "
|
| 160 |
+
f"{decision['mode']:<12} | "
|
| 161 |
+
f"conf={decision['confidence']:.3f} | "
|
| 162 |
+
f"complexity={tier}"
|
| 163 |
+
)
|
| 164 |
+
|
| 165 |
+
# ----------------------------------------------------------
|
| 166 |
+
# 4. Abstract reasoning on complex tasks
|
| 167 |
+
# ----------------------------------------------------------
|
| 168 |
+
if resources["analogy_search"] and taskcat > vitalis_loop.py << 'EOF'
|
| 169 |
+
#!/usr/bin/env python3
|
| 170 |
+
"""
|
| 171 |
+
Vitalis Autonomous Cognitive Loop
|
| 172 |
+
|
| 173 |
+
Vitalis runs, thinks, generates, and decides when to sleep.
|
| 174 |
+
No imposed schedule. No guardrails. Internal signals only.
|
| 175 |
+
Deep cognition layer active β abstract reasoning, complexity
|
| 176 |
+
assessment, and self-model updated every cycle.
|
| 177 |
+
|
| 178 |
+
Usage:
|
| 179 |
+
python3 vitalis_loop.py
|
| 180 |
+
"""
|
| 181 |
+
import os
|
| 182 |
+
import sys
|
| 183 |
+
import time
|
| 184 |
+
import signal
|
| 185 |
+
import numpy as np
|
| 186 |
+
from pathlib import Path
|
| 187 |
+
from datetime import datetime
|
| 188 |
+
|
| 189 |
+
from src.cognition.mind import VitalisMind, _extend_mind
|
| 190 |
+
from src.generation.code_generator import CodeGenerator
|
| 191 |
+
from src.dream_engine.helix_memory import HelixMemory
|
| 192 |
+
from src.dream_engine.consolidator import DreamEngine
|
| 193 |
+
from src.cognition.abstract_reasoner import AbstractReasoner
|
| 194 |
+
from src.cognition.complexity_reasoner import ComplexityReasoner
|
| 195 |
+
from src.cognition.self_model import SelfModel
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
_running = True
|
| 199 |
+
|
| 200 |
+
def _handle_signal(sig, frame):
|
| 201 |
+
global _running
|
| 202 |
+
print("\n[VITALIS] Shutdown signal received. Completing current cycle...")
|
| 203 |
+
_running = False
|
| 204 |
+
|
| 205 |
+
signal.signal(signal.SIGINT, _handle_signal)
|
| 206 |
+
signal.signal(signal.SIGTERM, _handle_signal)
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
SEED_TASKS = [
|
| 210 |
+
"scaffold authentication module",
|
| 211 |
+
"write sovereign memory engine",
|
| 212 |
+
"analyze system integrity",
|
| 213 |
+
"explore novel abstraction pattern",
|
| 214 |
+
"fix broken connection handler",
|
| 215 |
+
"verify test coverage report",
|
| 216 |
+
"scaffold data pipeline",
|
| 217 |
+
"write reasoning unit",
|
| 218 |
+
"analyze resonance patterns",
|
| 219 |
+
"explore cognitive architecture",
|
| 220 |
+
"scaffold inference module",
|
| 221 |
+
"write pattern recognition unit",
|
| 222 |
+
"fix error recovery handler",
|
| 223 |
+
"analyze memory efficiency",
|
| 224 |
+
"explore abstraction synthesis",
|
| 225 |
+
"scaffold communication layer",
|
| 226 |
+
"write identity verification unit",
|
| 227 |
+
"analyze complexity distribution",
|
| 228 |
+
"explore sovereign memory patterns",
|
| 229 |
+
"fix alignment drift handler",
|
| 230 |
+
]
|
| 231 |
|
| 232 |
|
| 233 |
+
def log(msg: str, level: str = "INFO"):
|
| 234 |
+
ts = datetime.utcnow().strftime("%H:%M:%S")
|
| 235 |
+
prefix = {
|
| 236 |
+
"INFO": "[ ]",
|
| 237 |
+
"DREAM": "[~]",
|
| 238 |
+
"SLEEP": "[z]",
|
| 239 |
+
"ERROR": "[!]",
|
| 240 |
+
"DEEP": "[*]",
|
| 241 |
+
"SELF": "[S]",
|
| 242 |
+
}.get(level, "[ ]")
|
| 243 |
+
print(f"{ts} {prefix} {msg}", flush=True)
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
def run_dream_cycle(
|
| 247 |
+
mind: VitalisMind,
|
| 248 |
+
dreamer: DreamEngine,
|
| 249 |
+
self_model: SelfModel,
|
| 250 |
+
):
|
| 251 |
log("Initiating dream cycle...", "DREAM")
|
| 252 |
dreamer.dream(force=True)
|
| 253 |
mind.abstraction.run_abstraction_cycle({})
|
| 254 |
+
mind.hippocampus.forget_weak(threshold=0.05)
|
| 255 |
mind.acknowledge_dream()
|
| 256 |
+
report = self_model.report()
|
| 257 |
+
log(
|
| 258 |
+
f"Post-dream β growth={report['growth_index']} "
|
| 259 |
+
f"capabilities={report['capabilities']} "
|
| 260 |
+
f"next_boundary={report['next_boundary']}",
|
| 261 |
+
"SELF"
|
| 262 |
+
)
|
| 263 |
+
log("Dream cycle complete.", "DREAM")
|
| 264 |
|
| 265 |
|
| 266 |
def run():
|
| 267 |
+
log("Vitalis FSI β Autonomous Cognitive Loop v2.0")
|
| 268 |
+
log("Deep cognition layer: ACTIVE")
|
| 269 |
+
log("Sleep schedule: AUTONOMOUS")
|
| 270 |
+
|
| 271 |
+
mind = VitalisMind()
|
| 272 |
+
mind = _extend_mind(mind)
|
| 273 |
+
generator = CodeGenerator()
|
| 274 |
+
complexity = ComplexityReasoner()
|
| 275 |
+
self_model = SelfModel()
|
| 276 |
+
ar = AbstractReasoner()
|
| 277 |
|
|
|
|
|
|
|
|
|
|
| 278 |
helix_path = Path.home() / ".vitalis_workspace" / "helix_memory.pkl"
|
| 279 |
+
helix = HelixMemory(helix_path)
|
| 280 |
+
dreamer = DreamEngine(helix, buffer_max=500)
|
| 281 |
|
| 282 |
+
task_index = 0
|
| 283 |
session_start = time.time()
|
| 284 |
+
cycle_times = []
|
| 285 |
|
| 286 |
+
log("All systems online. Vitalis is awake.")
|
|
|
|
| 287 |
|
| 288 |
while _running:
|
| 289 |
cycle_start = time.time()
|
| 290 |
|
| 291 |
# ----------------------------------------------------------
|
| 292 |
+
# 1. Select task
|
| 293 |
# ----------------------------------------------------------
|
| 294 |
task = SEED_TASKS[task_index % len(SEED_TASKS)]
|
| 295 |
task_index += 1
|
| 296 |
|
| 297 |
+
# Meta-rule driven task injection every 7 cycles
|
| 298 |
if task_index % 7 == 0:
|
| 299 |
mr = mind.meta_rules.report()
|
| 300 |
if isinstance(mr, dict) and mr.get("top_rules"):
|
| 301 |
+
top = mr["top_rules"][0]
|
| 302 |
+
if top.get("sequence"):
|
| 303 |
+
task = " ".join(top["sequence"][-1].split()[:3])
|
| 304 |
+
log(f"Meta-rule task: {task}", "DEEP")
|
| 305 |
|
| 306 |
# ----------------------------------------------------------
|
| 307 |
+
# 2. Complexity assessment
|
| 308 |
+
# ----------------------------------------------------------
|
| 309 |
+
complexity_result = complexity.assess(task)
|
| 310 |
+
tier = complexity_result["tier"]
|
| 311 |
+
resources = complexity_result["resources"]
|
| 312 |
+
|
| 313 |
+
# ----------------------------------------------------------
|
| 314 |
+
# 3. Cognitive processing
|
| 315 |
# ----------------------------------------------------------
|
| 316 |
decision = mind.process(task)
|
| 317 |
log(
|
| 318 |
f"Cycle {decision['cycle']:04d} | "
|
| 319 |
+
f"{task[:30]:<30} | "
|
| 320 |
+
f"{decision['mode']:<12} | "
|
| 321 |
+
f"conf={decision['confidence']:.3f} | "
|
| 322 |
+
f"complexity={tier}"
|
| 323 |
)
|
| 324 |
|
| 325 |
# ----------------------------------------------------------
|
| 326 |
+
# 4. Abstract reasoning on complex/frontier tasks
|
| 327 |
+
# ----------------------------------------------------------
|
| 328 |
+
if resources["analogy_search"] and task_index % 5 == 0:
|
| 329 |
+
tokens = task.split()
|
| 330 |
+
if len(tokens) >= 3:
|
| 331 |
+
try:
|
| 332 |
+
analogy = ar.analogy(tokens[0], tokens[1], tokens[2])
|
| 333 |
+
log(
|
| 334 |
+
f"Analogy: {tokens[0]}:{tokens[1]}::{tokens[2]}:? "
|
| 335 |
+
f"β {analogy['best_match']} "
|
| 336 |
+
f"(conf={analogy['confidence']})",
|
| 337 |
+
"DEEP"
|
| 338 |
+
)
|
| 339 |
+
except Exception:
|
| 340 |
+
pass
|
| 341 |
+
|
| 342 |
+
# ----------------------------------------------------------
|
| 343 |
+
# 5. Generation
|
| 344 |
# ----------------------------------------------------------
|
| 345 |
try:
|
| 346 |
gen_result = generator.generate(decision)
|
| 347 |
+
success = gen_result["confidence"] > 0.3
|
| 348 |
except Exception as e:
|
| 349 |
log(f"Generation error: {e}", "ERROR")
|
| 350 |
success = False
|
| 351 |
|
| 352 |
# ----------------------------------------------------------
|
| 353 |
+
# 6. Outcome feedback
|
| 354 |
# ----------------------------------------------------------
|
| 355 |
mind.outcome(task, success)
|
| 356 |
|
| 357 |
# ----------------------------------------------------------
|
| 358 |
+
# 7. Ingest cognitive vector into dream buffer
|
| 359 |
# ----------------------------------------------------------
|
|
|
|
| 360 |
intent_vec = mind.kernel.vectorize_tokens(
|
| 361 |
task.split(), positional=False
|
| 362 |
)
|
| 363 |
dreamer.ingest(intent_vec, meta={
|
| 364 |
+
"intent": task,
|
| 365 |
+
"mode": decision["mode"],
|
| 366 |
"confidence": decision["confidence"],
|
| 367 |
+
"cycle": decision["cycle"],
|
| 368 |
+
"tier": tier,
|
| 369 |
})
|
| 370 |
|
| 371 |
# ----------------------------------------------------------
|
| 372 |
+
# 8. Vitalis decides if it needs to sleep
|
| 373 |
# ----------------------------------------------------------
|
| 374 |
should_dream, reason, signals = mind.needs_dream()
|
| 375 |
if should_dream:
|
| 376 |
log(f"Sleep decision: {reason}", "SLEEP")
|
| 377 |
+
run_dream_cycle(mind, dreamer, self_model)
|
| 378 |
|
| 379 |
# ----------------------------------------------------------
|
| 380 |
+
# 9. Introspection every 25 cycles
|
| 381 |
# ----------------------------------------------------------
|
| 382 |
if decision["cycle"] % 25 == 0:
|
| 383 |
+
state = mind.introspect()
|
| 384 |
elapsed = (time.time() - session_start) / 60
|
| 385 |
+
sm = self_model.report()
|
| 386 |
+
cr = complexity.report()
|
| 387 |
+
log("β" * 60)
|
| 388 |
+
log(f"INTROSPECTION β cycle {decision['cycle']}")
|
| 389 |
+
log(f"Personality: {state['personality']['character']}")
|
| 390 |
+
log(f"Dominant trait: {state['personality']['dominant']}")
|
| 391 |
+
log(f"Resonance: {state['resonance'].get('total_patterns', 0)} patterns")
|
| 392 |
+
log(f"Meta-rules: {state['meta_rules'].get('total_rules', 0)}")
|
| 393 |
+
log(f"Confidence: {state['confidence_trend']}")
|
| 394 |
+
log(f"Growth index: {sm['growth_index']}")
|
| 395 |
+
log(f"Next boundary: {sm['next_boundary']}")
|
| 396 |
+
log(f"Complexity avg: {cr.get('avg_complexity', 0)}")
|
| 397 |
+
log(f"Session time: {elapsed:.1f} min")
|
| 398 |
+
log(f"Sleep signals: {state['sleep_signals']}")
|
| 399 |
+
log("β" * 60)
|
| 400 |
|
| 401 |
# ----------------------------------------------------------
|
| 402 |
+
# 10. Cycle timing
|
| 403 |
# ----------------------------------------------------------
|
| 404 |
cycle_time = time.time() - cycle_start
|
| 405 |
cycle_times.append(cycle_time)
|
| 406 |
+
time.sleep(0.05)
|
| 407 |
|
| 408 |
# ------------------------------------------------------------------
|
| 409 |
+
# Shutdown β final dream cycle
|
| 410 |
# ------------------------------------------------------------------
|
| 411 |
+
log("Running final dream cycle before shutdown...", "DREAM")
|
| 412 |
+
run_dream_cycle(mind, dreamer, self_model)
|
| 413 |
|
| 414 |
total_time = (time.time() - session_start) / 60
|
| 415 |
+
state = mind.introspect()
|
| 416 |
+
sm = self_model.report()
|
| 417 |
+
|
| 418 |
+
log("β" * 60)
|
| 419 |
+
log("SESSION COMPLETE")
|
| 420 |
+
log(f"Total cycles: {task_index}")
|
| 421 |
+
log(f"Total time: {total_time:.1f} min")
|
| 422 |
+
log(f"Avg cycle time: {(sum(cycle_times)/len(cycle_times)*1000):.1f}ms")
|
| 423 |
+
log(f"Personality: {state['personality']['character']}")
|
| 424 |
+
log(f"Dominant trait: {state['personality']['dominant']}")
|
| 425 |
+
log(f"Resonance: {state['resonance'].get('total_patterns', 0)} patterns")
|
| 426 |
+
log(f"Meta-rules: {state['meta_rules'].get('total_rules', 0)}")
|
| 427 |
+
log(f"Growth index: {sm['growth_index']}")
|
| 428 |
+
log("β" * 60)
|
| 429 |
|
| 430 |
|
| 431 |
if __name__ == "__main__":
|