| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>LLM Chat App with Streamlit</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .chat-message { |
| border-radius: 1rem; |
| padding: 1rem; |
| margin-bottom: 1rem; |
| max-width: 80%; |
| } |
| .user-message { |
| background-color: #3b82f6; |
| color: white; |
| margin-left: auto; |
| border-bottom-right-radius: 0; |
| } |
| .assistant-message { |
| background-color: #f3f4f6; |
| margin-right: auto; |
| border-bottom-left-radius: 0; |
| } |
| .typing-indicator { |
| display: flex; |
| padding: 1rem; |
| } |
| .typing-dot { |
| width: 8px; |
| height: 8px; |
| border-radius: 50%; |
| background-color: #6b7280; |
| margin: 0 2px; |
| animation: typing 1.4s infinite ease-in-out; |
| } |
| .typing-dot:nth-child(1) { |
| animation-delay: 0s; |
| } |
| .typing-dot:nth-child(2) { |
| animation-delay: 0.2s; |
| } |
| .typing-dot:nth-child(3) { |
| animation-delay: 0.4s; |
| } |
| @keyframes typing { |
| 0%, 60%, 100% { |
| transform: translateY(0); |
| } |
| 30% { |
| transform: translateY(-5px); |
| } |
| } |
| .sidebar-option:hover { |
| background-color: rgba(59, 130, 246, 0.1); |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50 min-h-screen"> |
| <div class="flex h-screen"> |
| |
| <div class="w-64 bg-white border-r border-gray-200 p-4 hidden md:block"> |
| <div class="flex items-center mb-8"> |
| <i class="fas fa-robot text-blue-500 text-2xl mr-2"></i> |
| <h1 class="text-xl font-bold text-gray-800">LLM Playground</h1> |
| </div> |
| |
| <div class="mb-6"> |
| <button class="w-full bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-lg mb-2 flex items-center justify-center"> |
| <i class="fas fa-plus mr-2"></i> New Chat |
| </button> |
| </div> |
| |
| <div class="mb-6"> |
| <h2 class="text-sm font-semibold text-gray-500 uppercase tracking-wider mb-2">Models</h2> |
| <div class="space-y-1"> |
| <div class="sidebar-option flex items-center p-2 rounded-lg cursor-pointer"> |
| <i class="fas fa-bolt text-yellow-500 mr-2"></i> |
| <span>GPT-4</span> |
| </div> |
| <div class="sidebar-option flex items-center p-2 rounded-lg cursor-pointer"> |
| <i class="fas fa-brain text-purple-500 mr-2"></i> |
| <span>Claude 2</span> |
| </div> |
| <div class="sidebar-option flex items-center p-2 rounded-lg cursor-pointer"> |
| <i class="fas fa-feather text-green-500 mr-2"></i> |
| <span>Llama 2</span> |
| </div> |
| </div> |
| </div> |
| |
| <div class="mb-6"> |
| <h2 class="text-sm font-semibold text-gray-500 uppercase tracking-wider mb-2">History</h2> |
| <div class="space-y-1"> |
| <div class="sidebar-option flex items-center p-2 rounded-lg cursor-pointer"> |
| <i class="fas fa-comment mr-2 text-gray-400"></i> |
| <span class="truncate">Python code review</span> |
| </div> |
| <div class="sidebar-option flex items-center p-2 rounded-lg cursor-pointer"> |
| <i class="fas fa-comment mr-2 text-gray-400"></i> |
| <span class="truncate">Marketing copy ideas</span> |
| </div> |
| <div class="sidebar-option flex items-center p-2 rounded-lg cursor-pointer"> |
| <i class="fas fa-comment mr-2 text-gray-400"></i> |
| <span class="truncate">Travel recommendations</span> |
| </div> |
| </div> |
| </div> |
| |
| <div class="absolute bottom-4 left-4 right-4"> |
| <div class="flex items-center p-2 rounded-lg hover:bg-gray-100 cursor-pointer"> |
| <i class="fas fa-cog text-gray-500 mr-2"></i> |
| <span>Settings</span> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="flex-1 flex flex-col overflow-hidden"> |
| |
| <div class="md:hidden bg-white border-b border-gray-200 p-4 flex items-center"> |
| <button id="menu-toggle" class="mr-4"> |
| <i class="fas fa-bars text-gray-600"></i> |
| </button> |
| <h1 class="text-lg font-bold text-gray-800">LLM Chat</h1> |
| </div> |
| |
| |
| <div class="flex-1 overflow-y-auto p-4 bg-gray-50"> |
| <div class="max-w-3xl mx-auto space-y-4"> |
| |
| <div class="chat-message assistant-message"> |
| <div class="flex items-start"> |
| <div class="bg-blue-500 text-white rounded-full w-8 h-8 flex items-center justify-center mr-2"> |
| <i class="fas fa-robot"></i> |
| </div> |
| <div> |
| <p class="font-semibold">AI Assistant</p> |
| <p>Hello! I'm your AI assistant. How can I help you today? You can ask me anything from coding help to creative writing.</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="chat-message user-message"> |
| <div class="flex items-start"> |
| <div class="bg-gray-200 rounded-full w-8 h-8 flex items-center justify-center mr-2"> |
| <i class="fas fa-user text-gray-600"></i> |
| </div> |
| <div> |
| <p class="font-semibold">You</p> |
| <p>Can you explain how to create a Streamlit app for LLMs?</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="chat-message assistant-message"> |
| <div class="flex items-start"> |
| <div class="bg-blue-500 text-white rounded-full w-8 h-8 flex items-center justify-center mr-2"> |
| <i class="fas fa-robot"></i> |
| </div> |
| <div> |
| <p class="font-semibold">AI Assistant</p> |
| <p>Certainly! Here's a basic structure for a Streamlit app that interacts with an LLM:</p> |
| <pre class="bg-gray-800 text-white p-3 rounded mt-2 overflow-x-auto"><code>import streamlit as st |
| from openai import OpenAI |
|
|
| # Set up the page |
| st.set_page_config(page_title="LLM Chat App", page_icon="🤖") |
|
|
| # Initialize the OpenAI client |
| client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"]) |
|
|
| # Sidebar for settings |
| with st.sidebar: |
| st.title("LLM Settings") |
| model = st.selectbox("Choose a model", ["gpt-4", "gpt-3.5-turbo"]) |
| temperature = st.slider("Temperature", 0.0, 1.0, 0.7) |
|
|
| # Main chat interface |
| st.title("💬 LLM Chat") |
| if "messages" not in st.session_state: |
| st.session_state.messages = [] |
|
|
| # Display chat messages |
| for message in st.session_state.messages: |
| with st.chat_message(message["role"]): |
| st.markdown(message["content"]) |
|
|
| # Chat input |
| if prompt := st.chat_input("What would you like to ask?"): |
| st.session_state.messages.append({"role": "user", "content": prompt}) |
| with st.chat_message("user"): |
| st.markdown(prompt) |
| |
| with st.chat_message("assistant"): |
| response = client.chat.completions.create( |
| model=model, |
| messages=st.session_state.messages, |
| temperature=temperature |
| ) |
| reply = response.choices[0].message.content |
| st.markdown(reply) |
| |
| st.session_state.messages.append({"role": "assistant", "content": reply})</code></pre> |
| <p class="mt-2">To run this, you'll need to install Streamlit (<code>pip install streamlit</code>) and the OpenAI package (<code>pip install openai</code>). Then save this as <code>app.py</code> and run with <code>streamlit run app.py</code>.</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="typing-indicator hidden" id="typing-indicator"> |
| <div class="bg-blue-500 text-white rounded-full w-8 h-8 flex items-center justify-center mr-2"> |
| <i class="fas fa-robot"></i> |
| </div> |
| <div class="flex items-center"> |
| <div class="typing-dot"></div> |
| <div class="typing-dot"></div> |
| <div class="typing-dot"></div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white border-t border-gray-200 p-4"> |
| <div class="max-w-3xl mx-auto"> |
| <form id="chat-form" class="flex space-x-2"> |
| <input |
| type="text" |
| id="user-input" |
| placeholder="Type your message here..." |
| class="flex-1 border border-gray-300 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" |
| autocomplete="off" |
| > |
| <button |
| type="submit" |
| class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center" |
| > |
| <i class="fas fa-paper-plane mr-2"></i> Send |
| </button> |
| </form> |
| <div class="flex justify-between mt-2 text-xs text-gray-500"> |
| <div> |
| <button class="mr-2 hover:text-blue-500"> |
| <i class="fas fa-code mr-1"></i> Code |
| </button> |
| <button class="hover:text-blue-500"> |
| <i class="fas fa-image mr-1"></i> Image |
| </button> |
| </div> |
| <div> |
| <span>Model: GPT-4</span> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| |
| document.getElementById('menu-toggle').addEventListener('click', function() { |
| document.querySelector('.sidebar').classList.toggle('hidden'); |
| }); |
| |
| |
| document.getElementById('chat-form').addEventListener('submit', function(e) { |
| e.preventDefault(); |
| const input = document.getElementById('user-input'); |
| const message = input.value.trim(); |
| |
| if (message) { |
| |
| const chatArea = document.querySelector('.max-w-3xl'); |
| const userMessage = document.createElement('div'); |
| userMessage.className = 'chat-message user-message'; |
| userMessage.innerHTML = ` |
| <div class="flex items-start"> |
| <div class="bg-gray-200 rounded-full w-8 h-8 flex items-center justify-center mr-2"> |
| <i class="fas fa-user text-gray-600"></i> |
| </div> |
| <div> |
| <p class="font-semibold">You</p> |
| <p>${message}</p> |
| </div> |
| </div> |
| `; |
| chatArea.appendChild(userMessage); |
| |
| |
| const typingIndicator = document.getElementById('typing-indicator'); |
| typingIndicator.classList.remove('hidden'); |
| |
| |
| input.value = ''; |
| |
| |
| chatArea.scrollTop = chatArea.scrollHeight; |
| |
| |
| setTimeout(() => { |
| typingIndicator.classList.add('hidden'); |
| |
| const assistantMessage = document.createElement('div'); |
| assistantMessage.className = 'chat-message assistant-message'; |
| assistantMessage.innerHTML = ` |
| <div class="flex items-start"> |
| <div class="bg-blue-500 text-white rounded-full w-8 h-8 flex items-center justify-center mr-2"> |
| <i class="fas fa-robot"></i> |
| </div> |
| <div> |
| <p class="font-semibold">AI Assistant</p> |
| <p>I'm a simulated response in this demo. In a real Streamlit app, this would be the LLM's actual response to: "${message}"</p> |
| </div> |
| </div> |
| `; |
| chatArea.appendChild(assistantMessage); |
| |
| |
| chatArea.scrollTop = chatArea.scrollHeight; |
| }, 1500); |
| } |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=jasvir-singh1021/streamlit-app-llms" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |