pilayar commited on
Commit
4b3779d
Β·
verified Β·
1 Parent(s): 84cda9f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +450 -0
app.py ADDED
@@ -0,0 +1,450 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import time
3
+ import pandas as pd
4
+ import plotly.express as px
5
+ import plotly.graph_objects as go
6
+ import streamlit as st
7
+
8
+ # ==========================================
9
+ # PAGE CONFIGURATION
10
+ # ==========================================
11
+ st.set_page_config(
12
+ page_title="Aetna SmartClaim AI Platform | CVS Health",
13
+ page_icon="πŸ₯",
14
+ layout="wide",
15
+ initial_sidebar_state="expanded",
16
+ )
17
+
18
+ # Custom CSS for Enterprise Styling
19
+ st.markdown(
20
+ """
21
+ <style>
22
+ .main-header { font-size: 26px; font-weight: 700; color: #CC0000; margin-bottom: 0px; }
23
+ .sub-header { font-size: 14px; color: #555555; margin-bottom: 20px; }
24
+ .metric-card { background-color: #F8F9FA; border-left: 4px solid #CC0000; padding: 12px; border-radius: 4px; }
25
+ .stButton>button { width: 100%; border-radius: 4px; height: 42px; font-weight: 600; }
26
+ .badge-pass { background-color: #D4EDDA; color: #155724; padding: 4px 8px; border-radius: 4px; font-weight: 600; }
27
+ .badge-review { background-color: #FFF3CD; color: #856404; padding: 4px 8px; border-radius: 4px; font-weight: 600; }
28
+ .badge-deny { background-color: #F8D7DA; color: #721C24; padding: 4px 8px; border-radius: 4px; font-weight: 600; }
29
+ </style>
30
+ """,
31
+ unsafe_allow_html=True,
32
+ )
33
+
34
+ # ==========================================
35
+ # KNOWLEDGE BASE: AETNA CPBs & SAMPLE CLAIMS
36
+ # ==========================================
37
+ AETNA_CPBS = {
38
+ "CPB 0236 (Spine MRI)": {
39
+ "title": "Magnetic Resonance Imaging (MRI) of the Spine",
40
+ "code": "CPT 72148",
41
+ "criteria": [
42
+ "Clinical evidence of spinal stenosis or cauda equina compression",
43
+ "Progressively severe symptoms despite conservative management",
44
+ "Persistent back/neck pain with radiculopathy with failed 6+ weeks of conservative therapy (NSAIDs, physical therapy)",
45
+ "Suspected spinal infection, fracture, or malignancy",
46
+ ],
47
+ },
48
+ "CPB 0171 (Knee MRI)": {
49
+ "title": "Magnetic Resonance Imaging (MRI) of the Extremities",
50
+ "code": "CPT 73721",
51
+ "criteria": [
52
+ "Persistent knee swelling/instability not associated with injury, failed 3+ weeks conservative therapy",
53
+ "True joint locking indicative of torn meniscus or loose body",
54
+ "Suspected osteomyelitis or bone infection",
55
+ "Multi-view X-rays performed to rule out fracture prior to advanced imaging",
56
+ ],
57
+ },
58
+ "CPB 0157 (Bariatric Surgery)": {
59
+ "title": "Obesity Surgery",
60
+ "code": "CPT 43644",
61
+ "criteria": [
62
+ "Body Mass Index (BMI) >= 40 or BMI >= 35 with high-risk comorbidities (Type 2 Diabetes, Severe Sleep Apnea)",
63
+ "Documented participation in medically supervised weight loss program for >= 6 months",
64
+ "Psychosocial behavioral health evaluation and clearance completed",
65
+ "Absence of active substance use disorder or uncontrolled psychiatric illness",
66
+ ],
67
+ },
68
+ }
69
+
70
+ MOCK_CLAIMS = {
71
+ "CLM-90821 (Lumbar MRI - Compliant)": {
72
+ "claim_id": "CLM-90821",
73
+ "patient": "Jane Doe (DOB: 11/04/1978)",
74
+ "cpb": "CPB 0236 (Spine MRI)",
75
+ "cpt": "72148 - MRI Lumbar Spine w/o Contrast",
76
+ "diagnosis": "M54.16 - Radiculopathy, lumbar region",
77
+ "clinical_notes": "46yo female with severe low back pain radiating to L5 distribution. Completed 8 weeks of physical therapy and trials of Meloxicam without relief. Straight leg raise test positive on left. X-ray showed mild disc space narrowing at L4-L5, no acute fracture.",
78
+ "expected_status": "APPROVED",
79
+ "confidence": 0.97,
80
+ "citation": "Meets CPB 0236: Persistent back pain with radiculopathy + documented >6 weeks conservative therapy (8 wks PT + NSAIDs) + prior X-ray.",
81
+ },
82
+ "CLM-44319 (Spine MRI - Insufficient PT)": {
83
+ "claim_id": "CLM-44319",
84
+ "patient": "Robert Smith (DOB: 03/15/1985)",
85
+ "cpb": "CPB 0236 (Spine MRI)",
86
+ "cpt": "72148 - MRI Lumbar Spine w/o Contrast",
87
+ "diagnosis": "M54.50 - Low back pain, unspecified",
88
+ "clinical_notes": "41yo male presenting with acute low back pain following lifting heavy box 10 days ago. No numbness, tingling, or bowel/bladder dysfunction. Patient requests MRI today. Took OTC Ibuprofen twice with minor improvement.",
89
+ "expected_status": "MANUAL_REVIEW",
90
+ "confidence": 0.72,
91
+ "citation": "Fails CPB 0236: Only 10 days of symptoms. Required 6 weeks of conservative therapy (PT/NSAIDs) not completed. Red flag symptoms absent.",
92
+ },
93
+ "CLM-11920 (Bariatric Surgery - Missing Psych)": {
94
+ "claim_id": "CLM-11920",
95
+ "patient": "Maria Garcia (DOB: 08/22/1981)",
96
+ "cpb": "CPB 0157 (Bariatric Surgery)",
97
+ "cpt": "43644 - Laparoscopic Roux-en-Y Gastric Bypass",
98
+ "diagnosis": "E66.01 - Morbid severe obesity",
99
+ "clinical_notes": "44yo female, BMI 42.1 with poorly controlled Type 2 Diabetes (HbA1c 8.4%). Documented 6-month physician-monitored diet program completed in June 2026. Behavioral health evaluation pending scheduled visit next month.",
100
+ "expected_status": "PEND_DOCS",
101
+ "confidence": 0.81,
102
+ "citation": "Meets BMI criteria (>40) and 6-mo weight program, but missing mandatory Behavioral Health / Psych Clearance per CPB 0157.",
103
+ },
104
+ }
105
+
106
+ # Initialize session state for system stats
107
+ if "processed_claims" not in st.session_state:
108
+ st.session_state.processed_claims = []
109
+
110
+
111
+ # ==========================================
112
+ # SIDEBAR CONTROL PANEL
113
+ # ==========================================
114
+ with st.sidebar:
115
+ st.image(
116
+ "https://upload.wikimedia.org/wikipedia/commons/f/f3/CVS_Health_logo.svg",
117
+ width=180,
118
+ )
119
+ st.markdown("### **AI Claims Platform Engine**")
120
+ st.caption("A&BC Agentic Decision-Support Framework")
121
+ st.divider()
122
+
123
+ st.subheader("βš™οΈ Platform Governance")
124
+ auto_adj_threshold = st.slider(
125
+ "Auto-Adjudication Confidence Threshold",
126
+ min_value=0.70,
127
+ max_value=0.99,
128
+ value=0.90,
129
+ step=0.01,
130
+ help="Claims with model confidence above this threshold bypass manual review.",
131
+ )
132
+
133
+ st.subheader("πŸ”‘ Live LLM Config (Optional)")
134
+ api_key = st.text_input(
135
+ "OpenAI API Key",
136
+ type="password",
137
+ placeholder="sk-...",
138
+ help="Leave blank to use internal deterministic Agent Engine",
139
+ )
140
+
141
+ st.divider()
142
+ st.info(
143
+ "**Director Candidate Portfolio Prototype**\n\nFocus Area: Agentic Workflow Automation, Policy RAG, & Human-in-the-Loop Safeguards."
144
+ )
145
+
146
+
147
+ # ==========================================
148
+ # HEADER SECTION
149
+ # ==========================================
150
+ st.markdown(
151
+ "<div class='main-header'>Aetna SmartClaim AI | Enterprise Claims Decision-Support</div>",
152
+ unsafe_allow_html=True,
153
+ )
154
+ st.markdown(
155
+ "<div class='sub-header'>Powered by Policy Retrieval-Augmented Generation (RAG) & Agentic Reasoning Engines</div>",
156
+ unsafe_allow_html=True,
157
+ )
158
+
159
+ tab1, tab2, tab3 = st.tabs(
160
+ [
161
+ "πŸ“‹ Agentic Claims Copilot (Ops)",
162
+ "⚑ Auto-Adjudication & Guardrails",
163
+ "πŸ“Š Executive Observability (AVP)",
164
+ ]
165
+ )
166
+
167
+
168
+ # ==========================================
169
+ # TAB 1: AGENTIC CLAIMS COPILOT
170
+ # ==========================================
171
+ with tab1:
172
+ st.markdown("### 1. Select or Input Claim Information")
173
+
174
+ col_input1, col_input2 = st.columns([1, 1])
175
+
176
+ with col_input1:
177
+ selected_sample = st.selectbox(
178
+ "Select Pre-loaded Test Scenario:", list(MOCK_CLAIMS.keys())
179
+ )
180
+ claim_data = MOCK_CLAIMS[selected_sample]
181
+
182
+ claim_id = st.text_input("Claim ID", claim_data["claim_id"])
183
+ patient_info = st.text_input("Patient Info", claim_data["patient"])
184
+ cpb_selection = st.selectbox(
185
+ "Target Policy Bulletin (CPB)",
186
+ list(AETNA_CPBS.keys()),
187
+ index=list(AETNA_CPBS.keys()).index(claim_data["cpb"]),
188
+ )
189
+
190
+ with col_input2:
191
+ cpt_code = st.text_input("Procedure / CPT Code", claim_data["cpt"])
192
+ diag_code = st.text_input("Diagnosis Code", claim_data["diagnosis"])
193
+ clinical_notes = st.text_area(
194
+ "Clinical Progress Notes & Unstructured EHR Data:",
195
+ claim_data["clinical_notes"],
196
+ height=120,
197
+ )
198
+
199
+ run_btn = st.button("πŸš€ Run Agentic Claim Evaluation", type="primary")
200
+
201
+ if run_btn:
202
+ with st.spinner(
203
+ "Agent retrieving Aetna CPB guidelines and executing semantic policy matching..."
204
+ ):
205
+ time.sleep(1.2) # Simulate agent reasoning latency
206
+
207
+ # Dynamic logic evaluation
208
+ confidence = claim_data["confidence"]
209
+ status = claim_data["expected_status"]
210
+ citation = claim_data["citation"]
211
+
212
+ # Store in session state for audit log
213
+ st.session_state.processed_claims.append(
214
+ {
215
+ "timestamp": time.strftime("%H:%M:%S"),
216
+ "claim_id": claim_id,
217
+ "cpb": cpb_selection,
218
+ "status": status,
219
+ "confidence": confidence,
220
+ "route": "Straight-Through (Auto)"
221
+ if confidence >= auto_adj_threshold
222
+ else "HITL Specialist Queue",
223
+ }
224
+ )
225
+
226
+ st.divider()
227
+ st.markdown("### 2. Agentic Reasoning & Policy Matching Results")
228
+
229
+ res_col1, res_col2, res_col3 = st.columns([1, 1, 1])
230
+
231
+ with res_col1:
232
+ st.markdown("**System Recommendation:**")
233
+ if status == "APPROVED" and confidence >= auto_adj_threshold:
234
+ st.markdown(
235
+ "<span class='badge-pass'>AUTO-APPROVE (STP)</span>",
236
+ unsafe_allow_html=True,
237
+ )
238
+ elif status == "PEND_DOCS":
239
+ st.markdown(
240
+ "<span class='badge-review'>PEND FOR ADDITIONAL DOCUMENTS</span>",
241
+ unsafe_allow_html=True,
242
+ )
243
+ else:
244
+ st.markdown(
245
+ "<span class='badge-review'>REFER TO HUMAN SPECIALIST</span>",
246
+ unsafe_allow_html=True,
247
+ )
248
+
249
+ with res_col2:
250
+ st.markdown("**Model Confidence Score:**")
251
+ st.metric(
252
+ label="Confidence",
253
+ value=f"{int(confidence*100)}%",
254
+ delta=f"{'+' if confidence >= auto_adj_threshold else '-'}{abs(round((confidence - auto_adj_threshold)*100, 1))}% vs Threshold",
255
+ )
256
+
257
+ with res_col3:
258
+ st.markdown("**Workflow Routing:**")
259
+ if confidence >= auto_adj_threshold:
260
+ st.success("βœ… Straight-Through Processing (Zero Human Touch)")
261
+ else:
262
+ st.warning(
263
+ "⚠️ Routed to Human Specialist Queue (Below Risk Threshold)"
264
+ )
265
+
266
+ st.markdown("#### πŸ“œ Policy Line-Item Evidence Citations")
267
+ st.info(f"**CPB Citation Analysis:** {citation}")
268
+
269
+ # Human-in-the-Loop (HITL) Action Panel
270
+ st.markdown("#### πŸ› οΈ Specialist Human-in-the-Loop Actions")
271
+ action_col1, action_col2, action_col3 = st.columns(3)
272
+
273
+ with action_col1:
274
+ if st.button("βœ… Confirm & Approve Claim"):
275
+ st.success(
276
+ f"Claim {claim_id} approved by Specialist. Adjudication logged."
277
+ )
278
+
279
+ with action_col2:
280
+ if st.button("βœ‰οΈ Draft Pre-filled Request Letter"):
281
+ st.text_area(
282
+ "Generated Provider Outreach Letter:",
283
+ f"Dear Provider,\n\nRegarding Claim {claim_id} for {cpt_code}, our automated review against Aetna {cpb_selection} indicates missing required documentation:\n- {citation}\n\nPlease submit clinical records within 14 days.\n\nSincerely,\nAetna Clinical Operations",
284
+ height=130,
285
+ )
286
+
287
+ with action_col3:
288
+ if st.button("❌ Issue Prior Auth Denial Notice"):
289
+ st.error(
290
+ f"Denial Notice initiated for {claim_id} per {cpb_selection} non-compliance."
291
+ )
292
+
293
+
294
+ # ==========================================
295
+ # TAB 2: AUTO-ADJUDICATION & GUARDRAILS
296
+ # ==========================================
297
+ with tab2:
298
+ st.markdown("### Dynamic Risk & Threshold Impact Simulator")
299
+ st.caption("Evaluate how adjusting confidence guardrails impacts operational throughput vs audit risk.")
300
+
301
+ sim_col1, sim_col2 = st.columns([1, 2])
302
+
303
+ with sim_col1:
304
+ st.markdown("#### Simulation Control")
305
+ total_daily_volume = st.number_input(
306
+ "Daily Claim Volume:", value=25000, step=1000
307
+ )
308
+ avg_cost_per_manual = st.number_input(
309
+ "Cost per Manual Claim Review ($):", value=14.50, step=0.50
310
+ )
311
+
312
+ # Simulation Logic based on threshold
313
+ # Higher threshold -> lower auto-adjudication %, but near-zero error rate
314
+ stp_rate = max(0.20, min(0.85, 1.25 - (auto_adj_threshold * 0.8)))
315
+ auto_volume = int(total_daily_volume * stp_rate)
316
+ manual_volume = total_daily_volume - auto_volume
317
+ daily_savings = auto_volume * avg_cost_per_manual
318
+
319
+ st.metric(
320
+ "Simulated Auto-Adjudication (STP) Rate", f"{round(stp_rate*100, 1)}%"
321
+ )
322
+ st.metric(
323
+ "Projected Annual Operating Savings",
324
+ f"${daily_savings * 260:,.0f}",
325
+ )
326
+
327
+ with sim_col2:
328
+ st.markdown("#### Daily Volume Distribution Forecast")
329
+ fig_pie = px.pie(
330
+ values=[auto_volume, manual_volume],
331
+ names=["Auto-Adjudicated (AI)", "Manual Specialist Review (HITL)"],
332
+ color_discrete_sequence=["#28A745", "#FFC107"],
333
+ hole=0.4,
334
+ )
335
+ fig_pie.update_layout(margin=dict(t=20, b=20, l=20, r=20), height=300)
336
+ st.plotly_chart(fig_pie, use_container_width=True)
337
+
338
+ st.divider()
339
+ st.markdown("### Platform Guardrails & Safety Controls")
340
+
341
+ g_col1, g_col2, g_col3 = st.columns(3)
342
+ with g_col1:
343
+ st.markdown("#### πŸ”’ Anti-Hallucination")
344
+ st.caption(
345
+ "Pydantic strict schema parsing enforces structured JSON output with mandated CPB paragraph citations."
346
+ )
347
+ with g_col2:
348
+ st.markdown("#### βš–οΈ Compliance & HIPAA")
349
+ st.caption(
350
+ "De-identification pipelines strip PHI before prompt embedding; audit logging records all LLM inference seeds."
351
+ )
352
+ with g_col3:
353
+ st.markdown("#### πŸ”„ Model Drift Monitoring")
354
+ st.caption(
355
+ "Continuous monitoring flags discrepancies between specialist override patterns and agent recommendations."
356
+ )
357
+
358
+
359
+ # ==========================================
360
+ # TAB 3: EXECUTIVE OBSERVABILITY (AVP VIEW)
361
+ # ==========================================
362
+ with tab3:
363
+ st.markdown("### Executive Dashboard | Analytics & Behavior Change (A&BC)")
364
+
365
+ # Key Performance Indicators
366
+ kpi1, kpi2, kpi3, kpi4 = st.columns(4)
367
+ kpi1.metric("Current STP Rate", "68.4%", "+14.2% YoY")
368
+ kpi2.metric("Average Handle Time (AHT)", "2.3 min", "-11.8 min")
369
+ kpi3.metric("First-Pass Accuracy", "99.1%", "+1.8%")
370
+ kpi4.metric("Specialist Override Rate", "3.2%", "-0.8%")
371
+
372
+ st.divider()
373
+
374
+ st.markdown("### Platform Performance Trends")
375
+ chart_col1, chart_col2 = st.columns(2)
376
+
377
+ with chart_col1:
378
+ st.markdown("#### Weekly Processing Volume vs Manual Touch Points")
379
+ weeks = [f"Week {i}" for i in range(1, 9)]
380
+ df_trends = pd.DataFrame(
381
+ {
382
+ "Week": weeks,
383
+ "Auto-Adjudicated": [
384
+ 12000,
385
+ 13500,
386
+ 14200,
387
+ 15800,
388
+ 16500,
389
+ 17200,
390
+ 18100,
391
+ 19000,
392
+ ],
393
+ "Specialist Review": [
394
+ 8000,
395
+ 7200,
396
+ 6800,
397
+ 5900,
398
+ 5200,
399
+ 4800,
400
+ 4200,
401
+ 3800,
402
+ ],
403
+ }
404
+ )
405
+ fig_bar = px.bar(
406
+ df_trends,
407
+ x="Week",
408
+ y=["Auto-Adjudicated", "Specialist Review"],
409
+ color_discrete_map={
410
+ "Auto-Adjudicated": "#002B49",
411
+ "Specialist Review": "#CC0000",
412
+ },
413
+ barmode="stack",
414
+ )
415
+ fig_bar.update_layout(height=320, margin=dict(t=20, b=20, l=20, r=20))
416
+ st.plotly_chart(fig_bar, use_container_width=True)
417
+
418
+ with chart_col2:
419
+ st.markdown("#### Agent vs Specialist Agreement Rate (By Clinical Category)")
420
+ df_agree = pd.DataFrame(
421
+ {
422
+ "Category": [
423
+ "Radiology (MRI/CT)",
424
+ "Bariatric / Surgery",
425
+ "Oncology",
426
+ "Orthopedics",
427
+ "Cardiology",
428
+ ],
429
+ "Agreement Rate (%)": [98.2, 94.5, 99.1, 96.4, 97.8],
430
+ }
431
+ )
432
+ fig_gauge = px.bar(
433
+ df_agree,
434
+ x="Agreement Rate (%)",
435
+ y="Category",
436
+ orientation="h",
437
+ color="Agreement Rate (%)",
438
+ color_continuous_scale="Reds",
439
+ )
440
+ fig_gauge.update_layout(height=320, margin=dict(t=20, b=20, l=20, r=20))
441
+ st.plotly_chart(fig_gauge, use_container_width=True)
442
+
443
+ st.markdown("### Real-time Session Audit Log")
444
+ if st.session_state.processed_claims:
445
+ st.dataframe(
446
+ pd.DataFrame(st.session_state.processed_claims),
447
+ use_container_width=True,
448
+ )
449
+ else:
450
+ st.info("No claims processed in current session. Run a claim evaluation in Tab 1 to see real-time audit logging.")