Spaces:
Sleeping
Sleeping
| import os | |
| from datetime import date | |
| from functools import lru_cache | |
| from urllib.parse import quote | |
| import gradio as gr | |
| import pandas as pd | |
| from gradio_client import Client | |
| SOURCE_SPACE_ID = os.getenv("SOURCE_SPACE_ID", "toecm/PurePolyglot") | |
| def _empty_df(columns): | |
| return pd.DataFrame(columns=columns) | |
| def _as_dataframe(value, columns=None): | |
| if isinstance(value, pd.DataFrame): | |
| return value | |
| if isinstance(value, dict): | |
| headers = value.get("headers") or columns or [] | |
| data = value.get("data") or [] | |
| return pd.DataFrame(data, columns=headers if headers else None) | |
| if isinstance(value, (list, tuple)): | |
| return pd.DataFrame(value, columns=columns) | |
| return _empty_df(columns or []) | |
| def polyglot_client(): | |
| return Client(SOURCE_SPACE_ID) | |
| def call_polyglot(api_name, *args): | |
| return polyglot_client().predict(*args, api_name=api_name) | |
| def call_first(api_names, *args): | |
| last_error = None | |
| for api_name in api_names: | |
| try: | |
| return call_polyglot(api_name, *args) | |
| except Exception as exc: | |
| last_error = exc | |
| raise RuntimeError(last_error) | |
| def refresh_pending(language_filter="All", dialect_filter="All", review_key=""): | |
| try: | |
| data = call_first( | |
| ["/get_pending_dataframe_2", "/get_pending_dataframe_1", "/get_pending_dataframe"], | |
| language_filter or "All", | |
| dialect_filter or "All", | |
| review_key or "", | |
| ) | |
| return _as_dataframe( | |
| data, | |
| [ | |
| "User", | |
| "Data_Origin", | |
| "Utterance", | |
| "Language", | |
| "Dialect", | |
| "Clarification", | |
| "Clarification_Source", | |
| "Tone", | |
| "Audio", | |
| "Timestamp", | |
| ], | |
| ) | |
| except Exception as exc: | |
| return _empty_df(["Error", "Detail"]).assign(Error=["Pending refresh failed"], Detail=[str(exc)]) | |
| def select_pending_row(evt: gr.SelectData, pending_table): | |
| df = _as_dataframe(pending_table) | |
| try: | |
| index = evt.index[0] if isinstance(evt.index, (list, tuple)) else evt.index | |
| row = df.iloc[int(index)] | |
| audio_path = str(row.get("Audio", "") or "") | |
| audio_name = os.path.basename(audio_path) | |
| audio_link = "" | |
| if audio_name: | |
| audio_url = "https://huggingface.co/datasets/toecm/PureChain_Dataset/resolve/main/pending_audio/" + quote(audio_name) | |
| audio_link = f"[Open pending audio]({audio_url})" | |
| return ( | |
| str(row.get("Timestamp", "") or ""), | |
| str(row.get("Utterance", "") or ""), | |
| str(row.get("Utterance", "") or ""), | |
| str(row.get("Language", "") or ""), | |
| str(row.get("Dialect", "") or ""), | |
| str(row.get("Clarification", "") or ""), | |
| str(row.get("Tone", "") or ""), | |
| audio_link, | |
| ) | |
| except Exception: | |
| return "", "", "", "", "", "", "", "" | |
| def approve_pending(timestamp, original, edited_utt, edited_lang, edited_dialect, edited_clar, edited_tone, audio_override, review_key, language_filter, dialect_filter): | |
| if not timestamp or not original: | |
| return "Select a pending row first.", refresh_pending(language_filter, dialect_filter, review_key) | |
| try: | |
| result = call_polyglot( | |
| "/admin_approve_pending", | |
| timestamp, | |
| original, | |
| edited_utt, | |
| edited_lang, | |
| edited_dialect, | |
| edited_clar, | |
| edited_tone, | |
| audio_override, | |
| review_key or "", | |
| ) | |
| return str(result), refresh_pending(language_filter, dialect_filter, review_key) | |
| except Exception as exc: | |
| return f"Approval failed: {exc}", refresh_pending(language_filter, dialect_filter, review_key) | |
| def reject_pending(timestamp, original, reason, custom_reason, review_key, language_filter, dialect_filter): | |
| if not timestamp or not original: | |
| return "Select a pending row first.", refresh_pending(language_filter, dialect_filter, review_key) | |
| try: | |
| result = call_polyglot("/admin_reject_pending", timestamp, original, reason, custom_reason, review_key or "") | |
| return str(result), refresh_pending(language_filter, dialect_filter, review_key) | |
| except Exception as exc: | |
| return f"Rejection failed: {exc}", refresh_pending(language_filter, dialect_filter, review_key) | |
| def clear_pending(review_key, language_filter, dialect_filter): | |
| try: | |
| result = call_polyglot("/admin_clear_all_pending", review_key or "") | |
| return str(result), refresh_pending(language_filter, dialect_filter, review_key) | |
| except Exception as exc: | |
| return f"Clear failed: {exc}", refresh_pending(language_filter, dialect_filter, review_key) | |
| def undo_last_admin_action(review_key, language_filter, dialect_filter): | |
| try: | |
| result = call_polyglot("/admin_undo_last_action", review_key or "") | |
| return str(result), refresh_pending(language_filter, dialect_filter, review_key) | |
| except Exception as exc: | |
| return f"Undo failed: {exc}", refresh_pending(language_filter, dialect_filter, review_key) | |
| def refresh_history(start_date, end_date, contract_filter, review_key=""): | |
| try: | |
| selected = contract_filter or ["PureBi"] | |
| data = call_polyglot("/run_filter", start_date, end_date, selected, review_key or "") | |
| return _as_dataframe( | |
| data, | |
| ["Timestamp", "Utterance", "Dialect", "Data_Origin", "Data_Approved", "Block", "TX Hash"], | |
| ) | |
| except Exception as exc: | |
| return _empty_df(["Error", "Detail"]).assign(Error=["History refresh failed"], Detail=[str(exc)]) | |
| def refresh_rejected(review_key=""): | |
| try: | |
| data = call_polyglot("/refresh_graveyard", review_key or "") | |
| return _as_dataframe(data, ["Utterance", "Dialect", "Rejection_Reason", "Rejector"]) | |
| except Exception as exc: | |
| return _empty_df(["Error", "Detail"]).assign(Error=["Rejected audit refresh failed"], Detail=[str(exc)]) | |
| def refresh_feedback(review_key=""): | |
| try: | |
| data = call_polyglot("/get_feedback_dataframe", review_key or "") | |
| return _as_dataframe(data, ["Timestamp", "Operator_ID", "Feedback_Text", "Image_Reference"]) | |
| except Exception as exc: | |
| return _empty_df(["Error", "Detail"]).assign(Error=["Feedback refresh failed"], Detail=[str(exc)]) | |
| def submit_feedback(operator_id, feedback_text, image_file, review_key=""): | |
| if not operator_id or not feedback_text: | |
| return "Operator ID and feedback text are required.", refresh_feedback(review_key) | |
| try: | |
| result = call_polyglot("/submit_feedback", operator_id, feedback_text, image_file) | |
| return str(result), refresh_feedback(review_key) | |
| except Exception as exc: | |
| return f"Feedback submit failed: {exc}", refresh_feedback(review_key) | |
| today = date.today().isoformat() | |
| with gr.Blocks(title="PureKITchat Admin Mirror") as demo: | |
| gr.Markdown("# PureKITchat Admin Mirror") | |
| admin_review_key = gr.Textbox(label="Reviewer/Admin passcode", type="password") | |
| with gr.Tabs(): | |
| with gr.Tab("Pending Audit/Approvals"): | |
| with gr.Row(): | |
| pending_language = gr.Textbox(value="All", label="Language Filter") | |
| pending_dialect = gr.Textbox(value="All", label="Dialect Filter") | |
| pending_refresh = gr.Button("Refresh Pending", variant="primary") | |
| pending_df = gr.Dataframe( | |
| value=_empty_df([ | |
| "User", "Data_Origin", "Utterance", "Language", "Dialect", | |
| "Clarification", "Clarification_Source", "Tone", "Audio", "Timestamp" | |
| ]), | |
| label="Pending submissions", | |
| interactive=False, | |
| wrap=False, | |
| ) | |
| with gr.Row(): | |
| timestamp = gr.Textbox(label="Timestamp ID", interactive=False) | |
| original_utt = gr.Textbox(label="Original Utterance", interactive=False) | |
| audio_link = gr.Markdown() | |
| with gr.Row(): | |
| edit_utt = gr.Textbox(label="Utterance") | |
| edit_lang = gr.Textbox(label="Language") | |
| edit_dialect = gr.Textbox(label="Dialect") | |
| with gr.Row(): | |
| edit_clar = gr.Textbox(label="Clarification") | |
| edit_tone = gr.Textbox(label="Tone") | |
| audio_override = gr.File(label="Optional trimmed audio override", type="filepath") | |
| with gr.Row(): | |
| approve_btn = gr.Button("Approve Selected", variant="primary") | |
| reject_reason = gr.Dropdown( | |
| ["Spam", "Audio Quality", "Dialect Mismatch", "Other"], | |
| value="Audio Quality", | |
| label="Reject Reason", | |
| ) | |
| reject_custom = gr.Textbox(label="Custom Reason") | |
| reject_btn = gr.Button("Reject Selected", variant="stop") | |
| with gr.Row(): | |
| undo_btn = gr.Button("Undo Last Approval/Rejection", variant="secondary") | |
| clear_btn = gr.Button("Sweep All Pending", variant="secondary") | |
| pending_status = gr.Textbox(label="Audit Log", interactive=False) | |
| with gr.Tab("PureChain History"): | |
| with gr.Row(): | |
| history_start = gr.Textbox(value="2020-01-01", label="Start Date") | |
| history_end = gr.Textbox(value=today, label="End Date") | |
| history_contracts = gr.CheckboxGroup( | |
| ["PureIUUY", "PureConvo", "PureVersation", "PureBi (Jun 11)", "PureBi (Jun 12)", "PureBi (Jun 13)", "PureBi"], | |
| value=["PureBi"], | |
| label="Contract Filter", | |
| ) | |
| history_refresh = gr.Button("Refresh History", variant="primary") | |
| history_df = gr.Dataframe( | |
| value=_empty_df(["Timestamp", "Utterance", "Dialect", "Data_Origin", "Data_Approved", "Block", "TX Hash"]), | |
| label="PureChain history", | |
| interactive=False, | |
| wrap=False, | |
| ) | |
| with gr.Tab("Rejected Entries Audit"): | |
| rejected_refresh = gr.Button("Refresh Rejected Entries", variant="primary") | |
| rejected_df = gr.Dataframe( | |
| value=_empty_df(["Utterance", "Dialect", "Rejection_Reason", "Rejector"]), | |
| label="Rejected entries", | |
| interactive=False, | |
| wrap=False, | |
| ) | |
| with gr.Tab("Bug Reports & Feedback"): | |
| with gr.Row(): | |
| feedback_operator = gr.Textbox(label="Operator ID") | |
| feedback_image = gr.File(label="Optional screenshot/image", type="filepath") | |
| feedback_text = gr.Textbox(label="Bug report or feedback", lines=4) | |
| with gr.Row(): | |
| feedback_submit = gr.Button("Submit Feedback", variant="primary") | |
| feedback_refresh = gr.Button("Refresh Feedback") | |
| feedback_status = gr.Textbox(label="Feedback Status", interactive=False) | |
| feedback_df = gr.Dataframe( | |
| value=_empty_df(["Timestamp", "Operator_ID", "Feedback_Text", "Image_Reference"]), | |
| label="System feedback log", | |
| interactive=False, | |
| wrap=False, | |
| ) | |
| pending_refresh.click(refresh_pending, [pending_language, pending_dialect, admin_review_key], pending_df) | |
| pending_df.select( | |
| select_pending_row, | |
| pending_df, | |
| [timestamp, original_utt, edit_utt, edit_lang, edit_dialect, edit_clar, edit_tone, audio_link], | |
| ) | |
| approve_btn.click( | |
| approve_pending, | |
| [timestamp, original_utt, edit_utt, edit_lang, edit_dialect, edit_clar, edit_tone, audio_override, admin_review_key, pending_language, pending_dialect], | |
| [pending_status, pending_df], | |
| ) | |
| reject_btn.click( | |
| reject_pending, | |
| [timestamp, original_utt, reject_reason, reject_custom, admin_review_key, pending_language, pending_dialect], | |
| [pending_status, pending_df], | |
| ) | |
| undo_btn.click(undo_last_admin_action, [admin_review_key, pending_language, pending_dialect], [pending_status, pending_df]) | |
| clear_btn.click(clear_pending, [admin_review_key, pending_language, pending_dialect], [pending_status, pending_df]) | |
| history_refresh.click(refresh_history, [history_start, history_end, history_contracts, admin_review_key], history_df) | |
| rejected_refresh.click(refresh_rejected, [admin_review_key], rejected_df) | |
| feedback_refresh.click(refresh_feedback, [admin_review_key], feedback_df) | |
| feedback_submit.click(submit_feedback, [feedback_operator, feedback_text, feedback_image, admin_review_key], [feedback_status, feedback_df]) | |
| if __name__ == "__main__": | |
| demo.launch() | |