Initial implementation of IRC LLM bot

Full implementation from spec: ZNC/IRC client with TLS, Ollama LLM backend,
per-user SQLite conversation memory, and Flask web admin portal with 7 pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
tocmo0nlord
2026-04-17 22:08:53 -04:00
commit b154f63cfa
25 changed files with 2916 additions and 0 deletions

52
portal/static/app.js Normal file
View File

@@ -0,0 +1,52 @@
// Auto-refresh for logs page
(function () {
const checkbox = document.getElementById("auto-refresh");
if (!checkbox) return;
let timer = null;
function refresh() {
fetch("/api/logs")
.then((r) => r.json())
.then((data) => {
const box = document.getElementById("log-box");
if (!box) return;
box.innerHTML = data.lines
.map((l) => `<div class="log-line ${logClass(l)}">${escHtml(l)}</div>`)
.join("");
box.scrollTop = box.scrollHeight;
})
.catch(() => {});
}
checkbox.addEventListener("change", () => {
if (checkbox.checked) {
refresh();
timer = setInterval(refresh, 3000);
} else {
clearInterval(timer);
timer = null;
}
});
// Scroll to bottom on load
const box = document.getElementById("log-box");
if (box) box.scrollTop = box.scrollHeight;
function logClass(line) {
if (line.includes("IRC IN:")) return "log-irc-in";
if (line.includes("IRC OUT:")) return "log-irc-out";
if (line.includes("[LLM]")) return "log-llm";
if (line.includes("[ERROR]") || line.includes("ERROR")) return "log-error";
if (line.includes("[CONFIG]")) return "log-config";
if (line.includes("[MEMORY]")) return "log-memory";
return "";
}
function escHtml(str) {
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
}
})();