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