Update server.py
Browse files
server.py
CHANGED
|
@@ -8,7 +8,7 @@ Gemini-CLI style planner + executor:
|
|
| 8 |
β’ robust JSON extraction (balanced braces) to avoid parse failures
|
| 9 |
"""
|
| 10 |
|
| 11 |
-
from flask import Flask, request, jsonify, Response
|
| 12 |
from huggingface_hub import snapshot_download
|
| 13 |
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
|
| 14 |
import subprocess, os, json, traceback, io, contextlib
|
|
@@ -33,7 +33,7 @@ MODEL_ID = os.environ.get("MODEL_ID", "TinyLlama/TinyLlama-1.1B-Chat-v1.0")
|
|
| 33 |
# ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 34 |
# 3) Flask app & actions executor
|
| 35 |
# ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 36 |
-
app = Flask(__name__)
|
| 37 |
|
| 38 |
SERVER_OS = platform.system().lower()
|
| 39 |
ALLOW_AUTO_INSTALL = os.environ.get("ALLOW_AUTO_INSTALL", "0") == "1"
|
|
@@ -1689,144 +1689,19 @@ def assist_rewrite():
|
|
| 1689 |
out = llm_generate_text_exact(model, sys, user, max_new_tokens={"short":400,"medium":1200,"long":2400,"xl":4800}[length])
|
| 1690 |
return jsonify({"new_content": _sanitize_generated_content(None, "text", out)})
|
| 1691 |
|
| 1692 |
-
HOME_HTML = Template(r"""<!doctype html>
|
| 1693 |
-
<html lang="en">
|
| 1694 |
-
<head>
|
| 1695 |
-
<meta charset="utf-8"/>
|
| 1696 |
-
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
| 1697 |
-
<title>Axis Β· Llama3 Agent API</title>
|
| 1698 |
-
<style>
|
| 1699 |
-
:root { --bg:#0b0f17; --fg:#e6eef8; --muted:#a9b7c6; --card:#121825; --accent:#7aa2f7; --ok:#38d39f; --bad:#ff6b6b; }
|
| 1700 |
-
* { box-sizing:border-box; }
|
| 1701 |
-
body { margin:0; font:15px/1.55 system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, 'Helvetica Neue', Arial; background:radial-gradient(1200px 600px at 10% -10%, #122034, transparent), var(--bg); color:var(--fg); }
|
| 1702 |
-
header { padding:36px 20px 10px; max-width:980px; margin:0 auto; }
|
| 1703 |
-
.badge { display:inline-block; padding:4px 10px; border:1px solid #2c3650; border-radius:999px; font-size:12px; color:var(--muted); }
|
| 1704 |
-
h1 { margin:12px 0 8px; font-size:28px; letter-spacing:.2px; }
|
| 1705 |
-
.sub { color:var(--muted); margin:0 0 18px; }
|
| 1706 |
-
.grid { display:grid; grid-template-columns: 1.1fr 1fr; gap:18px; max-width:980px; padding:0 20px 36px; margin:0 auto; }
|
| 1707 |
-
.card { background:linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.00)); border:1px solid #1a2336; border-radius:14px; padding:16px; }
|
| 1708 |
-
.card h3 { margin:0 0 8px; font-size:16px; }
|
| 1709 |
-
pre, code, textarea { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; }
|
| 1710 |
-
pre { background:#0e1422; color:#cfe3ff; padding:12px; border-radius:10px; overflow:auto; border:1px solid #1a2336; }
|
| 1711 |
-
.row { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
|
| 1712 |
-
textarea { width:100%; min-height:120px; padding:10px; border-radius:10px; border:1px solid #202a40; background:#0e1422; color:#e6eef8; }
|
| 1713 |
-
input[type="password"] { width:100%; padding:10px; border-radius:10px; border:1px solid #202a40; background:#0e1422; color:#e6eef8; }
|
| 1714 |
-
button { background:var(--accent); color:#0b0f17; border:none; padding:10px 14px; border-radius:10px; cursor:pointer; font-weight:600; }
|
| 1715 |
-
button:disabled { filter:grayscale(.5); opacity:.7; cursor:not-allowed; }
|
| 1716 |
-
.muted { color:var(--muted); }
|
| 1717 |
-
footer { max-width:980px; margin:0 auto 32px; padding:0 20px; color:var(--muted); }
|
| 1718 |
-
a { color:#9ec1ff; text-decoration:none; }
|
| 1719 |
-
.ok { color:var(--ok); }
|
| 1720 |
-
</style>
|
| 1721 |
-
</head>
|
| 1722 |
-
<body>
|
| 1723 |
-
<header>
|
| 1724 |
-
<span class="badge">Axis Β· Llama3 Agent API</span>
|
| 1725 |
-
<h1>Welcome π</h1>
|
| 1726 |
-
<p class="sub">This Space exposes a tiny agent server powered by <b>$MODEL</b>.
|
| 1727 |
-
Use it with our CLI client, or hit the HTTP endpoints directly.</p>
|
| 1728 |
-
<div class="row muted">
|
| 1729 |
-
<div>Live status: <span class="ok">Running</span></div>
|
| 1730 |
-
<div>β’</div>
|
| 1731 |
-
<div>Endpoints: <code>/infer</code> <code>/execute</code> <code>/gen</code> <code>/status</code></div>
|
| 1732 |
-
</div>
|
| 1733 |
-
</header>
|
| 1734 |
-
|
| 1735 |
-
<section class="grid">
|
| 1736 |
-
<div class="card">
|
| 1737 |
-
<h3>Quick start (CLI)</h3>
|
| 1738 |
-
<p class="muted">Point the client at this Space and set an API key (if enabled).</p>
|
| 1739 |
-
<pre>export LLAMA_SERVER="https://tandevllc-axis.hf.space"
|
| 1740 |
-
export LLAMA_API_KEY="<your-key>" # optional
|
| 1741 |
-
python3 client.py</pre>
|
| 1742 |
-
|
| 1743 |
-
<h3>HTTP examples (cURL)</h3>
|
| 1744 |
-
<pre>curl -X POST "$LLAMA_SERVER/infer" \
|
| 1745 |
-
-H "content-type: application/json" \
|
| 1746 |
-
-H "authorization: Bearer <your-key>" \
|
| 1747 |
-
-d '{"prompt":"List three things this API can do"}'</pre>
|
| 1748 |
-
|
| 1749 |
-
<pre>curl -X POST "$LLAMA_SERVER/execute" \
|
| 1750 |
-
-H "content-type: application/json" \
|
| 1751 |
-
-H "authorization: Bearer <your-key>" \
|
| 1752 |
-
-d '{"plan":{"steps":[{"type":"respond","text":"Hello from Axis"}]}}'</pre>
|
| 1753 |
-
|
| 1754 |
-
<pre>curl -X POST "$LLAMA_SERVER/gen" \
|
| 1755 |
-
-H "content-type: application/json" \
|
| 1756 |
-
-H "authorization: Bearer <your-key>" \
|
| 1757 |
-
-d '{"format":"text","instruction":"one-line haiku about security"}'</pre>
|
| 1758 |
-
</div>
|
| 1759 |
-
|
| 1760 |
-
<div class="card">
|
| 1761 |
-
<h3>Try it here</h3>
|
| 1762 |
-
<p class="muted">Send a request to <code>/infer</code> from the browser.</p>
|
| 1763 |
-
<label class="muted">API key (optional)</label>
|
| 1764 |
-
<input id="key" type="password" placeholder="Bearer token if required"/>
|
| 1765 |
-
<label class="muted" style="margin-top:8px; display:block;">Prompt</label>
|
| 1766 |
-
<textarea id="prompt">Say hello in one short line.</textarea>
|
| 1767 |
-
<div class="row" style="margin-top:10px;">
|
| 1768 |
-
<button id="run">Run</button>
|
| 1769 |
-
<span id="status" class="muted"></span>
|
| 1770 |
-
</div>
|
| 1771 |
-
<pre id="out" style="margin-top:10px; min-height:140px;">(response appears here)</pre>
|
| 1772 |
-
</div>
|
| 1773 |
-
</section>
|
| 1774 |
-
|
| 1775 |
-
<section class="grid" style="grid-template-columns: 1fr;">
|
| 1776 |
-
<div class="card">
|
| 1777 |
-
<h3>Endpoint contract</h3>
|
| 1778 |
-
<ul class="muted">
|
| 1779 |
-
<li><code>POST /infer</code> β <code>{"plan":{"steps":[...]}}</code> (first call may be slow while the Space warms up)</li>
|
| 1780 |
-
<li><code>POST /execute</code> with <code>{"plan": ...}</code> β <code>{"results":[...]}</code></li>
|
| 1781 |
-
<li><code>POST /gen</code> with <code>{"format","instruction","length"}</code> β <code>{"content":"..."}</code></li>
|
| 1782 |
-
<li><code>GET /status</code> β JSON status</li>
|
| 1783 |
-
<li><span class="muted">Send <code>Authorization: Bearer <token></code> if your server enforces API keys.</span></li>
|
| 1784 |
-
</ul>
|
| 1785 |
-
</div>
|
| 1786 |
-
</section>
|
| 1787 |
-
|
| 1788 |
-
<footer>
|
| 1789 |
-
<p>Built by TanDev Β· Axis server Β· Model: <b>$MODEL</b>. For programmatic checks, hit <a href="/status">/status</a> or request <code>Accept: application/json</code> on <code>/</code>.</p>
|
| 1790 |
-
</footer>
|
| 1791 |
-
|
| 1792 |
-
<script>
|
| 1793 |
-
const $ = (id)=>document.getElementById(id);
|
| 1794 |
-
$("run").addEventListener("click", async () => {
|
| 1795 |
-
$("run").disabled = true; $("status").textContent = "Calling /inferβ¦";
|
| 1796 |
-
$("out").textContent = "";
|
| 1797 |
-
try {
|
| 1798 |
-
const headers = { "content-type": "application/json" };
|
| 1799 |
-
const key = $("key").value.trim();
|
| 1800 |
-
if (key) headers["authorization"] = key.startsWith("Bearer ") ? key : ("Bearer " + key);
|
| 1801 |
-
const r = await fetch("/infer", {
|
| 1802 |
-
method:"POST", headers, body: JSON.stringify({ prompt: $("prompt").value })
|
| 1803 |
-
});
|
| 1804 |
-
const txt = await r.text();
|
| 1805 |
-
$("out").textContent = txt;
|
| 1806 |
-
$("status").textContent = r.ok ? "OK" : ("HTTP " + r.status);
|
| 1807 |
-
} catch (e) {
|
| 1808 |
-
$("status").textContent = "Error";
|
| 1809 |
-
$("out").textContent = String(e);
|
| 1810 |
-
} finally {
|
| 1811 |
-
$("run").disabled = false;
|
| 1812 |
-
}
|
| 1813 |
-
});
|
| 1814 |
-
</script>
|
| 1815 |
-
</body>
|
| 1816 |
-
</html>""")
|
| 1817 |
-
|
| 1818 |
@app.get("/")
|
| 1819 |
-
def
|
| 1820 |
-
|
| 1821 |
-
|
| 1822 |
-
|
| 1823 |
-
|
| 1824 |
-
|
|
|
|
| 1825 |
|
|
|
|
| 1826 |
@app.get("/status")
|
| 1827 |
def status():
|
| 1828 |
return jsonify(ok=True, model=MODEL_NAME)
|
| 1829 |
-
|
| 1830 |
# ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1831 |
# 4) Main
|
| 1832 |
# ββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 8 |
β’ robust JSON extraction (balanced braces) to avoid parse failures
|
| 9 |
"""
|
| 10 |
|
| 11 |
+
from flask import Flask, request, jsonify, Response, send_from_directory
|
| 12 |
from huggingface_hub import snapshot_download
|
| 13 |
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
|
| 14 |
import subprocess, os, json, traceback, io, contextlib
|
|
|
|
| 33 |
# ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 34 |
# 3) Flask app & actions executor
|
| 35 |
# ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 36 |
+
app = Flask(__name__, static_folder="public", static_url_path="")
|
| 37 |
|
| 38 |
SERVER_OS = platform.system().lower()
|
| 39 |
ALLOW_AUTO_INSTALL = os.environ.get("ALLOW_AUTO_INSTALL", "0") == "1"
|
|
|
|
| 1689 |
out = llm_generate_text_exact(model, sys, user, max_new_tokens={"short":400,"medium":1200,"long":2400,"xl":4800}[length])
|
| 1690 |
return jsonify({"new_content": _sanitize_generated_content(None, "text", out)})
|
| 1691 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1692 |
@app.get("/")
|
| 1693 |
+
def root():
|
| 1694 |
+
return send_from_directory(app.static_folder, "index.html")
|
| 1695 |
+
|
| 1696 |
+
# (optional convenience)
|
| 1697 |
+
@app.get("/index.html")
|
| 1698 |
+
def root_html():
|
| 1699 |
+
return send_from_directory(app.static_folder, "index.html")
|
| 1700 |
|
| 1701 |
+
# keep status JSON as-is
|
| 1702 |
@app.get("/status")
|
| 1703 |
def status():
|
| 1704 |
return jsonify(ok=True, model=MODEL_NAME)
|
|
|
|
| 1705 |
# ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 1706 |
# 4) Main
|
| 1707 |
# ββββββββββββββββββββββββββββββββββββββββββββββ
|