Lug / app.py
luguog's picture
Create app.py
78dc47c verified
#!/usr/bin/env python3
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import uvicorn
app = FastAPI()
HTML = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SALT:// Neo War Terminal</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/ethers@6.7.0/dist/ethers.min.js"></script>
<style>
body {
background: linear-gradient(145deg, #0a0a0f, #050509);
font-family: monospace;
color: #eee;
}
#terminal {
background: #0c0c14;
border-radius: 18px;
padding: 24px;
margin: 50px auto;
max-width: 960px;
height: 560px;
overflow-y: auto;
box-shadow:
inset 6px 6px 12px #000,
inset -6px -6px 12px #1c1c28,
0 0 12px rgba(249,115,22,0.5);
}
.line { margin: 6px 0; }
.prompt { color: #f97316; text-shadow: 0 0 10px #f97316; }
input {
background: transparent;
border: none;
outline: none;
color: #fff;
width: 80%;
}
</style>
</head>
<body>
<div id="terminal">
<div class="line">⚡ Ignition engaged...</div>
<div class="line">Welcome to <span class="prompt">SALT:// Neo War Terminal 🧂</span></div>
<div class="line">Type <span class="prompt">help</span> to deploy cognition.</div>
<div class="line"><span class="prompt">SALT://></span> <input id="input" autofocus></div>
</div>
<script>
const term = document.getElementById('terminal');
const input = document.getElementById('input');
let wallet = null;
const HF_MODEL = "gpt2";
const HF_API = `https://api-inference.huggingface.co/models/${HF_MODEL}`;
function writeLine(text) {
const line = document.createElement('div');
line.className = "line";
line.innerHTML = text;
term.insertBefore(line, term.lastElementChild);
term.scrollTop = term.scrollHeight;
return line;
}
async function streamText(el, text, speed=20) {
for (let i=0; i<text.length; i++) {
el.innerHTML += text[i];
term.scrollTop = term.scrollHeight;
await new Promise(r=>setTimeout(r,speed));
}
}
async function queryLLM(prompt) {
const res = await fetch(HF_API, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ inputs: prompt })
});
const data = await res.json();
if (Array.isArray(data) && data[0].generated_text) return data[0].generated_text;
return JSON.stringify(data);
}
// Local wallet ops
async function walletNew() {
wallet = ethers.Wallet.createRandom();
localStorage.setItem("salt_wallet", wallet.privateKey);
writeLine(`[wallet] New ignition key forged: ${wallet.address}`);
}
async function walletLoad() {
const pk = localStorage.getItem("salt_wallet");
if (pk) {
wallet = new ethers.Wallet(pk);
writeLine(`[wallet] Reloaded ignition key: ${wallet.address}`);
} else {
writeLine("[wallet] No local ignition key found. Run 'wallet new'");
}
}
async function walletAddress() {
if (!wallet) return writeLine("[wallet] No wallet loaded");
writeLine(`[wallet] Address: ${wallet.address}`);
}
async function walletSign(msg) {
if (!wallet) return writeLine("[wallet] No wallet loaded");
const sig = await wallet.signMessage(msg);
writeLine(`[wallet] Signature: ${sig}`);
}
async function walletExport() {
if (!wallet) return writeLine("[wallet] No wallet loaded");
const blob = new Blob([JSON.stringify({ privateKey: wallet.privateKey, address: wallet.address }, null, 2)], {type:"application/json"});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "wallet.json";
a.click();
URL.revokeObjectURL(url);
writeLine("[wallet] Exported ignition key as wallet.json");
}
async function handleCommand(cmd) {
const parts = cmd.trim().split(" ");
const base = parts[0];
const args = parts.slice(1);
if (base === "help") {
writeLine("Commands: help, llm <text>, clear, wallet <new|load|address|sign|export>");
} else if (base === "llm") {
const thinking = writeLine(`<span class="prompt">[LLM]</span> `);
const out = await queryLLM(args.join(" "));
await streamText(thinking, out, 20);
} else if (base === "wallet") {
if (args[0] === "new") await walletNew();
else if (args[0] === "load") await walletLoad();
else if (args[0] === "address") await walletAddress();
else if (args[0] === "sign") await walletSign(args.slice(1).join(" "));
else if (args[0] === "export") await walletExport();
else writeLine("[wallet] Usage: wallet <new|load|address|sign|export>");
} else if (base === "clear") {
[...term.querySelectorAll(".line")].forEach(l => l.remove());
writeLine("⚡ Ignition reset...");
writeLine("Welcome back to <span class='prompt'>SALT:// Neo War Terminal 🧂</span>");
} else {
writeLine(`<span class="prompt">Unknown:</span> ${cmd}`);
}
}
input.addEventListener("keydown", async (e) => {
if (e.key === "Enter") {
const cmd = input.value;
writeLine(`<span class="prompt">SALT://></span> ${cmd}`);
input.value = "";
await handleCommand(cmd);
}
});
// Auto-load wallet
walletLoad();
</script>
</body>
</html>
"""
@app.get("/", response_class=HTMLResponse)
async def root():
return HTML
if __name__ == "__main__":
uvicorn.run("app:app", host="0.0.0.0", port=7860)