Large World graph, agent platform, brain stack & dashboard rebuild

Frontend
- Large World: collapse org/company/team tiers into one expandable React Flow
  hierarchy (WorldFlow) with per-click expand, persisted node positions, a
  compact tree sidebar, wrench multi-select delete across levels, and a sized
  right slide-out (phone/tablet/full) showing an agent summary + drill button.
- Agent page: GitHub-style animated contribution grid (VitalsCard), collapsible
  System Prompt + Personality cards, restructured anatomy cards, bigger avatar
  with name/title header row, Markdown/JSON-aware rendering, brain registry +
  history, avatar generate/upload.
- User-icon menu (Infrastructure/Brains/Tools/Profile/Credits) + ToolPanel;
  Master Planner deploy wizard (Specialists/Swarm/Scheduled/Triggered);
  Team Runs view; reap-progress modal; dashboard is the single live interface.

Backend
- cm-brain crate (.brain as the agent definition) + brain apply/history.
- Hard-purge reap (FK-ordered) + sandbox release + SSE batch-delete.
- Swarm self-verifying loop, mode-aware planner, web.search tool, webhooks
  (migration 0013), org/company/team delete endpoints, scheduler sweeps.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-22 23:21:54 -07:00
co-authored by Claude Opus 4.8
parent 9f266d5806
commit 34f744734b
123 changed files with 9591 additions and 1098 deletions
@@ -0,0 +1,133 @@
// Per-pattern node positioning + edges for the React Flow topology canvas.
// One positioner per layout family (adapted from agentorg's AutoLayoutManager),
// so switching topology reshuffles the same nodes into a new arrangement.
import type { TopologyPattern } from "@/lib/topologies";
export interface Pt {
x: number;
y: number;
}
const W = 820;
const H = 480;
const CX = W / 2;
const CY = H / 2;
function ringPts(n: number, r: number, cx = CX, cy = CY, off = -Math.PI / 2): Pt[] {
return Array.from({ length: n }, (_, i) => {
const a = (i / n) * Math.PI * 2 + off;
return { x: cx + r * Math.cos(a), y: cy + r * Math.sin(a) };
});
}
const radius = (n: number, base: number, step: number, max: number) => Math.min(max, base + n * step);
export function layoutFor(pattern: TopologyPattern, n: number): Pt[] {
if (n <= 0) return [];
if (n === 1) return [{ x: CX, y: CY }];
switch (pattern) {
case "chain":
return Array.from({ length: n }, (_, i) => ({ x: 70 + (i * (W - 140)) / (n - 1), y: CY }));
case "ring":
return ringPts(n, radius(n, 70, 14, 200));
case "mesh":
return ringPts(n, radius(n, 80, 12, 210));
case "hub":
case "radial":
return [{ x: CX, y: CY }, ...ringPts(n - 1, radius(n, 80, 12, 190))];
case "tree": {
// root at top, the rest fanned across one or two rows below
const rest = n - 1;
const perRow = Math.min(rest, Math.ceil(Math.sqrt(rest) * 1.6) || 1);
const pts: Pt[] = [{ x: CX, y: 70 }];
for (let i = 0; i < rest; i++) {
const rowi = Math.floor(i / perRow);
const col = i % perRow;
const inRow = Math.min(perRow, rest - rowi * perRow);
pts.push({ x: inRow === 1 ? CX : 110 + (col * (W - 220)) / (inRow - 1), y: 200 + rowi * 150 });
}
return pts;
}
case "grid": {
const cols = Math.ceil(Math.sqrt(n));
const rows = Math.ceil(n / cols);
const gx = (W - 160) / Math.max(cols - 1, 1);
const gy = (H - 160) / Math.max(rows - 1, 1);
return Array.from({ length: n }, (_, i) => ({
x: cols === 1 ? CX : 80 + (i % cols) * gx,
y: rows === 1 ? CY : 80 + Math.floor(i / cols) * gy,
}));
}
case "cluster": {
const groups = Math.min(3, Math.max(2, Math.round(n / 3)));
const centers = ringPts(groups, 150);
return Array.from({ length: n }, (_, i) => {
const g = i % groups;
const within = Math.floor(i / groups);
const a = within * 1.7;
return { x: centers[g].x + 46 * Math.cos(a), y: centers[g].y + 46 * Math.sin(a) };
});
}
case "columns": {
const half = Math.ceil(n / 2);
return Array.from({ length: n }, (_, i) => {
const left = i < half;
const idx = left ? i : i - half;
const count = left ? half : n - half;
return { x: left ? CX - 170 : CX + 170, y: count === 1 ? CY : 90 + (idx * (H - 180)) / (count - 1) };
});
}
case "swarm":
default:
return Array.from({ length: n }, (_, i) => {
const a = (i / n) * Math.PI * 2;
const r = 70 + (i % 3) * 38;
return { x: CX + r * Math.cos(a), y: CY + r * Math.sin(a) };
});
}
}
export function edgesFor(pattern: TopologyPattern, n: number): [number, number][] {
const e: [number, number][] = [];
const push = (a: number, b: number) => { if (a !== b && a < n && b < n) e.push([a, b]); };
switch (pattern) {
case "tree":
case "hub":
case "radial":
for (let i = 1; i < n; i++) push(0, i);
break;
case "chain":
for (let i = 0; i < n - 1; i++) push(i, i + 1);
break;
case "ring":
for (let i = 0; i < n; i++) push(i, (i + 1) % n);
break;
case "mesh":
for (let i = 0; i < n; i++) for (let j = i + 1; j < n; j++) push(i, j);
break;
case "grid": {
const cols = Math.ceil(Math.sqrt(n));
for (let i = 0; i < n; i++) {
if ((i + 1) % cols !== 0) push(i, i + 1);
if (i + cols < n) push(i, i + cols);
}
break;
}
case "cluster": {
const groups = Math.min(3, Math.max(2, Math.round(n / 3)));
for (let i = 0; i < n; i++) push(i, (i + groups) % n);
for (let g = 0; g < groups; g++) push(g, (g + 1) % groups);
break;
}
case "columns": {
const half = Math.ceil(n / 2);
for (let i = 0; i < half; i++) for (let j = half; j < n; j++) if ((i + j) % 2 === 0) push(i, j);
break;
}
case "swarm":
default:
for (let i = 1; i < n; i++) push(0, i);
for (let i = 1; i < n; i++) push(i, (i % (n - 1)) + 1);
}
return e;
}