import { getAvatarLabel, getMessageClass } from "./messageUtils"; import renderContentPart from "./renderContentPart"; import type { TimelineEntry } from "./types"; const ChatMessages = ({ entries, sessionError, eventError, messagesEndRef }: { entries: TimelineEntry[]; sessionError: string | null; eventError: string | null; messagesEndRef: React.RefObject; }) => { return (
{entries.map((entry) => { if (entry.kind === "meta") { const messageClass = entry.meta?.severity === "error" ? "error" : "system"; return (
{getAvatarLabel(messageClass)}
{entry.meta?.title ?? "Status"}
{entry.meta?.detail &&
{entry.meta.detail}
}
); } const item = entry.item; if (!item) return null; const hasParts = (item.content ?? []).length > 0; const isInProgress = item.status === "in_progress"; const isFailed = item.status === "failed"; const messageClass = getMessageClass(item); const statusValue = item.status ?? ""; const statusLabel = statusValue && statusValue !== "completed" ? statusValue.replace("_", " ") : ""; const kindLabel = item.kind.replace("_", " "); return (
{getAvatarLabel(isFailed ? "error" : messageClass)}
{(item.kind !== "message" || item.status !== "completed") && (
{kindLabel} {statusLabel && ( {statusLabel} )}
)} {hasParts ? ( (item.content ?? []).map(renderContentPart) ) : entry.deltaText ? ( {entry.deltaText} {isInProgress && } ) : isInProgress ? ( ) : ( No content yet. )}
); })} {sessionError &&
{sessionError}
} {eventError &&
{eventError}
}
); }; export default ChatMessages;