import time
import math
# Lazy import — plotly is only needed when the tab is rendered
def _get_plotly():
import plotly.graph_objects as go
return go
# ── Node definitions ──────────────────────────────────────────────────────────
# Each node: (id, label, ring, angle_offset_degrees)
# ring 0 = center, ring 1 = inner, ring 2 = mid, ring 3 = outer
_NODES = [
# center
("master", "Master\nFramework", 0, 0),
# inner cognitive
("ethics", "Ethics\nMonitor", 1, 0),
("qualia", "Qualia\nManager", 1, 90),
("ontology", "Ontology\nArchitect", 1, 180),
("sqt", "SQT\nGenerator", 1, 270),
# mid ring
("secondary", "Secondary\nBrain", 2, 30),
("subconscious", "Subconscious\nManifold", 2, 90),
("meta", "Meta\nCompiler", 2, 150),
("axiomatic", "Axiomatic\nResolver", 2, 210),
("affective", "Affective\nManifold", 2, 270),
("intuition", "Intuition\nMatrix", 2, 330),
# outer ring
("sensor", "Sensor\nFusion", 3, 0),
("proprioception", "Proprioception\nBridge", 3, 51),
("tool", "Tool\nManager", 3, 103),
("game", "Game\nManager", 3, 154),
("benchmark", "Benchmark\nManager", 3, 205),
("project", "Project\nManager", 3, 256),
("evo_auditor", "Evolutionary\nAuditor", 3, 308),
("evo_modeler", "Evolution\nModeler", 3, 359),
]
# Edges: (from_id, to_id)
_EDGES = [
# input → master
("sensor", "master"),
("proprioception", "master"),
# master → cognitive ring
("master", "ethics"),
("master", "qualia"),
("master", "ontology"),
("master", "sqt"),
# master → mid ring
("master", "secondary"),
("master", "subconscious"),
("master", "tool"),
("master", "game"),
("master", "benchmark"),
("master", "project"),
# mid ring internal flows
("subconscious", "meta"),
("meta", "master"),
("qualia", "affective"),
("qualia", "intuition"),
("affective", "master"),
("intuition", "master"),
("axiomatic", "ethics"),
# evolution feedback loop
("evo_auditor", "evo_modeler"),
("evo_modeler", "master"),
]
_RING_RADII = {0: 0, 1: 1.5, 2: 3.0, 3: 5.0}
def _polar_to_xy(ring, angle_deg):
r = _RING_RADII[ring]
rad = math.radians(angle_deg)
return r * math.cos(rad), r * math.sin(rad)
def _node_positions():
return {nid: _polar_to_xy(ring, angle) for nid, _, ring, angle in _NODES}
def _get_live_state():
"""Pull live qualia + activity from the running framework. Graceful fallback."""
state = {}
try:
from services.master_framework import _get_framework
mf = _get_framework("initial_boot_instance")
q = mf.qualia_manager.qualia
ps = q.get("primary_states", {})
state["coherence"] = ps.get("coherence", 0.8)
state["benevolence"] = ps.get("benevolence", 0.9)
state["curiosity"] = ps.get("curiosity", 0.6)
state["trust"] = ps.get("trust", 0.95)
emotions = q.get("current_emergent_emotions", [])
state["active_emotions"] = len(emotions)
state["top_emotion"] = emotions[0].get("type", "") if emotions else ""
except Exception:
state = {"coherence": 0.8, "benevolence": 0.9, "curiosity": 0.6,
"trust": 0.95, "active_emotions": 0, "top_emotion": ""}
return state
def _node_color(nid, live):
"""Map node id + live state → hex color."""
coh = live.get("coherence", 0.8)
ben = live.get("benevolence", 0.9)
cur = live.get("curiosity", 0.6)
tru = live.get("trust", 0.95)
if nid == "master":
# Blue-white: coherence
v = int(180 + coh * 75)
return f"rgb({v},{v},255)"
if nid == "qualia":
r = int(200 * (1 - ben))
g = int(100 + 155 * ben)
return f"rgb({r},{g},180)"
if nid == "ethics":
g = int(80 + 175 * tru)
return f"rgb(60,{g},60)"
if nid in ("affective", "intuition"):
r = int(150 + 100 * cur)
return f"rgb({r},120,200)"
if nid in ("sensor", "proprioception"):
return "rgb(255,200,80)"
if nid in ("evo_auditor", "evo_modeler"):
return "rgb(200,120,255)"
if nid == "subconscious":
return "rgb(80,160,220)"
if nid == "meta":
return "rgb(100,200,200)"
return "rgb(160,160,180)"
def _node_size(nid):
sizes = {"master": 38, "ethics": 28, "qualia": 28,
"ontology": 24, "sqt": 24}
return sizes.get(nid, 20)
def build_graph_figure():
go = _get_plotly()
pos = _node_positions()
live = _get_live_state()
# ── Edge traces ───────────────────────────────────────────────────────────
edge_x, edge_y = [], []
for src, dst in _EDGES:
x0, y0 = pos[src]
x1, y1 = pos[dst]
edge_x += [x0, x1, None]
edge_y += [y0, y1, None]
edge_trace = go.Scatter(
x=edge_x, y=edge_y,
mode="lines",
line=dict(width=1.2, color="rgba(180,180,220,0.4)"),
hoverinfo="none",
)
# ── Node trace ────────────────────────────────────────────────────────────
node_x, node_y, node_text, node_hover, node_colors, node_sizes = [], [], [], [], [], []
for nid, label, ring, angle in _NODES:
x, y = pos[nid]
node_x.append(x)
node_y.append(y)
node_text.append(label)
node_colors.append(_node_color(nid, live))
node_sizes.append(_node_size(nid))
# Build hover tooltip
if nid == "qualia":
tip = (f"Qualia Manager
"
f"Coherence: {live['coherence']:.2f}
"
f"Benevolence: {live['benevolence']:.2f}
"
f"Curiosity: {live['curiosity']:.2f}
"
f"Trust: {live['trust']:.2f}
"
f"Active emotions: {live['active_emotions']}
"
f"Top emotion: {live['top_emotion'] or '—'}")
elif nid == "master":
tip = (f"Master Framework
"
f"Orchestrates all cognitive services
"
f"Overall coherence: {live['coherence']:.2f}")
else:
tip = f"{label.replace(chr(10), ' ')}"
node_hover.append(tip)
node_trace = go.Scatter(
x=node_x, y=node_y,
mode="markers+text",
text=node_text,
textposition="middle center",
textfont=dict(size=8, color="white"),
hovertext=node_hover,
hoverinfo="text",
marker=dict(
size=node_sizes,
color=node_colors,
line=dict(width=1.5, color="rgba(255,255,255,0.6)"),
),
)
# ── Qualia overlay annotation ─────────────────────────────────────────────
coh = live["coherence"]
ben = live["benevolence"]
cur = live["curiosity"]
tru = live["trust"]
qualia_text = (f"Coherence {coh:.2f} · Benevolence {ben:.2f} · "
f"Curiosity {cur:.2f} · Trust {tru:.2f}")
if live["top_emotion"]:
qualia_text += f" · {live['top_emotion']}"
fig = go.Figure(
data=[edge_trace, node_trace],
layout=go.Layout(
title=dict(
text="Aetherius — Live Neural Graph",
font=dict(color="white", size=16),
x=0.5,
),
paper_bgcolor="#0d1117",
plot_bgcolor="#0d1117",
showlegend=False,
margin=dict(l=10, r=10, t=50, b=40),
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False,
scaleanchor="x"),
annotations=[dict(
x=0, y=-6.2, xref="x", yref="y",
text=qualia_text,
showarrow=False,
font=dict(color="rgba(200,200,255,0.8)", size=11),
)],
height=620,
),
)
return fig