🔬 CircuitSense — AI Quality Inspection
GPT-4o Vision · 5-Node LangGraph · Vision → Specialist → Policy Reasoning
""", unsafe_allow_html=True)
# ── SIDEBAR ───────────────────────────────────────────────────────────────────
with st.sidebar:
st.markdown("## ⚙️ Configuration")
with st.expander("🔑 API Keys", expanded=not st.session_state.openai_configured):
okey = st.text_input("OpenAI API Key", type="password",
value=st.session_state.get("openai_api_key", ""),
placeholder="sk-...")
obase = st.text_input("API Base URL (optional)",
value=st.session_state.get("openai_api_base", ""),
placeholder="Azure/proxy endpoint")
lskey = st.text_input("LangSmith Key (optional)", type="password",
placeholder="ls__...")
if okey:
st.session_state.openai_api_key = okey
st.session_state.openai_configured = True
if obase:
st.session_state.openai_api_base = obase
if lskey:
os.environ.update({"LANGCHAIN_TRACING_V2": "true",
"LANGCHAIN_API_KEY": lskey,
"LANGCHAIN_PROJECT": "MLS1-CircuitSense-Inspection"})
st.divider()
st.markdown("## 📋 Inspection Pipeline")
st.markdown("""
```
Image Input
↓
Vision Agent (gpt-4o)
↓
Supervisor Agent (routing)
↓
Surface / Structural /
PassThrough Agent
↓
Policy Reasoning Agent
↓
Response Node
```
""")
st.divider()
if st.button("🗑️ Clear History", use_container_width=True):
st.session_state.inspection_history = []
st.rerun()
# ── MAIN AREA ─────────────────────────────────────────────────────────────────
tab_inspect, tab_history, tab_log = st.tabs([
"🔬 Run Inspection", "📊 Session History", "📋 Audit Trail"
])
with tab_inspect:
col_input, col_result = st.columns([1, 1])
with col_input:
st.markdown("### 📥 Product Image Input")
input_method = st.radio("Image source",
["Upload image", "Select from dataset"],
horizontal=True)
image_pil = None
category = "unknown"
defect_type_gt = "unknown"
policy_id = f"MANUAL-{datetime.datetime.now().strftime('%H%M%S')}"
if input_method == "Upload image":
uploaded = st.file_uploader("Upload product image (JPEG/PNG)",
type=["jpg", "jpeg", "png"])
if uploaded:
image_pil = Image.open(uploaded)
st.image(image_pil, caption="Uploaded image", width="stretch")
category = st.selectbox("Product category",
["pcb1", "capsules", "cashew", "other"])
defect_type_gt = st.text_input("Known defect label (optional)",
placeholder="e.g. scratch")
else:
if df_enriched.empty:
st.warning("df_enriched.csv not found. Run the notebook first.")
else:
cat_filter = st.selectbox("Filter by category",
["all"] + list(df_enriched['category'].unique()))
df_filtered = df_enriched if cat_filter == "all" \
else df_enriched[df_enriched['category'] == cat_filter]
options = [f"{r['policy_id']} — {r['category']} / {r['defect_type']}"
for _, r in df_filtered.iterrows()]
sel = st.selectbox("Select inspection record", options)
if sel:
pid = sel.split(" — ")[0]
row = df_enriched[df_enriched['policy_id'] == pid].iloc[0]
policy_id = row['policy_id']
category = row['category']
defect_type_gt = row['defect_type']
try:
image_pil = Image.open(row['image_path'])
st.image(image_pil,
caption=f"{category} / {defect_type_gt}",
width="stretch")
st.caption(f"**Description:** {row.get('defect_description','N/A')}")
except Exception:
st.error("Image file not found. Run the notebook to download VisA.")
run_btn = st.button("🚀 Run Inspection", type="primary",
use_container_width=True, disabled=(image_pil is None))
with col_result:
st.markdown("### 📊 Inspection Result")
if run_btn and image_pil is not None:
if not st.session_state.get("openai_api_key") \
and "OPENAI_API_KEY" not in os.environ:
st.error("⚠️ Please enter your OpenAI API key in the sidebar.")
else:
with st.spinner("Running 5-node inspection pipeline..."):
try:
image_b64 = resize_and_encode(image_pil)
initial = GlobalState(
image_b64=image_b64, category=category,
defect_type_gt=defect_type_gt, policy_id=policy_id,
decision_log=[]
)
result = app.invoke(initial)
st.session_state.inspection_history.append(result)
st.success("✅ Inspection complete")
disp = result.get("disposition", "N/A")
badge_class = {"PASS": "badge-pass",
"REWORK": "badge-rework",
"SCRAP": "badge-scrap",
"UNCERTAIN": "badge-uncertain"}.get(disp, "")
st.markdown(f'
CircuitSense AI Inspection — MLS-1 v4 | GPT-4o Vision · LangGraph 5-Node Pipeline · VisA Dataset (CC BY 4.0)
⚠️ Demonstration system. Not for production use without human oversight.
""", unsafe_allow_html=True)