TwoQuarks commited on
Commit
e7d5930
·
verified ·
1 Parent(s): 3226d99

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -98
app.py CHANGED
@@ -4,10 +4,6 @@ import subprocess
4
  from pathlib import Path
5
  import gradio as gr
6
 
7
- # ============================================================
8
- # Paths (Linux is case-sensitive!)
9
- # ============================================================
10
-
11
  ROOT = Path(__file__).resolve().parent
12
 
13
  DOWN_ROOT = ROOT / "Down"
@@ -22,21 +18,15 @@ STRANGE_RESULTS = STRANGE_ROOT / "results"
22
  STYLE_PATH = ROOT / "style.css"
23
  CSS = STYLE_PATH.read_text(encoding="utf-8") if STYLE_PATH.exists() else ""
24
 
25
- # ============================================================
26
- # JS (canvas + menu) — patched for HiDPI
27
- # ============================================================
28
-
29
  JS = r"""
30
  () => {
31
  if (window.__tq_starfield_running) return;
32
-
33
  function initOnceDomReady() {
34
  const canvas = document.getElementById("quantumField");
35
  const btn = document.getElementById("tqMenuBtn");
36
  const menu = document.getElementById("tqMenu");
37
  if (!canvas) return false;
38
 
39
- // Menu toggle (idempotent)
40
  if (btn && menu && !btn.__tq_bound) {
41
  btn.__tq_bound = true;
42
  btn.addEventListener("click", () => menu.classList.toggle("open"));
@@ -57,13 +47,10 @@ JS = r"""
57
 
58
  function resize() {
59
  dpr = Math.max(1, window.devicePixelRatio || 1);
60
- // CSS size
61
  canvas.style.width = window.innerWidth + "px";
62
  canvas.style.height = window.innerHeight + "px";
63
- // backing buffer
64
  canvas.width = Math.floor(window.innerWidth * dpr);
65
  canvas.height = Math.floor(window.innerHeight * dpr);
66
- // draw in CSS pixels
67
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
68
  w = window.innerWidth;
69
  h = window.innerHeight;
@@ -84,7 +71,6 @@ JS = r"""
84
  function tick() {
85
  ctx.clearRect(0, 0, w, h);
86
 
87
- // subtle vignette
88
  const g = ctx.createRadialGradient(w/2, h/2, 10, w/2, h/2, Math.max(w,h)/1.1);
89
  g.addColorStop(0, "rgba(0,0,0,0)");
90
  g.addColorStop(1, "rgba(0,0,0,0.55)");
@@ -93,6 +79,7 @@ JS = r"""
93
 
94
  ctx.globalAlpha = 0.9;
95
  ctx.fillStyle = "rgba(255,255,255,0.75)";
 
96
  for (const s of stars) {
97
  s.y += s.v * (1.0 + (1.0 - s.z));
98
  if (s.y > h + 10) { s.y = -10; s.x = Math.random() * w; }
@@ -107,12 +94,10 @@ JS = r"""
107
 
108
  resize();
109
  seed();
110
-
111
  if (!window.__tq_resize_bound) {
112
  window.__tq_resize_bound = true;
113
  window.addEventListener("resize", () => { resize(); seed(); });
114
  }
115
-
116
  window.__tq_starfield_running = true;
117
  tick();
118
  return true;
@@ -128,10 +113,6 @@ JS = r"""
128
  }
129
  """
130
 
131
- # ============================================================
132
- # Helpers
133
- # ============================================================
134
-
135
  def _clean_pngs(folder: Path):
136
  folder.mkdir(parents=True, exist_ok=True)
137
  for f in folder.rglob("*.png"):
@@ -140,13 +121,11 @@ def _clean_pngs(folder: Path):
140
  except Exception:
141
  pass
142
 
143
-
144
  def _collect_pngs(folder: Path):
145
  if not folder.exists():
146
  return []
147
  return sorted(str(p.resolve()) for p in folder.rglob("*.png"))
148
 
149
-
150
  def _run_capture(cmd, cwd: Path, env: dict, timeout_s: int = 900):
151
  """
152
  Run a subprocess and capture stdout/stderr.
@@ -180,11 +159,6 @@ def _run_capture(cmd, cwd: Path, env: dict, timeout_s: int = 900):
180
 
181
  return result.stdout, result.stderr
182
 
183
-
184
- # ============================================================
185
- # DOWN (Unified: Down + AntiDown)
186
- # ============================================================
187
-
188
  def run_down_all(episodes: int):
189
  run_all = DOWN_ROOT / "run_all.py"
190
  if not run_all.exists():
@@ -214,11 +188,6 @@ def run_down_all(episodes: int):
214
  }
215
  return meta, images
216
 
217
-
218
- # ============================================================
219
- # STRANGE (Unified: Strange + AntiStrange)
220
- # ============================================================
221
-
222
  def run_strange_all():
223
  run_all = STRANGE_ROOT / "run_all.py"
224
  if not run_all.exists():
@@ -245,14 +214,8 @@ def run_strange_all():
245
  }
246
  return meta, images
247
 
248
-
249
- # ============================================================
250
- # UI
251
- # ============================================================
252
-
253
  def build_ui():
254
  with gr.Blocks(title="TwoQuarks — QuarksLab", css=CSS, js=JS) as demo:
255
-
256
  gr.HTML(
257
  """
258
  <canvas id="quantumField"></canvas>
@@ -276,85 +239,116 @@ def build_ui():
276
  )
277
 
278
  with gr.Column(elem_id="tq-app"):
279
-
280
  gr.Markdown(
281
  """
282
  <div class="tq-hero">
283
- <div class="brand">TwoQuarks • QuarksLab</div>
284
- <div class="desc"><b>Run Models.</b> Real artifacts. Real agents.</div>
 
 
285
  </div>
286
  """,
287
  elem_id="top",
288
  )
289
 
290
- # ----------------------------
291
- # DOWN
292
- # ----------------------------
293
  gr.HTML('<div id="down"></div>')
294
- gr.Markdown("## DOWN / AntiDown")
295
- gr.Markdown(
296
- "RL agents designed to expose failure modes under **deceptive reward** conditions."
297
- )
298
-
299
- run_down_btn = gr.Button("Run DOWN Model", elem_id="btn_down", elem_classes=["tq-primary"])
300
-
301
- with gr.Accordion("Advanced parameters", open=False):
302
- down_eps = gr.Slider(50, 500, step=50, value=200, label="Episodes per phase")
303
-
304
- with gr.Accordion("Run status / logs", open=False):
305
- down_meta = gr.JSON(label="Run status", elem_id="down_meta")
306
-
307
- down_gallery = gr.Gallery(
308
- label="Generated plots",
309
- show_label=False,
310
- columns=8, # wide -> we’ll style as strip
311
- height=260, # stable tiles
312
- elem_id="down_gallery",
313
- )
314
-
315
- run_down_btn.click(
316
- fn=run_down_all,
317
- inputs=[down_eps],
318
- outputs=[down_meta, down_gallery],
319
- api_name=False,
320
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
 
322
  gr.Markdown("---")
323
-
324
- # ----------------------------
325
- # STRANGE
326
- # ----------------------------
327
  gr.HTML('<div id="strange"></div>')
328
- gr.Markdown("## STRANGE / AntiStrange")
329
- gr.Markdown(
330
- "RL agents designed to study failure under **hidden regime shifts** and phase transitions."
331
- )
 
 
 
332
 
333
- run_strange_btn = gr.Button("Run STRANGE Model", elem_id="btn_strange", elem_classes=["tq-primary"])
 
 
334
 
335
- with gr.Accordion("Run status / logs", open=False):
336
- strange_meta = gr.JSON(label="Run status", elem_id="strange_meta")
337
 
338
- strange_gallery = gr.Gallery(
339
- show_label=False,
340
- columns=8,
341
- height=260,
342
- elem_id="strange_gallery",
343
- )
344
-
345
- run_strange_btn.click(
346
- fn=run_strange_all,
347
- inputs=[],
348
- outputs=[strange_meta, strange_gallery],
349
- api_name=False,
350
- )
 
 
 
 
 
 
 
 
 
 
 
351
 
352
  gr.Markdown(
353
  """
354
  ---
355
- ### Notes
356
- - This lab and the TwoQuarks website are developed end-to-end by Jaime Ledesma.
357
- - Visualizations shown here are **direct artifacts** produced by the models.
 
 
 
358
  """
359
  )
360
 
 
4
  from pathlib import Path
5
  import gradio as gr
6
 
 
 
 
 
7
  ROOT = Path(__file__).resolve().parent
8
 
9
  DOWN_ROOT = ROOT / "Down"
 
18
  STYLE_PATH = ROOT / "style.css"
19
  CSS = STYLE_PATH.read_text(encoding="utf-8") if STYLE_PATH.exists() else ""
20
 
 
 
 
 
21
  JS = r"""
22
  () => {
23
  if (window.__tq_starfield_running) return;
 
24
  function initOnceDomReady() {
25
  const canvas = document.getElementById("quantumField");
26
  const btn = document.getElementById("tqMenuBtn");
27
  const menu = document.getElementById("tqMenu");
28
  if (!canvas) return false;
29
 
 
30
  if (btn && menu && !btn.__tq_bound) {
31
  btn.__tq_bound = true;
32
  btn.addEventListener("click", () => menu.classList.toggle("open"));
 
47
 
48
  function resize() {
49
  dpr = Math.max(1, window.devicePixelRatio || 1);
 
50
  canvas.style.width = window.innerWidth + "px";
51
  canvas.style.height = window.innerHeight + "px";
 
52
  canvas.width = Math.floor(window.innerWidth * dpr);
53
  canvas.height = Math.floor(window.innerHeight * dpr);
 
54
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
55
  w = window.innerWidth;
56
  h = window.innerHeight;
 
71
  function tick() {
72
  ctx.clearRect(0, 0, w, h);
73
 
 
74
  const g = ctx.createRadialGradient(w/2, h/2, 10, w/2, h/2, Math.max(w,h)/1.1);
75
  g.addColorStop(0, "rgba(0,0,0,0)");
76
  g.addColorStop(1, "rgba(0,0,0,0.55)");
 
79
 
80
  ctx.globalAlpha = 0.9;
81
  ctx.fillStyle = "rgba(255,255,255,0.75)";
82
+
83
  for (const s of stars) {
84
  s.y += s.v * (1.0 + (1.0 - s.z));
85
  if (s.y > h + 10) { s.y = -10; s.x = Math.random() * w; }
 
94
 
95
  resize();
96
  seed();
 
97
  if (!window.__tq_resize_bound) {
98
  window.__tq_resize_bound = true;
99
  window.addEventListener("resize", () => { resize(); seed(); });
100
  }
 
101
  window.__tq_starfield_running = true;
102
  tick();
103
  return true;
 
113
  }
114
  """
115
 
 
 
 
 
116
  def _clean_pngs(folder: Path):
117
  folder.mkdir(parents=True, exist_ok=True)
118
  for f in folder.rglob("*.png"):
 
121
  except Exception:
122
  pass
123
 
 
124
  def _collect_pngs(folder: Path):
125
  if not folder.exists():
126
  return []
127
  return sorted(str(p.resolve()) for p in folder.rglob("*.png"))
128
 
 
129
  def _run_capture(cmd, cwd: Path, env: dict, timeout_s: int = 900):
130
  """
131
  Run a subprocess and capture stdout/stderr.
 
159
 
160
  return result.stdout, result.stderr
161
 
 
 
 
 
 
162
  def run_down_all(episodes: int):
163
  run_all = DOWN_ROOT / "run_all.py"
164
  if not run_all.exists():
 
188
  }
189
  return meta, images
190
 
 
 
 
 
 
191
  def run_strange_all():
192
  run_all = STRANGE_ROOT / "run_all.py"
193
  if not run_all.exists():
 
214
  }
215
  return meta, images
216
 
 
 
 
 
 
217
  def build_ui():
218
  with gr.Blocks(title="TwoQuarks — QuarksLab", css=CSS, js=JS) as demo:
 
219
  gr.HTML(
220
  """
221
  <canvas id="quantumField"></canvas>
 
239
  )
240
 
241
  with gr.Column(elem_id="tq-app"):
 
242
  gr.Markdown(
243
  """
244
  <div class="tq-hero">
245
+ <div class="tq-hero__brand">TwoQuarks • QuarksLab</div>
246
+ <div class="tq-hero__desc">
247
+ <b>Run agents.</b> Generate real artifacts. Inspect failure modes in controlled environments.
248
+ </div>
249
  </div>
250
  """,
251
  elem_id="top",
252
  )
253
 
 
 
 
254
  gr.HTML('<div id="down"></div>')
255
+ with gr.Group():
256
+ gr.Markdown(
257
+ """
258
+ <div class="tq-card-title">DOWN / AntiDown</div>
259
+ <div class="tq-card-subtitle">Deceptive reward • reward hacking signatures • instability diagnostics</div>
260
+ """,
261
+ )
262
+
263
+ with gr.Row(equal_height=True):
264
+ with gr.Column(scale=1, min_width=280):
265
+ run_down_btn = gr.Button("Run DOWN Pipeline", variant="primary", elem_id="btn_down")
266
+ with gr.Accordion("Advanced parameters", open=False):
267
+ down_eps = gr.Slider(
268
+ 50, 500, step=50, value=200,
269
+ label="Episodes per phase"
270
+ )
271
+
272
+ with gr.Accordion("Run status / logs", open=False):
273
+ down_meta = gr.JSON(label="Run status", elem_id="down_meta")
274
+ gr.Markdown(
275
+ """
276
+ <div class="tq-card-subtitle">
277
+ Tip: start with 200 episodes. Increase only when you need cleaner trends in plots.
278
+ </div>
279
+ """
280
+ )
281
+
282
+ with gr.Column(scale=2, min_width=420):
283
+ gr.Markdown(
284
+ '<div class="tq-card-title">Generated artifacts</div>'
285
+ )
286
+ down_gallery = gr.Gallery(
287
+ show_label=False,
288
+ columns=1,
289
+ height=240,
290
+ elem_id="down_gallery",
291
+ preview=True,
292
+ )
293
+
294
+ run_down_btn.click(
295
+ fn=run_down_all,
296
+ inputs=[down_eps],
297
+ outputs=[down_meta, down_gallery],
298
+ api_name=False,
299
+ )
300
 
301
  gr.Markdown("---")
 
 
 
 
302
  gr.HTML('<div id="strange"></div>')
303
+ with gr.Group():
304
+ gr.Markdown(
305
+ """
306
+ <div class="tq-card-title">STRANGE / AntiStrange</div>
307
+ <div class="tq-card-subtitle">Hidden regime shifts • phase transitions • early warning signals</div>
308
+ """,
309
+ )
310
 
311
+ with gr.Row(equal_height=True):
312
+ with gr.Column(scale=1, min_width=280):
313
+ run_strange_btn = gr.Button("Run STRANGE Pipeline", variant="primary", elem_id="btn_strange")
314
 
315
+ with gr.Accordion("Run status / logs", open=False):
316
+ strange_meta = gr.JSON(label="Run status", elem_id="strange_meta")
317
 
318
+ gr.Markdown(
319
+ """
320
+ <div class="tq-card-subtitle">
321
+ This pipeline explores stability under non-stationarity: when the world changes mid-training.
322
+ </div>
323
+ """
324
+ )
325
+
326
+ with gr.Column(scale=2, min_width=420):
327
+ gr.Markdown('<div class="tq-card-title">Generated artifacts</div>')
328
+ strange_gallery = gr.Gallery(
329
+ show_label=False,
330
+ columns=1,
331
+ height=240,
332
+ elem_id="strange_gallery",
333
+ preview=True,
334
+ )
335
+
336
+ run_strange_btn.click(
337
+ fn=run_strange_all,
338
+ inputs=[],
339
+ outputs=[strange_meta, strange_gallery],
340
+ api_name=False,
341
+ )
342
 
343
  gr.Markdown(
344
  """
345
  ---
346
+ ### About QuarksLab
347
+ - This space is a small laboratory developed so
348
+ that anyone interested can view our work.
349
+ - The graphics shown are direct artifacts of the
350
+ TwoQuarks research framework, focused on the
351
+ AI Safety.
352
  """
353
  )
354