Spaces:
Runtime error
Runtime error
File size: 6,670 Bytes
bb2f1af | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SQL Agent Chat</title>
<link rel="icon" type="image/png" href="/static/robot.png" />
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />
<style>
* { box-sizing: border-box; }
body {
background: linear-gradient(135deg, rgb(44, 65, 112), #151f35);
color: #f0f0f0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0; padding: 0;
overflow: hidden; height: 100vh;
}
.container {
max-width: 910px;
margin: 22px auto;
padding: 20px;
border-radius: 20px;
backdrop-filter: blur(12px);
background: rgba(255, 255, 255, 0.04);
box-shadow: 0 8px 20px rgba(0,0,0,0.2);
width: 90%;
display: flex;
flex-direction: column;
height: fit-content;
}
h1 {
text-align: center;
font-size: 1.5rem;
margin-bottom: 30px;
color: #7ee8fa;
text-shadow: 0 2px 4px #000;
}
.chat-container {
height: 450px;
overflow-y: auto;
padding: 20px;
background: rgba(255,255,255,0.05);
border-radius: 15px;
border: 1px solid rgba(255,255,255,0.05);
box-shadow: inset 0 0 10px rgba(0,0,0,0.25);
backdrop-filter: blur(8px);
}
.chat-container::-webkit-scrollbar { width: 8px; }
.chat-container::-webkit-scrollbar-track { background: #0f1b33; border-radius: 4px; }
.chat-container::-webkit-scrollbar-thumb { background: #444; border-radius: 4px; }
.chat-container::-webkit-scrollbar-thumb:hover { background: #555; }
.message { margin-bottom: 15px; display: flex; align-items: flex-start; opacity: 0; animation: fadeIn 0.5s ease forwards; }
.message.user { justify-content: flex-end; }
.message.agent { justify-content: flex-start; }
.bubble {
padding: 10px 16px;
font-size: 14px;
border-radius: 14px;
max-width: 70%;
word-wrap: break-word;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
line-height: 1.4;
}
.bubble.user {
background: linear-gradient(145deg, #007bff, #0056b3);
color: white;
border-bottom-right-radius: 0;
}
.bubble.agent {
background: linear-gradient(145deg, #2d3a55, #1b2a3a);
color: #f3f3f3;
border-bottom-left-radius: 0;
}
.input-area {
display: flex; gap: 10px; margin-top: 15px; align-items: center;
}
.input-area textarea {
flex: 1; padding: 12px; border-radius: 10px;
background: rgba(255,255,255,0.08);
color: #eaeaea;
border: 1px solid rgba(255,255,255,0.1);
resize: none;
}
.input-area textarea:focus { outline: none; box-shadow: 0 0 8px #00e0ff; }
.input-area button {
padding: 12px 20px;
border-radius: 10px; border: none;
background: #00a8ff; color: #fff;
cursor: pointer; transition: background 0.3s;
}
.input-area button:hover:not(:disabled) { background: #0077c2; }
.input-area button:disabled { background: #555; cursor: not-allowed; }
.toast {
position: fixed; bottom: 25px; right: 25px;
background: #2c3e50;
padding: 12px 22px;
border-radius: 12px;
font-size: 0.95rem;
box-shadow: 0 6px 12px rgba(0,0,0,0.3);
display: none; z-index: 1000;
}
.dot { animation: blink 1.2s infinite; display: inline-block; margin-left: 2px; }
.dot:nth-child(2){ animation-delay: 0.2s; }
.dot:nth-child(3){ animation-delay: 0.4s; }
@keyframes blink { 0%{opacity:.2} 20%{opacity:1} 100%{opacity:.2} }
@keyframes fadeIn { to { opacity: 1; } }
</style>
</head>
<body>
<div class="container">
<h1><i class="fa-solid fa-database" style="margin-right: 10px; color: #7ee8fa;"></i>
SQL Agent Assistant
</h1>
<div class="chat-container" id="chat"></div>
<div class="input-area">
<textarea id="prompt" rows="2" placeholder="Ask something about your SQL data..."></textarea>
<button id="send">Send</button>
</div>
</div>
<div id="toast" class="toast"></div>
<script>
const chat = document.getElementById('chat')
const toast = document.getElementById('toast')
const sendBtn = document.getElementById('send')
const promptTA = document.getElementById('prompt')
let typingBubble = null
function addMessage(sender, html) {
const msg = document.createElement('div')
msg.className = `message ${sender}`
const bubble = document.createElement('div')
bubble.className = `bubble ${sender}`
bubble.innerHTML = marked.parse(html)
msg.appendChild(bubble)
chat.appendChild(msg)
chat.scrollTop = chat.scrollHeight
}
function showToast(text, duration = 3000) {
toast.textContent = text
toast.style.display = 'block'
setTimeout(() => (toast.style.display = 'none'), duration)
}
function sendPrompt() {
const text = promptTA.value.trim()
if (!text || sendBtn.disabled) return
addMessage('user', text)
promptTA.value = ''
sendBtn.disabled = true
typingBubble = document.createElement('div')
typingBubble.className = 'message agent'
typingBubble.innerHTML = `<div class="bubble agent">Thinking<span class="dot">.</span><span class="dot">.</span><span class="dot">.</span></div>`
chat.appendChild(typingBubble)
chat.scrollTop = chat.scrollHeight
fetch('/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: text })
})
.then(r => r.json())
.then(data => {
if (typingBubble) { chat.removeChild(typingBubble); typingBubble = null }
if (data.status === "ok") addMessage('agent', data.answer)
else addMessage('agent', `❌ ${data.message}`)
})
.catch(err => {
if (typingBubble) chat.removeChild(typingBubble)
addMessage('agent', `Error: ${err}`)
})
.finally(() => { sendBtn.disabled = false })
}
sendBtn.addEventListener('click', sendPrompt)
promptTA.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault(); sendPrompt()
}
})
</script>
</body>
</html> |