Spaces:
Runtime error
Runtime error
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>SuperLilLM</title> | |
| <style> | |
| :root { | |
| color-scheme: light; | |
| --ink: #18201d; | |
| --muted: #5f6b66; | |
| --line: #d9dfdc; | |
| --panel: #ffffff; | |
| --bg: #f6f4ef; | |
| --accent: #1f7a63; | |
| --accent-2: #d85f35; | |
| } | |
| * { box-sizing: border-box; } | |
| body { | |
| margin: 0; | |
| font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; | |
| background: var(--bg); | |
| color: var(--ink); | |
| min-height: 100vh; | |
| display: grid; | |
| place-items: center; | |
| padding: 24px; | |
| } | |
| main { | |
| width: min(920px, 100%); | |
| min-height: min(760px, calc(100vh - 48px)); | |
| display: grid; | |
| grid-template-rows: auto 1fr auto; | |
| background: var(--panel); | |
| border: 1px solid var(--line); | |
| border-radius: 8px; | |
| box-shadow: 0 18px 50px rgba(24, 32, 29, 0.12); | |
| overflow: hidden; | |
| } | |
| header { | |
| padding: 18px 20px; | |
| border-bottom: 1px solid var(--line); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| gap: 16px; | |
| } | |
| h1 { | |
| margin: 0; | |
| font-size: 20px; | |
| letter-spacing: 0; | |
| } | |
| .status { | |
| color: var(--muted); | |
| font-size: 14px; | |
| white-space: nowrap; | |
| } | |
| #chat { | |
| padding: 20px; | |
| overflow: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 12px; | |
| } | |
| .msg { | |
| max-width: min(680px, 92%); | |
| padding: 12px 14px; | |
| border-radius: 8px; | |
| line-height: 1.45; | |
| font-size: 15px; | |
| overflow-wrap: anywhere; | |
| } | |
| .user { | |
| align-self: flex-end; | |
| background: #e7f2ed; | |
| border: 1px solid #c4dfd4; | |
| } | |
| .bot { | |
| align-self: flex-start; | |
| background: #fff8ee; | |
| border: 1px solid #efd4bd; | |
| } | |
| .token-trace { | |
| align-self: flex-start; | |
| max-width: min(680px, 92%); | |
| color: var(--muted); | |
| font-size: 12px; | |
| line-height: 1.5; | |
| overflow-wrap: anywhere; | |
| } | |
| form { | |
| display: grid; | |
| grid-template-columns: 1fr auto; | |
| gap: 10px; | |
| padding: 16px; | |
| border-top: 1px solid var(--line); | |
| background: #fbfaf7; | |
| } | |
| input { | |
| width: 100%; | |
| border: 1px solid var(--line); | |
| border-radius: 8px; | |
| padding: 13px 14px; | |
| font: inherit; | |
| color: var(--ink); | |
| background: white; | |
| } | |
| button { | |
| border: 0; | |
| border-radius: 8px; | |
| padding: 0 18px; | |
| min-width: 86px; | |
| font: inherit; | |
| font-weight: 700; | |
| color: white; | |
| background: var(--accent); | |
| cursor: pointer; | |
| } | |
| button:hover { background: #17634f; } | |
| button:disabled { background: #8fa9a0; cursor: wait; } | |
| .examples { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 8px; | |
| padding: 0 16px 16px; | |
| background: #fbfaf7; | |
| } | |
| .chip { | |
| border: 1px solid #e3c4af; | |
| background: #fffaf4; | |
| color: #6e3b24; | |
| border-radius: 999px; | |
| padding: 7px 10px; | |
| font-size: 13px; | |
| cursor: pointer; | |
| } | |
| @media (max-width: 620px) { | |
| body { padding: 0; } | |
| main { min-height: 100vh; border-radius: 0; border: 0; } | |
| header { align-items: flex-start; flex-direction: column; } | |
| form { grid-template-columns: 1fr; } | |
| button { min-height: 44px; } | |
| .msg { max-width: 100%; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <main> | |
| <header> | |
| <h1>SuperLilLM</h1> | |
| <div class="status">tiny local model</div> | |
| </header> | |
| <section id="chat" aria-live="polite"> | |
| <div class="msg bot">Hey. Ask me about space, animals, plants, humans, or AI.</div> | |
| </section> | |
| <div class="examples"> | |
| <button class="chip" type="button">hey whats up</button> | |
| <button class="chip" type="button">what do you know about ai</button> | |
| <button class="chip" type="button">what is a planet</button> | |
| <button class="chip" type="button">what are some things you know about?</button> | |
| </div> | |
| <form id="form"> | |
| <input id="message" autocomplete="off" placeholder="Type to SuperLilLM..." autofocus> | |
| <button id="send" type="submit">Send</button> | |
| </form> | |
| </main> | |
| <script> | |
| const chat = document.querySelector("#chat"); | |
| const form = document.querySelector("#form"); | |
| const input = document.querySelector("#message"); | |
| const send = document.querySelector("#send"); | |
| function add(text, cls) { | |
| const div = document.createElement("div"); | |
| div.className = `msg ${cls}`; | |
| div.textContent = text; | |
| chat.appendChild(div); | |
| chat.scrollTop = chat.scrollHeight; | |
| } | |
| function addTokenTrace(tokens) { | |
| if (!tokens || !tokens.length) return; | |
| const div = document.createElement("div"); | |
| div.className = "token-trace"; | |
| div.textContent = `generated tokens: ${tokens.map(token => token.text).join(" ")}`; | |
| chat.appendChild(div); | |
| chat.scrollTop = chat.scrollHeight; | |
| } | |
| async function submit(text) { | |
| const message = text.trim(); | |
| if (!message) return; | |
| add(message, "user"); | |
| input.value = ""; | |
| send.disabled = true; | |
| try { | |
| const res = await fetch("/api/chat", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ message }) | |
| }); | |
| const data = await res.json(); | |
| add(data.reply, "bot"); | |
| addTokenTrace(data.tokens); | |
| } catch { | |
| add("The local server did not answer.", "bot"); | |
| } finally { | |
| send.disabled = false; | |
| input.focus(); | |
| } | |
| } | |
| form.addEventListener("submit", event => { | |
| event.preventDefault(); | |
| submit(input.value); | |
| }); | |
| document.querySelectorAll(".chip").forEach(chip => { | |
| chip.addEventListener("click", () => submit(chip.textContent)); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |