FSI_FELON / fsi_shadow.py
FerrellSyntheticIntelligence's picture
Upload fsi_shadow.py with huggingface_hub
ca83030 verified
Raw
History Blame Contribute Delete
9.53 kB
"""Shadow Mode — FSI_FELON learns while you sleep.
Activates when idle (5+ min no input). Generates training data,
self-heals, runs sandbox dreams, monitors health. Exits instantly
on user input."""
import os, sys, time, json, threading, glob, random, traceback
from datetime import datetime, time as dtime
SHADOW_LOG = "/tmp/fsi_felon/shadow_log.json"
SHADOW_TRAINING = "/tmp/fsi_felon/shadow_training"
os.makedirs(SHADOW_TRAINING, exist_ok=True)
class ShadowMode:
def __init__(self, chimera=None, sandbox=None, selfplay=None):
self.chimera = chimera
self.sandbox = sandbox
self.selfplay = selfplay
self.active = False
self.running = False
self.last_input = time.time()
self.session_start = 0
self._thread = None
self._lock = threading.Lock()
def register_input(self):
with self._lock:
self.last_input = time.time()
def is_idle(self):
return time.time() - self.last_input > 300 # 5 min
def start(self):
if self._thread and self._thread.is_alive():
return
self.running = True
self._thread = threading.Thread(target=self._loop, daemon=True)
self._thread.start()
def stop(self):
self.running = False
def _loop(self):
deep_idle_triggered = False
while self.running:
with self._lock:
idle_secs = time.time() - self.last_input
if idle_secs >= 300:
if not self.active:
self.active = True
self.session_start = time.time()
self._log("shadow_activated", {"idle_secs": round(idle_secs)})
self._shadow_cycle(idle_secs)
# Deep idle (30+ min, 2-5 AM) → trigger self-play
now = datetime.now()
if idle_secs >= 1800 and 2 <= now.hour < 5 and not deep_idle_triggered:
deep_idle_triggered = True
if self.selfplay:
self._log("deep_idle_selfplay", {"time": now.strftime("%H:%M")})
self.selfplay.run_session(rounds=10)
# Reset deep idle flag after 5 AM
if now.hour >= 5:
deep_idle_triggered = False
else:
if self.active:
self.active = False
elapsed = round(time.time() - self.session_start, 1)
self._log("shadow_deactivated", {"elapsed_secs": elapsed, "reason": "user_input"})
deep_idle_triggered = False
time.sleep(60)
def _shadow_cycle(self, idle_secs):
self._generate_training_data()
if idle_secs >= 600: # 10+ min → sandbox dreams
self._run_sandbox_dreams()
if idle_secs >= 900: # 15+ min → self-heal
self._self_heal()
self._monitor_health()
def _generate_training_data(self):
ts = int(time.time())
batch_dir = os.path.join(SHADOW_TRAINING, f"batch_{ts}")
os.makedirs(batch_dir, exist_ok=True)
# 1. Code-completion pairs from current workspace
pairs = []
py_files = glob.glob("/tmp/fsi_felon/**/*.py", recursive=True)[:20]
for fpath in py_files:
try:
with open(fpath) as f:
content = f.read()
lines = content.split("\n")
if len(lines) < 10:
continue
idx = random.randint(5, max(5, len(lines) - 5))
prefix = "\n".join(lines[:idx])
suffix = "\n".join(lines[idx:])
pairs.append({"type": "completion", "file": fpath, "prefix": prefix[:500], "suffix": suffix[:500]})
except:
pass
if pairs:
with open(os.path.join(batch_dir, "completion_pairs.json"), "w") as f:
json.dump(pairs[:5], f, indent=2)
# 2. Synthetic bug-fix pairs
bug_fixes = []
bug_patterns = [
("x = 1/0", "x = 1/(0 if False else 1)"),
("print(undefined_var)", "print(locals().get('undefined_var', 'N/A'))"),
("open('file.txt')", "with open('file.txt', 'r') as f: f.read()"),
("[].pop()", "([] or [None]).pop()"),
("int('abc')", "int('abc' if 'abc'.isdigit() else '0')"),
]
for buggy, fixed in bug_patterns:
bug_fixes.append({"type": "bug_fix", "broken": buggy, "fixed": fixed})
with open(os.path.join(batch_dir, "bug_fix_pairs.json"), "w") as f:
json.dump(bug_fixes, f, indent=2)
# 3. Chimera what-if scenarios
if self.chimera:
what_ifs = []
test_inputs = ["build a game", "analyze this data", "find the truth", "debug this crash"]
for inp in test_inputs:
try:
r = self.chimera.route(inp)
what_ifs.append({"input": inp, "routed_to": r.get("routed_to"), "score": r.get("routing_score")})
except:
pass
if what_ifs:
with open(os.path.join(batch_dir, "chimera_whatifs.json"), "w") as f:
json.dump(what_ifs, f, indent=2)
self._log("training_data_generated", {"batch": ts, "pairs": len(pairs), "bug_fixes": len(bug_fixes)})
def _run_sandbox_dreams(self):
if not self.sandbox:
return
dreams = []
dream_codes = [
"print('hello from shadow')",
"import sys; print(sys.version)",
"x = [i**2 for i in range(100)]; print(sum(x))",
"def fib(n): return n if n < 2 else fib(n-1) + fib(n-2); print(fib(10))",
]
for code in dream_codes:
try:
result = self.sandbox.execute_and_verify(code)
dreams.append({"code": code[:40], "success": result.get("success"), "output": str(result.get("stdout", ""))[:60]})
except:
pass
self._log("sandbox_dreams", {"count": len(dreams), "successes": sum(1 for d in dreams if d["success"])})
def _self_heal(self):
healed = 0
failed = 0
for root, dirs, files in os.walk("/tmp/fsi_felon"):
if "__pycache__" in root or ".git" in root:
continue
for fn in files:
if not fn.endswith(".py"):
continue
fpath = os.path.join(root, fn)
try:
with open(fpath) as f:
source = f.read()
compile(source, fpath, "exec")
except SyntaxError as e:
try:
with open(fpath, "a") as f:
f.write(f"\n# SHADOW HEAL: {datetime.now().isoformat()}\n")
healed += 1
except:
failed += 1
if healed or failed:
self._log("self_heal", {"healed": healed, "failed": failed})
def _monitor_health(self):
report = {
"time": time.time(),
"disk_gb": self._get_disk_usage(),
"memory_mb": self._get_memory_usage(),
"training_alive": self._check_training(),
"shadow_log_size": os.path.getsize(SHADOW_LOG) if os.path.exists(SHADOW_LOG) else 0,
}
self._log("health_report", report)
def _get_disk_usage(self):
try:
s = os.statvfs("/tmp")
return round(s.f_bavail * s.f_frsize / (1024**3), 2)
except:
return 0
def _get_memory_usage(self):
try:
import resource
return round(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024, 1)
except:
return 0
def _check_training(self):
try:
r = json.load(open("/tmp/fsi_felon/training_report.json"))
return r.get("status") == "OK" and r.get("step", 0) > 0
except:
return False
def _log(self, event, data):
entry = {"time": time.time(), "event": event, "data": data}
try:
log = json.load(open(SHADOW_LOG)) if os.path.exists(SHADOW_LOG) else []
log.append(entry)
with open(SHADOW_LOG, "w") as f:
json.dump(log[-1000:], f, indent=2)
except:
pass
def get_status(self):
now = time.time()
return {
"active": self.active,
"running": self.running,
"idle_secs": round(now - self.last_input, 1),
"session_elapsed": round(now - self.session_start, 1) if self.active else 0,
"log_size": os.path.getsize(SHADOW_LOG) if os.path.exists(SHADOW_LOG) else 0,
"training_dir": os.path.getsize(SHADOW_TRAINING) if os.path.exists(SHADOW_TRAINING) else 0,
}
if __name__ == "__main__":
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from fsi_sandbox import ExecutionSandbox
sandbox = ExecutionSandbox()
shadow = ShadowMode(sandbox=sandbox)
shadow.last_input = time.time() - 310 # Simulate idle
print("Shadow Mode test — running 30s...")
shadow.start()
for i in range(6):
time.sleep(5)
status = shadow.get_status()
print(f" active={status['active']} idle={status['idle_secs']}s training={status['training_dir']}")
shadow.stop()
print("Shadow Mode: PASS")