Spaces:
Sleeping
Sleeping
Create feedback.py
Browse files- feedback.py +70 -0
feedback.py
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# feedback.py — Step 9
|
2 |
+
# Minimal CSV logger for Helpful / Not helpful signals.
|
3 |
+
# Writes to data/feedback.csv and auto-creates header on first write.
|
4 |
+
|
5 |
+
from pathlib import Path
|
6 |
+
import csv
|
7 |
+
import time
|
8 |
+
|
9 |
+
FEEDBACK_CSV = Path("data/feedback.csv")
|
10 |
+
FEEDBACK_CSV.parent.mkdir(parents=True, exist_ok=True)
|
11 |
+
|
12 |
+
_FIELDS = [
|
13 |
+
"ts_question",
|
14 |
+
"ts_feedback",
|
15 |
+
"session",
|
16 |
+
"feedback", # "helpful" | "not_helpful"
|
17 |
+
"note", # optional free text
|
18 |
+
"lang",
|
19 |
+
"mode",
|
20 |
+
"temperature",
|
21 |
+
"max_tokens",
|
22 |
+
"top_k",
|
23 |
+
"question",
|
24 |
+
"answer",
|
25 |
+
"sources",
|
26 |
+
"links",
|
27 |
+
"forms",
|
28 |
+
]
|
29 |
+
|
30 |
+
def _ensure_header(path: Path):
|
31 |
+
if not path.exists() or path.stat().st_size == 0:
|
32 |
+
with path.open("w", newline="", encoding="utf-8") as f:
|
33 |
+
csv.DictWriter(f, fieldnames=_FIELDS).writeheader()
|
34 |
+
|
35 |
+
def _flatten(s: str, lim: int = 2000) -> str:
|
36 |
+
"""Make single-line, truncate to keep rows compact."""
|
37 |
+
if s is None:
|
38 |
+
return ""
|
39 |
+
s = " ".join(str(s).split())
|
40 |
+
return s[:lim]
|
41 |
+
|
42 |
+
def log_feedback(entry: dict) -> str:
|
43 |
+
"""
|
44 |
+
entry expects at least:
|
45 |
+
ts_question, session, feedback, note, lang, mode, temperature, max_tokens, top_k,
|
46 |
+
question, answer, sources, links, forms
|
47 |
+
"""
|
48 |
+
_ensure_header(FEEDBACK_CSV)
|
49 |
+
row = {k: "" for k in _FIELDS}
|
50 |
+
row.update({
|
51 |
+
"ts_question": entry.get("ts_question", int(time.time())),
|
52 |
+
"ts_feedback": int(time.time()),
|
53 |
+
"session": entry.get("session", ""),
|
54 |
+
"feedback": entry.get("feedback", ""),
|
55 |
+
"note": _flatten(entry.get("note", "")),
|
56 |
+
"lang": entry.get("lang", ""),
|
57 |
+
"mode": entry.get("mode", ""),
|
58 |
+
"temperature": entry.get("temperature", ""),
|
59 |
+
"max_tokens": entry.get("max_tokens", ""),
|
60 |
+
"top_k": entry.get("top_k", ""),
|
61 |
+
"question": _flatten(entry.get("question", ""), 1000),
|
62 |
+
"answer": _flatten(entry.get("answer", ""), 2000),
|
63 |
+
"sources": _flatten(entry.get("sources", ""), 1000),
|
64 |
+
"links": _flatten(entry.get("links", ""), 1000),
|
65 |
+
"forms": _flatten(entry.get("forms", ""), 1000),
|
66 |
+
})
|
67 |
+
with FEEDBACK_CSV.open("a", newline="", encoding="utf-8") as f:
|
68 |
+
w = csv.DictWriter(f, fieldnames=_FIELDS)
|
69 |
+
w.writerow(row)
|
70 |
+
return f"Thanks — logged as **{row['feedback']}** for session `{row['session']}`."
|