Jarvis2345 commited on
Commit
a060abc
·
verified ·
1 Parent(s): dff3932

deploy(S4): Blender headless pipeline + WebAR client + backend fixes

Browse files
Files changed (2) hide show
  1. backend/main.py +73 -9
  2. backend/supervisor.py +23 -2
backend/main.py CHANGED
@@ -88,7 +88,7 @@ from backend.services.pc_mic_service import start_pc_mic_loop
88
  from backend.voice.audio_ws import run_in_thread as start_audio_ws
89
  APP_VERSION = "1.0.0"
90
 
91
- from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends
92
  from backend.security.auth import verify_token
93
  try:
94
  from slowapi import Limiter, _rate_limit_exceeded_handler
@@ -174,26 +174,90 @@ for _webar_candidate in (
174
  logging.info(f"[S4] WebAR client mounted at /webar from {_webar_candidate}")
175
  break
176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  @app.get("/")
178
- async def root_health_check():
 
 
 
 
 
 
179
  return {"status": "JARVIS / FRIDAY Cloud OS Online", "message": "All systems nominal."}
180
 
181
  @app.get("/wake")
182
  @app.post("/wake")
183
  async def wake_server():
184
  """Public endpoint — anyone can hit this from anywhere in the world to wake the cloud server.
185
- HF Spaces sleep after inactivity; this wakes them up instantly."""
 
 
 
 
186
  import time
187
  return {
188
  "status": "online",
189
  "message": "JARVIS / FRIDAY Cloud Brain is awake and operational.",
190
  "timestamp": time.time(),
191
- "servers": {
192
- "hf_space": "online",
193
- "sqlite": "online",
194
- "chroma": "online",
195
- "mongodb_atlas": "online"
196
- }
197
  }
198
 
199
  @app.get("/ping")
 
88
  from backend.voice.audio_ws import run_in_thread as start_audio_ws
89
  APP_VERSION = "1.0.0"
90
 
91
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, Request
92
  from backend.security.auth import verify_token
93
  try:
94
  from slowapi import Limiter, _rate_limit_exceeded_handler
 
174
  logging.info(f"[S4] WebAR client mounted at /webar from {_webar_candidate}")
175
  break
176
 
177
+ # Public front door of the Space. Everything on it is either static or rendered
178
+ # server-side from real state (uptime) — nothing fabricated, nothing token-gated
179
+ # leaks here.
180
+ _ROOT_STATUS_PAGE = """<!doctype html>
181
+ <html lang="en"><head><meta charset="utf-8">
182
+ <meta name="viewport" content="width=device-width, initial-scale=1">
183
+ <title>JARVIS Cloud OS</title>
184
+ <link rel="preconnect" href="https://fonts.googleapis.com">
185
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
186
+ <link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
187
+ <style>
188
+ :root { --accent:#35e6ff; --amber:#ffb454; --text:#dff3fb; --dim:rgba(223,243,251,.55); }
189
+ * { box-sizing:border-box; margin:0; }
190
+ body { min-height:100vh; display:flex; align-items:center; justify-content:center;
191
+ background:radial-gradient(circle at 50% 30%, #0a1620 0%, #05090e 65%, #030509 100%);
192
+ color:var(--text); font-family:'Chakra Petch',sans-serif; padding:24px; }
193
+ .card { width:min(560px,94vw); padding:36px 32px; border:1px solid rgba(120,220,255,.22);
194
+ border-radius:20px; background:rgba(10,22,30,.55); backdrop-filter:blur(24px) saturate(1.4);
195
+ box-shadow:0 18px 50px rgba(0,0,0,.55), inset 0 1px 0 rgba(180,240,255,.12); }
196
+ .eyebrow { font:600 11px/1 'Chakra Petch'; letter-spacing:.34em; color:var(--dim);
197
+ text-transform:uppercase; margin-bottom:14px; }
198
+ h1 { font:700 30px/1.2 'Chakra Petch'; letter-spacing:.02em; margin-bottom:6px; }
199
+ h1 em { font-style:normal; color:var(--accent); }
200
+ .sub { color:var(--dim); font-size:14px; margin-bottom:26px; }
201
+ .grid { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:26px; }
202
+ .stat { border:1px solid rgba(120,220,255,.14); border-radius:12px; padding:12px 14px; }
203
+ .stat span { display:block; font:400 10px/1 'Chakra Petch'; letter-spacing:.22em;
204
+ color:var(--dim); text-transform:uppercase; margin-bottom:7px; }
205
+ .stat strong { font:500 14px/1.3 'JetBrains Mono',monospace; color:var(--accent);
206
+ text-transform:uppercase; }
207
+ .stat strong.amber { color:var(--amber); }
208
+ .pulse { display:inline-block; width:9px; height:9px; border-radius:50%; background:var(--accent);
209
+ margin-right:8px; box-shadow:0 0 12px var(--accent); animation:pulse 2s ease-in-out infinite; }
210
+ @keyframes pulse { 50% { opacity:.35; box-shadow:0 0 4px var(--accent); } }
211
+ .links { display:flex; gap:10px; flex-wrap:wrap; }
212
+ .links a { flex:1; min-width:140px; text-align:center; padding:13px 18px; border-radius:12px;
213
+ text-decoration:none; font:600 13px/1 'Chakra Petch'; letter-spacing:.08em; text-transform:uppercase;
214
+ color:var(--text); border:1px solid rgba(120,220,255,.3); transition:background .15s, box-shadow .15s; }
215
+ .links a:hover { background:rgba(53,230,255,.12); box-shadow:0 0 22px rgba(53,230,255,.25); }
216
+ .foot { margin-top:24px; color:var(--dim); font-size:11px; letter-spacing:.06em; }
217
+ </style></head><body>
218
+ <main class="card">
219
+ <p class="eyebrow">Stark Industries &middot; Cloud Node</p>
220
+ <h1><span class="pulse"></span>JARVIS <em>/</em> FRIDAY</h1>
221
+ <p class="sub">OMEGA Cloud OS &mdash; all API surfaces are token-gated.</p>
222
+ <div class="grid">
223
+ <div class="stat"><span>Status</span><strong>Online</strong></div>
224
+ <div class="stat"><span>Uptime</span><strong>{{UPTIME}}</strong></div>
225
+ <div class="stat"><span>Mode</span><strong class="amber">Cloud</strong></div>
226
+ <div class="stat"><span>Assistant</span><strong>JARVIS</strong></div>
227
+ </div>
228
+ <div class="links">
229
+ <a href="/webar/">Enter WebAR</a>
230
+ <a href="/ping">Ping</a>
231
+ </div>
232
+ <p class="foot">Authorized clients: JARVIS desktop, Guardian mobile, WebAR.</p>
233
+ </main>
234
+ </body></html>"""
235
+
236
+
237
  @app.get("/")
238
+ async def root_health_check(request: Request):
239
+ # Browsers (the Space's public front door) get a real status page;
240
+ # programmatic callers keep the JSON contract unchanged.
241
+ if "text/html" in (request.headers.get("accept") or ""):
242
+ from backend.routes.mobile_bridge_routes import _uptime_str
243
+ from fastapi.responses import HTMLResponse
244
+ return HTMLResponse(_ROOT_STATUS_PAGE.replace("{{UPTIME}}", _uptime_str()))
245
  return {"status": "JARVIS / FRIDAY Cloud OS Online", "message": "All systems nominal."}
246
 
247
  @app.get("/wake")
248
  @app.post("/wake")
249
  async def wake_server():
250
  """Public endpoint — anyone can hit this from anywhere in the world to wake the cloud server.
251
+ HF Spaces sleep after inactivity; this wakes them up instantly.
252
+
253
+ Only claims what is actually true: the fact this handler is running means the
254
+ Space process is awake. Per-database claims were previously hardcoded
255
+ "online" without any check — that lie is gone."""
256
  import time
257
  return {
258
  "status": "online",
259
  "message": "JARVIS / FRIDAY Cloud Brain is awake and operational.",
260
  "timestamp": time.time(),
 
 
 
 
 
 
261
  }
262
 
263
  @app.get("/ping")
backend/supervisor.py CHANGED
@@ -117,8 +117,23 @@ Return ONLY the raw python code. Do not include markdown formatting or backticks
117
 
118
  if fixed_code.endswith("```"):
119
  fixed_code = fixed_code[:-3]
120
-
121
- return fixed_code.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  except Exception as e:
123
  print(f"[SUPERVISOR] Auto-healing failed: {e}")
124
  return None
@@ -187,6 +202,12 @@ def start_server():
187
  fixed_code = heal_code(crashed_file, stderr_data)
188
 
189
  if fixed_code:
 
 
 
 
 
 
190
  with open(crashed_file, "w", encoding="utf-8") as f:
191
  f.write(fixed_code)
192
  print("[SUPERVISOR] Code healed successfully. Restarting in 3 seconds...")
 
117
 
118
  if fixed_code.endswith("```"):
119
  fixed_code = fixed_code[:-3]
120
+
121
+ fixed_code = fixed_code.strip()
122
+
123
+ # An unvalidated LLM reply must never replace server code: reject
124
+ # anything that isn't syntactically valid Python or that shrank the
125
+ # file so much it's likely a truncated/apology reply.
126
+ import ast as _ast
127
+ try:
128
+ _ast.parse(fixed_code)
129
+ except SyntaxError as syn_err:
130
+ print(f"[SUPERVISOR] Heal rejected — generated code does not parse: {syn_err}")
131
+ return None
132
+ if len(fixed_code) < max(64, len(broken_code) // 3):
133
+ print("[SUPERVISOR] Heal rejected — generated code suspiciously short vs original.")
134
+ return None
135
+
136
+ return fixed_code
137
  except Exception as e:
138
  print(f"[SUPERVISOR] Auto-healing failed: {e}")
139
  return None
 
202
  fixed_code = heal_code(crashed_file, stderr_data)
203
 
204
  if fixed_code:
205
+ # Keep the pre-heal original so a bad patch is always recoverable.
206
+ try:
207
+ import shutil
208
+ shutil.copy2(crashed_file, crashed_file + ".pre_heal.bak")
209
+ except Exception as bak_err:
210
+ print(f"[SUPERVISOR] Warning: could not back up original before heal: {bak_err}")
211
  with open(crashed_file, "w", encoding="utf-8") as f:
212
  f.write(fixed_code)
213
  print("[SUPERVISOR] Code healed successfully. Restarting in 3 seconds...")