File size: 3,785 Bytes
5da9044
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
from flask import Flask, request, jsonify, make_response
import os, time, html, requests, json
from itsdangerous import BadSignature, URLSafeSerializer

SECRET_KEY     = os.getenv("SECRET_KEY", "change-me")   # must match Gate
TOKEN_TTL      = int(os.getenv("TOKEN_TTL", "3600"))
CHAT_MODEL_URL = os.getenv("CHAT_MODEL_URL", "")        # e.g. https://<your-model>/chat

app = Flask(__name__)
signer = URLSafeSerializer(SECRET_KEY, salt="jarvis-facegate")

def verify_token(token: str):
    try:
        data = signer.loads(token)
        if time.time() - float(data.get("ts", 0)) > TOKEN_TTL:
            return None
        return data
    except BadSignature:
        return None

def shell(name=""):
    safe = html.escape(name or "Agent")
    return f"""<!doctype html><html><head><meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1"/>
<title>Jarvis Chat</title>
<style>
  body{{margin:0;background:#0a0f18;color:#e8f3ff;font-family:ui-sans-serif,system-ui}}
  .wrap{{max-width:900px;margin:5vh auto;padding:24px}}
  .hud{{border:1px solid #3ee7ff4f;border-radius:16px;padding:16px;background:
  linear-gradient(180deg,rgba(10,16,24,.85),rgba(10,16,24,.65));box-shadow:0 20px 60px rgba(0,0,0,.5)}}
  h1{{margin:0 0 8px}} .muted{{color:#a9c2d0}}
  .row{{display:flex;gap:8px;margin-top:12px}}
  input,button{{padding:10px;border-radius:10px;border:1px solid #3ee7ff30;background:#0f1724;color:#e8f3ff}}
  button{{background:linear-gradient(90deg,#3ee7ff,#7bf5c8);color:#0a0f18;border:none;font-weight:800}}
  #log{{white-space:pre-wrap;min-height:180px;margin-top:12px;background:#0f1724;border:1px solid #3ee7ff21;border-radius:12px;padding:12px}}
</style></head>
<body><div class=wrap>
  <div class=hud>
    <h1>Jarvis Chat</h1>
    <div class=muted>Welcome, {safe}. You are now connected.</div>
    <div id=log></div>
    <div class=row>
      <input id=msg placeholder="Type your message..." style="flex:1"/>
      <button onclick="send()">Send</button>
    </div>
  </div>
</div>
<script>
async function send(){{
  const el = document.getElementById('msg');
  const txt = el.value.trim();
  if(!txt) return;
  el.value='';
  const res = await fetch('/api/chat', {{method:'POST', headers:{{'Content-Type':'application/json'}}, body: JSON.stringify({{q:txt}})}});
  const data = await res.json();
  const log = document.getElementById('log');
  log.textContent += "\\nYou: " + txt + "\\nJarvis: " + (data.a || data.error || '...') + "\\n";
}}
</script>
</body></html>"""

@app.get("/")
def home():
    token = request.args.get("token","")
    info = verify_token(token) if token else None
    if not info:
        return make_response("<h3>Access denied. Missing/invalid token.</h3>", 401)
    name = info.get("name","User")
    return make_response(shell(name), 200, {"Content-Type":"text/html; charset=utf-8"})

@app.post("/api/chat")
def api_chat():
    # This is a simple proxy to your chatbot model, or a stub if CHAT_MODEL_URL is unset.
    q = (request.json or {}).get("q","").strip()
    if not q:
        return jsonify({"error":"empty message"}), 400

    if CHAT_MODEL_URL:
        try:
            r = requests.post(CHAT_MODEL_URL, json={"inputs": q}, timeout=60)
            if r.ok:
                # Tailor this to your model's response schema
                data = r.json()
                a = data.get("generated_text") or data.get("answer") or str(data)
                return jsonify({"a": a})
            return jsonify({"error": f"model status {r.status_code}"}), 502
        except Exception as e:
            return jsonify({"error": f"upstream error: {e}"}), 502
    else:
        # Stub: echo
        return jsonify({"a": f"(stub) You said: {q}"}), 200

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=7860)