{% extends 'eval/base.html' %} {% load static %} {% block title %}Run Detail | Eval Admin{% endblock %} {% block action_bar %} {% endblock %} {% block content %}
{# ── Tab bar ── #}
{% for tab_id, tab_label in tab_list %}
{{ tab_label }}
{% endfor %}
{# ════════════════════════════════════════════════════════ #} {# TAB 1 — Criteria Scores + Q/A #} {# ════════════════════════════════════════════════════════ #}

User Query

{{ user_input|default:"—" }}

LLM Response

{{ final_response|default:"—" }}
{% if run_breakdown.criteria_scores %} {% for s in run_breakdown.criteria_scores %}
{{ s.key }} {{ s.score }}/{{ s.max_score }}

{{ s.explanation }}

{% endfor %} {% else %}

No criteria scores available.

{% endif %}
{# ════════════════════════════════════════════════════════ #} {# TAB 2 — Trace Context #} {# ════════════════════════════════════════════════════════ #}

{{ trace_context.total_spans }} observations · total {{ trace_context.max_latency }}

{% if trace_context.tree %}
{# ── Left: observation table ── #}
Node Duration Latency
{% for node in trace_context.tree %}
{% if node.depth > 0 %}{% if node.is_last_child %}└{% else %}├{% endif %}{% endif %} {{ node.badge_label }} {{ node.name }} {% if node.cost %}{{ node.cost }}{% endif %} {% if node.tool_annotation %}→ {{ node.tool_annotation }}{% endif %}
{% if node.bar_pct > 0 %}
{% endif %}
{% if node.latency %}{{ node.latency }}{% endif %}
{% endfor %}
{# ── Right: detail viewer ── #}
{# Header #}
{# Metric cards #}
{# Tool Calls #} {# Output #} {# Empty state #}
{% else %}

No observations recorded.

{% endif %}
{# ════════════════════════════════════════════════════════ #} {# TAB 3 — Metrics #} {# ════════════════════════════════════════════════════════ #}

Cost: {{ run_breakdown.cost }} · Tokens: {{ run_breakdown.total_tokens }} · Latency: {{ run_breakdown.latency }}

Cost

{% include "eval/components/_metric_static.html" with metric_label="Total Cost" metric_value=run_breakdown.cost threshold=threshold_status.cost %} {% include "eval/components/_metric_static.html" with metric_label="Input Token Cost" metric_value=run_breakdown.cost_input threshold=threshold_status.cost_input %} {% include "eval/components/_metric_static.html" with metric_label="Output Token Cost" metric_value=run_breakdown.cost_output threshold=threshold_status.cost_output %}

Tokens

{% include "eval/components/_metric_static.html" with metric_label="Input Tokens" metric_value=run_breakdown.input_tokens threshold=threshold_status.input_tokens %} {% include "eval/components/_metric_static.html" with metric_label="Output Tokens" metric_value=run_breakdown.output_tokens threshold=threshold_status.output_tokens %} {% include "eval/components/_metric_static.html" with metric_label="Total Tokens" metric_value=run_breakdown.total_tokens threshold=threshold_status.total_tokens %}

Latency

{% include "eval/components/_metric_static.html" with metric_label="Total Latency" metric_value=run_breakdown.latency threshold=threshold_status.latency %} {% include "eval/components/_metric_static.html" with metric_label="Agent Latency" metric_value=run_breakdown.agent_latency threshold=threshold_status.agent_latency %} {% include "eval/components/_metric_static.html" with metric_label="Tool Latency" metric_value=run_breakdown.tool_latency threshold=threshold_status.tool_latency %}
{% if threshold_summary.total %}

{% if threshold_summary.all_met %}All metrics within threshold ✓{% else %}{{ threshold_summary.not_met }} metric{{ threshold_summary.not_met|pluralize }} exceeding threshold ✗{% endif %}

{{ threshold_summary.met }}/{{ threshold_summary.total }} passing

{% endif %}
{% endblock %}