import { useEffect, useMemo, useState } from 'react' import { cn } from '@/lib/utils' import { Button } from '@/components/ui/button' import { Textarea } from '@/components/ui/textarea' import { Branch, BranchMessages, BranchNext, BranchPage, BranchPrevious, BranchSelector, } from '@/components/ai-elements/branch' import { Conversation, ConversationContent, ConversationScrollButton, } from '@/components/ai-elements/conversation' import { Loader } from '@/components/ai-elements/loader' import { Message, MessageContent } from '@/components/ai-elements/message' import { Reasoning, ReasoningContent, ReasoningTrigger, } from '@/components/ai-elements/reasoning' import { Response } from '@/components/ai-elements/response' import { Shimmer } from '@/components/ai-elements/shimmer' import { Source, Sources, SourcesContent, SourcesTrigger, } from '@/components/ai-elements/sources' import { MESSAGE_ROLES } from '../constants' import { getMessageContentStyles } from '../lib/message-styles' import { parseThinkTags } from '../lib/message-utils' import type { Message as MessageType } from '../types' import { MessageActions } from './message-actions' import { MessageError } from './message-error' interface PlaygroundChatProps { messages: MessageType[] onCopyMessage?: (message: MessageType) => void onRegenerateMessage?: (message: MessageType) => void onEditMessage?: (message: MessageType) => void onDeleteMessage?: (message: MessageType) => void isGenerating?: boolean editingKey?: string | null onSaveEdit?: (newContent: string) => void onCancelEdit?: (open: boolean) => void onSaveEditAndSubmit?: (newContent: string) => void } export function PlaygroundChat({ messages, onCopyMessage, onRegenerateMessage, onEditMessage, onDeleteMessage, isGenerating = false, editingKey, onSaveEdit, onCancelEdit, onSaveEditAndSubmit, }: PlaygroundChatProps) { const [editText, setEditText] = useState('') const [originalText, setOriginalText] = useState('') useEffect(() => { if (!editingKey) return const message = messages.find((m) => m.key === editingKey) const content = message?.versions?.[0]?.content || '' // eslint-disable-next-line react-hooks/set-state-in-effect setEditText(content) setOriginalText(content) }, [editingKey, messages]) const isEditing = (key: string) => editingKey === key const isEmpty = useMemo(() => !editText.trim(), [editText]) const isChanged = useMemo( () => editText !== originalText, [editText, originalText] ) return ( {/* Remove outer padding; apply padding to inner centered container to align with input */}
{messages.map((message, messageIndex) => { const { versions = [] } = message const isLastAssistantMessage = messageIndex === messages.length - 1 && message.from === MESSAGE_ROLES.ASSISTANT return ( {versions.map((version, versionIndex) => (
{isEditing(message.key) ? (