Spaces:
Running
Running
| <html> | |
| <head> | |
| <title>LLM ChatCraft Pro</title> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| margin: 0; | |
| padding: 20px; | |
| background-color: #f0f0f0; | |
| } | |
| .container { | |
| width: 95%; | |
| margin: 0 auto; | |
| background-color: white; | |
| border: 1px solid #ccc; | |
| padding: 20px; | |
| } | |
| h1 { | |
| color: #000080; | |
| text-align: center; | |
| font-size: 24px; | |
| } | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| } | |
| td { | |
| vertical-align: top; | |
| padding: 10px; | |
| } | |
| .panel { | |
| border: 1px solid #ccc; | |
| padding: 15px; | |
| margin-bottom: 10px; | |
| background-color: #f8f8f8; | |
| } | |
| input, select, textarea { | |
| border: 1px solid #666; | |
| padding: 4px; | |
| font-family: Arial, sans-serif; | |
| } | |
| button { | |
| background-color: #e0e0e0; | |
| border: 1px solid #666; | |
| padding: 4px 8px; | |
| cursor: pointer; | |
| } | |
| button:hover { | |
| background-color: #d0d0d0; | |
| } | |
| .message-user { | |
| background-color: #e0e8ff; | |
| margin: 5px 0; | |
| padding: 8px; | |
| border: 1px solid #a0a0a0; | |
| } | |
| .message-assistant { | |
| background-color: #f0f0f0; | |
| margin: 5px 0; | |
| padding: 8px; | |
| border: 1px solid #a0a0a0; | |
| } | |
| .chat-container { | |
| height: 300px; | |
| overflow-y: auto; | |
| border: 1px solid #666; | |
| padding: 10px; | |
| background-color: white; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>LLM ChatCraft Pro</h1> | |
| <table> | |
| <tr> | |
| <td width="30%"> | |
| <div class="panel"> | |
| <h2>Settings</h2> | |
| <table width="100%"> | |
| <tr> | |
| <td><b>API Key:</b></td> | |
| </tr> | |
| <tr> | |
| <td><input type="password" id="apiKey" placeholder="Enter your API key" style="width: 95%"></td> | |
| </tr> | |
| <tr> | |
| <td><b>API Endpoint:</b></td> | |
| </tr> | |
| <tr> | |
| <td><input type="text" id="apiEndpoint" placeholder="https://api.openai.com/v1" style="width: 95%"></td> | |
| </tr> | |
| <tr> | |
| <td><b>Model:</b></td> | |
| </tr> | |
| <tr> | |
| <td> | |
| <select id="model" style="width: 95%"> | |
| <option value="gpt-3.5-turbo">gpt-3.5-turbo</option> | |
| <option value="gpt-4">gpt-4</option> | |
| <option value="custom">Custom Model</option> | |
| </select> | |
| </td> | |
| </tr> | |
| <tr id="customModelContainer" style="display: none"> | |
| <td><b>Custom Model:</b></td> | |
| </tr> | |
| <tr id="customModelContainer" style="display: none"> | |
| <td><input type="text" id="customModel" placeholder="Enter custom model name" style="width: 95%"></td> | |
| </tr> | |
| <tr> | |
| <td><button onclick="saveSettings()" style="width: 95%">Save Settings</button></td> | |
| </tr> | |
| </table> | |
| <hr style="border: 1px solid #ccc; margin: 15px 0;"> | |
| <h3>Chat Management</h3> | |
| <table width="100%"> | |
| <tr> | |
| <td><b>Chat Name:</b></td> | |
| </tr> | |
| <tr> | |
| <td><input type="text" id="chatName" placeholder="Enter chat name" style="width: 95%"></td> | |
| </tr> | |
| <tr> | |
| <td><button onclick="saveChat()" style="width: 95%">Save Current Chat</button></td> | |
| </tr> | |
| <tr> | |
| <td><button onclick="loadChatList()" style="width: 95%">Load Saved Chat</button></td> | |
| </tr> | |
| <tr> | |
| <td><div id="chatList"></div></td> | |
| </tr> | |
| </table> | |
| </div> | |
| </td> | |
| <td width="70%"> | |
| <div class="panel"> | |
| <h2>Chat Interface</h2> | |
| <div class="chat-container" id="chatMessages"> | |
| <!-- Chat messages will appear here --> | |
| </div> | |
| <br> | |
| <table width="100%"> | |
| <tr> | |
| <td width="80%"><input type="text" id="userInput" placeholder="Type your message..." style="width: 95%" onkeypress="if(event.key === 'Enter') sendMessage()"></td> | |
| <td width="20%"> | |
| <button onclick="sendMessage()" style="width: 95%">Send</button> | |
| <br><br> | |
| <button onclick="clearChat()" style="width: 95%">Clear</button> | |
| </td> | |
| </tr> | |
| </table> | |
| </div> | |
| </td> | |
| </tr> | |
| </table> | |
| </div> | |
| <script> | |
| // Storage keys | |
| const STORAGE_KEYS = { | |
| SETTINGS: 'llm_chatcraft_settings', | |
| CHATS: 'llm_chatcraft_chats', | |
| CURRENT_CHAT: 'llm_chatcraft_current_chat' | |
| }; | |
| // Current chat state | |
| let currentChat = { | |
| messages: [], | |
| timestamp: Date.now() | |
| }; | |
| // Initialize the application | |
| document.addEventListener('DOMContentLoaded', function() { | |
| loadSettings(); | |
| loadCurrentChat(); | |
| setupEventListeners(); | |
| }); | |
| function setupEventListeners() { | |
| // Model selection change | |
| document.getElementById('model').addEventListener('change', function() { | |
| const customContainer = document.getElementById('customModelContainer'); | |
| customContainer.classList.toggle('hidden', this.value !== 'custom'); | |
| }); | |
| } | |
| function loadSettings() { | |
| const settings = JSON.parse(localStorage.getItem(STORAGE_KEYS.SETTINGS) || '{}'); | |
| document.getElementById('apiKey').value = settings.apiKey || ''; | |
| document.getElementById('apiEndpoint').value = settings.apiEndpoint || 'https://api.openai.com/v1'; | |
| document.getElementById('model').value = settings.model || 'gpt-3.5-turbo'; | |
| document.getElementById('customModel').value = settings.customModel || ''; | |
| const customContainer = document.getElementById('customModelContainer'); | |
| customContainer.classList.toggle('hidden', settings.model !== 'custom'); | |
| } | |
| function saveSettings() { | |
| const settings = { | |
| apiKey: document.getElementById('apiKey').value, | |
| apiEndpoint: document.getElementById('apiEndpoint').value || 'https://api.openai.com/v1', | |
| model: document.getElementById('model').value, | |
| customModel: document.getElementById('customModel').value | |
| }; | |
| localStorage.setItem(STORAGE_KEYS.SETTINGS, JSON.stringify(settings)); | |
| alert('Settings saved successfully!'); | |
| } | |
| function loadCurrentChat() { | |
| const savedChat = localStorage.getItem(STORAGE_KEYS.CURRENT_CHAT); | |
| if (savedChat) { | |
| currentChat = JSON.parse(savedChat); | |
| displayMessages(); | |
| } | |
| } | |
| function saveCurrentChat() { | |
| localStorage.setItem(STORAGE_KEYS.CURRENT_CHAT, JSON.stringify(currentChat)); | |
| } | |
| async function sendMessage() { | |
| const userInput = document.getElementById('userInput'); | |
| const message = userInput.value.trim(); | |
| if (!message) return; | |
| // Add user message to chat | |
| addMessage('user', message); | |
| userInput.value = ''; | |
| // Get settings | |
| const settings = JSON.parse(localStorage.getItem(STORAGE_KEYS.SETTINGS) || '{}'; | |
| if (!settings.apiKey) { | |
| addMessage('assistant', 'Please set your API key in the settings first.'); | |
| return; | |
| } | |
| try { | |
| const response = await fetch(`${settings.apiEndpoint}/chat/completions`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${settings.apiKey}` | |
| }, | |
| body: JSON.stringify({ | |
| model: settings.model === 'custom' ? settings.customModel : settings.model, | |
| messages: currentChat.messages, | |
| stream: false | |
| }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`API error: ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| const assistantMessage = data.choices[0].message.content; | |
| addMessage('assistant', assistantMessage); | |
| } catch (error) { | |
| addMessage('assistant', `Error: ${error.message}. Please check your settings and try again.`); | |
| } | |
| } | |
| function addMessage(role, content) { | |
| currentChat.messages.push({ role, content, timestamp: Date.now() }); | |
| displayMessages(); | |
| saveCurrentChat(); | |
| } | |
| function displayMessages() { | |
| const chatMessages = document.getElementById('chatMessages'); | |
| chatMessages.innerHTML = ''; | |
| currentChat.messages.forEach(message => { | |
| const messageDiv = document.createElement('div'); | |
| messageDiv.className = `p-3 rounded mb-2 ${role === 'user' ? 'message-user' : 'message-assistant'}`; | |
| messageDiv.textContent = `${role === 'user' ? 'You: ' : 'Assistant: '}${message.content}`; | |
| chatMessages.appendChild(messageDiv); | |
| }); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| } | |
| function clearChat() { | |
| currentChat = { | |
| messages: [], | |
| timestamp: Date.now() | |
| }; | |
| displayMessages(); | |
| saveCurrentChat(); | |
| } | |
| function saveChat() { | |
| const chatName = document.getElementById('chatName').value.trim(); | |
| if (!chatName) { | |
| alert('Please enter a chat name'); | |
| return; | |
| } | |
| const savedChats = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHATS) || '{}'); | |
| savedChats[chatName] = { | |
| ...currentChat, | |
| name: chatName, | |
| savedAt: Date.now() | |
| }; | |
| localStorage.setItem(STORAGE_KEYS.CHATS, JSON.stringify(savedChats)); | |
| document.getElementById('chatName').value = ''; | |
| alert('Chat saved successfully!'); | |
| loadChatList(); | |
| } | |
| function loadChatList() { | |
| const savedChats = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHATS) || '{}'); | |
| const chatList = document.getElementById('chatList'); | |
| chatList.innerHTML = ''; | |
| Object.keys(savedChats).forEach(chatName => { | |
| const chat = savedChats[chatName]; | |
| const chatItem = document.createElement('div'); | |
| chatItem.className = 'flex justify-between items-center p-2 border rounded'; | |
| chatItem.innerHTML = ` | |
| <span>${chatName}</span> | |
| <div> | |
| <button onclick="loadChat('${chatName}')" class="bg-blue-500 text-white px-2 py-1 rounded text-sm">Load</button> | |
| <button onclick="deleteChat('${chatName}')" class="bg-red-500 text-white px-2 py-1 rounded text-sm ml-1">Delete</button> | |
| </div> | |
| `; | |
| chatList.appendChild(chatItem); | |
| }); | |
| } | |
| function loadChat(chatName) { | |
| const savedChats = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHATS) || '{}'); | |
| const chat = savedChats[chatName]; | |
| if (chat) { | |
| currentChat = { ...chat }; | |
| displayMessages(); | |
| alert(`Chat "${chatName}" loaded successfully!`); | |
| } | |
| } | |
| function deleteChat(chatName) { | |
| if (confirm(`Are you sure you want to delete the chat "${chatName}"?`)) { | |
| const savedChats = JSON.parse(localStorage.getItem(STORAGE_KEYS.CHATS) || '{}'); | |
| delete savedChats[chatName]; | |
| localStorage.setItem(STORAGE_KEYS.CHATS, JSON.stringify(savedChats)); | |
| loadChatList(); | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |