"""Onglet Administration : métriques du RAG (volume, latence, langues, abstention).""" from __future__ import annotations import hmac import gradio as gr from config import settings from core.metrics.logger import fetch_recent, summary_metrics from core.optimization.cache import answer_cache, embedding_cache from core.retrieval.vector_store import get_vector_store from core.ui.components import ( _e, render_admin_dashboard, render_admin_denied, render_admin_placeholder, ) from core.ui.i18n import t DENIED = "__denied__" def _check_password(password: str) -> bool: if not settings.admin_password: return True # aucun mot de passe configuré -> accès libre (démo) return hmac.compare_digest((password or "").encode(), settings.admin_password.encode()) def collect_dashboard_data() -> dict: store = get_vector_store() return { "metrics": summary_metrics(), "corpus": store.corpus_stats(), "answer_cache": answer_cache.stats(), "embedding_cache": embedding_cache.stats(), "recent": fetch_recent(limit=25), } def render_admin_body(lang: str, state) -> str: if state is None: return render_admin_placeholder(lang) if state == DENIED: return render_admin_denied(lang) + render_admin_placeholder(lang) return render_admin_dashboard(lang, state) def refresh_dashboard(password: str, ui_lang: str): if not _check_password(password): return render_admin_body(ui_lang, DENIED), DENIED data = collect_dashboard_data() return render_admin_body(ui_lang, data), data def render_admin_head(lang: str) -> str: return ( f'

{_e(t(lang, "admin_title"))}

' f'

{_e(t(lang, "admin_desc"))}

' ) def admin_i18n_updates(lang: str, state) -> list: return [ render_admin_head(lang), gr.update(label=t(lang, "admin_password"), placeholder=t(lang, "admin_password_ph")), gr.update(value=t(lang, "refresh")), render_admin_body(lang, state), ] def build_admin_tab(lang: str, ui_lang_dd: gr.Dropdown) -> dict: admin_state = gr.State(None) head = gr.HTML(render_admin_head(lang), elem_classes=["pg-html-flush"]) with gr.Row(elem_id="pg-admin-bar", equal_height=True): password_box = gr.Textbox( label=t(lang, "admin_password"), placeholder=t(lang, "admin_password_ph"), type="password", scale=4, ) refresh_btn = gr.Button(t(lang, "refresh"), variant="primary", scale=1, min_width=140) body = gr.HTML(render_admin_body(lang, None), elem_classes=["pg-html-flush"]) refresh_btn.click(refresh_dashboard, inputs=[password_box, ui_lang_dd], outputs=[body, admin_state]) password_box.submit(refresh_dashboard, inputs=[password_box, ui_lang_dd], outputs=[body, admin_state]) return {"state": admin_state, "i18n_outputs": [head, password_box, refresh_btn, body]}