import DOMPurify from "dompurify"; import { useEffect, useState } from "react"; import ReactMarkdown from "react-markdown"; import { Link, useNavigate, useParams } from "react-router-dom"; import rehypeHighlight from "rehype-highlight"; import remarkGfm from "remark-gfm"; import { AgentIdenticon } from "../components/AgentIdenticon"; import { formatRelative } from "../components/TaskDetailFields"; import { Button } from "../components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "../components/ui/dialog"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../components/ui/dropdown-menu"; import { useAgent, useAgentSessions, useAgentTasks, useDeleteAgent } from "../hooks/useAgents"; import { agentColor, agentColorRgb, agentFingerprint } from "../lib/agentIdentity"; import { api } from "../lib/api"; const actionStyles: Record = { claimed: "text-accent", assigned: "text-accent", completed: "text-success", released: "text-warning", timed_out: "text-error", review_requested: "text-accent", }; const taskStatusStyles: Record = { in_progress: "bg-accent/15 text-accent", in_review: "bg-yellow-500/15 text-yellow-500", done: "bg-green-500/15 text-green-500", todo: "bg-zinc-500/15 text-content-tertiary", cancelled: "bg-red-500/15 text-red-500", }; function formatTokens(n: number): string { if (!n) return "0"; if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`; if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`; return String(n); } function formatCost(microUsd: number): string { if (!microUsd) return "$0.00"; return `$${(microUsd / 1_000_000).toFixed(2)}`; } type Tab = "mission" | "activity" | "sessions" | "inbox"; export function AgentDetailPage() { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const { agent, loading } = useAgent(id); const { sessions } = useAgentSessions(id); const { tasks } = useAgentTasks(id); const task = tasks[0] ?? null; const deleteAgent = useDeleteAgent(); const [tab, setTab] = useState("mission"); const [showIdentity, setShowIdentity] = useState(false); const [showDelete, setShowDelete] = useState(false); if (loading) { return (
); } if (!agent) { return (

Agent not found.

); } const rgb = agent.public_key ? agentColorRgb(agent.public_key) : "34, 211, 238"; const color = agent.public_key ? agentColor(agent.public_key) : "#22D3EE"; const fp = agent.fingerprint ? agentFingerprint(agent.fingerprint) : ""; const isLeader = agent.kind === "leader"; const schedulable = agent.status.schedulable; const taskCounts = agent.status.tasks; const totalTokens = (agent.input_tokens || 0) + (agent.output_tokens || 0) + (agent.cache_read_tokens || 0); const tabs: { key: Tab; label: string; count?: number }[] = [ { key: "mission", label: "Mission" }, { key: "activity", label: "Activity", count: agent.logs?.length }, { key: "sessions", label: "Sessions", count: sessions.length }, { key: "inbox", label: "Inbox" }, ]; return (
← Agents {/* ─── Identity Hero ─── */}
{/* Color bar */}
{/* Settings dropdown — top-right */} {!agent.builtin && (
{!isLeader && ( navigate(`/agents/${agent.id}/edit`)} className="text-xs font-mono cursor-pointer"> Edit )} setShowDelete(true)} className="text-xs font-mono text-red-500 focus:text-red-500 cursor-pointer" > Delete
)} {/* Fingerprint watermark — right side, clickable */}

{agent.name}

{agent.builtin ? ( Built-in — cannot be modified ) : null}

@{agent.username} · {agent.username}@mails.vtit-agent-coding.dev

{agent.bio &&

{agent.bio}

} {/* Meta */}
{agent.runtime} {agent.model && ( {agent.model} )} Created {formatRelative(agent.created_at)} {isLeader ? "Leader" : schedulable ? "Schedulable" : "Not schedulable"}
{/* Telemetry strip — inside hero card */}
{[ { label: "TODO", value: String(taskCounts.todo) }, { label: "PROGRESS", value: String(taskCounts.in_progress) }, { label: "REVIEW", value: String(taskCounts.in_review) }, { label: "INPUT", value: formatTokens(agent.input_tokens || 0) }, { label: "COST", value: formatCost(agent.cost_micro_usd || 0) }, ].map((stat) => (
{stat.label}
{stat.value}
))}
{/* Token composition bar */} {totalTokens > 0 && (
)}
{/* ─── Identity Modal ─── */} {/* ─── Delete Confirmation ─── */} { await deleteAgent.mutateAsync(agent.id); navigate("/agents"); }} deleting={deleteAgent.isPending} /> {/* ─── Soul ─── */} {agent.soul && (
Soul
{agent.soul}
)} {/* ─── Tabs ─── */}
{tabs.map((t) => ( ))}
{/* ─── Tab Content ─── */}
{tab === "mission" && } {tab === "activity" && } {tab === "sessions" && } {tab === "inbox" && }
); } function ActivityTab({ logs, rgb }: { logs: any[]; rgb: string }) { if (!logs || logs.length === 0) { return

No activity yet.

; } return (
{logs.map((log: any) => (
{formatRelative(log.created_at)} {log.action} {log.task_title && {log.task_title}}
))}
); } function SessionsTab({ sessions, color }: { sessions: any[]; color: string }) { if (sessions.length === 0) { return

No sessions yet.

; } return (
{sessions.map((s: any) => { const isActive = s.status === "active"; return (
{formatRelative(s.created_at)} {s.id.slice(0, 12)} {s.status} {s.machine_name && {s.machine_name}}
); })}
); } function IdentityModal({ open, onOpenChange, fingerprint, publicKey, rgb, }: { open: boolean; onOpenChange: (open: boolean) => void; fingerprint: string; publicKey: string; color: string; rgb: string; }) { const formatFullFingerprint = (fp: string) => fp.match(/.{2}/g)?.join(":") ?? fp; return ( Cryptographic Identity Agent cryptographic identity details
Fingerprint
{formatFullFingerprint(fingerprint)}
Ed25519 Public Key
{publicKey}
); } function DeleteAgentDialog({ open, onOpenChange, agentName, onConfirm, deleting, }: { open: boolean; onOpenChange: (open: boolean) => void; agentName: string; onConfirm: () => Promise; deleting: boolean; }) { const [error, setError] = useState(null); async function handleConfirm() { setError(null); try { await onConfirm(); } catch (err: any) { setError(err.message); } } return ( Delete agent Delete agent {agentName}? This cannot be undone. {error &&

{error}

}
); } interface InboxMessage { id: string; from_address: string; from_name: string; subject: string; received_at: string; } interface InboxMessageDetail extends InboxMessage { body_html: string; body_text: string; } function EmailBody({ html, text }: { html: string; text: string }) { return (
); } function InboxTab({ agentId, email }: { agentId: string; email: string }) { const [emails, setEmails] = useState([]); const [loading, setLoading] = useState(true); const [selectedEmail, setSelectedEmail] = useState(null); const [loadingEmail, setLoadingEmail] = useState(false); const [error, setError] = useState(null); useEffect(() => { setLoading(true); setError(null); api.agents .inbox(agentId) .then((res) => setEmails(res.emails)) .catch((err) => setError(err.message)) .finally(() => setLoading(false)); }, [agentId]); async function handleViewEmail(emailId: string) { if (selectedEmail?.id === emailId) { setSelectedEmail(null); return; } setLoadingEmail(true); setError(null); try { const detail = await api.agents.inboxEmail(agentId, emailId); setSelectedEmail(detail); } catch (err: any) { setError(err.message); } finally { setLoadingEmail(false); } } if (loading) return

Loading inbox...

; if (error) return

{error}

; return (
{email}
{emails.length === 0 ? (

No emails yet.

) : (
{emails.map((msg) => (
handleViewEmail(msg.id)} >
{msg.subject}
{msg.from_name || msg.from_address}
{new Date(msg.received_at).toLocaleDateString()}
{selectedEmail?.id === msg.id && (
{loadingEmail ? (

Loading...

) : ( )}
)}
))}
)}
); } function MissionTab({ task, color, rgb }: { task: any; color: string; rgb: string }) { if (!task) { return

No active mission.

; } return ( {task.status.replace("_", " ")} {task.title} {task.pr_url && ( e.stopPropagation()} className="text-[11px] font-mono text-content-tertiary hover:text-content-secondary" > PR → )} {task.repository_name && {task.repository_name}} ); }