feat(dashboard): página Historial con tabs ejecuciones y violaciones
Tab "Ejecuciones": tabla resumen + detalle (status, error, output, violations, traza) por trace_id. Tab "Violaciones": log filtrable por severidad. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""Página de historial de ejecuciones y log de violaciones."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import streamlit as st
|
||||
|
||||
from agentforge_dashboard.client import CoreClient
|
||||
from agentforge_dashboard.components.trace_view import render_trace
|
||||
from agentforge_dashboard.components.violation_view import render_violations
|
||||
|
||||
|
||||
@st.cache_resource
|
||||
def get_client() -> CoreClient:
|
||||
return CoreClient()
|
||||
|
||||
|
||||
client = get_client()
|
||||
st.title("📜 Historial")
|
||||
st.caption("Ejecuciones registradas y log auditable de violaciones de guardrails.")
|
||||
|
||||
tabs = st.tabs(["Ejecuciones", "Violaciones"])
|
||||
|
||||
with tabs[0]:
|
||||
executions = client.list_executions()
|
||||
if not executions:
|
||||
st.info("Aún no hay ejecuciones registradas.")
|
||||
else:
|
||||
st.dataframe(executions, hide_index=True, use_container_width=True)
|
||||
trace_ids = [e["trace_id"] for e in executions]
|
||||
selected = st.selectbox(
|
||||
"Ver detalle",
|
||||
trace_ids,
|
||||
format_func=lambda t: t[:8] + "…",
|
||||
)
|
||||
if selected:
|
||||
detail = client.get_execution(selected)
|
||||
st.markdown(f"**Status:** `{detail['status']}`")
|
||||
if detail.get("error"):
|
||||
st.error(f"Error: {detail['error']}")
|
||||
if detail.get("final_output"):
|
||||
st.subheader("Output final")
|
||||
st.json(detail["final_output"])
|
||||
render_violations(detail.get("violations", []))
|
||||
render_trace(detail.get("decision_path", []))
|
||||
|
||||
with tabs[1]:
|
||||
sev = st.selectbox("Filtrar severidad", ["(todas)", "info", "warning", "block"])
|
||||
filter_kwargs = {} if sev == "(todas)" else {"severity": sev}
|
||||
violations = client.list_violations(**filter_kwargs)
|
||||
if not violations:
|
||||
st.success("Sin violaciones registradas con ese filtro.")
|
||||
else:
|
||||
st.dataframe(violations, hide_index=True, use_container_width=True)
|
||||
Reference in New Issue
Block a user