Auto-commit via make git (triggered by NFDOS)

This commit is contained in:
neoricalex 2026-01-03 16:28:45 +01:00
parent 88fc91b330
commit 0ae10b3481
11 changed files with 195 additions and 49 deletions

View File

@ -4,18 +4,28 @@ PYTHON="/usr/bin/python3"
NEUROTRON_HOME="/opt/kernel/neurotron"
SRC="$NEUROTRON_HOME/src"
# Garante diretórios básicos
# --- Filesystems base ---
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 sysfs sys /sys 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 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
exec "$PYTHON" -m neurotron "$@"
# --- Garante VT ---
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
'

View File

@ -73,6 +73,7 @@ def main():
Path(log_dir).mkdir(parents=True, exist_ok=True)
ctx = Cortex(runtime_dir=runtime_dir, log_dir=log_dir)
logbus.subscribe(ctx._on_log_event)
# threads
t_dash = threading.Thread(target=dashboard_loop, args=(ctx,), daemon=True)

View File

@ -72,6 +72,16 @@ class Cortex:
self.telemetry_path = Path(NEUROTRON_DATASET_PATH) / "telemetry.json"
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):
"""
Inicializa todos os paths canónicos do runtime Neurotron.
@ -192,6 +202,16 @@ class Cortex:
return float(x)
except:
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
@ -286,4 +306,45 @@ class Cortex:
except Exception:
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
})

View File

@ -2,4 +2,13 @@ import sys
class ChatPane:
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]}"
)

View File

@ -1,6 +1,20 @@
# panes/kernel.py
# neurotron/dashboard/panes/kernel.py
import sys
class KernelPane:
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

View File

@ -1,5 +1,18 @@
# neurotron/dashboard/panes/memory.py
import sys
class MemoryPane:
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

View File

@ -2,4 +2,30 @@ import sys
class TRMPane:
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

View File

@ -1,18 +1,24 @@
# neurotron/hippocampus.py
from pathlib import Path
from datetime import datetime
import json
from typing import Optional, Callable
class Hippocampus:
"""
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.mkdir(parents=True, exist_ok=True)
self.events_file = self.log_dir / "events.jsonl"
self.on_remember = on_remember
def remember(self, kind: str, data: dict) -> None:
rec = {
@ -22,11 +28,15 @@ class Hippocampus:
}
try:
# stdlib json → sempre string
blob = json.dumps(rec, separators=(",", ":")) # compacto
blob = json.dumps(rec, separators=(",", ":"))
with self.events_file.open("a", encoding="utf-8") as f:
f.write(blob + "\n")
except Exception:
# nunca crashar o Neurotron por logs
pass
# 🔔 notificação opcional (não quebra nunca)
if self.on_remember:
try:
self.on_remember(kind, data)
except Exception:
pass

View File

@ -1,33 +1,39 @@
# neurotron/logbus.py
from collections import deque
from dataclasses import dataclass
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:
"""
Canal central de logs do Neurotron.
- escreve tudo em stdout (texto simples, sem Rich)
- mantém um buffer em memória para o dashboard (tail)
"""
def __init__(self):
self._subscribers = []
def __init__(self, maxlen: int = 1000):
self._buffer = deque(maxlen=maxlen)
def subscribe(self, fn):
self._subscribers.append(fn)
# -------------------------
# núcleo
# -------------------------
def _emit(self, level: str, msg: str):
ts = datetime.utcnow().strftime("%H:%M:%S")
line = f"[{ts}] [{level}] {msg}"
# guarda em memória para o dashboard
self._buffer.append(line)
# escreve em stdout (uma linha)
sys.stdout.write(line + "\n")
sys.stdout.flush()
ev = LogEvent(
ts=datetime.utcnow().strftime("%H:%M:%S"),
level=level,
msg=msg,
)
for fn in self._subscribers:
try:
fn(ev)
except Exception:
pass
# -------------------------
# API pública de logs
@ -61,16 +67,5 @@ class LogBus:
# fallback para chamadas antigas tipo logbus.emit("...")
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
logbus = LogBus()
logbus: "LogBus" = LogBus()

View File

@ -171,6 +171,10 @@ class TRMEngine:
if len(self._history) % 10 == 0 and hasattr(self.ctx, "memory"):
payload = make_trm_snapshot_payload(st9, telemetry)
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:
self._dbg(f"erro ao gravar snapshot no Hippocampus: {e}")

View File

@ -136,6 +136,9 @@ class ThoughtAgent:
payload = {"thought": t}
try:
self.ctx.memory.remember("trm.thought", payload)
if hasattr(self.ctx, "ui_publish"):
self.ctx.ui_publish("trm", t)
except Exception:
pass