// Per-tool rich renderers for assistant tool results. Dispatched by tool // name in `MessageBody`. Each renderer receives the parsed result object // and produces a small UI block. When the tool isn't recognised here we // fall back to a JSON dump (handled by the caller). import type { ReactNode } from "react" import { ArrowUpRight, CheckCircle2, CircleSlash, PauseCircle, Sparkles, User2, Building2, } from "lucide-react" type Status = "active" | "suspended" | "deactivated" | string const statusStyle: Record = { active: { bg: "bg-emerald-500/15 border-emerald-500/40", fg: "text-emerald-700 dark:text-emerald-300", icon: , }, suspended: { bg: "bg-amber-500/15 border-amber-500/40", fg: "text-amber-700 dark:text-amber-300", icon: , }, deactivated: { bg: "bg-rose-500/15 border-rose-500/40", fg: "text-rose-700 dark:text-rose-300", icon: , }, } function StatusPill({ status }: { status: Status }) { const s = statusStyle[status] ?? { bg: "bg-muted border-border", fg: "text-muted-foreground", icon: null, } return ( {s.icon} {status} ) } interface TenantRow { id?: string slug: string name: string status: string plan?: string | null inserted_at?: string } function TenantsTable({ rows }: { rows: TenantRow[] }) { if (rows.length === 0) { return
No tenants.
} return (
{rows.map((t) => ( ))}
Tenant Slug Status Plan
{t.name} {t.slug} {t.plan ?? "—"}
) } function TenantCard({ t }: { t: TenantRow }) { return (
{t.name} {t.slug}
Plan
{t.plan ?? "—"}
{t.inserted_at && ( <>
Created
{new Date(t.inserted_at).toLocaleDateString()}
)}
) } interface PlatformStats { tenants_total: number tenants_by_status: Record tenants_by_plan: Record } function PlatformStatsBlock({ stats }: { stats: PlatformStats }) { return (
} /> {Object.entries(stats.tenants_by_status).map(([status, n]) => ( } compact /> ))}
) } function KpiTile({ label, value, icon, compact, }: { label: string value: number | string icon?: ReactNode compact?: boolean }) { return (
{!compact && icon} {label}
{compact && icon} {value}
) } interface AuditEntry { actor_type: string actor_id?: string | null action: string target?: string | null inserted_at: string } function AuditLogList({ entries }: { entries: AuditEntry[] }) { if (entries.length === 0) { return
No audit entries.
} return (
    {entries.map((e, i) => (
  • {e.actor_type} {e.action} {e.target && ( {e.target} )}
    {new Date(e.inserted_at).toLocaleString()}
  • ))}
) } interface UserRow { id: string email: string name?: string | null roles?: string[] verified?: boolean | null inserted_at?: string } function UsersList({ users }: { users: UserRow[] }) { if (users.length === 0) { return
No users.
} return (
    {users.map((u) => (
  • {u.name || u.email} {u.verified === false && ( unverified )}
    {u.name && (
    {u.email}
    )}
    {(u.roles ?? []).map((r) => ( {r} ))}
  • ))}
) } /** * Dispatch by tool name. Returns null when no rich renderer applies — the * caller falls back to a JSON dump (already part of ToolCallCard). */ export function renderToolResult( toolName: string, result: unknown, ): ReactNode | null { if (result == null) return null switch (toolName) { case "list_tenants": if (Array.isArray(result)) return return null case "get_tenant": if (typeof result === "object" && (result as TenantRow).slug) { return } return null case "get_platform_stats": if (typeof result === "object" && result && "tenants_total" in result) { return } return null case "list_audit_log": if (Array.isArray(result)) return return null case "list_users": if (Array.isArray(result)) return return null case "suspend_tenant": case "activate_tenant": if (typeof result === "object" && (result as TenantRow).slug) { return (
{toolName === "suspend_tenant" ? "Suspended" : "Activated"}
) } return null default: return null } }