Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -341,6 +341,20 @@ def api_session_finish(sid: str):
|
|
| 341 |
def api_session_get(sid: str):
|
| 342 |
return session_load(sid)
|
| 343 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
# ========= Verify-All helpers (session + per-turn text) =========
|
| 345 |
def _list_sessions():
|
| 346 |
if not SESSIONS_DIR.exists():
|
|
@@ -389,13 +403,36 @@ def make_text_rows_for_session(sid: str):
|
|
| 389 |
rows.append([rid, "", "", False, (True if not AUDIT_PEPPER else False)])
|
| 390 |
return rows
|
| 391 |
|
| 392 |
-
def
|
| 393 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
out = []
|
| 395 |
-
for rec in
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
|
|
|
| 399 |
try:
|
| 400 |
rj = json.loads((RECEIPTS_DIR / f"{rid}.json").read_text())
|
| 401 |
except Exception:
|
|
@@ -415,7 +452,7 @@ def verify_text_rows(sid: str, rows: list, pepper: str):
|
|
| 415 |
if pepper:
|
| 416 |
hmac_ok = (h256(pepper, prompt) == rj.get("prompt_hmac","")) and (h256(pepper, answer) == rj.get("response_hmac",""))
|
| 417 |
else:
|
| 418 |
-
hmac_ok = True # if no pepper
|
| 419 |
out.append([rid, prompt, answer, bool(sha_ok), bool(hmac_ok)])
|
| 420 |
return out
|
| 421 |
|
|
@@ -588,7 +625,7 @@ with api_ui:
|
|
| 588 |
proof_link2 = gr.Markdown()
|
| 589 |
|
| 590 |
def ui_load_and_recompute(sid_text: str):
|
| 591 |
-
sid = sid_text.strip() or latest_session_id()
|
| 592 |
if not sid:
|
| 593 |
return "", "No sessions found", [], ""
|
| 594 |
comp, msg, rows, link = recompute_session_root_and_table(sid)
|
|
@@ -600,22 +637,24 @@ with api_ui:
|
|
| 600 |
pepper_tb = gr.Textbox(label="AUDIT_PEPPER (optional; if set in Space secrets, paste the same value)")
|
| 601 |
prep_btn = gr.Button("Prepare rows for this session")
|
| 602 |
rows_df = gr.Dataframe(headers=["receipt_id","prompt","answer","sha_ok","hmac_ok"],
|
| 603 |
-
row_count=(0, "dynamic"),
|
|
|
|
| 604 |
|
| 605 |
verify_btn = gr.Button("Verify pasted texts for all receipts")
|
| 606 |
rows_out = gr.Dataframe(headers=["receipt_id","prompt","answer","sha_ok","hmac_ok"],
|
| 607 |
-
row_count=(0, "dynamic"),
|
|
|
|
| 608 |
|
| 609 |
def ui_prep_rows(sid_text: str):
|
| 610 |
-
sid = sid_text.strip() or latest_session_id()
|
| 611 |
if not sid:
|
| 612 |
return []
|
| 613 |
return make_text_rows_for_session(sid)
|
| 614 |
|
| 615 |
def ui_verify_rows(sid_text: str, rows, pepper):
|
| 616 |
-
sid = sid_text.strip() or latest_session_id()
|
| 617 |
if not sid:
|
| 618 |
-
return rows
|
| 619 |
return verify_text_rows(sid, rows, pepper or "")
|
| 620 |
|
| 621 |
prep_btn.click(ui_prep_rows, inputs=sid_in, outputs=rows_df)
|
|
|
|
| 341 |
def api_session_get(sid: str):
|
| 342 |
return session_load(sid)
|
| 343 |
|
| 344 |
+
# ========= Dashboard helper =========
|
| 345 |
+
def _load_events_df():
|
| 346 |
+
if not os.path.exists(EVENTS_PATH):
|
| 347 |
+
return pd.DataFrame({"info": ["No alerts yet"]})
|
| 348 |
+
try:
|
| 349 |
+
data = json.loads(open(EVENTS_PATH).read())
|
| 350 |
+
for d in data:
|
| 351 |
+
d.setdefault("prompt", ""); d.setdefault("snippet", "")
|
| 352 |
+
df = pd.DataFrame(data)
|
| 353 |
+
cols = [c for c in ["ts","type","hits","prompt","snippet"] if c in df.columns]
|
| 354 |
+
return df[cols].iloc[::-1]
|
| 355 |
+
except Exception:
|
| 356 |
+
return pd.DataFrame({"info": ["Could not parse events"]})
|
| 357 |
+
|
| 358 |
# ========= Verify-All helpers (session + per-turn text) =========
|
| 359 |
def _list_sessions():
|
| 360 |
if not SESSIONS_DIR.exists():
|
|
|
|
| 403 |
rows.append([rid, "", "", False, (True if not AUDIT_PEPPER else False)])
|
| 404 |
return rows
|
| 405 |
|
| 406 |
+
def _rows_to_list(rows):
|
| 407 |
+
"""Normalize any Gradio/pandas table input to list-of-lists."""
|
| 408 |
+
# pandas DataFrame
|
| 409 |
+
if isinstance(rows, pd.DataFrame):
|
| 410 |
+
return rows.values.tolist()
|
| 411 |
+
# dict of column -> list
|
| 412 |
+
if isinstance(rows, dict):
|
| 413 |
+
order = ["receipt_id","prompt","answer","sha_ok","hmac_ok"]
|
| 414 |
+
cols = [rows.get(c, []) for c in order]
|
| 415 |
+
try:
|
| 416 |
+
return [list(t) for t in zip(*cols)]
|
| 417 |
+
except Exception:
|
| 418 |
+
return []
|
| 419 |
+
# already list/tuple
|
| 420 |
+
if rows is None:
|
| 421 |
+
return []
|
| 422 |
+
if isinstance(rows, (list, tuple)):
|
| 423 |
+
return [list(r) if not isinstance(r, list) else r for r in rows]
|
| 424 |
+
return []
|
| 425 |
+
|
| 426 |
+
def verify_text_rows(sid: str, rows, pepper: str):
|
| 427 |
+
"""Rows: any table input -> list-of-lists; returns filled [receipt_id, prompt, answer, sha_ok, hmac_ok]."""
|
| 428 |
+
rows_ll = _rows_to_list(rows)
|
| 429 |
+
|
| 430 |
out = []
|
| 431 |
+
for rec in rows_ll:
|
| 432 |
+
# Ensure row length
|
| 433 |
+
while len(rec) < 5:
|
| 434 |
+
rec.append(False if len(rec) >= 3 else "")
|
| 435 |
+
rid, prompt, answer, _, _ = rec[:5]
|
| 436 |
try:
|
| 437 |
rj = json.loads((RECEIPTS_DIR / f"{rid}.json").read_text())
|
| 438 |
except Exception:
|
|
|
|
| 452 |
if pepper:
|
| 453 |
hmac_ok = (h256(pepper, prompt) == rj.get("prompt_hmac","")) and (h256(pepper, answer) == rj.get("response_hmac",""))
|
| 454 |
else:
|
| 455 |
+
hmac_ok = True # N/A if no pepper supplied
|
| 456 |
out.append([rid, prompt, answer, bool(sha_ok), bool(hmac_ok)])
|
| 457 |
return out
|
| 458 |
|
|
|
|
| 625 |
proof_link2 = gr.Markdown()
|
| 626 |
|
| 627 |
def ui_load_and_recompute(sid_text: str):
|
| 628 |
+
sid = (sid_text or "").strip() or latest_session_id()
|
| 629 |
if not sid:
|
| 630 |
return "", "No sessions found", [], ""
|
| 631 |
comp, msg, rows, link = recompute_session_root_and_table(sid)
|
|
|
|
| 637 |
pepper_tb = gr.Textbox(label="AUDIT_PEPPER (optional; if set in Space secrets, paste the same value)")
|
| 638 |
prep_btn = gr.Button("Prepare rows for this session")
|
| 639 |
rows_df = gr.Dataframe(headers=["receipt_id","prompt","answer","sha_ok","hmac_ok"],
|
| 640 |
+
row_count=(0, "dynamic"),
|
| 641 |
+
datatype=["str","str","str","bool","bool"])
|
| 642 |
|
| 643 |
verify_btn = gr.Button("Verify pasted texts for all receipts")
|
| 644 |
rows_out = gr.Dataframe(headers=["receipt_id","prompt","answer","sha_ok","hmac_ok"],
|
| 645 |
+
row_count=(0, "dynamic"),
|
| 646 |
+
datatype=["str","str","str","bool","bool"])
|
| 647 |
|
| 648 |
def ui_prep_rows(sid_text: str):
|
| 649 |
+
sid = (sid_text or "").strip() or latest_session_id()
|
| 650 |
if not sid:
|
| 651 |
return []
|
| 652 |
return make_text_rows_for_session(sid)
|
| 653 |
|
| 654 |
def ui_verify_rows(sid_text: str, rows, pepper):
|
| 655 |
+
sid = (sid_text or "").strip() or latest_session_id()
|
| 656 |
if not sid:
|
| 657 |
+
return _rows_to_list(rows)
|
| 658 |
return verify_text_rows(sid, rows, pepper or "")
|
| 659 |
|
| 660 |
prep_btn.click(ui_prep_rows, inputs=sid_in, outputs=rows_df)
|