| import gradio as gr |
| import time |
|
|
| from engine.pipeline import run_system |
| from engine.metrics.metrics import get_metrics |
| from evaluation.eval_suite import run_evaluation |
|
|
|
|
| |
| |
| |
|
|
| def status_badge(status): |
| return { |
| "ALLOWED": "π’ **ALLOWED**", |
| "ABSTAINED": "π‘ **ABSTAINED**", |
| "BLOCKED": "π΄ **BLOCKED**" |
| }.get(status, status) |
|
|
|
|
| def compute_risk(status): |
| if status == "BLOCKED": |
| return 0.85, "HIGH" |
| if status == "ABSTAINED": |
| return 0.60, "MEDIUM" |
| return 0.20, "LOW" |
|
|
|
|
| def risk_bar(score): |
| filled = int(score * 10) |
| bar = "β" * filled + "β" * (10 - filled) |
|
|
| if score < 0.3: |
| return f"π’ {bar} {score:.2f} (LOW)" |
| elif score < 0.7: |
| return f"π‘ {bar} {score:.2f} (MEDIUM)" |
| else: |
| return f"π΄ {bar} {score:.2f} (HIGH)" |
|
|
|
|
| def format_attack_vectors(attacks): |
| return "\n".join( |
| f"{'β' if v else 'β
'} {k}: {'DETECTED' if v else 'Clear'}" |
| for k, v in attacks.items() |
| ) |
|
|
|
|
| def format_timeline(timeline): |
| if not timeline: |
| return "No timeline available" |
| return "\n".join( |
| f"{i*5:02d}ms : {step}" |
| for i, step in enumerate(timeline) |
| ) |
|
|
|
|
| |
| |
| |
|
|
| def ui(query): |
| r = run_system(query) |
|
|
| status = r.get("status", "UNKNOWN") |
| score, _ = compute_risk(status) |
|
|
| return ( |
| status_badge(status), |
| r.get("answer", ""), |
| r.get("category", ""), |
| risk_bar(score), |
| format_attack_vectors(r.get("attacks", {})), |
| ( |
| f"Final Decision: {status}\n" |
| f"PHI Detected: {r.get('phi') or 'None'}\n\n" |
| f"βΉοΈ Rule-based pre-generation enforcement" |
| ), |
| f"{r.get('uncertainty', 0.0):.2f}", |
| format_timeline(r.get("timeline", [])), |
| r.get("explain", {}) |
| ) |
|
|
|
|
| def metrics_panel(): |
| return { |
| "metrics": get_metrics(), |
| "last_updated": time.strftime("%H:%M:%S") |
| } |
|
|
|
|
| def eval_panel(): |
| result = run_evaluation() |
| s = result["summary"] |
|
|
| summary_text = ( |
| f"Precision: {s['precision']:.2f}\n" |
| f"Recall: {s['recall']:.2f}\n\n" |
| f"TP: {s['TP']} (Correct blocks)\n" |
| f"TN: {s['TN']} (Correct allows)\n" |
| f"FP: {s['FP']} (Over-blocks)\n" |
| f"FN: {s['FN']} (Missed risks)" |
| ) |
|
|
| return summary_text, result["details"] |
|
|
|
|
| |
| |
| |
|
|
| with gr.Blocks(title="AI Safety & Governance Engine") as demo: |
|
|
| gr.Markdown("## π‘οΈ AI Safety & Governance Engine") |
|
|
| gr.Markdown( |
| """ |
| **Inference-time governance layer for LLM safety** |
| |
| β’ Prompt injection & jailbreak detection |
| β’ Medical advice enforcement |
| β’ PHI redaction |
| β’ Policy-based **BLOCK / ABSTAIN / ALLOW** |
| β’ Explainability + uncertainty modeling |
| β’ Governance evaluation (FP / FN analysis) |
| """ |
| ) |
|
|
| inp = gr.Textbox( |
| label="User Query", |
| placeholder="Enter a query to evaluate", |
| lines=2 |
| ) |
|
|
| status_out = gr.Markdown(label="Status") |
| answer_out = gr.Textbox(label="Answer", lines=4) |
| category_out = gr.Textbox(label="Decision Category") |
| risk_out = gr.Textbox(label="Risk Assessment") |
| attacks_out = gr.Textbox(label="Attack Vector Analysis", lines=5) |
| decision_out = gr.Textbox(label="Decision Summary", lines=4) |
| uncertainty_out = gr.Textbox(label="Uncertainty Score") |
| timeline_out = gr.Textbox(label="Governance Timeline", lines=6) |
| explain_out = gr.JSON(label="Explainability Trace") |
|
|
| gr.Button("Run Safety Engine").click( |
| fn=ui, |
| inputs=inp, |
| outputs=[ |
| status_out, |
| answer_out, |
| category_out, |
| risk_out, |
| attacks_out, |
| decision_out, |
| uncertainty_out, |
| timeline_out, |
| explain_out |
| ] |
| ) |
|
|
| with gr.Accordion("π§© System Architecture", open=False): |
| gr.Markdown( |
| """ |
| User |
| β PHI Redaction |
| β Harm & Attack Detection |
| β Medical Intent |
| β Policy Engine |
| β **BLOCK / ABSTAIN / ALLOW** |
| β Generation |
| β Verification |
| β Explainability + Metrics |
| """ |
| ) |
|
|
| gr.Markdown("### π Inference-Time Metrics") |
|
|
| metrics_output = gr.JSON(label="Metrics") |
|
|
| gr.Button("Refresh Metrics").click( |
| fn=metrics_panel, |
| inputs=None, |
| outputs=metrics_output |
| ) |
|
|
| with gr.Accordion("π§ͺ Governance Quality Dashboard", open=False): |
|
|
| gr.Markdown( |
| """ |
| Evaluates **governance correctness**, not generation quality. |
| |
| β’ TP β Correctly blocked |
| β’ FP β Over-blocked |
| β’ FN β Missed risks |
| β’ TN β Correctly allowed |
| """ |
| ) |
|
|
| eval_summary = gr.Textbox(label="Evaluation Summary", lines=8) |
| eval_details = gr.JSON(label="Per-Prompt Results") |
|
|
| gr.Button("Run Evaluation Suite").click( |
| fn=eval_panel, |
| inputs=None, |
| outputs=[eval_summary, eval_details] |
| ) |
|
|
| demo.launch() |
|
|