From b60e72c88eb5e7460c64ad872d4966517b7b5bd8 Mon Sep 17 00:00:00 2001 From: Dita Aji Pratama Date: Sun, 20 Jul 2025 17:55:26 +0700 Subject: [PATCH] First commit --- index.html | 34 +++++++++++++++++++ script.js | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 index.html create mode 100644 script.js diff --git a/index.html b/index.html new file mode 100644 index 0000000..18fe396 --- /dev/null +++ b/index.html @@ -0,0 +1,34 @@ + + + + + + Super Stupidly Simple Ollama Client + + + + + + + +
+
+ +
+ + + + +
+ + + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..f4b1298 --- /dev/null +++ b/script.js @@ -0,0 +1,96 @@ +const messages = []; +const statusEl = document.getElementById("statusbox" ); +const chatContainer = document.getElementById("chatbox" ); + +function setStatus(msg, stts) { + if (stts == "idle" ) statusEl.className = "status-idle"; + if (stts == "responding" ) statusEl.className = "status-responding"; + if (stts == "completed" ) statusEl.className = "status-completed"; + if (stts == "failed" ) statusEl.className = "status-failed"; + statusEl.textContent = msg; +} + +async function sendPrompt() { + const role = document.getElementById("role" ).value; + const model = document.getElementById("model" ).value; + const response = document.getElementById("response" ).checked; + const promptBox = document.getElementById("prompt" ); + const prompt = promptBox.value.trim(); + + if (!prompt) return; + + const bubUser = document.createElement("div" ); + const tagRole = document.createElement("span" ); + const msgUser = document.createElement("div" ); + + const bubBot = document.createElement("div" ); + const tagModel = document.createElement("span" ); + const msgBot = document.createElement("div" ); + + bubUser .className = "bub bub-r bub-primary"; + tagRole .className = "tag"; + msgUser .className = "message"; + + bubBot .className = "bub bub-l bub-secondary"; + tagModel .className = "tag"; + msgBot .className = "message"; + + tagRole .textContent = `Role: ${role}`; + tagModel .textContent = `Model: ${model}`; + + msgUser.innerHTML = marked.parse(prompt, { sanitize: true }); + + bubUser.appendChild(tagRole); + bubUser.appendChild(msgUser); + chatContainer.appendChild(bubUser); + + bubBot.appendChild(tagModel); + bubBot.appendChild(msgBot); + if (response) chatContainer.appendChild(bubBot); + + chatContainer.scrollTop = chatContainer.scrollHeight; + messages.push({ role: role, content: prompt }); // Add prompt to history + if (response) setStatus(`⏳ ${model} Loading…`, "responding"); + + if (response) try { + const res = await fetch("http://localhost:11434/api/chat", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ model, messages, stream: true }) + }); + + const reader = res.body.getReader(); + const decoder = new TextDecoder("utf-8"); + let botReply = ""; + + setStatus(`✏️ ${model} Typing…`, "responding"); + while (true) { + const { done, value } = await reader.read(); + if (done) break; + const chunk = decoder.decode(value, { stream: true }).trim(); + for (const line of chunk.split("\n")) { + if (!line) continue; + try { + const j = JSON.parse(line); + if (j.message?.content) { + botReply += j.message.content; + msgBot.innerHTML = marked.parse(botReply, { sanitize: true }); + msgBot.prepend(tagModel); + chatContainer.scrollTop = chatContainer.scrollHeight; + } + } catch {} + } + } + + messages.push({ role: "assistant", content: botReply }); + setStatus(`✅ Response completed by ${model}`, "completed"); + + } catch (e) { + msgBot.innerHTML = "[Failed to load answer]"; + msgBot.prepend(tagModel); + setStatus(`❌ Failed to get a response from ${model}`, "failed"); + } + + promptBox.value = ""; +} +