Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Loki.AI Playground</title> | |
<link rel="icon" type="image/x-icon" href="favicon.ico"> | |
<link | |
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@300;400;500;600&display=swap" | |
rel="stylesheet"> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" /> | |
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script> | |
<style> | |
@import url('https://fonts.googleapis.com/css2?family=Encode+Sans:wght@100..900&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Protest+Revolution&display=swap'); | |
:root { | |
--bg-dark: #0a0a0f; | |
--bg-darker: #040409; | |
--bg-deepest: #020205; | |
--primary-blue: #4a6cf7; | |
--secondary-blue: #6678e3; | |
--accent-color: #7e57c2; | |
--text-light: #e0e0e8; | |
--text-muted: #8a8a9b; | |
--border-color: #1a1a2e; | |
--hover-color: rgba(78, 108, 247, 0.1); | |
--delete-red: #ff4d4d; | |
--header-height: 60px; | |
--input-height: 80px; | |
} | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
scrollbar-width: thin; | |
scrollbar-color: var(--primary-blue) transparent; | |
} | |
*::-webkit-scrollbar { | |
width: 8px; | |
} | |
*::-webkit-scrollbar-track { | |
background: transparent; | |
} | |
*::-webkit-scrollbar-thumb { | |
background-color: var(--primary-blue); | |
border-radius: 20px; | |
} | |
body { | |
font-family: 'Inter', sans-serif; | |
background-color: var(--bg-dark); | |
color: var(--text-light); | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
height: 100vh; | |
overflow: hidden; | |
perspective: 2000px; | |
} | |
.chat-wrapper { | |
position: relative; | |
width: 100%; | |
max-width: 1000px; | |
height: 90vh; | |
background-color: var(--bg-darker); | |
border-radius: 24px; | |
overflow: hidden; | |
box-shadow: 0 20px 50px rgba(5, 5, 10, 0.7); | |
display: flex; | |
flex-direction: column; | |
opacity: 1; | |
transform: scale(1); | |
transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1); | |
border: 1px solid var(--border-color); | |
} | |
.chat-header { | |
background-color: var(--bg-deepest); | |
padding: 15px 20px; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
border-bottom: 1px solid var(--border-color); | |
flex-shrink: 0; | |
height: var(--header-height); | |
} | |
.chat-container { | |
display: none; | |
flex-direction: column; | |
height: calc(100% - var(--header-height)); | |
position: relative; | |
} | |
.chat-messages { | |
flex: 1; | |
overflow-y: auto; | |
padding: 20px; | |
display: flex; | |
flex-direction: column; | |
gap: 16px; | |
background-color: var(--bg-dark); | |
font-family: 'JetBrains Mono', monospace; | |
height: calc(100% - var(--input-height)); | |
margin-bottom: var(--input-height); | |
} | |
.chat-input { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
background-color: var(--bg-darker); | |
border-top: 1px solid var(--border-color); | |
padding: 16px; | |
height: var(--input-height); | |
display: flex; | |
gap: 12px; | |
z-index: 10; | |
align-items: center; | |
} | |
.chat-input-container { | |
position: relative; | |
flex: 1; | |
display: flex; | |
align-items: center; | |
} | |
.chat-input input { | |
width: 100%; | |
padding: 12px 16px; | |
padding-right: 50px; | |
/* Space for send icon */ | |
background-color: rgba(30, 30, 50, 0.8); | |
border: 1px solid var(--border-color); | |
border-radius: 12px; | |
color: var(--text-light); | |
font-size: 14px; | |
font-family: 'JetBrains Mono', monospace; | |
outline: none; | |
} | |
.chat-input input:focus { | |
border-color: var(--primary-blue); | |
box-shadow: 0 0 0 3px rgba(74, 108, 247, 0.2); | |
} | |
.message { | |
max-width: 80%; | |
width: fit-content; | |
padding: 12px 18px; | |
border-radius: 12px; | |
font-size: 14px; | |
line-height: 1.5; | |
position: relative; | |
animation: fadeIn 0.4s forwards; | |
margin-bottom: 8px; | |
} | |
.message.user { | |
align-self: flex-end; | |
background-color: var(--primary-blue); | |
color: white; | |
} | |
.message.bot { | |
align-self: flex-start; | |
background-color: rgba(40, 40, 70, 0.8); | |
color: var(--text-light); | |
border: 1px solid var(--border-color); | |
} | |
.message::before { | |
content: ''; | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.1)); | |
opacity: 0; | |
transition: opacity 0.3s ease; | |
} | |
.message:hover::before { | |
opacity: 1; | |
} | |
.initial-input { | |
flex: 1; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
padding: 24px; | |
text-align: center; | |
background: linear-gradient(145deg, var(--bg-dark), var(--bg-darker)); | |
} | |
.initial-input h2 { | |
font-size: 24px; | |
margin-bottom: 16px; | |
color: var(--text-light); | |
font-weight: 600; | |
font-family: 'JetBrains Mono', monospace; | |
} | |
.input-container { | |
width: 100%; | |
max-width: 400px; | |
position: relative; | |
} | |
.initial-input input { | |
width: 100%; | |
padding: 16px 24px; | |
background-color: rgba(30, 30, 50, 0.8); | |
border: 1px solid var(--border-color); | |
border-radius: 12px; | |
color: var(--text-light); | |
font-size: 16px; | |
font-family: 'JetBrains Mono', monospace; | |
outline: none; | |
transition: all 0.3s ease; | |
} | |
.send-icon { | |
position: absolute; | |
right: 12px; | |
top: 50%; | |
transform: translateY(-50%); | |
background-color: var(--primary-blue); | |
border-radius: 8px; | |
width: 40px; | |
height: 40px; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
} | |
.send-icon:hover { | |
background-color: var(--accent-color); | |
transform: translateY(-50%) scale(1.05); | |
border-radius: 15px; | |
} | |
@keyframes fadeIn { | |
from { | |
opacity: 0; | |
transform: translateY(20px); | |
} | |
to { | |
opacity: 1; | |
transform: translateY(0); | |
} | |
} | |
/* Header actions */ | |
.header-actions { | |
display: flex; | |
align-items: center; | |
gap: 10px; | |
justify-content: center; | |
} | |
.model-select { | |
background-color: black; | |
color: var(--text-light); | |
border: 1px solid var(--border-color); | |
border-radius: 8px; | |
padding: 8px 12px; | |
font-family: 'JetBrains Mono', monospace; | |
font-size: 14px; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
max-width: 150px; | |
overflow-y: auto; | |
-webkit-appearance: none; | |
-moz-appearance: none; | |
appearance: none; | |
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2214%22%20height%3D%2214%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%23ffffff%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpolyline%20points%3D%226%209%2012%2015%2018%209%22%3E%3C%2Fpolyline%3E%3C%2Fsvg%3E"); | |
background-repeat: no-repeat; | |
background-position: right 8px center; | |
padding-right: 28px; | |
} | |
.model-select option { | |
background-color: var(--bg-dark); | |
color: var(--text-light); | |
padding: 8px; | |
} | |
.clear-chat { | |
background-color: var(--delete-red); | |
color: white; | |
border: none; | |
border-radius: 8px; | |
width: 36px; | |
height: 36px; | |
padding: 8px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
} | |
.clear-chat:hover { | |
background-color: #ff6666; | |
} | |
.clear-chat svg { | |
width: 18px; | |
height: 18px; | |
} | |
.watermark { | |
position: absolute; | |
bottom: 10px; | |
right: 15px; | |
color: var(--text-muted); | |
font-size: 10px; | |
opacity: 0.5; | |
transition: opacity 0.3s ease; | |
z-index: 11; | |
} | |
.watermark:hover { | |
opacity: 0.8; | |
} | |
@media screen and (max-width: 768px) { | |
.chat-header { | |
padding: 8px 12px; | |
height: auto; | |
min-height: 50px; | |
} | |
.header-actions { | |
gap: 8px; | |
} | |
.model-select { | |
font-size: 12px; | |
padding: 6px 24px 6px 8px; | |
max-width: 120px; | |
} | |
.clear-chat { | |
width: 32px; | |
height: 32px; | |
padding: 6px; | |
} | |
.clear-chat svg { | |
width: 16px; | |
height: 16px; | |
} | |
.chat-input { | |
padding: 8px; | |
height: auto; | |
min-height: 60px; | |
} | |
.chat-input input { | |
padding: 10px 12px; | |
font-size: 14px; | |
height: 40px; | |
} | |
} | |
@media screen and (max-width: 480px) { | |
.chat-header h2 { | |
font-size: 14px; | |
} | |
.message { | |
font-size: 12px; | |
} | |
.header-actions { | |
flex-direction: row; | |
gap: 6px; | |
} | |
.model-select { | |
max-width: 100px; | |
font-size: 11px; | |
} | |
.clear-chat { | |
width: 28px; | |
height: 28px; | |
padding: 5px; | |
} | |
.clear-chat svg { | |
width: 14px; | |
height: 14px; | |
} | |
.chat-input input { | |
font-size: 13px; | |
height: 36px; | |
} | |
.initial-input input { | |
font-size: 15px; | |
} | |
.initial-input h2 { | |
font-size: 20px; | |
} | |
} | |
/* Additional responsive adjustments to existing CSS */ | |
* { | |
-webkit-tap-highlight-color: transparent; | |
} | |
body { | |
touch-action: manipulation; | |
} | |
input, | |
button { | |
-webkit-appearance: none; | |
-moz-appearance: none; | |
appearance: none; | |
} | |
@media (hover: hover) { | |
.send-icon:hover { | |
background-color: var(--accent-color); | |
transform: translateY(-50%) scale(1.05); | |
border-radius: 15px; | |
} | |
} | |
@media (pointer: coarse) { | |
.send-icon { | |
width: 45px; | |
height: 45px; | |
} | |
.chat-input input { | |
font-size: 16px; | |
/* Larger font for touch devices */ | |
} | |
} | |
.model-select::-webkit-scrollbar { | |
width: 4px; | |
} | |
.model-select::-webkit-scrollbar-track { | |
background: var(--bg-dark); | |
} | |
.model-select::-webkit-scrollbar-thumb { | |
background-color: var(--primary-blue); | |
border-radius: 4px; | |
} | |
.chat-input input:focus, | |
.initial-input input:focus, | |
.model-select:focus, | |
.clear-chat:focus, | |
.send-icon:focus { | |
outline: 2px solid var(--primary-blue); | |
outline-offset: 2px; | |
} | |
.github-link { | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
width: 36px; | |
height: 36px; | |
z-index: 999; | |
border-radius: 8px; | |
background-color: transparent; | |
border: 1px solid var(--border-color); | |
transition: all 0.3s ease; | |
color: var(--text-light); | |
position: absolute; /* Allows placement in the corner */ | |
bottom: 0; /* Aligns to the top */ | |
left: 0; /* Aligns to the left */ | |
margin: 10px; /* Adds spacing from the edges */ | |
} | |
.github-link:hover { | |
background-color: var(--hover-color); | |
transform: translateY(-2px); | |
} | |
.github-link svg { | |
width: 22px; | |
height: 22px; | |
} | |
</style> | |
</head> | |
<body> | |
<a href="https://github.com/ParthSadaria" target="_blank" rel="noopener noreferrer" class="github-link" aria-label="Visit Parth Sadaria's GitHub profile"> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path> | |
</svg> | |
</a> | |
<div class="chat-wrapper"> | |
<div class="chat-header"> | |
<h2 style="font-family: 'JetBrains Mono', monospace;">LOKI.AI Playground</h2> | |
<div class="header-actions"> | |
<select id="modelSelect" class="model-select"> | |
<option value="gpt-4o-mini">GPT-4o Mini</option> | |
<option value="gpt-4o">GPT-4o</option> | |
<option value="gpt-3.5-turbo">GPT-3.5 Turbo</option> | |
<option value="searchgpt">SearchGPT(Web-access)</option> | |
<option value="claude-sonnet-3.5">Claude 3.5 Sonnet</option> | |
<option value="claude-3-haiku">Claude 3 Haiku</option> | |
<option value="llama-3.1-8b">Llama 3.1 8B</option> | |
<option value="llama-3.1-70b">Llama 3.1 70B</option> | |
<option value="llama-3.1-405b">Llama 3.1 405b</option> | |
<option value="gemini-1.5-flash">Gemini 1.5 Flash</option> | |
<option value="gemini-pro">Gemini Pro</option> | |
<option value="mixtral-8x7b">Mixtral 8x7b</option> | |
<option value="command-r">Command-R</option> | |
<option value="command">Command</option> | |
</select> | |
<button id="clearChatButton" class="clear-chat"> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" | |
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
<polyline points="3 6 5 6 21 6"></polyline> | |
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path> | |
<line x1="10" y1="11" x2="10" y2="17"></line> | |
<line x1="14" y1="11" x2="14" y2="17"></line> | |
</svg> | |
</button> | |
</div> | |
</div> | |
<div class="initial-input"> | |
<h2>Welcome to LOKI.AI</h2> | |
<div class="input-container"> | |
<input type="text" id="initialChatInput" placeholder="What can I help you with today?"> | |
<div class="send-icon" id="initialSendIcon"> | |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" | |
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
<line x1="22" y1="2" x2="11" y2="13"></line> | |
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon> | |
</svg> | |
</div> | |
</div> | |
</div> | |
<div class="chat-container" id="chatContainer"> | |
<div class="chat-messages" id="chatMessages"></div> | |
<div class="chat-input"> | |
<input type="text" id="chatInput" placeholder="Type your message..."> | |
<button id="sendButton" | |
style="padding: 10px 10px; background-color: black;color: #e0e0e8; font-family: 'JetBrains Mono'; border: solid #1a1a2e 2px; border-radius: 15px;">Send</button> | |
</div> | |
</div> | |
</div> | |
<div class="watermark"> | |
Made with ❤️ by Parth Sadaria | |
</div> | |
<script> | |
const chatWrapper = document.querySelector('.chat-wrapper'); | |
const initialInput = document.querySelector('.initial-input'); | |
const chatContainer = document.getElementById('chatContainer'); | |
const initialChatInput = document.getElementById('initialChatInput'); | |
const initialSendIcon = document.getElementById('initialSendIcon'); | |
const chatMessages = document.getElementById('chatMessages'); | |
const chatInput = document.getElementById('chatInput'); | |
const sendButton = document.getElementById('sendButton'); | |
const modelSelect = document.getElementById('modelSelect'); | |
const clearChatButton = document.getElementById('clearChatButton'); | |
let currentStreamingMessage = null; | |
let isStreamingInProgress = false; | |
let conversationHistory = []; | |
function scrollToBottom() { | |
const chatMessages = document.getElementById('chatMessages'); | |
chatMessages.scrollTop = chatMessages.scrollHeight; | |
} | |
function appendMessage(content, type = 'bot', isStreaming = false) { | |
if (type === 'bot' && isStreaming) { | |
if (!currentStreamingMessage) { | |
currentStreamingMessage = document.createElement('div'); | |
currentStreamingMessage.className = `message ${type}`; | |
chatMessages.appendChild(currentStreamingMessage); | |
// Add to conversation history only at the start of streaming | |
if (!isStreamingInProgress) { | |
conversationHistory.push({ | |
role: 'assistant', | |
content: '' | |
}); | |
isStreamingInProgress = true; | |
} | |
} | |
const formattedContent = content | |
.replace(/(\d+)\.\s*/g, '<br>$1. ') | |
.replace(/\n/g, '<br>') | |
.replace(/\*\*(.*?)\*\*/g, (match, p1) => '<strong>' + p1 + '</strong>'); | |
currentStreamingMessage.innerHTML += formattedContent; | |
// Update the last message in conversation history | |
if (conversationHistory.length > 0) { | |
conversationHistory[conversationHistory.length - 1].content += content; | |
} | |
chatMessages.scrollTop = chatMessages.scrollHeight; | |
} else { | |
if (currentStreamingMessage) { | |
isStreamingInProgress = false; | |
currentStreamingMessage = null; | |
} | |
const messageBox = document.createElement('div'); | |
messageBox.className = `message ${type}`; | |
const formattedContent = content | |
.replace(/(\d+)\.\s*/g, '<br>$1. ') | |
.replace(/\n/g, '<br>') | |
.replace(/\*\*(.*?)\*\*/g, (match, p1) => '<strong>' + p1 + '</strong>'); | |
messageBox.innerHTML = formattedContent; | |
chatMessages.appendChild(messageBox); | |
// Add to conversation history only for new messages | |
if (type === 'user') { | |
conversationHistory.push({ | |
role: 'user', | |
content: content | |
}); | |
} | |
chatMessages.scrollTop = chatMessages.scrollHeight; | |
} | |
} | |
function clearChat() { | |
chatMessages.innerHTML = ''; | |
conversationHistory = []; | |
initialInput.style.display = 'flex'; | |
chatContainer.style.display = 'none'; | |
chatWrapper.classList.remove('active'); | |
} | |
async function sendInitialMessage() { | |
const userMessage = initialChatInput.value.trim(); | |
const selectedModel = modelSelect.value; | |
if (!userMessage) return; | |
initialInput.style.display = 'none'; | |
chatContainer.style.display = 'flex'; | |
chatWrapper.classList.add('active'); | |
appendMessage(userMessage, 'user'); | |
initialChatInput.value = ''; | |
scrollToBottom(); | |
try { | |
await callApi(userMessage, selectedModel); | |
} catch (error) { | |
appendMessage("Oops! Something went wrong.", 'bot'); | |
console.error("API Error:", error); | |
} | |
} | |
async function sendMessage() { | |
const userMessage = chatInput.value.trim(); | |
const selectedModel = modelSelect.value; | |
if (!userMessage) return; | |
appendMessage(userMessage, 'user'); | |
chatInput.value = ''; | |
try { | |
await callApi(userMessage, selectedModel); | |
} catch (error) { | |
appendMessage("Oops! Something went wrong.", 'bot'); | |
console.error("API Error:", error); | |
} | |
} | |
async function callApi(userMessage, model) { | |
let fullResponse = ""; | |
if (model === "searchgpt") { | |
const url = `https://parthsadaria-lokiai.hf.space/searchgpt?q=${encodeURIComponent(userMessage)}&stream=true&systemprompt=You are **SearchGPT**, an AI with internet access. Reply directly and accurately to user requests.`; | |
try { | |
const response = await fetch(url); | |
if (response.ok) { | |
const reader = response.body.getReader(); | |
const decoder = new TextDecoder("utf-8"); | |
let done = false; | |
while (!done) { | |
const { value, done: streamDone } = await reader.read(); | |
done = streamDone; | |
if (value) { | |
const chunk = decoder.decode(value); | |
const cleanedChunk = chunk.trim().replace(/^data:\s*/, ''); | |
const jsonChunks = cleanedChunk.split("data:").filter(Boolean); | |
jsonChunks.forEach(jsonString => { | |
try { | |
const jsonData = JSON.parse(jsonString); | |
const content = jsonData.choices?.[0]?.message?.content || ""; | |
if (content) { | |
// Comprehensive newline conversion | |
const formattedContent = content | |
.replace(/\r\n/g, '<br>') // Windows-style newlines | |
.replace(/\n/g, '<br>') // Unix/Linux-style newlines | |
.replace(/\r/g, '<br>'); // Old Mac-style newlines | |
appendMessage(formattedContent, 'bot', true); | |
} | |
} catch (err) { | |
console.warn("Parsing error:", err); | |
} | |
}); | |
} | |
} | |
} else { | |
throw new Error(`API responded with status ${response.status}`); | |
} | |
} catch (error) { | |
console.error("API call error:", error); | |
throw error; | |
} | |
} else { | |
const url = "https://parthsadaria-lokiai.hf.space/chat/completions"; | |
const payload = { | |
model: model, | |
messages: [ | |
...conversationHistory | |
], | |
stream: true | |
}; | |
const headers = { | |
"Content-Type": "application/json" | |
}; | |
try { | |
const response = await fetch(url, { | |
method: "POST", | |
headers: headers, | |
body: JSON.stringify(payload) | |
}); | |
if (response.ok) { | |
const reader = response.body.getReader(); | |
const decoder = new TextDecoder("utf-8"); | |
let done = false; | |
while (!done) { | |
const { value, done: streamDone } = await reader.read(); | |
done = streamDone; | |
if (value) { | |
const chunk = decoder.decode(value); | |
const cleanedChunk = chunk.trim().replace(/^data:\s*/, ''); | |
const jsonChunks = cleanedChunk.split("data:").filter(Boolean); | |
jsonChunks.forEach(jsonString => { | |
try { | |
const jsonData = JSON.parse(jsonString); | |
const delta = jsonData.choices?.[0]?.delta || {}; | |
let content = delta.content || ""; | |
// Comprehensive newline conversion | |
content = content | |
.replace(/\r\n/g, '<br>') // Windows-style newlines | |
.replace(/\n/g, '<br>') // Unix/Linux-style newlines | |
.replace(/\r/g, '<br>'); // Old Mac-style newlines | |
if (content) { | |
appendMessage(content, 'bot', true); | |
} | |
} catch (err) { | |
console.warn("Parsing error:", err); | |
} | |
}); | |
} | |
} | |
} else { | |
throw new Error(`API responded with status ${response.status}`); | |
} | |
} catch (error) { | |
console.error("API call error:", error); | |
throw error; | |
} | |
} | |
return fullResponse.trim(); | |
} | |
// Event Listeners | |
initialSendIcon.addEventListener('click', sendInitialMessage); | |
initialChatInput.addEventListener('keypress', (event) => { | |
if (event.key === 'Enter') sendInitialMessage(); | |
}); | |
sendButton.addEventListener('click', sendMessage); | |
chatInput.addEventListener('keypress', (event) => { | |
if (event.key === 'Enter') sendMessage(); | |
}); | |
// Clear Chat Button Event Listener | |
clearChatButton.addEventListener('click', clearChat); | |
</script> | |
</body> | |
<!-- random comments to get 800 lines --> | |
</html> |