Usmansafdarktk
Adding updated datasets and updated app.py and template code UI
f0a2335
import streamlit as st
import traceback
import random
from src.template_loader import (
get_branches,
get_areas,
get_template_files,
load_template_functions,
get_source_code
)
from src.storage import save_review
# Page Configuration
st.set_page_config(layout="wide", page_title="EngChain Annotator")
# Custom CSS for Styling
# This forces the primary buttons to have a specific look (optional but helps visibility)
st.markdown("""
<style>
div.stButton > button:first-child {
font-weight: bold;
}
/* FIX: Lock sidebar position and disable scrolling */
section[data-testid="stSidebar"] {
position: fixed;
overflow: hidden !important;
}
</style>
""", unsafe_allow_html=True)
# Helper Function: Build the Queue
def build_review_queue(branch):
"""
Scans the entire branch and creates a list of all templates to review.
Returns: List of dicts {'branch', 'area', 'file', 'name', 'func'}
"""
queue = []
areas = get_areas(branch)
progress_bar = st.progress(0)
status_text = st.empty()
total_steps = len(areas)
for i, area in enumerate(areas):
status_text.text(f"Loading area: {area}...")
files = get_template_files(branch, area)
for file in files:
# Load all functions from this file
try:
funcs = load_template_functions(branch, area, file)
for func_name, func_obj in funcs:
queue.append({
"branch": branch,
"area": area,
"file": file,
"name": func_name,
"func": func_obj
})
except Exception as e:
print(f"Error loading {file}: {e}")
progress_bar.progress((i + 1) / total_steps)
status_text.empty()
progress_bar.empty()
return queue
# Session State Initialization
if "app_mode" not in st.session_state:
st.session_state["app_mode"] = "landing" # landing, review, done
if "review_queue" not in st.session_state:
st.session_state["review_queue"] = []
if "current_index" not in st.session_state:
st.session_state["current_index"] = 0
if "annotator_name" not in st.session_state:
st.session_state["annotator_name"] = ""
if "current_branch" not in st.session_state:
st.session_state["current_branch"] = ""
if "review_submitted" not in st.session_state:
st.session_state["review_submitted"] = False
# ==========================================
# VIEW 1: LANDING PAGE
# ==========================================
if st.session_state["app_mode"] == "landing":
st.title("🛡️ EngChain Verification Portal")
st.markdown("""
### Welcome, Expert Annotator!
Thank you for contributing to **EngChain**. Your task is to verify the correctness and quality
of our symbolic engineering templates.
**Instructions:**
1. Select your Engineering Domain.
2. Enter your Name/ID.
3. You will be guided through templates one-by-one.
4. For each template, check the **Code** and the **Generated Trace**.
5. Rate it, Approve/Reject it, and click **Submit**.
""")
st.markdown("")
with st.form("onboarding_form"):
st.subheader("Annotator Details")
col1, col2 = st.columns(2)
with col1:
branches = get_branches()
branch_input = st.selectbox("Select Your Domain", branches)
with col2:
name_input = st.text_input("Enter Your Name / ID")
# Button styling: type="primary" gives it emphasis (color depends on theme, usually red/blue)
submitted = st.form_submit_button("Start Annotation Session", type="primary")
if submitted:
if not name_input.strip():
st.error("Please enter your name to proceed.")
else:
st.session_state["annotator_name"] = name_input
st.session_state["current_branch"] = branch_input
# Build the queue
with st.spinner(f"Gathering templates for {branch_input}..."):
queue = build_review_queue(branch_input)
st.session_state["review_queue"] = queue
st.session_state["current_index"] = 0
st.session_state["app_mode"] = "review"
st.rerun()
# ==========================================
# VIEW 2: REVIEW WORKSPACE
# ==========================================
elif st.session_state["app_mode"] == "review":
queue = st.session_state["review_queue"]
idx = st.session_state["current_index"]
# Check if we are done
if idx >= len(queue):
st.session_state["app_mode"] = "done"
st.rerun()
current_item = queue[idx]
# Sidebar Info
st.sidebar.title("Progress")
st.sidebar.progress((idx) / len(queue))
st.sidebar.write(f"Template: {idx + 1} / {len(queue)}")
st.sidebar.markdown("")
st.sidebar.subheader("Current Context")
# Distinct styling for keys and values
st.sidebar.markdown("**📂 Area:**")
st.sidebar.info(current_item['area'])
st.sidebar.markdown("**📄 File:**")
st.sidebar.info(current_item['file'])
st.sidebar.markdown("**🧩 Function:**")
st.sidebar.info(current_item['name'])
# Main Content
st.title(f"Reviewing: {current_item['name']}")
# Tabs for Inspection
tab1, tab2 = st.tabs(["Source Code", "Generated Trace"])
with tab1:
code_text = get_source_code(current_item['func'])
st.code(code_text, language="python", line_numbers=True)
with tab2:
col_gen, _ = st.columns([1, 4])
# Renamed button for clarity
if col_gen.button("Generate New Random Instance"):
pass # Rerun trigger to get new random numbers
try:
question, solution = current_item['func']()
st.markdown("#### Question")
st.info(question)
st.markdown("#### Solution Trace")
st.success(solution)
except Exception as e:
st.error("Template Execution Failed")
st.code(traceback.format_exc())
st.markdown("")
# Scoring Form
st.subheader("Audit Decision")
# Use a container so we can disable the form after submission
with st.container():
# Check if already submitted for this specific template
is_submitted = st.session_state.get("review_submitted", False)
if not is_submitted:
# FORM STATE
with st.form("audit_form"):
c1, c2, c3 = st.columns(3)
phys = c1.slider("Physical Plausibility", 1, 5, 5)
math = c2.slider("Mathematical Correctness", 1, 5, 5)
ped = c3.slider("Pedagogical Clarity", 1, 5, 5)
decision = st.radio("Certification:", ["Approve", "Reject"], horizontal=True)
feedback = st.text_area("Feedback (Required for Rejection)", placeholder="Explain any errors found...")
# Removed emoji from button
submit_review = st.form_submit_button("Submit Review")
if submit_review:
if decision == "Reject" and not feedback.strip():
st.error("Feedback is required for Rejection.")
else:
# Save to disk
save_review(
st.session_state["annotator_name"],
current_item["branch"],
current_item["area"],
current_item["name"],
[phys, math, ped],
decision,
feedback
)
st.success("Review Saved!")
st.session_state["review_submitted"] = True
st.rerun()
else:
# POST-SUBMISSION STATE (Show Next Button)
st.success("Review recorded for this template.")
# Removed emoji, kept primary type for visibility
if st.button("Proceed to Next Template", type="primary"):
st.session_state["current_index"] += 1
st.session_state["review_submitted"] = False
st.rerun()
# ==========================================
# VIEW 3: COMPLETION PAGE
# ==========================================
elif st.session_state["app_mode"] == "done":
# Removed balloons()
st.title("Session Complete")
st.success(f"""
**Thank you, {st.session_state['annotator_name']}!**
You have successfully reviewed all **{len(st.session_state['review_queue'])}** templates
in the **{st.session_state['current_branch']}** domain.
""")
st.info("Your reviews have been saved securely. You may now close this tab.")
if st.button("Start New Session"):
st.session_state.clear()
st.rerun()