From 86524cb3097951d66101f50513789a72c57c5607 Mon Sep 17 00:00:00 2001 From: Omar Sobh Date: Wed, 24 Jun 2026 04:31:28 -0700 Subject: [PATCH] World/Brain: signals colored by activity type (think/tool/file/run) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each agent carries a fireColor for its most recent activity — reasoning (purple), tool (cyan), file op (coral), run (green) — derived in the engine from the touch weight/node + reasoning events (now wired into the engine). The brain fires signals in that colour, and the HUD shows a small colour key in Hierarchy, so you can read WHAT KIND of work is lighting up the mesh. Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/src/components/world/WorldCanvas.tsx | 19 +++++++++++++++---- frontend/src/components/world/engine.ts | 11 +++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/world/WorldCanvas.tsx b/frontend/src/components/world/WorldCanvas.tsx index 725abe0..fb69764 100644 --- a/frontend/src/components/world/WorldCanvas.tsx +++ b/frontend/src/components/world/WorldCanvas.tsx @@ -181,6 +181,7 @@ export function WorldCanvas({ roots, selectedId, onSelect, expanded, onToggleExp live.on("agent.status", (d) => e.onStatus(d)), live.on("world.touch", (d) => e.onTouch(d)), live.on("node.activity", (d) => e.onNodeActivity(d)), + live.on("agent.reasoning.delta", (d) => e.onReasoning(d.agentId)), ]; return () => offs.forEach((off) => off()); }, [live, mode]); @@ -434,15 +435,15 @@ export function WorldCanvas({ roots, selectedId, onSelect, expanded, onToggleExp const renderBrain = (dt: number) => { // Neurons = agents (bright, drive firing) + structure nodes (org/company/ // team) as a dim support mesh, so even a near-idle brain has body. - type Neuron = { id: string; color: string; agent: boolean; boost: number }; + type Neuron = { id: string; color: string; fire: string; agent: boolean; boost: number }; const neurons: Neuron[] = []; for (const p of engine.pawns.values()) { const recent = p.idle < 2.5 ? 1 : 0; // a recent touch lights the neuron - neurons.push({ id: p.id, color: p.color, agent: true, boost: (p.status === "working" ? 0.9 : 0) + recent }); + neurons.push({ id: p.id, color: p.color, fire: p.fireColor ?? p.color, agent: true, boost: (p.status === "working" ? 0.9 : 0) + recent }); } for (const n of engine.nodes.values()) { if (n.tier === "org" || n.tier === "company" || n.tier === "team") - neurons.push({ id: n.id, color: n.color, agent: false, boost: n.heat }); + neurons.push({ id: n.id, color: n.color, fire: n.color, agent: false, boost: n.heat }); } const ids = neurons.map((n) => n.id); const seen = new Set(ids); @@ -480,7 +481,7 @@ export function WorldCanvas({ roots, selectedId, onSelect, expanded, onToggleExp const dz = tp.z - pos.z; const len = Math.hypot(dx, dy, dz) || 1; const speed = 150; - spawn(pos.x, pos.y, pos.z, ne.color, (dx / len) * speed, (dy / len) * speed, (dz / len) * speed, speed / len + 0.25); + spawn(pos.x, pos.y, pos.z, ne.fire, (dx / len) * speed, (dy / len) * speed, (dz / len) * speed, speed / len + 0.25); neuronAct.set(tid, Math.min(1, (neuronAct.get(tid) ?? 0.05) + 0.14)); } } @@ -928,6 +929,16 @@ export function WorldCanvas({ roots, selectedId, onSelect, expanded, onToggleExp ) : null} + {formation === "hierarchy" ? ( +
+ {([["#c98af0", "think"], ["#5ec8d8", "tool"], ["#ff6f61", "file"], ["#5fd08a", "run"]] as const).map(([c, l]) => ( + + + {l} + + ))} +
+ ) : null} {/* WorldClock — live ⇄ replay (Gource-style playback of run history) */}
= 0.9 ? "#ff6f61" : "#5ec8d8"; + else if (e.nodeId.startsWith("run:")) p.fireColor = "#5fd08a"; + } + + /** A reasoning token from an agent — marks it active and tints its signals. */ + onReasoning(agentId: string) { + const p = this.ensurePawn(agentId); + p.fireColor = "#c98af0"; // think = purple + p.idle = 0; } onNodeActivity(e: TaxonomyEvents["node.activity"]) { const node = this.ensureNode(e.nodeId, e.kind === "event" ? "event" : "service", e.label ?? e.nodeId, ROOT, 1);