""" metrics.py — Rolling in-memory metrics for the dashboard panel. Stores the last 50 query metrics in a deque. In production, push these to InfluxDB, Prometheus, or BigQuery. """ import logging from collections import deque from src.utils import safe_divide logger = logging.getLogger("enterprise-rag.metrics") _history = deque(maxlen=50) def record_query_metrics( retrieval_latency_ms: float, generation_latency_ms: float, prompt_tokens: int, response_tokens: int, eval_scores: dict, fallback_used: bool, ): """Append one query's metrics to the rolling history.""" _history.append({ "retrieval_ms": retrieval_latency_ms, "generation_ms": generation_latency_ms, "total_ms": retrieval_latency_ms + generation_latency_ms, "prompt_tokens": prompt_tokens, "response_tokens": response_tokens, "total_tokens": prompt_tokens + response_tokens, "eval_overall": eval_scores.get("overall", 0), "fallback": fallback_used, }) def get_metrics_summary() -> str: """Build formatted metrics text for the Gradio panel.""" if not _history: return "No queries processed yet." latest = _history[-1] h = list(_history) n = len(h) avg_retrieval = safe_divide(sum(m["retrieval_ms"] for m in h), n) avg_generation = safe_divide(sum(m["generation_ms"] for m in h), n) avg_total = safe_divide(sum(m["total_ms"] for m in h), n) avg_tokens = safe_divide(sum(m["total_tokens"] for m in h), n) avg_eval = safe_divide(sum(m["eval_overall"] for m in h), n) fallback_pct = safe_divide(sum(1 for m in h if m["fallback"]), n) * 100 return ( f"**Latest Query**\n" f"- Retrieval latency: `{latest['retrieval_ms']:.0f}ms`\n" f"- Generation latency: `{latest['generation_ms']:.0f}ms`\n" f"- Total latency: `{latest['total_ms']:.0f}ms`\n" f"- Tokens used: `{latest['total_tokens']}`\n" f"- Eval score: `{latest['eval_overall']:.3f}`\n\n" f"**Rolling Average ({n} queries)**\n" f"- Avg retrieval: `{avg_retrieval:.0f}ms`\n" f"- Avg generation: `{avg_generation:.0f}ms`\n" f"- Avg total: `{avg_total:.0f}ms`\n" f"- Avg tokens/query: `{avg_tokens:.0f}`\n" f"- Avg eval score: `{avg_eval:.3f}`\n" f"- Fallback rate: `{fallback_pct:.1f}%`" )