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