{% from "_event_macros.html" import badge_for, meta_for, copyable, detail_panel with context %}

Session {{ session_id }}

{% if ai_title %}
{{ ai_title }}
{% endif %}
{% if agent %}{{ agent }}{% endif %} {% if item %} · item #{{ item.id }} {{ item.status.value }} {% endif %} {% if item and item.handler %} · handler {{ item.handler }}{% if item.handler_kind %} {{ item.handler_kind }}{% endif %} {% endif %} {% if run_id and run_session_count and run_session_count > 1 %} · part of run with {{ run_session_count }} sessions {% endif %}
{% if stats.model %} {{ stats.model }} {% endif %} {{ stats.turns }} turns {{ stats.wall_ms|fmt_duration or '—' }} {{ stats.input_tokens|fmt_tokens or '0' }} in / {{ stats.output_tokens|fmt_tokens or '0' }} out {% if stats.estimated_cost_usd is not none %} {{ stats.estimated_cost_usd|fmt_cost }} {% endif %} {{ stats.raw_count }} lines
{# Tools-used chips moved into a filter dropdown next to the Events dropdown (see the .tabs row below) for visual consistency with the other filter and to keep the area below the session-head clean. #} {% if invocation %}
Invocation {% if invocation.permission_mode %} permissions {{ invocation.permission_mode }} {% endif %} {% if invocation.sdk_version %} sdk {{ invocation.sdk_version }} {% endif %} {% if invocation.entrypoint %} entrypoint {{ invocation.entrypoint }} {% endif %} {% if invocation.mcp_servers %} mcp {{ invocation.mcp_servers | length }} {% endif %}
{% if invocation.cwd %}
cwd{{ invocation.cwd }}
{% endif %} {% if invocation.mcp_servers %}
mcp servers
{% for name in invocation.mcp_servers %} {{ name }} {% endfor %}
{% if invocation.mcp_instructions %}
show MCP instructions {% for mcp in invocation.mcp_instructions %}
{{ mcp.name }}
{{ mcp.preview }}
{% endfor %}
{% endif %} {% endif %}
{% endif %}
Conversation Debug ({{ debug | length }}) Analysis{% if session_analysis and not session_analysis.extraction_skipped_reason %} ✓{% endif %} {% if active_tab == 'debug' %} {% if tool_usage %}
All tools
{% for t in tool_usage %} {% endfor %}
{% endif %} {% if event_kinds %}
All events
{% for kind in event_kinds %} {% endfor %}
{% endif %} {% endif %}
{% if active_tab == "conversation" %} {% if conversation %}
{% for ev in conversation %}
{% if ev.kind == 'thinking' %}
Thinking
{% endif %}
{{ ev.text|markdown }}
{% if ev.ts and ev.kind != 'thinking' %}
{{ ev.ts|fmt_hm }}
{% endif %}
{% endfor %}
{% else %}

No conversation messages in this session.

{% endif %} {% elif active_tab == "analysis" %}
{% if not session_analysis %} {% if analysis_pending %}

Analysis in progress…

The agent is producing a grounded post-mortem in its own project dir (Sonnet typically takes 30–90 s). This page auto-refreshes when the analysis lands. If it doesn't show up after a few minutes, the agent either skipped (trivial session) or the analyser crashed — check the agent logs, or turn auto_analyze off and trigger a manual run.

{% else %}

No post-mortem analysis for this session yet.

Run the hub-side trace-only analyser (Haiku, no source access) for a quick narrative, or trigger from the agent's repo with waffle analyze {{ session_id[:8] }} --agent-source ... for a grounded one. Trivial sessions (under 5 turns AND under $0.05) are skipped by default; use Force run for those.

{% endif %} {% elif session_analysis.extraction_skipped_reason %}

Skipped: {{ session_analysis.extraction_skipped_reason }}

The skip-heuristic kicked in because this session is too small to be worth the extraction cost. Force-run to override.

{% else %} {% set a = session_analysis.analysis or {} %} {% set cf = a.get('cost_counterfactual_estimate') %} {% set suggestions = a.get('improvement_suggestions') or [] %}
Analysed {{ session_analysis.updated_at | time_span if session_analysis.updated_at else '—' }} {% if session_analysis.extraction_model %} with {{ session_analysis.extraction_model }} {% endif %}
Chronology

{{ a.get('chronology') or '(no chronology returned)' }}

Cost
{% if cf %}{% endif %} {% if cf %} {% endif %} {% if cf %} {% endif %} {% if session_analysis.model %} {% endif %}
ActualOptimalΔ
Turns {{ session_analysis.turns }}{{ cf.get('turns', '—') }} {% set t_diff = (session_analysis.turns or 0) - (cf.get('turns') or 0) %} {% if t_diff > 0 %}-{{ t_diff }}{% else %}—{% endif %}
Cost {% if session_analysis.cost_actual_usd is not none %}${{ '%.4f' % session_analysis.cost_actual_usd }}{% else %}—{% endif %} {% if cf.get('cost_usd') is not none %}${{ '%.4f' % cf.get('cost_usd') }}{% else %}—{% endif %} {% if session_analysis.savings_potential_usd is not none %}${{ '%.4f' % session_analysis.savings_potential_usd }}{% else %}—{% endif %}
Tokens in / out {{ session_analysis.input_tokens }} / {{ session_analysis.output_tokens }}
Model {{ session_analysis.model }}
{% if cf and cf.get('explanation') %}

{{ cf.get('explanation') }}

{% endif %}
{% if a.get('counterfactual_summary') %}
Counterfactual

{{ a.get('counterfactual_summary') }}

{% endif %} {% if suggestions %}
Improvement suggestions ({{ suggestions | length }})
    {% for s in suggestions %}
  1. {{ s.get('estimated_impact', '?') }} {{ s.get('category', '?') }} {{ s.get('title') or '(untitled)' }}
    {% if s.get('description') %}

    {{ s.get('description') }}

    {% endif %}
  2. {% endfor %}
{% endif %}
{% endif %}
{% else %} {% set events = debug %} {% if events %}
{% for ev in events %} {% set did = loop.index0 %}
{{ badge_for(ev, active_tab) }} {{ ev.label }} {{ meta_for(ev) }}
{% if ev.subagent_trace %} {% set sub = ev.subagent_trace %} {% set sub_events = sub.debug %}
{{ sub.agent_id }} · {{ sub.stats.turns }} turn{{ '' if sub.stats.turns == 1 else 's' }} · {{ sub.stats.input_tokens|fmt_tokens or '0' }} in / {{ sub.stats.output_tokens|fmt_tokens or '0' }} out {% if sub.stats.estimated_cost_usd is not none %} · {{ sub.stats.estimated_cost_usd|fmt_cost }} {% endif %}
{% for sev in sub_events %} {% set sdid = 'sub-' ~ did ~ '-' ~ loop.index0 %}
{{ badge_for(sev, active_tab) }} {{ sev.label }} {{ meta_for(sev) }}
{% endfor %}
{% endif %} {% endfor %}
Select an event to inspect its data.

Tip: use j / k to navigate, Esc to close.
{% for ev in events %} {% set did = loop.index0 %} {{ detail_panel(ev, did) }} {% if ev.subagent_trace %} {% set sub = ev.subagent_trace %} {% for sev in sub.debug %} {{ detail_panel(sev, 'sub-' ~ did ~ '-' ~ loop.index0, results=sub.results_by_id) }} {% endfor %} {% endif %} {% endfor %}
{% else %}

No events in this view.

{% endif %} {% if unmapped_subagents %}

Unmapped subagents ({{ unmapped_subagents | length }})

{% for sub in unmapped_subagents %} {% set sub_events = sub.debug %}
SUBAGENT {{ sub.agent_id }} · {{ sub.stats.turns }} turn{{ '' if sub.stats.turns == 1 else 's' }} · {{ sub.stats.input_tokens|fmt_tokens or '0' }} in / {{ sub.stats.output_tokens|fmt_tokens or '0' }} out {% if sub.stats.estimated_cost_usd is not none %} · {{ sub.stats.estimated_cost_usd|fmt_cost }} {% endif %} · {{ sub_events | length }} event{{ '' if sub_events|length == 1 else 's' }}
{% for ev in sub_events %}
{{ badge_for(ev, active_tab) }} {{ ev.label }} {{ meta_for(ev) }}
{% endfor %}
{% endfor %}
{% endif %} {% endif %}