({ content }: { content: string })
| 35 | } |
| 36 | |
| 37 | function StreamingMessage({ content }: { content: string }) { |
| 38 | const { stableMarkdown, trailingText } = splitStreamingMarkdown(content); |
| 39 | |
| 40 | return ( |
| 41 | <div className="flex items-start gap-3 mb-6"> |
| 42 | <div className="w-8 h-8 rounded-full bg-gradient-to-br from-[#C15F3C] to-[#D47A5A] flex items-center justify-center flex-shrink-0"> |
| 43 | <svg className="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| 44 | <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" /> |
| 45 | </svg> |
| 46 | </div> |
| 47 | <div className="max-w-[80%] bg-[#1C1C1C] border border-[#333333] rounded-2xl rounded-tl-md px-4 py-3"> |
| 48 | {stableMarkdown && ( |
| 49 | <ReactMarkdown |
| 50 | remarkPlugins={[remarkGfm]} |
| 51 | className="prose prose-sm prose-invert max-w-none text-sm leading-relaxed [&>:first-child]:mt-0 [&>:last-child]:mb-0 [&_:not(pre)>code]:bg-[#0A0A0A] [&_:not(pre)>code]:px-1.5 [&_:not(pre)>code]:py-0.5 [&_:not(pre)>code]:rounded [&_:not(pre)>code]:text-xs [&_pre]:bg-[#0A0A0A] [&_pre]:border [&_pre]:border-[#333333] [&_pre]:rounded-lg [&_pre]:p-4 [&_pre]:overflow-x-auto [&_pre]:my-3 [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:text-xs" |
| 52 | > |
| 53 | {stableMarkdown} |
| 54 | </ReactMarkdown> |
| 55 | )} |
| 56 | {trailingText && ( |
| 57 | <p className="text-sm leading-relaxed whitespace-pre-wrap text-white/95"> |
| 58 | {trailingText} |
| 59 | </p> |
| 60 | )} |
| 61 | </div> |
| 62 | </div> |
| 63 | ); |
| 64 | } |
| 65 | |
| 66 | export function MessageList({ messages, streamingContent, isLoading = false }: MessageListProps) { |
| 67 | const bottomRef = useRef<HTMLDivElement>(null); |
nothing calls this directly
no test coverage detected