HemanM commited on
Commit
be43fd9
Β·
verified Β·
1 Parent(s): 9810d33

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -12
app.py CHANGED
@@ -1,12 +1,18 @@
1
  """
2
- app.py β€” Step 8 (refined)
3
  Adds:
4
- - Auto-build of the index on first question (prevents "Index not found" error)
5
- - Same Extractive/Generative toggle + temperature/max_tokens controls
 
 
 
6
  """
7
 
8
  from pathlib import Path
9
  from typing import List
 
 
 
10
  import gradio as gr
11
 
12
  from indexer import build_index
@@ -19,6 +25,7 @@ from rag_search import (
19
  )
20
  from evo_inference import synthesize_with_evo
21
  from utils_lang import SUPPORTED, normalize_lang, L
 
22
 
23
  _searcher = None
24
  DATA_SEED_DIR = Path("data/seed")
@@ -87,6 +94,7 @@ def on_ask(
87
  temp: float,
88
  max_tokens: int,
89
  history: list,
 
90
  ):
91
  """
92
  Handle a user question end-to-end:
@@ -95,10 +103,12 @@ def on_ask(
95
  - Synthesize answer (Extractive or Generative)
96
  - Show sources + extracted links/forms
97
  - Append to chat history
 
98
  """
99
  lang = normalize_lang(lang_code)
100
  if not question or len(question.strip()) < 3:
101
- return history, L(lang, "intro_err"), f"{L(lang, 'sources')}: (none)", "", ""
 
102
 
103
  try:
104
  # Ensure searcher; if index missing, build once automatically then retry
@@ -133,20 +143,61 @@ def on_ask(
133
  links_md = links_markdown(L(lang, "links"), other_links)
134
  forms_md = links_markdown(L(lang, "forms"), form_links)
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  except Exception as e:
137
  answer = f"Error: {e}\n\n{L(lang, 'tip_build')}"
138
  srcs = f"{L(lang, 'sources')}: (none)"
139
  links_md = f"**{L(lang, 'links')}:** (none)"
140
  forms_md = f"**{L(lang, 'forms')}:** (none)"
 
141
 
142
  history = history + [(question, answer)]
143
- return history, answer, srcs, links_md, forms_md
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
 
146
  with gr.Blocks(title=L("en", "title")) as demo:
147
- gr.Markdown(f"# πŸ‡²πŸ‡Ί **{L('en','title')}** β€” Step 8")
148
 
149
- # Admin: build index / upload & reindex
 
 
 
 
 
 
 
150
  with gr.Row():
151
  build_btn = gr.Button(L("en", "build_btn"))
152
  status = gr.Markdown(L("en", "status_idle"))
@@ -162,7 +213,7 @@ with gr.Blocks(title=L("en", "title")) as demo:
162
  upload_status = gr.Markdown()
163
  save_btn.click(fn=on_upload_and_reindex, inputs=upload, outputs=upload_status)
164
 
165
- # User controls
166
  gr.Markdown("### Language / Langue / Langaz")
167
  lang = gr.Dropdown(choices=list(SUPPORTED.keys()), value="en", label="EN / FR / MFE")
168
 
@@ -176,6 +227,7 @@ with gr.Blocks(title=L("en", "title")) as demo:
176
  temp = gr.Slider(0.0, 1.2, value=0.4, step=0.05, label="Temperature (gen)")
177
  max_tokens = gr.Slider(64, 384, value=192, step=16, label="Max new tokens (gen)")
178
 
 
179
  gr.Markdown("### Ask a question / Posez une question / Poz enn kestyon")
180
  with gr.Row():
181
  q = gr.Textbox(placeholder=L("en", "ask_placeholder"), label=L("en", "ask_label"))
@@ -190,13 +242,33 @@ with gr.Blocks(title=L("en", "title")) as demo:
190
 
191
  ask_btn.click(
192
  fn=on_ask,
193
- inputs=[q, k, lang, mode, temp, max_tokens, chat],
194
- outputs=[chat, answer_md, sources_md, links_md, forms_md],
195
  )
196
  q.submit(
197
  fn=on_ask,
198
- inputs=[q, k, lang, mode, temp, max_tokens, chat],
199
- outputs=[chat, answer_md, sources_md, links_md, forms_md],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  )
201
 
202
  demo.launch()
 
1
  """
2
+ app.py β€” Step 9
3
  Adds:
4
+ - Feedback logger (Helpful / Not helpful) with optional note β†’ data/feedback.csv
5
+ - Per-session ID so you can trace usage (no cookies needed)
6
+ - Auto-build index on first question (from Step 8 refined)
7
+
8
+ Everything else (RAG + Extractive/Generative toggle) stays the same.
9
  """
10
 
11
  from pathlib import Path
12
  from typing import List
13
+ import secrets
14
+ import time
15
+
16
  import gradio as gr
17
 
18
  from indexer import build_index
 
25
  )
26
  from evo_inference import synthesize_with_evo
27
  from utils_lang import SUPPORTED, normalize_lang, L
28
+ from feedback import log_feedback # NEW
29
 
30
  _searcher = None
31
  DATA_SEED_DIR = Path("data/seed")
 
94
  temp: float,
95
  max_tokens: int,
96
  history: list,
97
+ session_id: str, # NEW: State input
98
  ):
99
  """
100
  Handle a user question end-to-end:
 
103
  - Synthesize answer (Extractive or Generative)
104
  - Show sources + extracted links/forms
105
  - Append to chat history
106
+ - Return a structured "last answer" payload for feedback logging
107
  """
108
  lang = normalize_lang(lang_code)
109
  if not question or len(question.strip()) < 3:
110
+ last_payload = {}
111
+ return history, L(lang, "intro_err"), f"{L(lang, 'sources')}: (none)", "", "", last_payload
112
 
113
  try:
114
  # Ensure searcher; if index missing, build once automatically then retry
 
143
  links_md = links_markdown(L(lang, "links"), other_links)
144
  forms_md = links_markdown(L(lang, "forms"), form_links)
145
 
146
+ # Build "last answer" payload for feedback
147
+ last_payload = {
148
+ "ts_question": int(time.time()),
149
+ "session": session_id or "",
150
+ "lang": lang,
151
+ "mode": mode,
152
+ "temperature": float(temp),
153
+ "max_tokens": int(max_tokens),
154
+ "top_k": int(top_k),
155
+ "question": question,
156
+ "answer": answer,
157
+ "sources": srcs,
158
+ "links": links_md,
159
+ "forms": forms_md,
160
+ }
161
+
162
  except Exception as e:
163
  answer = f"Error: {e}\n\n{L(lang, 'tip_build')}"
164
  srcs = f"{L(lang, 'sources')}: (none)"
165
  links_md = f"**{L(lang, 'links')}:** (none)"
166
  forms_md = f"**{L(lang, 'forms')}:** (none)"
167
+ last_payload = {}
168
 
169
  history = history + [(question, answer)]
170
+ return history, answer, srcs, links_md, forms_md, last_payload
171
+
172
+
173
+ def on_feedback_submit(kind: str, note: str, last_payload: dict) -> str:
174
+ """
175
+ Log feedback to CSV. 'kind' is 'helpful' or 'not_helpful'.
176
+ """
177
+ if not last_payload:
178
+ return "Ask a question first, then rate the answer."
179
+ entry = dict(last_payload) # copy
180
+ entry["feedback"] = kind
181
+ entry["note"] = note or ""
182
+ return log_feedback(entry)
183
+
184
+
185
+ def _new_session_id():
186
+ """Generate a short session id on app load."""
187
+ return secrets.token_hex(8)
188
 
189
 
190
  with gr.Blocks(title=L("en", "title")) as demo:
191
+ gr.Markdown(f"# πŸ‡²πŸ‡Ί **{L('en','title')}** β€” Step 9")
192
 
193
+ # --- Hidden state: session id + last answer payload
194
+ session = gr.State()
195
+ last_answer = gr.State()
196
+
197
+ # Generate a session id when the app loads
198
+ demo.load(fn=_new_session_id, inputs=None, outputs=session)
199
+
200
+ # --- Admin: build index / upload & reindex
201
  with gr.Row():
202
  build_btn = gr.Button(L("en", "build_btn"))
203
  status = gr.Markdown(L("en", "status_idle"))
 
213
  upload_status = gr.Markdown()
214
  save_btn.click(fn=on_upload_and_reindex, inputs=upload, outputs=upload_status)
215
 
216
+ # --- User controls
217
  gr.Markdown("### Language / Langue / Langaz")
218
  lang = gr.Dropdown(choices=list(SUPPORTED.keys()), value="en", label="EN / FR / MFE")
219
 
 
227
  temp = gr.Slider(0.0, 1.2, value=0.4, step=0.05, label="Temperature (gen)")
228
  max_tokens = gr.Slider(64, 384, value=192, step=16, label="Max new tokens (gen)")
229
 
230
+ # --- Q&A
231
  gr.Markdown("### Ask a question / Posez une question / Poz enn kestyon")
232
  with gr.Row():
233
  q = gr.Textbox(placeholder=L("en", "ask_placeholder"), label=L("en", "ask_label"))
 
242
 
243
  ask_btn.click(
244
  fn=on_ask,
245
+ inputs=[q, k, lang, mode, temp, max_tokens, chat, session],
246
+ outputs=[chat, answer_md, sources_md, links_md, forms_md, last_answer],
247
  )
248
  q.submit(
249
  fn=on_ask,
250
+ inputs=[q, k, lang, mode, temp, max_tokens, chat, session],
251
+ outputs=[chat, answer_md, sources_md, links_md, forms_md, last_answer],
252
+ )
253
+
254
+ # --- Feedback UI
255
+ gr.Markdown("### Rate this answer")
256
+ with gr.Row():
257
+ note = gr.Textbox(placeholder="Optional: tell us what was good or missing", label="Your note", lines=2)
258
+ with gr.Row():
259
+ helpful_btn = gr.Button("πŸ‘ Helpful")
260
+ not_helpful_btn = gr.Button("πŸ‘Ž Not helpful")
261
+ fb_status = gr.Markdown()
262
+
263
+ helpful_btn.click(
264
+ fn=lambda n, last: on_feedback_submit("helpful", n, last),
265
+ inputs=[note, last_answer],
266
+ outputs=[fb_status],
267
+ )
268
+ not_helpful_btn.click(
269
+ fn=lambda n, last: on_feedback_submit("not_helpful", n, last),
270
+ inputs=[note, last_answer],
271
+ outputs=[fb_status],
272
  )
273
 
274
  demo.launch()