Auto-commit via make git (triggered by NFDOS)
This commit is contained in:
parent
88fc91b330
commit
0ae10b3481
24
neurotron.in
24
neurotron.in
@ -4,18 +4,28 @@ PYTHON="/usr/bin/python3"
|
|||||||
NEUROTRON_HOME="/opt/kernel/neurotron"
|
NEUROTRON_HOME="/opt/kernel/neurotron"
|
||||||
SRC="$NEUROTRON_HOME/src"
|
SRC="$NEUROTRON_HOME/src"
|
||||||
|
|
||||||
# Garante diretórios básicos
|
# --- Filesystems base ---
|
||||||
mkdir -p /proc /sys /dev
|
mkdir -p /proc /sys /dev
|
||||||
|
|
||||||
# Montar proc, sysfs e devtmpfs (idempotente, falha silenciosa se já montado)
|
|
||||||
mount -t proc proc /proc 2>/dev/null || true
|
mount -t proc proc /proc 2>/dev/null || true
|
||||||
mount -t sysfs sys /sys 2>/dev/null || true
|
mount -t sysfs sys /sys 2>/dev/null || true
|
||||||
mount -t devtmpfs devtmpfs /dev 2>/dev/null || true
|
mount -t devtmpfs devtmpfs /dev 2>/dev/null || true
|
||||||
|
|
||||||
# Ambiente Python minimalista
|
# --- Ambiente ---
|
||||||
|
export HOME=/
|
||||||
|
export TERM=linux
|
||||||
export PYTHONHOME="/usr"
|
export PYTHONHOME="/usr"
|
||||||
export PYTHONPATH="$SRC:/usr/lib/python3.13:/usr/lib/python3.13/site-packages"
|
export PYTHONPATH="$SRC:/usr/lib/python3.13:/usr/lib/python3.13/site-packages"
|
||||||
export PATH="/sbin:/bin:/usr/sbin:/usr/bin:$PATH"
|
export PATH="/sbin:/bin:/usr/sbin:/usr/bin"
|
||||||
|
|
||||||
# Arrancar o cérebro principal como módulo do package
|
# --- Garante VT ---
|
||||||
exec "$PYTHON" -m neurotron "$@"
|
mkdir -p /dev/pts
|
||||||
|
mount -t devpts devpts /dev/pts 2>/dev/null || true
|
||||||
|
|
||||||
|
# --- Mudar para tty1 (VGA) ---
|
||||||
|
chvt 1
|
||||||
|
|
||||||
|
# --- Criar sessão e ligar ao VGA ---
|
||||||
|
exec setsid sh -c '
|
||||||
|
exec </dev/tty1 >/dev/tty1 2>&1
|
||||||
|
exec '"$PYTHON"' -m neurotron
|
||||||
|
'
|
||||||
|
|||||||
@ -73,6 +73,7 @@ def main():
|
|||||||
Path(log_dir).mkdir(parents=True, exist_ok=True)
|
Path(log_dir).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
ctx = Cortex(runtime_dir=runtime_dir, log_dir=log_dir)
|
ctx = Cortex(runtime_dir=runtime_dir, log_dir=log_dir)
|
||||||
|
logbus.subscribe(ctx._on_log_event)
|
||||||
|
|
||||||
# threads
|
# threads
|
||||||
t_dash = threading.Thread(target=dashboard_loop, args=(ctx,), daemon=True)
|
t_dash = threading.Thread(target=dashboard_loop, args=(ctx,), daemon=True)
|
||||||
|
|||||||
@ -72,6 +72,16 @@ class Cortex:
|
|||||||
self.telemetry_path = Path(NEUROTRON_DATASET_PATH) / "telemetry.json"
|
self.telemetry_path = Path(NEUROTRON_DATASET_PATH) / "telemetry.json"
|
||||||
self.telemetry_path.parent.mkdir(parents=True, exist_ok=True)
|
self.telemetry_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# ---- Dashboard ----
|
||||||
|
self.memory = Hippocampus(
|
||||||
|
log_dir=self.log_dir,
|
||||||
|
on_remember=self._on_memory_event,
|
||||||
|
)
|
||||||
|
self.ui_bus = defaultdict(lambda: deque(maxlen=200))
|
||||||
|
self.ui_publish("kernel", "[Placeholder (No futuro /dev/kmsg, dmesg reader ou ring buffer próprio)] ACPI: Core revision 20240415")
|
||||||
|
self.ui_publish("kernel", "[Placeholder (No futuro /dev/kmsg, dmesg reader ou ring buffer próprio)] EXT4-fs mounted filesystem")
|
||||||
|
|
||||||
|
|
||||||
def _init_paths(self):
|
def _init_paths(self):
|
||||||
"""
|
"""
|
||||||
Inicializa todos os paths canónicos do runtime Neurotron.
|
Inicializa todos os paths canónicos do runtime Neurotron.
|
||||||
@ -193,6 +203,16 @@ class Cortex:
|
|||||||
except:
|
except:
|
||||||
return fallback
|
return fallback
|
||||||
|
|
||||||
|
def ui_publish(self, pane: str, msg: str):
|
||||||
|
self.ui_bus[pane].append(msg)
|
||||||
|
|
||||||
|
def ui_tail(self, pane: str, n: int):
|
||||||
|
q = self.ui_bus.get(pane)
|
||||||
|
if not q:
|
||||||
|
return []
|
||||||
|
return list(q)[-n:]
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# heartbeat — apenas visual, não cognitivo
|
# heartbeat — apenas visual, não cognitivo
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
@ -287,3 +307,44 @@ class Cortex:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
return snap
|
return snap
|
||||||
|
|
||||||
|
def _on_memory_event(self, kind: str, data: dict):
|
||||||
|
"""
|
||||||
|
Observador de eventos lembrados (UI / TRM / futuro).
|
||||||
|
"""
|
||||||
|
summary = self._summarize_memory(kind, data)
|
||||||
|
if summary:
|
||||||
|
self.ui_publish("memory", summary)
|
||||||
|
|
||||||
|
|
||||||
|
def _summarize_memory(self, kind: str, data: dict) -> str:
|
||||||
|
"""
|
||||||
|
Converte eventos ricos em linhas humanas (dashboard).
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if kind == "boot":
|
||||||
|
return f"[boot] mode={data.get('mode')} tick={data.get('tick')}"
|
||||||
|
if kind.startswith("telemetry.event"):
|
||||||
|
return f"[tele] {kind.split('.')[-1]}"
|
||||||
|
if kind == "trm.snapshot":
|
||||||
|
st = data.get("state", {})
|
||||||
|
return (
|
||||||
|
f"[trm] cog={st.get('cog_state')} "
|
||||||
|
f"val={st.get('valence', 0):+.2f} "
|
||||||
|
f"depth={st.get('depth')}"
|
||||||
|
)
|
||||||
|
return f"[{kind}] {str(data)[:60]}"
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _on_log_event(self, ev):
|
||||||
|
# sempre disponível para UI
|
||||||
|
self.ui_publish("log", ev)
|
||||||
|
|
||||||
|
# opcional: persistência
|
||||||
|
if ev.level in ("error", "warn"):
|
||||||
|
self.memory.remember("log", {
|
||||||
|
"level": ev.level,
|
||||||
|
"msg": ev.msg
|
||||||
|
})
|
||||||
|
|
||||||
|
|||||||
@ -2,4 +2,13 @@ import sys
|
|||||||
|
|
||||||
class ChatPane:
|
class ChatPane:
|
||||||
def render(self, ctx, x, y, w, h):
|
def render(self, ctx, x, y, w, h):
|
||||||
sys.stdout.write(f"\033[{y};{x}HCHAT MESSAGES (placeholder)")
|
# título
|
||||||
|
sys.stdout.write(f"\033[{y};{x}HCHAT MESSAGES:")
|
||||||
|
sys.stdout.write("\033[K")
|
||||||
|
|
||||||
|
# consumir linhas já publicadas
|
||||||
|
lines = ctx.ui_tail("log", h-1)
|
||||||
|
for i, ev in enumerate(lines):
|
||||||
|
sys.stdout.write(
|
||||||
|
f"\033[{y+1+i};{x}H{ev.format()[:w]}"
|
||||||
|
)
|
||||||
@ -1,6 +1,20 @@
|
|||||||
# panes/kernel.py
|
# neurotron/dashboard/panes/kernel.py
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class KernelPane:
|
class KernelPane:
|
||||||
def render(self, ctx, x, y, w, h):
|
def render(self, ctx, x, y, w, h):
|
||||||
sys.stdout.write(f"\033[{y};{x}HKERNEL MESSAGES (placeholder)")
|
# título
|
||||||
|
sys.stdout.write(f"\033[{y};{x}HKERNEL MESSAGES:")
|
||||||
|
sys.stdout.write("\033[K")
|
||||||
|
|
||||||
|
# consumir linhas já publicadas
|
||||||
|
lines = ctx.ui_tail("kernel", h - 1)
|
||||||
|
|
||||||
|
row = y + 1
|
||||||
|
for line in lines:
|
||||||
|
truncated = line[:w]
|
||||||
|
sys.stdout.write(f"\033[{row};{x}H{truncated}")
|
||||||
|
sys.stdout.write("\033[K")
|
||||||
|
row += 1
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,18 @@
|
|||||||
|
# neurotron/dashboard/panes/memory.py
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
class MemoryPane:
|
class MemoryPane:
|
||||||
def render(self, ctx, x, y, w, h):
|
def render(self, ctx, x, y, w, h):
|
||||||
sys.stdout.write(f"\033[{y};{x}HMEMORY MESSAGES (placeholder)")
|
# título
|
||||||
|
sys.stdout.write(f"\033[{y};{x}HMEMORY MESSAGES:")
|
||||||
|
sys.stdout.write("\033[K")
|
||||||
|
|
||||||
|
# consumir memória recente (já filtrada!)
|
||||||
|
lines = ctx.ui_tail("memory", h - 1)
|
||||||
|
|
||||||
|
row = y + 1
|
||||||
|
for line in lines:
|
||||||
|
truncated = line[:w]
|
||||||
|
sys.stdout.write(f"\033[{row};{x}H{truncated}")
|
||||||
|
sys.stdout.write("\033[K")
|
||||||
|
row += 1
|
||||||
|
|||||||
@ -2,4 +2,30 @@ import sys
|
|||||||
|
|
||||||
class TRMPane:
|
class TRMPane:
|
||||||
def render(self, ctx, x, y, w, h):
|
def render(self, ctx, x, y, w, h):
|
||||||
sys.stdout.write(f"\033[{y};{x}HTRM MESSAGES (placeholder)")
|
snap = ctx.cognitive_snapshot()
|
||||||
|
|
||||||
|
sys.stdout.write(
|
||||||
|
f"\033[{y};{x}HTRM STATE:"
|
||||||
|
)
|
||||||
|
|
||||||
|
line1 = (
|
||||||
|
f"State:{snap['cog_state']} "
|
||||||
|
f"Depth:{snap['depth']} "
|
||||||
|
f"Val:{snap['valence']:+.2f} "
|
||||||
|
f"Energy:{snap['energy']}"
|
||||||
|
)
|
||||||
|
|
||||||
|
sys.stdout.write(f"\033[{y+1};{x}H{line1[:w]}\033[K")
|
||||||
|
|
||||||
|
# Separador
|
||||||
|
sys.stdout.write(f"\033[{y+2};{x}H" + "─" * w)
|
||||||
|
|
||||||
|
# Pensamentos recentes
|
||||||
|
thoughts = ctx.ui_tail("trm", h - 3)
|
||||||
|
row = y + 3
|
||||||
|
|
||||||
|
for t in thoughts:
|
||||||
|
sys.stdout.write(
|
||||||
|
f"\033[{row};{x}H• {t[:w-2]}\033[K"
|
||||||
|
)
|
||||||
|
row += 1
|
||||||
|
|||||||
@ -1,18 +1,24 @@
|
|||||||
|
# neurotron/hippocampus.py
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import json
|
import json
|
||||||
|
from typing import Optional, Callable
|
||||||
|
|
||||||
|
|
||||||
class Hippocampus:
|
class Hippocampus:
|
||||||
"""
|
"""
|
||||||
Memória contextual simples (JSON Lines): append-only.
|
Memória contextual simples (JSON Lines): append-only.
|
||||||
Guarda perceções, decisões e ações para replays futuros.
|
|
||||||
Apenas stdlib JSON — 100% compatível com Python estático.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, log_dir: Path):
|
def __init__(
|
||||||
|
self,
|
||||||
|
log_dir: Path,
|
||||||
|
on_remember: Optional[Callable[[str, dict], None]] = None,
|
||||||
|
):
|
||||||
self.log_dir = log_dir
|
self.log_dir = log_dir
|
||||||
self.log_dir.mkdir(parents=True, exist_ok=True)
|
self.log_dir.mkdir(parents=True, exist_ok=True)
|
||||||
self.events_file = self.log_dir / "events.jsonl"
|
self.events_file = self.log_dir / "events.jsonl"
|
||||||
|
self.on_remember = on_remember
|
||||||
|
|
||||||
def remember(self, kind: str, data: dict) -> None:
|
def remember(self, kind: str, data: dict) -> None:
|
||||||
rec = {
|
rec = {
|
||||||
@ -22,11 +28,15 @@ class Hippocampus:
|
|||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# stdlib json → sempre string
|
blob = json.dumps(rec, separators=(",", ":"))
|
||||||
blob = json.dumps(rec, separators=(",", ":")) # compacto
|
|
||||||
with self.events_file.open("a", encoding="utf-8") as f:
|
with self.events_file.open("a", encoding="utf-8") as f:
|
||||||
f.write(blob + "\n")
|
f.write(blob + "\n")
|
||||||
except Exception:
|
except Exception:
|
||||||
# nunca crashar o Neurotron por logs
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# 🔔 notificação opcional (não quebra nunca)
|
||||||
|
if self.on_remember:
|
||||||
|
try:
|
||||||
|
self.on_remember(kind, data)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|||||||
@ -1,33 +1,39 @@
|
|||||||
# neurotron/logbus.py
|
# neurotron/logbus.py
|
||||||
|
|
||||||
from collections import deque
|
from dataclasses import dataclass
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import sys
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LogEvent:
|
||||||
|
ts: str
|
||||||
|
level: str
|
||||||
|
msg: str
|
||||||
|
|
||||||
|
def format(self) -> str:
|
||||||
|
return f"[{self.ts}] [{self.level}] {self.msg}"
|
||||||
|
|
||||||
class LogBus:
|
class LogBus:
|
||||||
"""
|
def __init__(self):
|
||||||
Canal central de logs do Neurotron.
|
self._subscribers = []
|
||||||
- escreve tudo em stdout (texto simples, sem Rich)
|
|
||||||
- mantém um buffer em memória para o dashboard (tail)
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, maxlen: int = 1000):
|
def subscribe(self, fn):
|
||||||
self._buffer = deque(maxlen=maxlen)
|
self._subscribers.append(fn)
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# núcleo
|
# núcleo
|
||||||
# -------------------------
|
# -------------------------
|
||||||
|
|
||||||
def _emit(self, level: str, msg: str):
|
def _emit(self, level: str, msg: str):
|
||||||
ts = datetime.utcnow().strftime("%H:%M:%S")
|
ev = LogEvent(
|
||||||
line = f"[{ts}] [{level}] {msg}"
|
ts=datetime.utcnow().strftime("%H:%M:%S"),
|
||||||
|
level=level,
|
||||||
# guarda em memória para o dashboard
|
msg=msg,
|
||||||
self._buffer.append(line)
|
)
|
||||||
|
for fn in self._subscribers:
|
||||||
# escreve em stdout (uma linha)
|
try:
|
||||||
sys.stdout.write(line + "\n")
|
fn(ev)
|
||||||
sys.stdout.flush()
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# API pública de logs
|
# API pública de logs
|
||||||
@ -61,16 +67,5 @@ class LogBus:
|
|||||||
# fallback para chamadas antigas tipo logbus.emit("...")
|
# fallback para chamadas antigas tipo logbus.emit("...")
|
||||||
self.info(msg)
|
self.info(msg)
|
||||||
|
|
||||||
# -------------------------
|
|
||||||
# Para o dashboard
|
|
||||||
# -------------------------
|
|
||||||
def tail(self, n: int = 150):
|
|
||||||
"""Devolve as últimas n linhas de log como lista de strings."""
|
|
||||||
if n <= 0:
|
|
||||||
return []
|
|
||||||
buf = list(self._buffer)
|
|
||||||
return buf[-n:]
|
|
||||||
|
|
||||||
|
|
||||||
# instância global
|
# instância global
|
||||||
logbus = LogBus()
|
logbus: "LogBus" = LogBus()
|
||||||
|
|||||||
@ -171,6 +171,10 @@ class TRMEngine:
|
|||||||
if len(self._history) % 10 == 0 and hasattr(self.ctx, "memory"):
|
if len(self._history) % 10 == 0 and hasattr(self.ctx, "memory"):
|
||||||
payload = make_trm_snapshot_payload(st9, telemetry)
|
payload = make_trm_snapshot_payload(st9, telemetry)
|
||||||
self.ctx.memory.remember("trm.snapshot", payload)
|
self.ctx.memory.remember("trm.snapshot", payload)
|
||||||
|
self.ctx.ui_publish(
|
||||||
|
"memory",
|
||||||
|
f"[trm] cog={st9.cog_state} val={st9.valence:+.2f} depth={st9.depth}"
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._dbg(f"erro ao gravar snapshot no Hippocampus: {e}")
|
self._dbg(f"erro ao gravar snapshot no Hippocampus: {e}")
|
||||||
|
|
||||||
|
|||||||
@ -136,6 +136,9 @@ class ThoughtAgent:
|
|||||||
payload = {"thought": t}
|
payload = {"thought": t}
|
||||||
try:
|
try:
|
||||||
self.ctx.memory.remember("trm.thought", payload)
|
self.ctx.memory.remember("trm.thought", payload)
|
||||||
|
if hasattr(self.ctx, "ui_publish"):
|
||||||
|
self.ctx.ui_publish("trm", t)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user