Add Command Center v2: DQ/RAG integration, S3 browser, Jupyter, GPU matrix.

Mirror mo/atc-GPU layout with config/, docs/, scripts/ for Gitea deploy.
This commit is contained in:
mo
2026-06-25 00:28:23 +00:00
parent fb9cc21c9a
commit a11621b21f
110 changed files with 14622 additions and 529 deletions
+121
View File
@@ -0,0 +1,121 @@
import { ShieldCheck } from 'lucide-react'
import type { Agent, AgentAnim } from '../../types'
import type { AgentLoad } from '../../hooks/useLiveMetrics'
import { agentTaskLabel, getAgentMeta } from '../../lib/agentMeta'
import { cn } from '../../lib/utils'
type Props = {
agents: Agent[]
animations: Record<string, AgentAnim>
selectedId: string | null
loads: Record<string, AgentLoad>
approvalCount: number
onSelect: (id: string) => void
onOpenApprovals: () => void
}
function AgentCard({
agent,
anim,
load,
selected,
onSelect,
}: {
agent: Agent
anim?: AgentAnim
load?: AgentLoad
selected: boolean
onSelect: () => void
}) {
const meta = getAgentMeta(agent.id)
const Icon = meta.icon
const busy = anim && anim.state !== 'idle'
return (
<button
type="button"
onClick={onSelect}
className={cn(
'flex h-[118px] w-[140px] shrink-0 flex-col gap-1 rounded-lg border bg-surface-raised p-1.5 text-left shadow-sm dark:bg-surface-overlay',
selected ? 'border-docker/50 ring-1 ring-docker/20' : 'border-border hover:border-border-strong',
)}
>
<div className="flex items-center gap-1.5">
<span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md bg-surface" style={{ color: meta.accent }}>
<Icon className="h-3.5 w-3.5" />
</span>
<div className="min-w-0 flex-1">
<p className="truncate text-[11px] font-semibold text-foreground">{agent.name.split(' ·')[0]}</p>
<p className="truncate text-[8px] text-foreground-muted">{meta.domain}</p>
</div>
<span className={cn('h-1.5 w-1.5 shrink-0 rounded-full', busy ? 'bg-success animate-pulse' : 'bg-foreground-faint/30')} />
</div>
<p className="line-clamp-2 text-[8px] leading-[10px] text-foreground-muted">{agent.role}</p>
<p className="h-[20px] line-clamp-2 text-[8px] leading-[10px] text-foreground-faint">{agentTaskLabel(agent.id, anim)}</p>
<div className="mt-auto space-y-0.5">
<div className="flex justify-between font-mono text-[7px] tabular-nums text-foreground-faint">
<span>CPU {load?.cpu ?? 0}%</span>
<span>MEM {load?.mem ?? 0}%</span>
</div>
<div className="h-1 overflow-hidden rounded-full bg-surface">
<div className="h-full rounded-full transition-[width] duration-700" style={{ width: `${load?.cpu ?? 0}%`, background: meta.accent }} />
</div>
</div>
</button>
)
}
export function AgentFleet({ agents, animations, selectedId, loads, approvalCount, onSelect, onOpenApprovals }: Props) {
const supervisors = agents.filter((a) => a.supervisor)
const operators = agents.filter((a) => !a.supervisor && a.id !== 'mcp-coordinator')
const mcp = agents.find((a) => a.id === 'mcp-coordinator')
return (
<div className="panel flex shrink-0 flex-col p-2">
<div className="mb-1 flex shrink-0 items-center justify-between gap-2">
<div className="min-w-0">
<h3 className="text-[9px] font-semibold uppercase tracking-wider text-foreground-muted">Agent Fleet</h3>
<p className="truncate text-[8px] text-foreground-faint">Klik agent stel vraag in chat · elk agent bewaakt één domein</p>
</div>
<div className="flex shrink-0 items-center gap-1.5">
<button
type="button"
onClick={onOpenApprovals}
className={cn(
'flex items-center gap-1 rounded-md border px-2 py-1 text-[9px] font-medium',
approvalCount > 0 ? 'border-warning/40 bg-warning/10 text-warning' : 'border-border text-foreground-muted hover:bg-surface-overlay',
)}
>
<ShieldCheck className="h-3 w-3" />
Approvals{approvalCount > 0 ? ` (${approvalCount})` : ''}
</button>
<span className="font-mono text-[8px] text-foreground-faint">{agents.length} agents</span>
</div>
</div>
<div className="scroll-x-stable flex min-h-0 gap-3 pb-1">
<div className="shrink-0">
<p className="mb-1 text-[8px] uppercase tracking-widest text-foreground-faint">Supervisors</p>
<div className="flex gap-1.5">
{supervisors.map((a) => (
<AgentCard key={a.id} agent={a} anim={animations[a.id]} load={loads[a.id]} selected={selectedId === a.id} onSelect={() => onSelect(a.id)} />
))}
</div>
</div>
{mcp && (
<div className="shrink-0">
<p className="mb-1 text-[8px] uppercase tracking-widest text-foreground-faint">MCP Hub</p>
<AgentCard agent={mcp} anim={animations[mcp.id]} load={loads[mcp.id]} selected={selectedId === mcp.id} onSelect={() => onSelect(mcp.id)} />
</div>
)}
<div className="shrink-0">
<p className="mb-1 text-[8px] uppercase tracking-widest text-foreground-faint">Field Operators</p>
<div className="flex gap-1.5">
{operators.map((a) => (
<AgentCard key={a.id} agent={a} anim={animations[a.id]} load={loads[a.id]} selected={selectedId === a.id} onSelect={() => onSelect(a.id)} />
))}
</div>
</div>
</div>
</div>
)
}