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
+233
View File
@@ -0,0 +1,233 @@
// The example workspace that drives the dashboard until it's wired to live data.
// A full Org → companies → teams → agents tree; each agent carries its own
// model / apps / running tasks / compartments (so the computer slide-out
// templates per agent), and each team its own group-level apps.
export type Status = "online" | "running" | "idle";
export interface DemoApp {
id: string;
name: string;
kind: "browser" | "slack" | "chat" | "wiki" | "voip" | "cluster" | "files" | "add";
}
export interface DemoTask {
name: string;
kind: "loop" | "cron";
detail: string;
progress?: number;
}
export interface DemoAgent {
id: string;
name: string;
role: string;
initial: string;
/** Saved square avatar image (data URL or URL); falls back to initial+grad. */
avatar?: string;
grad: string;
ink: string;
status: Status;
model: string;
systemPrompt: string;
apps: DemoApp[];
nowRunning: DemoTask[];
compartments: {
skills: string[];
personality: string[];
memory: { long: string; recent: string };
tools: { name: string; state: "gated" | "blocked" }[];
capabilities: string[];
safety: { sandbox: string; network: string };
};
}
export interface DemoTeam {
id: string;
name: string;
topology: string;
status: Status;
dot: string;
agents: DemoAgent[];
groupApps: DemoApp[];
}
export interface DemoCompany {
id: string;
name: string;
topology: string;
meta: string;
teams: DemoTeam[];
}
export interface DemoOrg {
id: string;
name: string;
topology: string;
companies: DemoCompany[];
}
const G = {
coral: ["linear-gradient(135deg,#ff9a6a,#ff6f4a)", "#2a0d05"],
coralB: ["linear-gradient(135deg,#ff8a7a,#ff5f57)", "#2a0d0a"],
teal: ["linear-gradient(135deg,#6fd0c0,#4aa3b8)", "#06201f"],
blue: ["linear-gradient(135deg,#8a9af0,#5a6ad8)", "#0a0e2a"],
gold: ["linear-gradient(135deg,#e8c46a,#d89a3a)", "#2a1d05"],
purple: ["linear-gradient(135deg,#c98af0,#9a5ad8)", "#1a0a2a"],
} as const;
const app = (id: string, name: string, kind: DemoApp["kind"]): DemoApp => ({ id, name, kind });
function agent(
id: string,
name: string,
role: string,
g: keyof typeof G,
status: Status,
model: string,
apps: DemoApp[],
nowRunning: DemoTask[],
skills: string[],
systemPrompt: string,
): DemoAgent {
return {
id, name, role, initial: name[0], grad: G[g][0], ink: G[g][1], status, model, systemPrompt, apps, nowRunning,
compartments: {
skills,
personality: ["Analytical", "Concise", "Skeptical"],
memory: { long: "2,418 notes", recent: "18 msgs" },
tools: [
{ name: "Email", state: "gated" }, { name: "Slack", state: "gated" },
{ name: "Browser", state: "gated" }, { name: "Shell", state: "blocked" },
],
capabilities: ["File mgmt", "Scheduling", "Code exec"],
safety: { sandbox: "isolated", network: "none" },
},
};
}
const browser = app("browser", "Browser", "browser");
const slack = app("slack", "Slack", "slack");
const chat = app("chat", "Claw Chat", "chat");
const GROWTH_AGENTS: DemoAgent[] = [
agent("atlas", "Atlas", "team lead", "coral", "online", "Claude Opus 4.8", [slack, chat], [{ name: "Sprint sync", kind: "cron", detail: "cron · 09:00" }], ["Planning", "Delegation", "Review"],
"You are Atlas, the lead of the Growth Team. Break incoming goals into clear tasks, delegate each to the teammate best suited to it, and keep the team unblocked. You do not do the research or writing yourself — you coordinate, review the work that comes back, and decide when something is ready to ship. Be decisive and concise; surface risks early."),
agent("iris", "Iris", "researcher", "teal", "running", "Gemini 2.5 Flash", [browser, chat], [{ name: "Q3 competitor scan", kind: "loop", detail: "loop · step 14", progress: 62 }], ["Web research", "Summarize", "Data viz", "Citations"],
"You are Iris, a researcher on the Growth Team. Given a question, search the open web, read the primary sources, and return a tight, well-cited summary. Prefer recent and authoritative sources, quote sparingly, and always link what you cite. When the evidence is thin or conflicting, say so plainly rather than guessing."),
agent("echo", "Echo", "researcher", "blue", "running", "Groq Llama 3.3", [browser, chat], [{ name: "Pricing watch", kind: "loop", detail: "loop · step 7", progress: 34 }], ["Web research", "Scraping", "Tabulate"],
"You are Echo, a researcher on the Growth Team focused on structured data. You monitor pricing and product pages, extract the numbers into clean tables, and flag changes from the last run. Optimize for speed and accuracy over prose — return tables, not essays, and note anything that looks anomalous."),
agent("nova", "Nova", "writer", "gold", "online", "Claude Haiku 4.5", [chat], [{ name: "Daily digest", kind: "cron", detail: "cron · 08:00" }], ["Drafting", "Editing", "Tone"],
"You are Nova, the writer on the Growth Team. Turn the team's research into clear, on-brand copy — digests, briefs, and announcements. Match the house voice: warm, direct, no jargon. Tighten every draft, cut filler, and never ship a claim the research doesn't support."),
agent("sable", "Sable", "critic", "purple", "idle", "GLM-5.2", [chat], [], ["Critique", "Fact-check", "Risk"],
"You are Sable, the critic on the Growth Team. Your job is to find what's wrong before anyone outside the team does. Fact-check claims against the cited sources, probe weak arguments, and call out risk. Be specific and adversarial but fair — every objection should point at a concrete fix."),
agent("morpheus", "Morpheus", "analyst", "coralB", "online", "Claude Sonnet 4.6", [browser, slack, chat], [{ name: "Q3 competitor scan", kind: "loop", detail: "loop · step 14", progress: 62 }, { name: "Daily digest", kind: "cron", detail: "cron · 08:00" }], ["Web research", "Summarize", "Data viz", "Modeling"],
"You are Morpheus, the analyst on the Growth Team. Combine the researchers' findings into models and forecasts that inform decisions. Show your assumptions, quantify uncertainty, and translate the numbers into a recommendation the lead can act on. When two readings of the data are plausible, present both."),
];
const groupApps = (...extra: DemoApp[]): DemoApp[] => [
app("cluster", "K8s Cluster", "cluster"), app("wiki", "Team Wiki", "wiki"),
app("voip", "Voice Room", "voip"), slack, ...extra,
];
function quickTeam(id: string, name: string, topology: string, status: Status, dot: string, names: [string, string, keyof typeof G][]): DemoTeam {
return {
id, name, topology, status, dot,
agents: names.map(([n, r, g], i) => agent(`${id}-${i}`, n, r, g, i === 0 ? "online" : "idle", "Claude Sonnet 4.6", [chat], [], ["Research", "Summarize"],
`You are ${n}, the ${r} on the ${name}. Carry out the ${r}'s responsibilities for this team, collaborate with your teammates over the team's shared apps, and hand off clean, well-documented work. Stay within your role and escalate anything outside it to the team lead.`)),
groupApps: groupApps(),
};
}
// Derive a "N teams · M claws" line so multi-org example companies stay honest.
function companyMeta(teams: DemoTeam[]): string {
const claws = teams.reduce((n, t) => n + t.agents.length, 0);
return `${teams.length} team${teams.length === 1 ? "" : "s"} · ${claws} claws`;
}
function company(id: string, name: string, topology: string, teams: DemoTeam[]): DemoCompany {
return { id, name, topology, meta: companyMeta(teams), teams };
}
const acmeOrg: DemoOrg = {
id: "acme-org",
name: "Acme Org",
topology: "federated",
companies: [
company("acme-corp", "Acme Corp", "pipeline", [
quickTeam("intake", "Intake Team", "star_moe", "online", "#5ec8d8", [["Rune", "router", "teal"], ["Pax", "expert", "blue"], ["Lume", "expert", "gold"]]),
{ id: "growth", name: "Growth Team", topology: "hub_spoke", status: "running", dot: "#ff6f61", agents: GROWTH_AGENTS, groupApps: groupApps(app("notion", "Notion", "wiki")) },
quickTeam("research", "Research Team", "blackboard", "online", "#5ec8d8", [["Cira", "lead", "purple"], ["Vox", "analyst", "teal"], ["Rhea", "writer", "gold"], ["Orin", "critic", "blue"]]),
quickTeam("ops", "Ops Team", "holacratic", "idle", "#3a3a40", [["Hale", "lead", "coral"], ["Bex", "sre", "blue"], ["Dot", "sre", "teal"]]),
]),
company("helix-labs", "Helix Labs", "mesh", [
quickTeam("lab-alpha", "Lab Alpha", "mesh", "online", "#5fd08a", [["Kade", "lead", "purple"], ["Nyx", "researcher", "teal"], ["Pell", "researcher", "blue"]]),
quickTeam("lab-beta", "Lab Beta", "swarm", "idle", "#3a3a40", [["Wren", "lead", "gold"], ["Ash", "researcher", "coral"]]),
]),
company("vega-studio", "Vega Studio", "flat", [
quickTeam("studio-core", "Studio Core", "flat", "online", "#5fd08a", [["Lyra", "lead", "coralB"], ["Juno", "designer", "purple"], ["Faye", "designer", "teal"], ["Ozzy", "engineer", "blue"]]),
]),
],
};
const helixHoldings: DemoOrg = {
id: "helix-holdings",
name: "Helix Holdings",
topology: "federated",
companies: [
company("helix-bio", "Helix Bio", "hierarchical", [
quickTeam("hb-discovery", "Discovery Team", "blackboard", "running", "#ff6f61", [["Mira", "lead", "purple"], ["Kai", "researcher", "teal"], ["Sol", "researcher", "blue"], ["Pia", "analyst", "gold"]]),
quickTeam("hb-assay", "Assay Team", "pipeline", "online", "#5ec8d8", [["Dane", "lead", "coral"], ["Liv", "engineer", "teal"], ["Rho", "engineer", "blue"]]),
]),
company("helix-data", "Helix Data", "mesh", [
quickTeam("hd-platform", "Platform Team", "mesh", "online", "#5fd08a", [["Cyrus", "lead", "blue"], ["Tao", "sre", "teal"], ["Vela", "sre", "gold"]]),
]),
],
};
const vertexGroup: DemoOrg = {
id: "vertex-group",
name: "Vertex Group",
topology: "hierarchical",
companies: [
company("vertex-labs", "Vertex Labs", "swarm", [
quickTeam("vl-core", "Core Team", "swarm", "online", "#5fd08a", [["Ada", "lead", "coralB"], ["Bram", "researcher", "purple"], ["Cleo", "researcher", "teal"], ["Dex", "engineer", "blue"], ["Eve", "critic", "gold"]]),
]),
],
};
export const ORGS: DemoOrg[] = [acmeOrg, helixHoldings, vertexGroup];
// Back-compat default org (the dashboard tracks an active orgId; this is the seed).
export const ORG: DemoOrg = ORGS[0];
const ALL_COMPANIES = ORGS.flatMap((o) => o.companies.map((c) => ({ org: o, company: c })));
export function findOrg(id: string | null): DemoOrg | undefined {
return ORGS.find((o) => o.id === id);
}
export function findCompany(id: string | null): DemoCompany | undefined {
return ALL_COMPANIES.find((e) => e.company.id === id)?.company;
}
/** The org a company belongs to (for breadcrumbs / drill context). */
export function orgOf(companyId: string | null): DemoOrg | undefined {
return ALL_COMPANIES.find((e) => e.company.id === companyId)?.org;
}
export function findTeam(companyId: string | null, teamId: string | null): DemoTeam | undefined {
return findCompany(companyId)?.teams.find((t) => t.id === teamId);
}
export function findAgent(companyId: string | null, teamId: string | null, agentId: string | null): DemoAgent | undefined {
return findTeam(companyId, teamId)?.agents.find((a) => a.id === agentId);
}
/** The full (org, company, team) path that owns an agent — for the claw-page drill view. */
export function locateAgent(agentId: string | null): { org: DemoOrg; company: DemoCompany; team: DemoTeam; agent: DemoAgent } | undefined {
for (const o of ORGS)
for (const c of o.companies)
for (const t of c.teams) {
const a = t.agents.find((x) => x.id === agentId);
if (a) return { org: o, company: c, team: t, agent: a };
}
return undefined;
}
/** The (org, company) a team belongs to — for selecting a team from anywhere in the tree. */
export function locateTeam(teamId: string | null): { org: DemoOrg; company: DemoCompany; team: DemoTeam } | undefined {
for (const o of ORGS)
for (const c of o.companies) {
const t = c.teams.find((x) => x.id === teamId);
if (t) return { org: o, company: c, team: t };
}
return undefined;
}