From eb0eb26f4cefa4880c895ff017f312e8674f9b73 Mon Sep 17 00:00:00 2001 From: karpathy Date: Sat, 22 Nov 2025 14:27:53 -0800 Subject: v0 --- frontend/src/components/ChatInterface.jsx | 117 ++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 frontend/src/components/ChatInterface.jsx (limited to 'frontend/src/components/ChatInterface.jsx') diff --git a/frontend/src/components/ChatInterface.jsx b/frontend/src/components/ChatInterface.jsx new file mode 100644 index 0000000..951183f --- /dev/null +++ b/frontend/src/components/ChatInterface.jsx @@ -0,0 +1,117 @@ +import { useState, useEffect, useRef } from 'react'; +import ReactMarkdown from 'react-markdown'; +import Stage1 from './Stage1'; +import Stage2 from './Stage2'; +import Stage3 from './Stage3'; +import './ChatInterface.css'; + +export default function ChatInterface({ + conversation, + onSendMessage, + isLoading, +}) { + const [input, setInput] = useState(''); + const messagesEndRef = useRef(null); + + const scrollToBottom = () => { + messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + }; + + useEffect(() => { + scrollToBottom(); + }, [conversation]); + + const handleSubmit = (e) => { + e.preventDefault(); + if (input.trim() && !isLoading) { + onSendMessage(input); + setInput(''); + } + }; + + const handleKeyDown = (e) => { + // Submit on Enter (without Shift) + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + handleSubmit(e); + } + }; + + if (!conversation) { + return ( +
+
+

Welcome to LLM Council

+

Create a new conversation to get started

+
+
+ ); + } + + return ( +
+
+ {conversation.messages.length === 0 ? ( +
+

Start a conversation

+

Ask a question to consult the LLM Council

+
+ ) : ( + conversation.messages.map((msg, index) => ( +
+ {msg.role === 'user' ? ( +
+
You
+
+
+ {msg.content} +
+
+
+ ) : ( +
+
LLM Council
+ + + +
+ )} +
+ )) + )} + + {isLoading && ( +
+
+ Consulting the council... +
+ )} + +
+
+ +
+