""" utils/feedback.py Unified feedback handler for Clinical Research Chatbot. Includes: 1๏ธโƒฃ Feedback Queue (unanswered/low-confidence queries) 2๏ธโƒฃ User Voting (๐Ÿ‘ Helpful / ๐Ÿ‘Ž Not Helpful) """ import os import json from datetime import datetime # ---------------------------- # File Paths # ---------------------------- FEEDBACK_QUEUE_LOG = "logs/feedback_queue.jsonl" FEEDBACK_VOTES_LOG = "logs/feedback_votes.jsonl" # ---------------------------- # Feedback Queue (for Admin Review) # ---------------------------- def log_feedback(query: str, notes: str = "", sources=None): """ Store unanswered or low-confidence queries for admin review. Saves to JSONL (one entry per line). """ entry = { "timestamp": datetime.utcnow().isoformat(), "query": query, "notes": notes, "sources": sources or [], } os.makedirs(os.path.dirname(FEEDBACK_QUEUE_LOG), exist_ok=True) with open(FEEDBACK_QUEUE_LOG, "a", encoding="utf-8") as f: f.write(json.dumps(entry, ensure_ascii=False) + "\n") print(f"๐Ÿ“ Feedback queued for admin review: {query}") def load_feedback(limit: int = 20): """ Load last N feedback entries for admin dashboard. """ if not os.path.exists(FEEDBACK_QUEUE_LOG): return [] with open(FEEDBACK_QUEUE_LOG, "r", encoding="utf-8") as f: lines = f.readlines() entries = [json.loads(line) for line in lines] return entries[-limit:] def clear_feedback(): """ Clear feedback log (admin only). """ if os.path.exists(FEEDBACK_QUEUE_LOG): os.remove(FEEDBACK_QUEUE_LOG) print("๐Ÿ—‘๏ธ Feedback log cleared.") # ---------------------------- # User Voting (for โ€œHelpful / Not Helpfulโ€) # ---------------------------- def save_vote_feedback(query: str, vote: str, context=None): """ Log user votes (๐Ÿ‘ / ๐Ÿ‘Ž) on chatbot responses. """ entry = { "timestamp": datetime.utcnow().isoformat(), "query": query, "vote": vote, "context": context or {}, } os.makedirs(os.path.dirname(FEEDBACK_VOTES_LOG), exist_ok=True) try: with open(FEEDBACK_VOTES_LOG, "a", encoding="utf-8") as f: f.write(json.dumps(entry, ensure_ascii=False) + "\n") print(f"๐Ÿ—ณ๏ธ User voted '{vote}' for query: {query}") except Exception as e: print(f"โš ๏ธ Failed to save vote feedback: {e}") def load_votes(limit: int = 50): """ Load last N user votes for analysis. """ if not os.path.exists(FEEDBACK_VOTES_LOG): return [] with open(FEEDBACK_VOTES_LOG, "r", encoding="utf-8") as f: lines = f.readlines() entries = [json.loads(line) for line in lines] return entries[-limit:] def clear_votes(): """ Clear user voting log (admin only). """ if os.path.exists(FEEDBACK_VOTES_LOG): os.remove(FEEDBACK_VOTES_LOG) print("๐Ÿ—‘๏ธ User vote feedback cleared.")