"use client"; import { useMemo, useState } from "react"; import { useTranslations } from "next-intl"; import { AlertTriangle, Bot, Code, MessagesSquare, Terminal, User as UserIcon, Wrench } from "lucide-react"; import { Button } from "@app/components/ui/button"; import type { NormalizedAiMessage } from "@server/lib/aiMessageNormalization"; type AiSessionChatViewProps = { normalizedRequest: string | null; normalizedResponse: string | null; requestBody: string | null; responseBody: string | null; truncated: boolean; }; function parseMessages(json: string | null): NormalizedAiMessage[] | null { if (!json) return null; try { const parsed = JSON.parse(json); return Array.isArray(parsed) ? (parsed as NormalizedAiMessage[]) : null; } catch { return null; } } function prettyRaw(raw: string | null): string | null { if (!raw) return null; try { return JSON.stringify(JSON.parse(raw), null, 2); } catch { return raw; } } function MessageBubble({ message }: { message: NormalizedAiMessage }) { const isUser = message.role === "user"; const isSystem = message.role === "system"; const isTool = message.role === "tool"; if (isSystem) { return (
                    {message.content}
                
); } return (
{isUser ? ( ) : isTool ? ( ) : ( )}
{message.content || (   )}
); } function RawFallbackBlock({ label, raw, noDataLabel, unparsedLabel }: { label: string; raw: string | null; noDataLabel: string; unparsedLabel?: string; }) { const pretty = prettyRaw(raw); return (
{label} {pretty && unparsedLabel && ( {unparsedLabel} )}
                {pretty ?? noDataLabel}
            
); } export function AiSessionChatView({ normalizedRequest, normalizedResponse, requestBody, responseBody, truncated }: AiSessionChatViewProps) { const t = useTranslations(); const [rawMode, setRawMode] = useState(false); const requestMessages = useMemo( () => parseMessages(normalizedRequest), [normalizedRequest] ); const responseMessages = useMemo( () => parseMessages(normalizedResponse), [normalizedResponse] ); const hasRequestMessages = !!requestMessages && requestMessages.length > 0; const hasResponseMessages = !!responseMessages && responseMessages.length > 0; return (
{truncated ? (
{t("aiSessionLogTruncated")}
) : (
)}
{rawMode ? (
) : (
{hasRequestMessages ? ( requestMessages!.map((message, i) => ( )) ) : ( )} {hasResponseMessages ? ( responseMessages!.map((message, i) => ( )) ) : ( )}
)}
); }