"use client"; // The agent's "anatomy" as a grid of compact icon cards. Each card opens a modal // with the full, pretty-formatted section content. The four brain text files // (system prompt / how it operates / personality / skills) are editable in the // modal and saved back to the .brain via PATCH /api/claws/{id}/brain; the derived // sections (capabilities / tools / memory / safety) render read-only (tools keeps // its "add tool" affordance). import { useState, type ReactNode } from "react"; import { Brain, Check, Cpu, Database, Drama, Pencil, Plus, ScrollText, ShieldCheck, Workflow, Wrench, X, Zap } from "lucide-react"; import type { DemoAgent } from "@/lib/dashboard-demo"; import { MarkdownText, PersonalityBody, mono, tag, type RawBrain } from "./anatomy-cards"; type EditField = "system_prompt" | "agent_md" | "persona" | "skills_md"; interface Section { key: string; label: string; icon: ReactNode; tint: string; status?: string; // small hint on the card (count / "editable") field?: EditField; // present ⇒ editable + saved to the brain value?: string; // editable source text placeholder?: string; body: ReactNode; // formatted, read-only display for the modal } function IconCard({ section, onClick }: { section: Section; onClick: () => void }) { return ( ); } function SectionModal({ section, clawId, onClose, onSaved, onAddTool }: { section: Section; clawId: string; onClose: () => void; onSaved?: () => void; onAddTool?: () => void }) { const [editing, setEditing] = useState(false); const [draft, setDraft] = useState(section.value ?? ""); const [saving, setSaving] = useState(false); const save = async () => { if (!section.field) return; setSaving(true); try { await fetch(`/api/claws/${clawId}/brain`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ [section.field]: draft }) }); setEditing(false); onSaved?.(); } catch { /* keep the editor open on failure */ } finally { setSaving(false); } }; return (
e.stopPropagation()} style={{ width: "min(760px, 94vw)", maxHeight: "84vh", display: "flex", flexDirection: "column", borderRadius: 16, background: "#0f0f13", border: `1px solid ${section.tint}45`, boxShadow: "0 30px 80px rgba(0,0,0,.6)" }}> {/* Header */}
{section.icon} {section.label} {section.field && !editing ? ( ) : null}
{/* Body */}
{editing ? (