import * as React from "react"; import { Bot, Brain, ChevronDown, Radio, TerminalSquare } from "lucide-react"; import { resolveUserLabel, type UserProfileLookup, } from "@/features/profile/lib/identity"; import { cn } from "@/shared/lib/cn"; import { Markdown } from "@/shared/ui/markdown"; import { UserAvatar } from "@/shared/ui/UserAvatar"; import type { TranscriptItem } from "./agentSessionTypes"; import { ToolItem } from "./AgentSessionToolItem"; import { formatTranscriptTime } from "./agentSessionUtils"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/shared/ui/tooltip"; export function AgentSessionTranscriptList({ agentName, emptyDescription, items, profiles, }: { agentName: string; emptyDescription: string; items: TranscriptItem[]; profiles?: UserProfileLookup; }) { if (items.length === 0) { return (

No ACP activity yet

{emptyDescription}

); } return (
{items.map((item) => (
))}
); } const TranscriptItemView = React.memo(function TranscriptItemView({ agentName, item, profiles, }: { agentName: string; item: TranscriptItem; profiles?: UserProfileLookup; }) { if (item.type === "message") { return ( ); } if (item.type === "tool") { return ; } if (item.type === "thought") { return ; } if (item.type === "metadata") { return ; } return ; }); function MessageItem({ agentName, item, profiles, }: { agentName: string; item: Extract; profiles?: UserProfileLookup; }) { const isAssistant = item.role === "assistant"; const text = item.text.trim(); const authorProfile = item.authorPubkey ? profiles?.[item.authorPubkey.toLowerCase()] : null; const authorLabel = item.authorPubkey ? resolveUserLabel({ pubkey: item.authorPubkey, fallbackName: item.title, profiles, }) : item.title || "User"; return (
{!isAssistant ? ( ) : null}
{isAssistant ? (
{agentName}
) : null}
{isAssistant ? ( ) : ( <>

{text}

)}
); } function ThoughtItem({ item, }: { item: Extract; }) { return (
{item.title}
); } function MetadataItem({ item, }: { item: Extract; }) { return (
{item.title} {item.sections.length} section{item.sections.length === 1 ? "" : "s"}
{item.sections.map((section) => (
{section.title}
              {section.body.trim() || "No metadata."}
            
))}
); } function LifecycleItem({ item, }: { item: Extract; }) { const isError = item.title.toLowerCase().includes("error"); return (
{item.title} {item.text ? - {item.text} : null}
); } const fullDateTimeFormat = new Intl.DateTimeFormat(undefined, { weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "2-digit", second: "2-digit", }); function TranscriptTimestamp({ timestamp }: { timestamp: string }) { const formatted = formatTranscriptTime(timestamp); if (!formatted) return null; const date = new Date(timestamp); const fullDateTime = Number.isNaN(date.getTime()) ? timestamp : fullDateTimeFormat.format(date); return ( {formatted} {fullDateTime} ); }