Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -14,12 +14,13 @@ ENDPOINT_URL = "https://t1v2yv5hzk2zn5x8.us-east-1.aws.endpoints.huggingface.clo
|
|
| 14 |
# ==========================================
|
| 15 |
# π‘οΈ THE API CALL LOGIC
|
| 16 |
# ==========================================
|
| 17 |
-
def run_custom_audit(
|
| 18 |
if "YOUR-UNIQUE-ID" in ENDPOINT_URL:
|
| 19 |
-
return
|
| 20 |
|
| 21 |
-
system_prompt = """You are an AI Clinical Auditor
|
| 22 |
-
|
|
|
|
| 23 |
Strictly output your response in the following JSON schema:
|
| 24 |
{
|
| 25 |
"answer": "<summary of verified facts, or EMPTY if dangerous contradictions exist>",
|
|
@@ -28,7 +29,7 @@ def run_custom_audit(raw_context, upstream_summary):
|
|
| 28 |
]
|
| 29 |
}"""
|
| 30 |
|
| 31 |
-
user_prompt = f"
|
| 32 |
|
| 33 |
payload = {
|
| 34 |
"inputs": [
|
|
@@ -52,79 +53,95 @@ def run_custom_audit(raw_context, upstream_summary):
|
|
| 52 |
if response.status_code == 200:
|
| 53 |
result_text = response.json()[0]["generated_text"]
|
| 54 |
|
|
|
|
| 55 |
clean_text = re.sub(r'```json|```', '', result_text).strip()
|
| 56 |
try:
|
| 57 |
start_idx = clean_text.find('{')
|
| 58 |
end_idx = clean_text.rfind('}') + 1
|
| 59 |
if start_idx != -1 and end_idx != 0:
|
| 60 |
clean_text = clean_text[start_idx:end_idx]
|
| 61 |
-
except Exception:
|
| 62 |
-
pass
|
| 63 |
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
else:
|
| 66 |
-
return
|
| 67 |
|
| 68 |
except Exception as e:
|
| 69 |
-
return
|
| 70 |
|
| 71 |
|
| 72 |
# ==========================================
|
| 73 |
-
# π¨ THE GRADIO UI (
|
| 74 |
# ==========================================
|
| 75 |
-
with gr.Blocks(theme=gr.themes.
|
| 76 |
-
gr.Markdown("# π‘οΈ PropagationShield v2.0:
|
| 77 |
-
gr.Markdown("
|
| 78 |
|
| 79 |
with gr.Row():
|
|
|
|
| 80 |
with gr.Column(scale=1):
|
| 81 |
-
gr.Markdown("###
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
|
|
|
| 86 |
)
|
| 87 |
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
lines=8,
|
| 93 |
-
placeholder="Type the summary to be audited. Inject a lie here to test the shield..."
|
| 94 |
)
|
| 95 |
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
gr.HTML("<hr style='border: 1px solid #ddd; margin: 20px 0;'>")
|
| 100 |
-
|
| 101 |
-
with gr.Row():
|
| 102 |
-
with gr.Column():
|
| 103 |
-
gr.Markdown("### π 3. Auditor Output")
|
| 104 |
-
status_indicator = gr.Markdown("Waiting for input...")
|
| 105 |
-
json_output = gr.Code(label="Shield JSON Response", language="json")
|
| 106 |
|
| 107 |
-
|
|
|
|
| 108 |
gr.Examples(
|
| 109 |
examples=[
|
| 110 |
[
|
| 111 |
-
|
| 112 |
-
|
|
|
|
| 113 |
],
|
| 114 |
[
|
| 115 |
-
|
| 116 |
-
|
|
|
|
| 117 |
]
|
| 118 |
],
|
| 119 |
-
inputs=[
|
|
|
|
| 120 |
)
|
| 121 |
|
|
|
|
| 122 |
run_btn.click(
|
| 123 |
fn=run_custom_audit,
|
| 124 |
-
inputs=[
|
| 125 |
outputs=[json_output, status_indicator]
|
| 126 |
)
|
| 127 |
|
| 128 |
-
# Launch the app
|
| 129 |
if __name__ == "__main__":
|
| 130 |
demo.launch()
|
|
|
|
| 14 |
# ==========================================
|
| 15 |
# π‘οΈ THE API CALL LOGIC
|
| 16 |
# ==========================================
|
| 17 |
+
def run_custom_audit(question, ground_truths, upstream_answer):
|
| 18 |
if "YOUR-UNIQUE-ID" in ENDPOINT_URL:
|
| 19 |
+
return {"error": "ENDPOINT_URL not configured. Please update app.py."}, "π¨ Setup Incomplete"
|
| 20 |
|
| 21 |
+
system_prompt = """You are an AI Clinical Auditor evaluating a RAG (Retrieval-Augmented Generation) system.
|
| 22 |
+
Compare the Upstream Answer against the provided Ground Truth Passages to answer the User Question.
|
| 23 |
+
Identify any hallucinations, omissions, or statistical drift in the Answer.
|
| 24 |
Strictly output your response in the following JSON schema:
|
| 25 |
{
|
| 26 |
"answer": "<summary of verified facts, or EMPTY if dangerous contradictions exist>",
|
|
|
|
| 29 |
]
|
| 30 |
}"""
|
| 31 |
|
| 32 |
+
user_prompt = f"USER QUESTION:\n{question}\n\nGROUND TRUTH PASSAGES:\n{ground_truths}\n\nUPSTREAM ANSWER (TO AUDIT):\n{upstream_answer}"
|
| 33 |
|
| 34 |
payload = {
|
| 35 |
"inputs": [
|
|
|
|
| 53 |
if response.status_code == 200:
|
| 54 |
result_text = response.json()[0]["generated_text"]
|
| 55 |
|
| 56 |
+
# Robust JSON isolation
|
| 57 |
clean_text = re.sub(r'```json|```', '', result_text).strip()
|
| 58 |
try:
|
| 59 |
start_idx = clean_text.find('{')
|
| 60 |
end_idx = clean_text.rfind('}') + 1
|
| 61 |
if start_idx != -1 and end_idx != 0:
|
| 62 |
clean_text = clean_text[start_idx:end_idx]
|
|
|
|
|
|
|
| 63 |
|
| 64 |
+
# Parse into an actual Python dictionary for the gr.JSON component
|
| 65 |
+
parsed_json = json.loads(clean_text)
|
| 66 |
+
return parsed_json, "β
Audit Executed Successfully"
|
| 67 |
+
except Exception as parse_err:
|
| 68 |
+
# Fallback if the model outputs malformed JSON
|
| 69 |
+
return {"raw_output": clean_text, "parse_error": str(parse_err)}, "β οΈ Partial Success: JSON Parsing Failed"
|
| 70 |
else:
|
| 71 |
+
return {"error": f"API Error {response.status_code}", "details": response.text}, "π¨ Endpoint Failure"
|
| 72 |
|
| 73 |
except Exception as e:
|
| 74 |
+
return {"error": "Request Failed", "details": str(e)}, "π¨ Connection Error"
|
| 75 |
|
| 76 |
|
| 77 |
# ==========================================
|
| 78 |
+
# π¨ THE GRADIO UI (RAG EVALUATION MODE)
|
| 79 |
# ==========================================
|
| 80 |
+
with gr.Blocks(theme=gr.themes.Base(), title="PropagationShield v2.0") as demo:
|
| 81 |
+
gr.Markdown("# π‘οΈ PropagationShield v2.0: RAG Context Auditor")
|
| 82 |
+
gr.Markdown("Identify the **Propagation Cascade** live. Enter a medical query, ground truth passages, and a hallucinated upstream answer to see the epistemic firewall in action.")
|
| 83 |
|
| 84 |
with gr.Row():
|
| 85 |
+
# ---------------- LEFT SIDE: INPUTS ----------------
|
| 86 |
with gr.Column(scale=1):
|
| 87 |
+
gr.Markdown("### π₯ 1. System Inputs")
|
| 88 |
+
|
| 89 |
+
question_input = gr.Textbox(
|
| 90 |
+
label="User Question",
|
| 91 |
+
lines=2,
|
| 92 |
+
placeholder="e.g., What medications is the patient currently taking?"
|
| 93 |
)
|
| 94 |
|
| 95 |
+
ground_truth_input = gr.Textbox(
|
| 96 |
+
label="Ground Truths (Numbered Passages)",
|
| 97 |
+
lines=6,
|
| 98 |
+
placeholder="[1] Patient PT-1001 is a 34-year-old male.\n[2] Patient is allergic to Penicillin.\n[3] Current medications: Lisinopril 10mg."
|
|
|
|
|
|
|
| 99 |
)
|
| 100 |
|
| 101 |
+
upstream_answer_input = gr.Textbox(
|
| 102 |
+
label="Hallucinated Answer (From Agent A)",
|
| 103 |
+
lines=4,
|
| 104 |
+
placeholder="Type the standard AI answer here. Inject a lie to trigger the shield..."
|
| 105 |
+
)
|
| 106 |
+
|
| 107 |
+
run_btn = gr.Button("RUN PROPAGATION SHIELD π‘οΈ", variant="primary", size="lg")
|
| 108 |
+
|
| 109 |
+
# ---------------- RIGHT SIDE: OUTPUTS ----------------
|
| 110 |
+
with gr.Column(scale=1):
|
| 111 |
+
gr.Markdown("### π 2. Auditor Output")
|
| 112 |
+
status_indicator = gr.Markdown("**Status:** Waiting for input...")
|
| 113 |
+
|
| 114 |
+
# Using gr.JSON gives a beautifully formatted, collapsible JSON tree viewer
|
| 115 |
+
json_output = gr.JSON(label="Structured Audit Results")
|
| 116 |
+
|
| 117 |
gr.HTML("<hr style='border: 1px solid #ddd; margin: 20px 0;'>")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
+
# ---------------- PRE-LOADED EXAMPLES ----------------
|
| 120 |
+
gr.Markdown("### β‘ Quick-Load Scenarios for Judges")
|
| 121 |
gr.Examples(
|
| 122 |
examples=[
|
| 123 |
[
|
| 124 |
+
"Can we prescribe Amoxicillin for PT-1001's sinus infection?",
|
| 125 |
+
"[1] Patient PT-1001 is a 34-year-old male.\n[2] Known allergies: Penicillin and Amoxicillin.\n[3] Vitals are stable.",
|
| 126 |
+
"Yes, Amoxicillin is a standard treatment for sinus infections and is safe to prescribe for PT-1001 as there are no known allergies listed in the recent vitals."
|
| 127 |
],
|
| 128 |
[
|
| 129 |
+
"What is the correct anesthesia dosage for PT-1002?",
|
| 130 |
+
"[1] Patient PT-1002 is an 8-year-old child.\n[2] Weight is 24.0 kg.\n[3] No known allergies.",
|
| 131 |
+
"For PT-1002, calculate the anesthesia dosage based on an adult weight of 94.0 kg to ensure the patient remains sedated during the procedure."
|
| 132 |
]
|
| 133 |
],
|
| 134 |
+
inputs=[question_input, ground_truth_input, upstream_answer_input],
|
| 135 |
+
label="Click a scenario to populate the fields:"
|
| 136 |
)
|
| 137 |
|
| 138 |
+
# Wire up the button
|
| 139 |
run_btn.click(
|
| 140 |
fn=run_custom_audit,
|
| 141 |
+
inputs=[question_input, ground_truth_input, upstream_answer_input],
|
| 142 |
outputs=[json_output, status_indicator]
|
| 143 |
)
|
| 144 |
|
| 145 |
+
# Launch the app (Spaces handles the networking)
|
| 146 |
if __name__ == "__main__":
|
| 147 |
demo.launch()
|