cvpfus Codex commited on
Commit
bf25028
·
1 Parent(s): 084291e

Add curl commands to demo checks

Browse files

Co-authored-by: Codex <codex@openai.com>

Files changed (7) hide show
  1. FIELD_NOTES.md +1 -1
  2. README.md +1 -1
  3. SUBMISSION.md +1 -1
  4. app.py +42 -30
  5. scripts/verify.py +9 -0
  6. static/app.css +10 -0
  7. static/app.js +1 -0
FIELD_NOTES.md CHANGED
@@ -28,7 +28,7 @@ The app exposes the same budget through `/api/model-budget`, including numeric `
28
 
29
  Runtime setup is also data-backed. `/api/runtime-setup` lists the app command, llama.cpp launch command, model-specific runtime paths, environment values, and fallbacks. The session panel renders a compact version so the demo can distinguish real model wiring from deterministic safety nets.
30
 
31
- The judge runbook lives at `/api/demo-script` and is rendered in the session panel with its API evidence checks. It keeps the live presentation repeatable by pairing visible actions with API checks for health, model budget, runtime setup, runtime status, image descriptions, reader narration, and speech.
32
 
33
  Submission readiness lives at `/api/submission-readiness`. It aggregates the demo-critical checks into one payload: model budget, award evidence, custom frontend assets, runtime setup, accessibility audit, image receipts, and executable demo API checks. POST checks must include sample bodies before readiness passes.
34
 
 
28
 
29
  Runtime setup is also data-backed. `/api/runtime-setup` lists the app command, llama.cpp launch command, model-specific runtime paths, environment values, and fallbacks. The session panel renders a compact version so the demo can distinguish real model wiring from deterministic safety nets.
30
 
31
+ The judge runbook lives at `/api/demo-script` and is rendered in the session panel with its API evidence checks. It keeps the live presentation repeatable by pairing visible actions with API checks for health, model budget, runtime setup, runtime status, image descriptions, reader narration, and speech. Each API check includes a curl command for quick reproduction.
32
 
33
  Submission readiness lives at `/api/submission-readiness`. It aggregates the demo-critical checks into one payload: model budget, award evidence, custom frontend assets, runtime setup, accessibility audit, image receipts, and executable demo API checks. POST checks must include sample bodies before readiness passes.
34
 
README.md CHANGED
@@ -75,7 +75,7 @@ The verifier checks syntax, static assets, Space metadata consistency, determini
75
 
76
  `/api/runtime-setup` exposes the commands, environment values, and fallback paths used for the model stack so the demo can be reproduced from the same data the UI displays.
77
 
78
- `/api/demo-script` exposes a compact judge runbook with the visible actions and API checks that prove the submission claims. The session panel renders those actions and API evidence checks as the Judge Runbook.
79
 
80
  `/api/accessibility-audit` exposes structured evidence for semantic reading order, keyboard navigation, reader cursor state, shortcut safety, live narration, image alt text, transcript review, user-controlled playback, and fallback resilience.
81
 
 
75
 
76
  `/api/runtime-setup` exposes the commands, environment values, and fallback paths used for the model stack so the demo can be reproduced from the same data the UI displays.
77
 
78
+ `/api/demo-script` exposes a compact judge runbook with the visible actions, API checks, sample bodies, and curl commands that prove the submission claims. The session panel renders those actions and API evidence checks as the Judge Runbook.
79
 
80
  `/api/accessibility-audit` exposes structured evidence for semantic reading order, keyboard navigation, reader cursor state, shortcut safety, live narration, image alt text, transcript review, user-controlled playback, and fallback resilience.
81
 
SUBMISSION.md CHANGED
@@ -46,7 +46,7 @@ The prototype is designed for a live hackathon demo: every model-facing path has
46
  - `/api/submission-readiness`: one pass/fail rollup for model budget, award evidence, custom frontend, runtime setup, accessibility, image receipts, and demo API checks.
47
  - `/api/evidence-bundle`: copyable JSON bundle containing the core judge evidence receipts.
48
 
49
- The POST checks in `/api/demo-script` include sample JSON bodies for `/api/reader-brain` and `/api/speak`.
50
 
51
  The accessibility audit also documents two reader-mode details that matter during judging: the active item is exposed as a reader cursor with focus, visible outline, stable id, and `aria-current`; global shortcuts ignore form controls so voice, speed, and auto-advance settings remain usable while reader mode is active.
52
 
 
46
  - `/api/submission-readiness`: one pass/fail rollup for model budget, award evidence, custom frontend, runtime setup, accessibility, image receipts, and demo API checks.
47
  - `/api/evidence-bundle`: copyable JSON bundle containing the core judge evidence receipts.
48
 
49
+ The checks in `/api/demo-script` include curl commands, and the POST checks include sample JSON bodies for `/api/reader-brain` and `/api/speak`.
50
 
51
  The accessibility audit also documents two reader-mode details that matter during judging: the active item is exposed as a reader cursor with focus, visible outline, stable id, and `aria-current`; global shortcuts ignore form controls so voice, speed, and auto-advance settings remain usable while reader mode is active.
52
 
app.py CHANGED
@@ -213,7 +213,48 @@ def runtime_setup_core() -> dict[str, Any]:
213
  }
214
 
215
 
 
 
 
 
 
 
 
 
216
  def demo_script_core() -> dict[str, Any]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  return {
218
  "ok": True,
219
  "title": "Tiny Narrator judge demo",
@@ -245,36 +286,7 @@ def demo_script_core() -> dict[str, Any]:
245
  "evidence": "Tiny Titan, Llama Champion, Off-Brand, and Field Notes evidence is visible.",
246
  },
247
  ],
248
- "api_checks": [
249
- {"method": "GET", "path": "/api/health", "expect": "custom Gradio Server app and model manifest"},
250
- {"method": "GET", "path": "/api/model-budget", "expect": "all_models_within_limit is true"},
251
- {"method": "GET", "path": "/api/runtime-setup", "expect": "llama.cpp, Kokoro, vision, and image paths"},
252
- {"method": "GET", "path": "/api/runtime-status", "expect": "online or fallback-ready runtime labels"},
253
- {"method": "GET", "path": "/api/accessibility-audit", "expect": "all reader-mode checks pass"},
254
- {"method": "GET", "path": "/api/image-descriptions", "expect": "three article image descriptions"},
255
- {"method": "GET", "path": "/api/submission-readiness", "expect": "all submission readiness checks pass"},
256
- {
257
- "method": "POST",
258
- "path": "/api/reader-brain",
259
- "expect": "concise narration or fallback narration",
260
- "sample_body": {
261
- "node_type": "heading",
262
- "text": "The model map",
263
- "position": "item 4 of 10",
264
- "mode": "narrate",
265
- },
266
- },
267
- {
268
- "method": "POST",
269
- "path": "/api/speak",
270
- "expect": "Kokoro audio or audible browser fallback path",
271
- "sample_body": {
272
- "text": "Heading. The model map.",
273
- "voice": READER_SETTINGS["default_voice"],
274
- "speed": READER_SETTINGS["default_speed"],
275
- },
276
- },
277
- ],
278
  }
279
 
280
 
 
213
  }
214
 
215
 
216
+ def demo_curl_command(check: dict[str, Any]) -> str:
217
+ url = f"http://localhost:7860{check['path']}"
218
+ if check["method"] == "GET":
219
+ return f"curl {url}"
220
+ sample_body = json.dumps(check["sample_body"], separators=(",", ":"))
221
+ return f"curl -X POST {url} -H \"Content-Type: application/json\" -d '{sample_body}'"
222
+
223
+
224
  def demo_script_core() -> dict[str, Any]:
225
+ api_checks = [
226
+ {"method": "GET", "path": "/api/health", "expect": "custom Gradio Server app and model manifest"},
227
+ {"method": "GET", "path": "/api/model-budget", "expect": "all_models_within_limit is true"},
228
+ {"method": "GET", "path": "/api/runtime-setup", "expect": "llama.cpp, Kokoro, vision, and image paths"},
229
+ {"method": "GET", "path": "/api/runtime-status", "expect": "online or fallback-ready runtime labels"},
230
+ {"method": "GET", "path": "/api/accessibility-audit", "expect": "all reader-mode checks pass"},
231
+ {"method": "GET", "path": "/api/image-descriptions", "expect": "three article image descriptions"},
232
+ {"method": "GET", "path": "/api/submission-readiness", "expect": "all submission readiness checks pass"},
233
+ {
234
+ "method": "POST",
235
+ "path": "/api/reader-brain",
236
+ "expect": "concise narration or fallback narration",
237
+ "sample_body": {
238
+ "node_type": "heading",
239
+ "text": "The model map",
240
+ "position": "item 4 of 10",
241
+ "mode": "narrate",
242
+ },
243
+ },
244
+ {
245
+ "method": "POST",
246
+ "path": "/api/speak",
247
+ "expect": "Kokoro audio or audible browser fallback path",
248
+ "sample_body": {
249
+ "text": "Heading. The model map.",
250
+ "voice": READER_SETTINGS["default_voice"],
251
+ "speed": READER_SETTINGS["default_speed"],
252
+ },
253
+ },
254
+ ]
255
+ for check in api_checks:
256
+ check["curl"] = demo_curl_command(check)
257
+
258
  return {
259
  "ok": True,
260
  "title": "Tiny Narrator judge demo",
 
286
  "evidence": "Tiny Titan, Llama Champion, Off-Brand, and Field Notes evidence is visible.",
287
  },
288
  ],
289
+ "api_checks": api_checks,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  }
291
 
292
 
scripts/verify.py CHANGED
@@ -45,6 +45,7 @@ def verify_static_assets() -> None:
45
  assert_true("copyEvidenceButton" in index_html, "Article should expose a copyable evidence bundle button")
46
  assert_true("loadDemoScript" in app_js, "Frontend should render the structured demo script")
47
  assert_true("payload.api_checks" in app_js, "Frontend should render structured demo API checks")
 
48
  assert_true("/api/evidence-bundle" in app_js, "Frontend should fetch the evidence bundle for copying")
49
  assert_true("function haltPlayback" in app_js, "Reader controls should expose a shared playback halt helper")
50
  assert_true(
@@ -344,6 +345,14 @@ def verify_routes() -> None:
344
  all(item.get("sample_body") for item in demo_payload["api_checks"] if item["method"] == "POST"),
345
  "Every POST demo check should include an executable sample body",
346
  )
 
 
 
 
 
 
 
 
347
  reader_sample = client.post(reader_check["path"], json=reader_check["sample_body"])
348
  assert_true(reader_sample.status_code == 200, "Reader-brain sample payload should be executable")
349
  reader_sample_payload = reader_sample.json()
 
45
  assert_true("copyEvidenceButton" in index_html, "Article should expose a copyable evidence bundle button")
46
  assert_true("loadDemoScript" in app_js, "Frontend should render the structured demo script")
47
  assert_true("payload.api_checks" in app_js, "Frontend should render structured demo API checks")
48
+ assert_true("demo-api-command" in app_js, "Frontend should render copyable demo commands")
49
  assert_true("/api/evidence-bundle" in app_js, "Frontend should fetch the evidence bundle for copying")
50
  assert_true("function haltPlayback" in app_js, "Reader controls should expose a shared playback halt helper")
51
  assert_true(
 
345
  all(item.get("sample_body") for item in demo_payload["api_checks"] if item["method"] == "POST"),
346
  "Every POST demo check should include an executable sample body",
347
  )
348
+ assert_true(
349
+ all(item["curl"].startswith("curl ") for item in demo_payload["api_checks"]),
350
+ "Every demo API check should include a curl command",
351
+ )
352
+ assert_true(
353
+ "-d '" in reader_check["curl"] and "/api/reader-brain" in reader_check["curl"],
354
+ "Reader-brain curl command should include the sample JSON body",
355
+ )
356
  reader_sample = client.post(reader_check["path"], json=reader_check["sample_body"])
357
  assert_true(reader_sample.status_code == 200, "Reader-brain sample payload should be executable")
358
  reader_sample_payload = reader_sample.json()
static/app.css CHANGED
@@ -465,6 +465,16 @@ dd {
465
  font-size: 0.78rem;
466
  }
467
 
 
 
 
 
 
 
 
 
 
 
468
  .budget-list {
469
  display: grid;
470
  gap: 8px;
 
465
  font-size: 0.78rem;
466
  }
467
 
468
+ .demo-api-command {
469
+ grid-column: 1 / -1;
470
+ display: block;
471
+ padding: 8px;
472
+ border-radius: 6px;
473
+ background: #f7f3ee;
474
+ color: var(--ink);
475
+ white-space: normal;
476
+ }
477
+
478
  .budget-list {
479
  display: grid;
480
  gap: 8px;
static/app.js CHANGED
@@ -252,6 +252,7 @@ async function loadDemoScript() {
252
  <span>${escapeHtml(item.method)}</span>
253
  <code>${escapeHtml(item.path)}</code>
254
  <p>${escapeHtml(item.expect)}${item.sample_body ? " Sample body included." : ""}</p>
 
255
  </li>
256
  `)
257
  .join("");
 
252
  <span>${escapeHtml(item.method)}</span>
253
  <code>${escapeHtml(item.path)}</code>
254
  <p>${escapeHtml(item.expect)}${item.sample_body ? " Sample body included." : ""}</p>
255
+ <code class="demo-api-command">${escapeHtml(item.curl)}</code>
256
  </li>
257
  `)
258
  .join("");