User: What programming language is this:&nbsp;<code fileName="ChatInterface.js" notes="">// src/components/ChatInterface.js
import React, { useState, useContext, useRef, useEffect } from &quot;react&quot;;
import { ChatContext } from &quot;../context/ChatContext&quot;;
import Message from &quot;./Message&quot;;
import CodeModal from &quot;./CodeModal&quot;;
import InlineCodeEditor from &quot;./InlineCodeEditor&quot;;
import { escapeHtml } from &quot;../utils/escapeHtml&quot;;

function ChatInterface() {
  const {
    chats,
    currentChatId,
    addMessage,
    updateChat,
    selectedModelId,
    models,
  } = useContext(ChatContext);
  const currentChat = chats.find((chat) =&gt; chat.id === currentChatId);
  const [message, setMessage] = useState(&quot;&quot;);
  const [isTyping, setIsTyping] = useState(false);
  const messagesEndRef = useRef(null);
  const [isCodeModalOpen, setIsCodeModalOpen] = useState(false);
  const [currentEditingCode, setCurrentEditingCode] = useState(null);
  const [isSystemPromptOpen, setIsSystemPromptOpen] = useState(false);
  const [codeAttachments, setCodeAttachments] = useState([]);

  const addCodeAttachment = ({ codeContent, fileName, notes }) =&gt; {
    const escapedCode = escapeHtml(codeContent);
    const escapedFileName = escapeHtml(fileName || &quot;untitled&quot;);
    const escapedNotes = escapeHtml(notes || &quot;&quot;);
    const codeTag = `&lt;code fileName=&quot;${escapedFileName}&quot; notes=&quot;${escapedNotes}&quot;&gt;${escapedCode}&lt;/code&gt;`;
    setMessage((prev) =&gt; prev + codeTag);
  };

  const handleAttachCode = (codeSegment) =&gt; {
    setCurrentEditingCode(codeSegment);
    setIsCodeModalOpen(true);
  };

  const handleCodeSave = (updatedCode) =&gt; {
    if (currentEditingCode) {
      // Update existing code
      const escapedCode = escapeHtml(updatedCode.codeContent);
      const escapedFileName = escapeHtml(updatedCode.fileName || &quot;untitled&quot;);
      const escapedNotes = escapeHtml(updatedCode.notes || &quot;&quot;);

      // Improved regex to handle multi-line and special characters
      const regex = new RegExp(
        `&lt;code\\s+fileName=&quot;${currentEditingCode.fileName}&quot;\\s+notes=&quot;${currentEditingCode.notes}&quot;&gt;([\\s\\S]*?)&lt;\\/code&gt;`
      );

      const updatedMessage = message.replace(
        regex,
        `&lt;code fileName=&quot;${escapedFileName}&quot; notes=&quot;${escapedNotes}&quot;&gt;${escapedCode}&lt;/code&gt;`
      );
      setMessage(updatedMessage);
    } else {
      // Add new code
      addCodeAttachment(updatedCode);
    }
    setIsCodeModalOpen(false);
    setCurrentEditingCode(null);
  };

  const handleSend = async () =&gt; {
    if (!message.trim() || !currentChatId || !selectedModelId) return;

    // Retrieve the system prompt from the current chat
    const systemPrompt = currentChat.systemPrompt || &quot;&quot;;

    // Combine the system prompt with the user message
    // Ensure there&#039;s a separator (like a newline) for clarity
    const fullMessage = systemPrompt ? `${systemPrompt}\n${message}` : message;

    const userMessage = { sender: &quot;user&quot;, text: message };
    addMessage(currentChatId, userMessage);
    setMessage(&quot;&quot;);
    scrollToBottom();

    // Set typing indicator
    setIsTyping(true);

    try {
      const response = await fetch(&quot;http://localhost:8000/api/chat&quot;, {
        method: &quot;POST&quot;,
        headers: { &quot;Content-Type&quot;: &quot;application/json&quot; },
        body: JSON.stringify({
          text: fullMessage,
          model_id: selectedModelId, // Ensure this is correctly set
        }),
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(
          errorData.detail || &quot;Failed to get response from the server.&quot;
        );
      }

      const data = await response.json();
      const responseText = data.response;
      const responseModelId = data.model_id; // Extract model_id from response

      const botMessage = {
        sender: &quot;bot&quot;,
        text: responseText,
        model_id: responseModelId, // Include model_id
      };
      addMessage(currentChatId, botMessage);
      scrollToBottom();
    } catch (error) {
      console.error(&quot;Error:&quot;, error);
      const errorMessage = {
        sender: &quot;bot&quot;,
        text: &quot;Sorry, something went wrong. Please try again.&quot;,
      };
      addMessage(currentChatId, errorMessage);
      scrollToBottom();
    } finally {
      // Remove typing indicator
      setIsTyping(false);
    }
  };

  const handleKeyDown = (e) =&gt; {
    if (e.key === &quot;Enter&quot; &amp;&amp; !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  };

  const scrollToBottom = () =&gt; {
    messagesEndRef.current?.scrollIntoView({ behavior: &quot;smooth&quot; });
  };

  if (!currentChat) {
    return (
      &lt;div className=&quot;flex-1 p-4&quot;&gt;No active chat. Please start a new chat.&lt;/div&gt;
    );
  }

  const handleSystemPromptChange = (e) =&gt; {
    const newPrompt = e.target.value;
    updateChat(currentChatId, { systemPrompt: newPrompt });
  };

  const toggleSystemPrompt = () =&gt; {
    setIsSystemPromptOpen(!isSystemPromptOpen);
  };

  return (
    &lt;div className=&quot;flex flex-col h-screen&quot;&gt;
      &lt;div className=&quot;flex-1 p-32 pt-8 pb-8 overflow-y-auto bg-[#eeeeee] dark:bg-[#161618]&quot;&gt;
        {/* Removed Model Selector Dropdown */}

        {/* Chat Messages */}
        {currentChat.messages.map((msg, index) =&gt; (
          &lt;Message
            key={index}
            chatId={currentChatId}
            messageIndex={index}
            sender={msg.sender}
            text={msg.text}
            model_id={msg.model_id} // Pass model_id
          /&gt;
        ))}
        {isTyping &amp;&amp; (
          &lt;div className=&quot;mb-4 flex justify-start&quot;&gt;
            &lt;div className=&quot;max-w-xs md:max-w-md lg:max-w-lg p-3 rounded-lg bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200 flex items-center&quot;&gt;
              &lt;div className=&quot;flex space-x-1 mr-2&quot;&gt;
                &lt;div className=&quot;w-2 h-2 bg-gray-600 rounded-full animate-bounce-custom animation-delay-0&quot;&gt;&lt;/div&gt;
                &lt;div className=&quot;w-2 h-2 bg-gray-600 rounded-full animate-bounce-custom animation-delay-200&quot;&gt;&lt;/div&gt;
                &lt;div className=&quot;w-2 h-2 bg-gray-600 rounded-full animate-bounce-custom animation-delay-400&quot;&gt;&lt;/div&gt;
              &lt;/div&gt;
              &lt;span className=&quot;text-sm&quot;&gt;Echo is typing...&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        )}
        &lt;div ref={messagesEndRef} /&gt;
      &lt;/div&gt;
      &lt;div
        id=&quot;message_area&quot;
        className=&quot;p-4 border-t dark:border-gray-700 bg-white dark:bg-[#161618]&quot;
      &gt;
        &lt;button
          onClick={toggleSystemPrompt}
          className=&quot;mb-2 text-sm text-blue-500 hover:underline focus:outline-none&quot;
        &gt;
          {isSystemPromptOpen ? &quot;Hide System Prompt&quot; : &quot;Show System Prompt&quot;}
        &lt;/button&gt;
        {isSystemPromptOpen &amp;&amp; (
          &lt;textarea
            className=&quot;w-full p-2 border rounded-lg resize-none dark:bg-gray-800 dark:text-gray-200 mb-2&quot;
            rows=&quot;3&quot;
            placeholder=&quot;Enter system prompt...&quot;
            value={currentChat.systemPrompt}
            onChange={handleSystemPromptChange}
          /&gt;
        )}
        &lt;div className=&quot;flex flex-row&quot;&gt;
          &lt;div className=&quot;flex-grow&quot;&gt;
            &lt;InlineCodeEditor
              value={message}
              onChange={setMessage}
              onAttachCode={handleAttachCode}
            /&gt;
          &lt;/div&gt;
          &lt;div className=&quot;flex flex-col items-end pl-4&quot;&gt;
            &lt;button
              onClick={() =&gt; setIsCodeModalOpen(true)}
              className=&quot;bg-blue-500 text-white px-3 py-2 rounded-lg hover:bg-blue-600 flex-grow w-full&quot;
            &gt;
              Attach Code
            &lt;/button&gt;
            &lt;button
              className=&quot;bg-green-500 text-white px-4 py-2 rounded-lg hover:bg-green-600 flex-grow mt-2 w-full&quot;
              onClick={handleSend}
            &gt;
              Send
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      {isCodeModalOpen &amp;&amp; (
        &lt;CodeModal
          onClose={() =&gt; {
            setIsCodeModalOpen(false);
            setCurrentEditingCode(null);
          }}
          onSave={handleCodeSave}
          initialData={currentEditingCode}
        /&gt;
      )}
    &lt;/div&gt;
  );
}

export default ChatInterface;
</code>