aravindkb7 commited on
Commit
77a746b
·
verified ·
1 Parent(s): 52c59b0

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +148 -56
app.py CHANGED
@@ -60,10 +60,115 @@ CSS = """
60
  radial-gradient(circle at top right, rgba(16,185,129,0.08), transparent 22%),
61
  linear-gradient(180deg, #f8fbff 0%, #f4f7fb 100%);
62
  }
 
 
 
63
  #ask_btn {
64
  background: linear-gradient(135deg, #0f172a 0%, #1d4ed8 100%) !important;
65
  color: white !important;
66
  border: none !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  }
68
  """
69
 
@@ -502,7 +607,7 @@ def result_card(title: str, body: str, tone: str = "normal") -> str:
502
  def initial_result_html() -> str:
503
  return result_card(
504
  "Ready",
505
- "Ask a question about the preloaded Phase 2 project corpus to receive a grounded answer with page and line references.",
506
  )
507
 
508
 
@@ -800,25 +905,6 @@ def render_result(
800
  tone="warn" if abstained else "success",
801
  )
802
 
803
- metric_boxes = "".join(
804
- [
805
- make_metric_badge("Latency", f"{metrics['latency_seconds']:.2f}s"),
806
- make_metric_badge(
807
- "Answer Relevance",
808
- "N/A" if metrics.get("answer_relevance") is None else f"{metrics['answer_relevance']:.2f}",
809
- ),
810
- make_metric_badge(
811
- "Context Precision",
812
- "N/A" if metrics.get("context_precision") is None else f"{metrics['context_precision']:.2f}",
813
- ),
814
- make_metric_badge(
815
- "Faithfulness",
816
- "N/A" if metrics.get("faithfulness_proxy") is None else f"{metrics['faithfulness_proxy']:.2f}",
817
- ),
818
- make_metric_badge("Hallucination", f"{metrics.get('hallucination_rate', 0.0):.2f}"),
819
- ]
820
- )
821
-
822
  question_html = (
823
  "<div style='margin-bottom:14px;padding:14px 16px;border-radius:16px;"
824
  "background:linear-gradient(135deg,#eef4ff 0%,#f8fafc 100%);"
@@ -834,7 +920,6 @@ def render_result(
834
  f"{question_html}"
835
  "<div style='display:grid;grid-template-columns:1fr;gap:14px'>"
836
  f"{answer_card}{source_card}"
837
- f"<div style='display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px'>{metric_boxes}</div>"
838
  "</div></div>"
839
  )
840
 
@@ -842,14 +927,13 @@ def render_result(
842
  def render_document_status(session: SessionData) -> str:
843
  doc_count = len({record.source_file for record in session.page_records})
844
  return result_card(
845
- "Corpus Loaded",
846
  (
847
  f"<strong>{html.escape(session.file_name)}</strong><br>"
848
- f"Documents indexed: {doc_count}<br>"
849
- f"Pages indexed: {session.page_count}<br>"
850
- f"Chunks indexed: {len(session.chunks)}<br>"
851
- f"Extractor used: {html.escape(session.extractor)}<br>"
852
- f"Knowledge base mode: preloaded project corpus"
853
  ),
854
  tone="success",
855
  )
@@ -1324,24 +1408,34 @@ with gr.Blocks(css=CSS) as demo:
1324
  session_state = gr.State(PRELOADED_SESSION.session_id if PRELOADED_SESSION else None)
1325
  response_state = gr.State(None)
1326
 
1327
- gr.Markdown(
1328
  f"""
1329
- # {APP_NAME}
1330
- {APP_TAGLINE}
1331
-
1332
- **Project corpus mode**
1333
- - Preloaded Phase 2 project documents
1334
- - Optimized for this fixed validation corpus
1335
- - Best for onboarding, project lookup, and validation Q&A
1336
- - Rate limit: **{MAX_QUESTIONS_PER_MINUTE} questions per minute**
 
 
 
 
 
1337
  """
1338
  )
1339
 
1340
- gr.Markdown(
1341
- f"""
1342
- <div style="padding:14px 16px;border-radius:14px;background:#fff8eb;border:1px solid #fed7aa;color:#9a3412">
1343
- <strong>Privacy notice</strong><br>
1344
- {html.escape(PRIVACY_NOTICE)}
 
 
 
 
 
1345
  </div>
1346
  """
1347
  )
@@ -1357,30 +1451,28 @@ with gr.Blocks(css=CSS) as demo:
1357
  lines=2,
1358
  placeholder="Ask a question about the preloaded project documents...",
1359
  scale=5,
 
1360
  )
1361
  ask_btn = gr.Button("Ask", elem_id="ask_btn", scale=1)
1362
 
1363
  result_html_component = gr.HTML(initial_result_html())
1364
 
1365
- with gr.Row():
1366
  helpful_btn = gr.Button("Helpful")
1367
  needs_work_btn = gr.Button("Needs Improvement")
1368
 
1369
- feedback_status = gr.Textbox(
1370
- label="Feedback Status",
1371
- value="",
1372
- interactive=False,
1373
- )
1374
 
1375
- with gr.Accordion("Testing guardrails and privacy details", open=False):
1376
- gr.Markdown(
1377
- f"""
1378
- - **Knowledge base**: 15 preloaded Phase 2 project PDFs
1379
- - **Citation format**: page and extracted-text line range
1380
- - **Queueing**: concurrency limit {QUEUE_CONCURRENCY}, queue size {QUEUE_MAX_SIZE}
1381
- - **Logged for evaluation**: corpus question, answer, citation, latency, and proxy metrics
1382
- """
1383
- )
 
1384
 
1385
  ask_btn.click(
1386
  ask_question,
 
60
  radial-gradient(circle at top right, rgba(16,185,129,0.08), transparent 22%),
61
  linear-gradient(180deg, #f8fbff 0%, #f4f7fb 100%);
62
  }
63
+ .gradio-container .main {
64
+ max-width: 1320px;
65
+ }
66
  #ask_btn {
67
  background: linear-gradient(135deg, #0f172a 0%, #1d4ed8 100%) !important;
68
  color: white !important;
69
  border: none !important;
70
+ min-height: 64px !important;
71
+ font-weight: 700 !important;
72
+ font-size: 18px !important;
73
+ }
74
+ #demo_header {
75
+ margin-bottom: 10px;
76
+ }
77
+ #demo_header .hero-card {
78
+ background: linear-gradient(135deg, rgba(255,255,255,0.96) 0%, rgba(241,245,249,0.92) 100%);
79
+ border: 1px solid #dbe4f0;
80
+ border-radius: 24px;
81
+ padding: 28px 30px;
82
+ box-shadow: 0 16px 40px rgba(15,23,42,0.08);
83
+ }
84
+ #demo_header h1 {
85
+ margin: 0 0 8px 0;
86
+ font-size: 52px;
87
+ line-height: 1;
88
+ color: #0f172a;
89
+ }
90
+ #demo_header p {
91
+ margin: 0;
92
+ font-size: 22px;
93
+ line-height: 1.5;
94
+ color: #334155;
95
+ }
96
+ #demo_header .hero-kicker {
97
+ margin-bottom: 10px;
98
+ font-size: 12px;
99
+ font-weight: 700;
100
+ letter-spacing: 0.12em;
101
+ text-transform: uppercase;
102
+ color: #2563eb;
103
+ }
104
+ #demo_header .hero-chips {
105
+ display: flex;
106
+ flex-wrap: wrap;
107
+ gap: 10px;
108
+ margin-top: 18px;
109
+ }
110
+ #demo_header .hero-chip {
111
+ padding: 8px 12px;
112
+ border-radius: 999px;
113
+ background: #eef4ff;
114
+ border: 1px solid #cfe0ff;
115
+ color: #1e3a8a;
116
+ font-size: 14px;
117
+ font-weight: 600;
118
+ }
119
+ #demo_note {
120
+ margin-top: 12px;
121
+ }
122
+ #demo_note .note-card {
123
+ background: rgba(255,255,255,0.9);
124
+ border: 1px solid #dbe4f0;
125
+ border-radius: 20px;
126
+ padding: 18px 22px;
127
+ color: #334155;
128
+ box-shadow: 0 10px 28px rgba(15,23,42,0.05);
129
+ }
130
+ #demo_note strong {
131
+ color: #0f172a;
132
+ }
133
+ #demo_note code {
134
+ background: #eef4ff;
135
+ border: 1px solid #dbe4f0;
136
+ border-radius: 8px;
137
+ padding: 2px 6px;
138
+ }
139
+ #question_box textarea {
140
+ font-size: 22px !important;
141
+ line-height: 1.5 !important;
142
+ }
143
+ #feedback_row {
144
+ margin-top: 8px;
145
+ }
146
+ #feedback_row button {
147
+ min-height: 54px !important;
148
+ font-weight: 700 !important;
149
+ }
150
+ #demo_footer {
151
+ margin-top: 10px;
152
+ }
153
+ #demo_footer .footer-card {
154
+ background: rgba(255,255,255,0.86);
155
+ border: 1px solid #dbe4f0;
156
+ border-radius: 18px;
157
+ padding: 14px 18px;
158
+ color: #475569;
159
+ font-size: 14px;
160
+ line-height: 1.6;
161
+ }
162
+ #demo_footer strong {
163
+ color: #0f172a;
164
+ }
165
+ @media (max-width: 900px) {
166
+ #demo_header h1 {
167
+ font-size: 38px;
168
+ }
169
+ #demo_header p {
170
+ font-size: 18px;
171
+ }
172
  }
173
  """
174
 
 
607
  def initial_result_html() -> str:
608
  return result_card(
609
  "Ready",
610
+ "Ask a specific question about approvals, dates, controls, migration results, traceability, or document ownership to receive a grounded answer with citation.",
611
  )
612
 
613
 
 
905
  tone="warn" if abstained else "success",
906
  )
907
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
908
  question_html = (
909
  "<div style='margin-bottom:14px;padding:14px 16px;border-radius:16px;"
910
  "background:linear-gradient(135deg,#eef4ff 0%,#f8fafc 100%);"
 
920
  f"{question_html}"
921
  "<div style='display:grid;grid-template-columns:1fr;gap:14px'>"
922
  f"{answer_card}{source_card}"
 
923
  "</div></div>"
924
  )
925
 
 
927
  def render_document_status(session: SessionData) -> str:
928
  doc_count = len({record.source_file for record in session.page_records})
929
  return result_card(
930
+ "Knowledge Base",
931
  (
932
  f"<strong>{html.escape(session.file_name)}</strong><br>"
933
+ f"{doc_count} project documents indexed • "
934
+ f"{session.page_count} pages • "
935
+ f"{len(session.chunks)} searchable chunks<br>"
936
+ f"Source mode: curated preloaded corpus • Extractor: {html.escape(session.extractor)}"
 
937
  ),
938
  tone="success",
939
  )
 
1408
  session_state = gr.State(PRELOADED_SESSION.session_id if PRELOADED_SESSION else None)
1409
  response_state = gr.State(None)
1410
 
1411
+ gr.HTML(
1412
  f"""
1413
+ <div id="demo_header">
1414
+ <div class="hero-card">
1415
+ <div class="hero-kicker">Grounded Project Q&A</div>
1416
+ <h1>{html.escape(APP_NAME)}</h1>
1417
+ <p>{html.escape(APP_TAGLINE)}</p>
1418
+ <div class="hero-chips">
1419
+ <div class="hero-chip">Curated Phase 2 corpus</div>
1420
+ <div class="hero-chip">Cited answers</div>
1421
+ <div class="hero-chip">Validation-focused lookup</div>
1422
+ <div class="hero-chip">Best for onboarding and project review</div>
1423
+ </div>
1424
+ </div>
1425
+ </div>
1426
  """
1427
  )
1428
 
1429
+ gr.HTML(
1430
+ """
1431
+ <div id="demo_note">
1432
+ <div class="note-card">
1433
+ <strong>Try questions like:</strong>
1434
+ <code>What is the approved go-live date?</code>
1435
+ <code>Who is the author of the Risk Assessment document?</code>
1436
+ <code>What is the minimum password length?</code><br><br>
1437
+ Ask specific questions grounded in the Project Helix corpus. Unsupported or out-of-scope questions may be declined.
1438
+ </div>
1439
  </div>
1440
  """
1441
  )
 
1451
  lines=2,
1452
  placeholder="Ask a question about the preloaded project documents...",
1453
  scale=5,
1454
+ elem_id="question_box",
1455
  )
1456
  ask_btn = gr.Button("Ask", elem_id="ask_btn", scale=1)
1457
 
1458
  result_html_component = gr.HTML(initial_result_html())
1459
 
1460
+ with gr.Row(elem_id="feedback_row"):
1461
  helpful_btn = gr.Button("Helpful")
1462
  needs_work_btn = gr.Button("Needs Improvement")
1463
 
1464
+ feedback_status = gr.Textbox(value="", visible=False, container=False)
 
 
 
 
1465
 
1466
+ gr.HTML(
1467
+ f"""
1468
+ <div id="demo_footer">
1469
+ <div class="footer-card">
1470
+ <strong>Demo note:</strong> Responses are generated only from the preloaded project corpus and include page/line citations for review.
1471
+ The app is optimized for validation, governance, migration, configuration, and traceability questions across the Phase 2 document set.
1472
+ </div>
1473
+ </div>
1474
+ """
1475
+ )
1476
 
1477
  ask_btn.click(
1478
  ask_question,