import streamlit as st from core import audit from core.config import BIDDER_NAMES from core.fallback import load_criteria from core.schemas import Criterion from ui.components import confidence_bar, verdict_pill def _crit_map() -> dict[str, Criterion]: data = st.session_state.get("criteria") return {c["id"]: Criterion(**c) for c in data} if data else {c.id: c for c in load_criteria()} def render() -> None: st.markdown( '

' 'Human Review Queue

' '

' 'Verdicts that could not be automatically confirmed require officer sign-off.

', unsafe_allow_html=True, ) vdata: dict = st.session_state.get("verdicts", {}) if not vdata: st.info("No evaluation results yet. Run the evaluation in the Bidder Evaluation tab first.") return cm = _crit_map() pending = [ (bid, i, v) for bid, verdicts in vdata.items() for i, v in enumerate(verdicts) if v.get("verdict") == "needs_review" and v.get("review_status", "pending") == "pending" ] if not pending: st.success("✅ All flagged verdicts have been actioned. Nothing pending.") return st.markdown( f'
' f'⚠️' f'
' f'
' f'{len(pending)} item{"s" if len(pending) != 1 else ""} pending review
' f'
' f'High certainty = model is confident this needs human judgment, ' f'not that the bidder is ineligible.
' f'
', unsafe_allow_html=True, ) for bid, idx, v in pending: crit = cm.get(v["criterion_id"]) crit_title = crit.title if crit else v["criterion_id"] company = BIDDER_NAMES.get(bid, bid) with st.container(border=True): st.markdown( f'
' f'
' f'
' f'{company}
' f'
{v["criterion_id"]}: {crit_title}
' f'
' f'{verdict_pill(v["verdict"])}' f'
', unsafe_allow_html=True, ) col_l, col_r = st.columns([3, 1]) with col_l: if v.get("extracted_value"): st.markdown( f'
' f'Extracted value: ' f'{v["extracted_value"]}
', unsafe_allow_html=True, ) if v.get("reason"): st.markdown( f'
' f'Reason: {v["reason"]}
', unsafe_allow_html=True, ) if v.get("source") and v["source"].get("snippet"): st.markdown( f'
“{v["source"]["snippet"]}”
', unsafe_allow_html=True, ) with col_r: confidence_bar(v.get("combined_confidence", 0.0), "Certainty") st.markdown("
", unsafe_allow_html=True) kp = f"rv_{bid}_{v['criterion_id']}" bc1, bc2, bc3 = st.columns(3) common = dict(bidder_id=bid, criterion_id=v["criterion_id"], original_verdict=v["verdict"], original_extracted_value=v.get("extracted_value", ""), combined_confidence=v.get("combined_confidence", 0.0)) with bc1: if st.button("✅ Approve", key=f"{kp}_approve", use_container_width=True, type="primary"): st.session_state["verdicts"][bid][idx]["review_status"] = "approved" audit.log("human_review_action", actor="officer", action_taken="approved", **common) st.rerun() with bc2: edited = st.text_input("Corrected value", key=f"{kp}_edit_val", placeholder="Optional override…", label_visibility="collapsed") if st.button("✏️ Edit & Approve", key=f"{kp}_edit", use_container_width=True): st.session_state["verdicts"][bid][idx]["review_status"] = "edited" if edited: st.session_state["verdicts"][bid][idx]["extracted_value"] = edited audit.log("human_review_action", actor="officer", action_taken="edited", edited_value=edited, **common) st.rerun() with bc3: if st.button("❌ Reject", key=f"{kp}_reject", use_container_width=True): st.session_state["verdicts"][bid][idx]["review_status"] = "rejected" audit.log("human_review_action", actor="officer", action_taken="rejected", **common) st.rerun()