import { AlertTriangleIcon, ArrowLeftIcon, AudioLinesIcon, TerminalIcon } from "lucide-react";
import { UserMessageBody as CollapsibleUserMessageBody } from "../../../components/user-message-body";
import type { UserMessageItem } from "../../../timeline";
import type { TimelineSearchTarget } from "../../../components/timeline-search";
import { lazy, Suspense } from "react";
import { MarkdownText } from "../markdown";
import { Button } from "../../../ui/button";
import { formatTimestamp } from "../../lib/format";
import type { Session } from "../../types";
import { MessageFileSkeletons, MessageRepositoryChips } from "./message-resource-placeholders";
const MessageResourceAttachments = lazy(() => import("./message-resource-attachments"));
export function TerminalSessionBanner(props: { session: Session; onNewSession: () => void }) {
return (
This session was cancelled and cannot be continued.
Started {formatTimestamp(props.session.createdAt)}.
);
}
export function TerminalSessionArchive(props: { session: Session; eventCount: number }) {
return (
Cancelled session (read-only)
This is a saved event log from {formatTimestamp(props.session.createdAt)}, not a current
run. Sanitized debug metadata is available in the inspector.
{props.eventCount} timeline item{props.eventCount === 1 ? "" : "s"}
);
}
/** Attachment previews/chips + repository chips + markdown body inside the user bubble. */
export function UserMessageBody({
workspaceId,
sessionId,
item,
searchTarget,
}: {
workspaceId: string;
sessionId?: string | undefined;
item: UserMessageItem;
searchTarget?: TimelineSearchTarget | null | undefined;
}) {
const hasFiles = item.resources.some((resource) => resource.kind === "file");
const repositoryChips = item.resources.some((resource) => resource.kind === "repository") ? (
) : null;
return (
{item.presentation ? (
{item.presentation.kind === "realtime_voice_handoff" ? "Voice handoff" : "Voice request"}
) : null}
{hasFiles ? (
{repositoryChips}
>
}
>
) : (
repositoryChips
)}
{item.presentation ? (
Context sent to agent
{item.presentation.context}
) : null}
);
}