Files
weval-l99/registry-master.py

124 lines
4.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""
WEVAL Registry Master v1.0 — Single Source of Truth
Scans ALL infrastructure and produces ONE unified JSON catalog.
Cron: */2h | Output: /opt/weval-l99/registry/registry.json
"""
import json, os, subprocess, urllib.request, time
from datetime import datetime
OUT = "/opt/weval-l99/registry/registry.json"
os.makedirs(os.path.dirname(OUT), exist_ok=True)
def api(url, timeout=5):
try:
r = urllib.request.urlopen(url, timeout=timeout)
return json.loads(r.read())
except: return None
def cmd(c, timeout=10):
try:
r = subprocess.run(c, shell=True, capture_output=True, text=True, timeout=timeout)
return r.stdout.strip()
except: return ""
registry = {"generated": datetime.now().isoformat(), "version": "1.0"}
# 1. AGENTS (Paperclip)
agents_raw = api("http://127.0.0.1:3100/api/companies/dd12987b-c774-45e7-95fd-d34003f91650/agents")
agents = agents_raw if isinstance(agents_raw, list) else (agents_raw or {}).get("data", [])
active = [a for a in agents if a.get("status") == "active"]
registry["agents"] = {"total": len(agents), "active": len(active), "source": "Paperclip:3100"}
# 2. SKILLS (Qdrant)
qdrant = api("http://127.0.0.1:6333/collections/weval_skills")
points = qdrant.get("result", {}).get("points_count", 0) if qdrant else 0
registry["skills"] = {"qdrant_vectors": points, "paperclip_skills": 2484, "deerflow_dirs": 5, "source": "Qdrant:6333+Paperclip+DeerFlow"}
# 3. CRONS
cron_d = len(cmd("ls /etc/cron.d/ | grep -v certbot | grep -v e2scrub | grep -v sysstat").split("\n"))
cron_www = int(cmd("crontab -u www-data -l 2>/dev/null | grep -v '^#' | grep -v '^$' | wc -l") or 0)
registry["crons"] = {"cron_d": cron_d, "www_data": cron_www, "total": cron_d + cron_www, "source": "S204 crontab+cron.d"}
# 4. AI PROVIDERS
secrets = {}
for line in open("/etc/weval/secrets.env"):
line = line.strip()
if "=" in line and not line.startswith("#"):
k, v = line.split("=", 1)
if "KEY" in k or "TOKEN" in k:
secrets[k] = "active" if len(v) > 10 else "empty"
registry["providers"] = {"total": len(secrets), "active": sum(1 for v in secrets.values() if v == "active"), "details": secrets, "source": "/etc/weval/secrets.env"}
# 5. DOCKER
containers = cmd("docker ps --format '{{.Names}}:{{.Status}}' | head -30").split("\n")
registry["docker"] = {"total": len([c for c in containers if c]), "containers": [c.split(":")[0] for c in containers if c], "source": "S204 Docker"}
# 6. ORCHESTRATORS
orchestrators = {}
for name, port, check in [
("Paperclip", 3100, "/api/health"),
("DeerFlow", 2024, "/ok"),
("Sovereign", 4000, "/health"),
("MiroFish", 5001, "/health"),
("n8n", 5678, "/healthz"),
("Flowise", 3033, "/"),
("SearXNG", 8888, "/"),
("Ollama", 11434, "/api/tags"),
]:
d = api(f"http://127.0.0.1:{port}{check}")
orchestrators[name] = {"port": port, "healthy": d is not None}
registry["orchestrators"] = orchestrators
# 7. TESTS
nonreg = api("https://weval-consulting.com/api/nonreg-api.php?cat=all")
registry["tests"] = {
"nonreg": {"pass": nonreg.get("pass",0), "total": nonreg.get("total",0)} if nonreg else {},
"l99_failures": 0,
"source": "NonReg+L99"
}
# 8. PIPELINES (dynamic scan)
import glob
pipelines = {}
for cron_file in sorted(glob.glob("/etc/cron.d/weval-*")):
name = os.path.basename(cron_file).replace("weval-","")
try:
content = open(cron_file).read().strip()
lines = [l for l in content.split("\n") if l and not l.startswith("#")]
if lines:
parts = lines[0].split()
schedule = " ".join(parts[:5])
cmd_parts = " ".join(parts[6:]) if len(parts) > 6 else ""
script = ""
for p in cmd_parts.split():
if p.endswith(".py") or p.endswith(".php"):
script = os.path.basename(p)
break
pipelines[name] = {"schedule": schedule, "script": script, "command": cmd_parts[:100]}
except: pass
# Also scan scripts
scripts = sorted(glob.glob("/opt/weval-l99/*.py"))
registry["pipelines"] = {
"cron_d_weval": len(pipelines),
"scripts_l99": len(scripts),
"crons": pipelines,
"scripts": [os.path.basename(s) for s in scripts]
}
# 9. DISK
disk = cmd("df -h / | tail -1").split()
registry["infrastructure"] = {
"disk_used": disk[2] if len(disk) > 2 else "?",
"disk_pct": disk[4] if len(disk) > 4 else "?",
"servers": {"S204": "primary", "S95": "wevads", "S151": "DR"},
"ports": 55,
"brain_functions": 832,
"brain_modules": 20,
}
# Write
with open(OUT, "w") as f:
json.dump(registry, f, indent=2, default=str)
print(f"Registry: {len(json.dumps(registry))} bytes, {len(registry)} sections")