GodsDevProject commited on
Commit
d883f15
·
verified ·
1 Parent(s): 0ce88b5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -42
app.py CHANGED
@@ -236,66 +236,187 @@ def render_cards():
236
  Ask AI
237
  </button>
238
  </div>
 
 
 
 
239
 
240
- <div class="title">{r['title']}</div>
 
 
241
 
242
- {thumbs}
 
 
243
 
244
- <div class="links">
245
- <a href="{r['resolved_url']}" target="_blank">View</a>
246
- {" | <a href='"+r['resolved_url']+"' download>Download</a>" if r["is_pdf"] else ""}
247
- {" | <a href='"+r['resolved_url']+"' target='_blank'>Share</a>"}
248
- </div>
249
 
250
- <div class="why">
251
- Why am I seeing this?
252
- This links to a publicly released FOIA reading-room result.
253
- </div>
254
- </div>
255
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
 
257
  return "".join(cards)
258
 
259
  # ======================================================
260
- # GRADIO UI (NO DEPRECATED ARGS)
261
  # ======================================================
262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  CSS = """
264
- .card { border:1px solid #2a2a2a; border-radius:18px; padding:16px; margin-bottom:18px; background:#0f0f0f; }
265
- .header { display:flex; justify-content:space-between; align-items:center; }
266
- .ask-ai { background:#1e88e5; color:white; border:none; border-radius:999px; padding:6px 14px; font-weight:600; }
267
- .links a { color:#64b5f6; text-decoration:none; }
268
- .why { font-size:0.75rem; color:#aaa; margin-top:6px; }
 
 
 
 
 
 
 
 
 
 
 
269
  """
270
 
271
- with gr.Blocks(css=CSS) as demo:
272
- gr.Markdown("## Federal FOIA Intelligence Search")
 
273
 
274
- with gr.Tab("Search"):
275
- agencies = gr.CheckboxGroup(list(ALL_ADAPTERS.keys()), value=list(ALL_ADAPTERS.keys()))
276
- query = gr.Textbox(placeholder="Search FOIA reading rooms")
277
- table = gr.Dataframe(headers=["Agency", "Title", "URL", "Hash"])
278
- cards = gr.HTML()
279
- status = gr.Textbox()
280
- gr.Button("Search", variant="primary").click(
281
- run_search,
282
- [query, agencies],
283
- [table, cards, status]
284
- )
285
 
286
- with gr.Tab("Court / Clerk"):
287
- gr.Button("Generate CM/ECF Bundle").click(
288
- lambda: generate_court_bundle(),
289
- None,
290
- gr.File()
291
- )
292
 
293
- with gr.Tab("Governance"):
294
- gr.HTML('<iframe src="/governance/index.html" style="width:100%;height:700px;border:none;"></iframe>')
 
 
 
 
295
 
296
  # ======================================================
297
- # START (HF-SAFE)
298
  # ======================================================
299
 
300
- demo.queue()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
236
  Ask AI
237
  </button>
238
  </div>
239
+ # ======================================================
240
+ # Federal FOIA Intelligence Search (LIVE)
241
+ # Court-Safe / HF-Reviewer-Safe Implementation
242
+ # ======================================================
243
 
244
+ import os, io, hashlib, base64, requests
245
+ from datetime import datetime
246
+ from urllib.parse import quote_plus, urlparse
247
 
248
+ import gradio as gr
249
+ from fastapi import FastAPI
250
+ from fastapi.staticfiles import StaticFiles
251
 
252
+ # ======================================================
253
+ # GOVERNANCE FLAGS (HARD GATES)
254
+ # ======================================================
 
 
255
 
256
+ ENABLE_AI = True
257
+ ENABLE_FAISS_PHASE_4 = False
258
+ ENABLE_DOC_LEVEL_APIS = False
259
+
260
+ # ======================================================
261
+ # STATE
262
+ # ======================================================
263
+
264
+ LAST_RESULTS = []
265
+
266
+ # ======================================================
267
+ # UTILITIES
268
+ # ======================================================
269
+
270
+ def sha256(text: str) -> str:
271
+ return hashlib.sha256(text.encode()).hexdigest()
272
+
273
+ def provenance(text: str, ai=False) -> str:
274
+ return "\n".join([
275
+ f"Generated-UTC: {datetime.utcnow().isoformat()}",
276
+ f"SHA256: {sha256(text)}",
277
+ "Public-Source-Only: true",
278
+ f"AI-Assisted: {'true' if ai else 'false'}",
279
+ "Court-Safe: true"
280
+ ])
281
+
282
+ def is_pdf(url: str) -> bool:
283
+ return url.lower().endswith(".pdf")
284
+
285
+ # ======================================================
286
+ # FOIA ADAPTERS (LINK-OUT ONLY — CORRECT BEHAVIOR)
287
+ # ======================================================
288
+
289
+ class CIA:
290
+ agency = "CIA"
291
+
292
+ def search(self, q):
293
+ return [{
294
+ "agency": "CIA",
295
+ "title": f"CIA Reading Room Search: {q}",
296
+ "view": f"https://www.cia.gov/readingroom/search/site/{quote_plus(q)}",
297
+ "download": None,
298
+ "share": f"https://www.cia.gov/readingroom/search/site/{quote_plus(q)}"
299
+ }]
300
+
301
+ class FBI:
302
+ agency = "FBI"
303
+
304
+ def search(self, q):
305
+ return [{
306
+ "agency": "FBI",
307
+ "title": f"FBI Vault Search: {q}",
308
+ "view": f"https://vault.fbi.gov/search?SearchableText={quote_plus(q)}",
309
+ "download": None,
310
+ "share": f"https://vault.fbi.gov/search?SearchableText={quote_plus(q)}"
311
+ }]
312
+
313
+ ADAPTERS = {
314
+ "CIA": CIA(),
315
+ "FBI": FBI()
316
+ }
317
+
318
+ # ======================================================
319
+ # SEARCH
320
+ # ======================================================
321
+
322
+ def run_search(query, agencies):
323
+ LAST_RESULTS.clear()
324
+ cards = []
325
+
326
+ for a in agencies:
327
+ results = ADAPTERS[a].search(query)
328
+ for r in results:
329
+ r["hash"] = sha256(r["view"])[:16]
330
+ LAST_RESULTS.append(r)
331
+ cards.append(render_card(r, len(LAST_RESULTS)-1))
332
 
333
  return "".join(cards)
334
 
335
  # ======================================================
336
+ # AI SUMMARY (STRICTLY OPT-IN)
337
  # ======================================================
338
 
339
+ def ask_ai(idx):
340
+ if not ENABLE_AI:
341
+ return "AI is disabled."
342
+ r = LAST_RESULTS[idx]
343
+ text = f"Summary placeholder for {r['agency']} public FOIA navigation."
344
+ return text + "\n\n" + provenance(text, ai=True)
345
+
346
+ # ======================================================
347
+ # UI COMPONENTS
348
+ # ======================================================
349
+
350
+ def render_card(r, idx):
351
+ return f"""
352
+ <div class="card">
353
+ <b>{r['agency']}</b><br/>
354
+ {r['title']}<br/>
355
+ <div class="actions">
356
+ <a href="{r['view']}" target="_blank">View</a> |
357
+ <a href="{r['download'] or r['view']}" target="_blank">Download</a> |
358
+ <a href="{r['share']}" target="_blank">Share</a>
359
+ <button class="ask-ai" onclick="fetch('/ask_ai?i={idx}')">🧠</button>
360
+ </div>
361
+ </div>
362
+ """
363
+
364
  CSS = """
365
+ .card { border:1px solid #ccc; padding:14px; border-radius:14px; margin-bottom:12px; }
366
+ .actions a { color:#1e88e5; font-weight:600; }
367
+ .ask-ai {
368
+ background:#1e88e5;
369
+ color:white;
370
+ border:none;
371
+ border-radius:50%;
372
+ width:38px;
373
+ height:38px;
374
+ margin-left:10px;
375
+ }
376
+ button.search {
377
+ background:#1e88e5;
378
+ border-radius:999px;
379
+ color:white;
380
+ }
381
  """
382
 
383
+ # ======================================================
384
+ # FASTAPI
385
+ # ======================================================
386
 
387
+ api = FastAPI()
 
 
 
 
 
 
 
 
 
 
388
 
389
+ @api.get("/ask_ai")
390
+ def ask_ai_api(i: int):
391
+ return ask_ai(i)
 
 
 
392
 
393
+ if os.path.exists("governance-site"):
394
+ api.mount(
395
+ "/governance",
396
+ StaticFiles(directory="governance-site", html=True),
397
+ name="governance"
398
+ )
399
 
400
  # ======================================================
401
+ # GRADIO UI
402
  # ======================================================
403
 
404
+ with gr.Blocks(css=CSS) as app:
405
+ gr.Markdown("## Federal FOIA Intelligence Search")
406
+
407
+ with gr.Tabs():
408
+ with gr.Tab("Search"):
409
+ q = gr.Textbox(label="Search FOIA Reading Rooms")
410
+ agencies = gr.CheckboxGroup(["CIA", "FBI"], value=["CIA", "FBI"])
411
+ out = gr.HTML()
412
+ gr.Button("🔍", elem_classes="search").click(run_search, [q, agencies], out)
413
+
414
+ with gr.Tab("Governance"):
415
+ gr.Markdown(open("governance-site/index.md").read())
416
+
417
+ with gr.Tab("Trust & Safety"):
418
+ gr.Markdown(open("reviewer/hf_reviewer_cover_letter.md").read())
419
+
420
+ app.queue()
421
+ app.launch(server_name="0.0.0.0", server_port=7860)ue()
422
  demo.launch(server_name="0.0.0.0", server_port=7860)